byoc-storage
Python SDK for BYOC (Bring Your Own Cloud): one storage API for Google Drive, Nextcloud, and S3-compatible clouds, so files live in accounts the end user already owns.
Part of the BYOC monorepo. Peer implementation of
@byoc/coreon npm, verified interoperable by an automated cross-SDK suite.
Why
Rather than paying to host every file in one central bucket, BYOC lets an application read and write storage the end user already owns: a personal Google Drive, a company Nextcloud, an organization's own R2 bucket.
FastAPI / Django / Celery
│
├── PostgreSQL → users, jobs, metadata pointers
│
└── byoc → the actual PDFs, images, audio, model artifacts
│
└── the user's own cloud
Use Postgres for application data. Use BYOC for the user's files.
Install
pip install byoc-storage
The distribution is named byoc-storage because byoc on PyPI belongs to an
unrelated CLI framework. The import name is still byoc:
import byoc
If you also depend on the unrelated
byocCLI framework, do not install both into the same environment: they share thebyocimport name and will shadow each other.
Usage
Start with no credentials at all. LocalFileSystemProvider and
MemoryProvider are bundled, need no account and no network, and behave like
every other provider:
from byoc import AsyncBYOC, LocalFileSystemProvider
storage = AsyncBYOC(provider=LocalFileSystemProvider("./storage"))
async with storage:
await storage.write_text("documents/welcome.md", "# Hello from BYOC!")
content = await storage.read_text("documents/welcome.md")
Swap in S3CompatibleProvider, WebDAVProvider, or GoogleDriveProvider and
none of the calling code changes:
import os
from byoc import AsyncBYOC
from byoc.providers.s3 import S3CompatibleProvider
storage = AsyncBYOC(
provider=S3CompatibleProvider(
endpoint="https://<account_id>.r2.cloudflarestorage.com",
bucket="user-assets",
region="auto",
access_key_id=os.environ["R2_ACCESS_KEY_ID"],
secret_access_key=os.environ["R2_SECRET_ACCESS_KEY"],
)
)
async with storage:
await storage.write_text("documents/welcome.md", "# Hello from BYOC!")
content = await storage.read_text("documents/welcome.md")
Testing without a cloud
MemoryProvider is a test double that behaves like a real provider, so your
tests exercise the same code path production does:
from byoc import AsyncBYOC, MemoryProvider
async def test_report_is_archived():
provider = MemoryProvider()
await archive_report(AsyncBYOC(provider=provider), report)
assert provider.snapshot() == {"reports/q3.pdf": b"..."}
Like S3, it models a flat object store and reports folders=False. If your
production provider has real folders, use LocalFileSystemProvider against a
tmp_path instead.
Multiple providers and migration
storage = AsyncBYOC(providers=[drive, r2, nextcloud], default_provider_id="s3-compatible")
storage.use_provider("webdav")
await storage.write_bytes("images/banner.png", data)
report = await storage.migrate(
source="s3-compatible",
target="webdav",
paths=["documents/report.pdf"],
on_progress=lambda p: print(f"{p.current_file} ({p.percentage}%)"),
)
report.files_partial counts files that reached the target but whose source
cleanup failed. The transfer is done, so retrying those would re-upload for
nothing.
Async only for now. A synchronous facade for Celery, Django, and scripts is planned but not yet implemented; use
asyncio.run()in the meantime.
Google Drive
Drive needs a Google Cloud OAuth client. See Google Drive OAuth Setup, then verify your setup with:
.venv/bin/python scripts/validate_gdrive_live.py
Cross-SDK compatibility
This SDK and the TypeScript SDK are peer implementations of the same contract. Both run against the shared conformance vectors in spec/fixtures, so a file written by a Next.js frontend can be read by a FastAPI backend, including client-side encrypted files, whose envelope format is byte-identical across both.
Development
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest # unit + conformance suite
mypy src # strict type checking
ruff check . # lint
Without activating, call the venv binaries directly: .venv/bin/pytest,
.venv/bin/mypy src, .venv/bin/ruff check .
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file byoc_storage-0.4.0.tar.gz.
File metadata
- Download URL: byoc_storage-0.4.0.tar.gz
- Upload date:
- Size: 95.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
347575288dc3d230588ff6acf71dde4d6a0e97765c003312822cda758148e396
|
|
| MD5 |
c513691fa65a5728de792bbf6a5b35e7
|
|
| BLAKE2b-256 |
1dc67c31afbbae91f09ab10b2a0ce8aa440d563cabef95bc2a98f99737a5047b
|
File details
Details for the file byoc_storage-0.4.0-py3-none-any.whl.
File metadata
- Download URL: byoc_storage-0.4.0-py3-none-any.whl
- Upload date:
- Size: 77.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
657ee76d148e9a22c3a1b6a25fd0758a4830f5ac07d8247077b5910416c4c43d
|
|
| MD5 |
efb7e3e2c4a8ef2cc0c6ad692bf7222c
|
|
| BLAKE2b-256 |
f3e920430498ef5f685be9b6d35fa8805f7c74989ffdb5cf623f1b5a21629b04
|