Files and folders
Upload, find, download, version and share files in Object Storage from Python.
(DataObject Storage) keeps any file (PDFs, images, exports, raw data) in folders, with every earlier version. Use nexus.folders for folders and their files, and nexus.files to find single files anywhere.
File bytes travel directly between your machine and storage through short-lived links, never through the API. You only see what your access reaches.
Before you start
- Folder access decides what you can do: read, write or manage. Owners and admins reach everything.
- Every example assumes
nexus = Nexus.connect().
Open a folder
Folders are addressed by path, the way you see them in Object Storage:
from klarety import NotFoundError
try:
reports = nexus.folders.at("reports/q3")
except NotFoundError:
reports = nexus.folders.create("reports").mkdir("q3")nexus.folders.list()lists the folders you start from.nexus.folders.create(name)makes a top-level folder that you manage.folder.mkdir(name)makes a folder inside another and returns it.folder.ensure(["2026/11", "2026/12"])makes any missing folders along each path and returns each path's folder ID.nexus.folders.home(project_id)is a 's own folder.
Upload a file
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() accepts a path or raw bytes, and an optional name for the file in the folder. It waits until the file is recorded (up to a minute) and returns its details. Reusing a name keeps the old file as an earlier version.
For a burst of uploads, pass wait=False: the upload is only accepted, and the file appears within seconds.
List, find and download
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 folderfind() returns newest first, page by page, and can filter by folder, project, uploaded_by, type, extension and upload or capture dates. For a large file, use download() rather than open().
Share a link
url = nexus.files.link(file_id, expires_in_seconds=3600, preview=True)A link lasts five minutes unless you ask for longer, up to one hour. preview=True opens the file in a browser instead of downloading it.
Versions, moves and the trash
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)Folders work the same way: folder.rename(), folder.move(), folder.delete() (with everything inside) and folder.restore().
Give access to a folder
print(folder.access()) # who reaches it, and which folder that comes from
folder.grant("person", user_id, "read")
folder.revoke("person", user_id)grant() takes the kind of principal (person, project or org for the whole ), its ID and a level: read, write or manage. A folder follows its parent's access until you call folder.own_access(), and folder.follow_parent() goes back.
To let a project reach a folder, link it: nexus.folders.link(project_id, folder) (read only unless you pass level="write"). nexus.folders.unlink() removes the link and keeps the folder.
Turn files into a table
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"])A watch loads each new file in the folder into the once. To stream events from your app, folder.send_events(events) writes them as JSON Lines files for the watch to load. See Ingest data for modes and keys.
Follow what changed
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 sinceKeep the cursor between runs to process each change once.
What can go wrong
| Exception | Cause | What to do |
|---|---|---|
NotFoundError | The path does not exist, or you cannot reach it. | Check the path as Object Storage shows it. |
RefusedError | You lack the access level, or the file is larger than your plan allows. | Ask for access, or connect the bucket it lives in. |
ConflictError | The folder or file changed while you worked on it. | Read it again, then retry. |
Next steps
- Ingest data to load files into tables.
- Connections to read files that stay in your own bucket.
- Limits and rate limits for upload size and undelete window.