Read and update files
Configure your key and drive as shown in the quickstart. File IDs identify documents; paths and filenames help you find them.
Find a file
List the drive, following next_cursor until it is empty:
import os
from flashdrive import Flashdrive
with Flashdrive(drive_id=os.environ["FLASHDRIVE_DRIVE_ID"]) as client:
cursor = None
while True:
page = client.files.list(limit=100, cursor=cursor)
for file in page.files:
print(file.document_id, file.path, file.revision)
cursor = page.next_cursor
if cursor is None:
breakUse client.files.glob("**/*.md") for matching paths. Pass folder_id= to restrict a listing or glob to a folder.
Read text or download the original
This reads up to 50 lines, starting at line 1:
import os
from flashdrive import Flashdrive
document_id = input("Document ID: ").strip()
with Flashdrive(drive_id=os.environ["FLASHDRIVE_DRIVE_ID"]) as client:
text = client.files.read(document_id, start_line=1, line_count=50)
print(text.text)
print("Revision:", text.revision, "Next line:", text.next_line)If next_line is set, request the next page with that starting line and the same revision=. This avoids combining text from different revisions. Check line_truncated when a line is too large for one response; byte-range reads use offset= and length= instead.
For an original file, download it to a new local path:
import os
from flashdrive import Flashdrive
document_id = input("Document ID: ").strip()
with Flashdrive(drive_id=os.environ["FLASHDRIVE_DRIVE_ID"]) as client:
size = client.files.download(document_id, "downloaded-handbook.md")
print("Downloaded bytes:", size)Choose the destination deliberately; a completed download replaces that local file. Downloads can resume their temporary .part file when the source version is unchanged. For a small binary range, use client.files.read_bytes(document_id, offset=0, length=1024).
Edit without overwriting someone else’s work
Read the file first, then send the revision you observed. The following replaces one exact phrase in a text file:
import os
from uuid import uuid4
from flashdrive import Flashdrive, PreconditionFailedError
document_id = input("Document ID: ").strip()
operation_key = str(uuid4())
with Flashdrive(drive_id=os.environ["FLASHDRIVE_DRIVE_ID"]) as client:
observed = client.files.read(document_id)
try:
change = client.files.edit_text(
document_id,
[{"old": "Draft policy", "new": "Approved policy"}],
revision=observed.revision,
idempotency_key=operation_key,
)
print("Accepted change:", change.upload_id, change.operation_id)
except PreconditionFailedError:
print("The file changed. Read it again and review the edit before retrying.")
raiseEach old string must occur exactly once in the file as earlier edits leave it. An unmatched or ambiguous edit writes nothing. Keep the original revision and operation key when retrying the same request. After a revision conflict, read and reconcile the changes before submitting a new operation.
Replace a complete text file
Use documents.get() to observe the revision, then replace_text() to replace its content while keeping its document identity:
import os
from pathlib import Path
from uuid import uuid4
from flashdrive import Flashdrive
document_id = input("Document ID: ").strip()
replacement = Path("revised-handbook.md").read_text(encoding="utf-8")
with Flashdrive(drive_id=os.environ["FLASHDRIVE_DRIVE_ID"]) as client:
observed = client.documents.get(document_id)
receipt = client.documents.replace_text(
document_id,
replacement,
expected_revision=observed.latest_revision,
idempotency_key=str(uuid4()),
)
print("Processing operation:", receipt.operation_id)replace_text() accepts nonempty UTF-8 text up to 2,000,000 bytes. Use documents.replace_file(document_id, path, expected_revision=...) for a file replacement. Rename, move, and delete methods also require the revision from an earlier read. An accepted change can still be processing; use operations.get() to check its status.
These API writes check revisions; they do not merge CSV rows or SQLite databases. See file workflows for collaborative formats.