# 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.