# Archivos y carpetas El Almacenamiento de objetos () guarda cualquier archivo (PDF, imágenes, exportaciones, datos en bruto) en carpetas, con cada versión anterior. Use `nexus.folders` para carpetas y sus archivos, y `nexus.files` para buscar archivos sueltos donde estén. Los bytes viajan directo entre su equipo y el almacenamiento por enlaces de corta duración, nunca por la API. Usted solo ve lo que alcanza su acceso. ## Antes de empezar [#antes-de-empezar] - El acceso a la carpeta decide qué puede hacer: **read** (leer), **write** (escribir) o **manage** (administrar). Los propietarios y administradores llegan a todo. - Todos los ejemplos suponen `nexus = Nexus.connect()`. ## Abra una carpeta [#abra-una-carpeta] Las carpetas se indican por ruta, como las ve en el Almacenamiento de objetos: ```python from klarety import NotFoundError try: reports = nexus.folders.at("reports/q3") except NotFoundError: reports = nexus.folders.create("reports").mkdir("q3") ``` - `nexus.folders.list()` lista las carpetas desde las que usted parte. - `nexus.folders.create(name)` crea una carpeta de primer nivel que usted administra. - `folder.mkdir(name)` crea una carpeta dentro de otra y la devuelve. - `folder.ensure(["2026/11", "2026/12"])` crea las carpetas que falten en cada ruta y devuelve el ID de carpeta de cada una. - `nexus.folders.home(project_id)` es la carpeta propia de un proyecto. ## Suba un archivo [#suba-un-archivo] ```python title="upload_report.py" from klarety import Nexus, RefusedError with Nexus.connect() as nexus: folder = nexus.folders.at("reports/q3") try: saved = folder.upload("q3-summary.pdf") except RefusedError as refused: raise SystemExit(f"Upload refused: {refused}") print(saved["file_id"], saved["version"]) ``` `upload()` acepta una ruta o `bytes`, y un `name` opcional para el archivo en la carpeta. Espera hasta que el archivo quede registrado (hasta un minuto) y devuelve sus datos. Reutilizar un nombre conserva el archivo anterior como versión previa. Para una ráfaga de subidas, pase `wait=False`: la subida solo se acepta, y el archivo aparece en segundos. ## Liste, busque y descargue [#liste-busque-y-descargue] ```python for entry in folder.list(): # folders first, then files print(entry["kind"], entry["name"]) for found in nexus.files.find("invoice"): print(found["name"]) nexus.files.download(file_id, "local-copy.pdf") # streams to disk data = nexus.files.open(file_id) # whole file in memory folder.download("./q3") # every file directly in the folder ``` `find()` devuelve primero lo más reciente, página por página, y puede filtrar por `folder`, `project`, `uploaded_by`, `type`, `extension` y fechas de subida o captura. Para un archivo grande, use `download()` en vez de `open()`. ### Comparta un enlace [#comparta-un-enlace] ```python url = nexus.files.link(file_id, expires_in_seconds=3600, preview=True) ``` Un enlace dura cinco minutos salvo que pida más, hasta una hora. `preview=True` abre el archivo en el navegador en vez de descargarlo. ## Versiones, movimientos y la papelera [#versiones-movimientos-y-la-papelera] ```python nexus.files.versions(file_id) nexus.files.restore_version(file_id, 2) nexus.files.update(file_id, name="q3-final.pdf", tags=["finance"], description="Board pack") nexus.files.move(file_id, nexus.folders.at("archive")) nexus.files.delete(file_id) # restorable for your plan's undelete window nexus.files.restore(file_id) ``` Las carpetas funcionan igual: `folder.rename()`, `folder.move()`, `folder.delete()` (con todo su contenido) y `folder.restore()`. ## Dé acceso a una carpeta [#dé-acceso-a-una-carpeta] ```python print(folder.access()) # who reaches it, and which folder that comes from folder.grant("person", user_id, "read") folder.revoke("person", user_id) ``` `grant()` recibe el tipo de destinatario (`person`, `project` u `org` para todo el espacio de trabajo), su ID y un nivel: `read`, `write` o `manage`. Una carpeta sigue el acceso de su carpeta superior hasta que llame a `folder.own_access()`, y `folder.follow_parent()` lo vuelve a heredar. Para que un proyecto llegue a una carpeta, vincúlela: `nexus.folders.link(project_id, folder)` (solo lectura salvo que pase `level="write"`). `nexus.folders.unlink()` quita el vínculo y conserva la carpeta. ## Convierta archivos en una tabla [#convierta-archivos-en-una-tabla] ```python run = folder.load(into="daily_exports", mode="append") # every file in the folder, now watch = folder.watch(into="daily_exports", mode="append") # each new file, from now on folder.unwatch(watch["watch_id"]) ``` Una vigilancia carga una vez en la tabla cada archivo nuevo de la carpeta. Para enviar eventos desde su app, `folder.send_events(events)` los escribe como archivos JSON Lines que la vigilancia carga. Vea [Cargar datos](/docs/es/developers/ingest) para modos y claves. ## Siga qué cambió [#siga-qué-cambió] ```python for event in nexus.files.activity(folder=folder.folder_id): print(event) events, cursor = nexus.files.changes() # every change, oldest first events, cursor = nexus.files.changes(cursor) # only what changed since ``` Guarde el cursor entre ejecuciones para procesar cada cambio una sola vez. ## Qué puede salir mal [#qué-puede-salir-mal] | Excepción | Causa | Qué hacer | | --- | --- | --- | | `NotFoundError` | La ruta no existe, o no puede llegar a ella. | Revise la ruta como la muestra el Almacenamiento de objetos. | | `RefusedError` | No tiene el nivel de acceso, o el archivo supera lo que permite su plan. | Pida acceso, o conecte el bucket donde está. | | `ConflictError` | La carpeta o el archivo cambió mientras trabajaba. | Léalo de nuevo y reintente. | ## Próximos pasos [#próximos-pasos] - [Cargar datos](/docs/es/developers/ingest) para cargar archivos en tablas. - [Conexiones](/docs/es/developers/connections) para leer archivos que se quedan en su propio bucket. - [Límites y límites de solicitudes](/docs/es/developers/limits) para el tamaño de subida y el periodo de recuperación.