diff --git a/.github/workflows/publish-python.yml b/.github/workflows/publish-python.yml index acffdb9..e6c02f1 100644 --- a/.github/workflows/publish-python.yml +++ b/.github/workflows/publish-python.yml @@ -13,6 +13,7 @@ env: CARGO_INCREMENTAL: "0" MATURIN_VERSION: "1.14.1" PYTHON_VERSION: "3.12" + TWINE_VERSION: "6.2.0" UV_VERSION: "0.11.24" jobs: @@ -65,6 +66,9 @@ jobs: - name: Build Python wheel run: uvx maturin==${{ env.MATURIN_VERSION }} build --release --manifest-path bindings/python/Cargo.toml --interpreter python --out dist + - name: Check Python wheel metadata + run: uvx twine==${{ env.TWINE_VERSION }} check dist/*.whl + - name: Smoke-test Python wheel run: uv run --isolated --with "$(find dist -name '*.whl' -print -quit)" python -c "from smolfs import SmolFS, SmolFSError, doctor; assert 'storage_backend' in doctor()" @@ -107,6 +111,9 @@ jobs: - name: Build sdist run: uvx maturin==${{ env.MATURIN_VERSION }} sdist --manifest-path bindings/python/Cargo.toml --out dist + - name: Check sdist metadata + run: uvx twine==${{ env.TWINE_VERSION }} check dist/*.tar.gz + - name: Smoke-test source distribution run: uv run --isolated --with "$(find dist -name '*.tar.gz' -print -quit)" python -c "from smolfs import SmolFS, SmolFSError, doctor; assert 'storage_backend' in doctor()" diff --git a/bindings/python/README.md b/bindings/python/README.md new file mode 100644 index 0000000..26f17d3 --- /dev/null +++ b/bindings/python/README.md @@ -0,0 +1,96 @@ +# SmolFS Python SDK + +SmolFS gives Python agents a workspace folder that can survive after the agent +process stops. You can create a volume, mount it like a normal directory, write +files into it, flush important changes, unmount it, and mount the same files +again later. + +The Python package is a native SDK over the same Rust core as the `smolfs` +command. It is useful when an agent runner or automation service wants to manage +workspace volumes without shelling out for every operation. + +## Install + +Install the Python SDK with `uv`: + +```bash +uv add smolfs +``` + +Mounting volumes also needs SmolFS' managed storage backend on the machine. The +installer sets up both the CLI and backend: + +```bash +curl -fsSL https://raw.githubusercontent.com/CelestoAI/smolfs/main/scripts/install.sh | SMOLFS_INSTALL_PYTHON=1 sh +``` + +If you only need the Python package inside an existing project or virtual +environment, `uv add smolfs` is enough. + +## Quickstart + +Start with a local development volume: + +```python +from pathlib import Path + +from smolfs import SmolFS, doctor + +report = doctor() +if not report["storage_backend"]["found"] or not report["mount_support"]["found"]: + raise RuntimeError(f"SmolFS is not ready: {report}") + +fs = SmolFS.from_env() +volume = fs.ensure_volume("demo", dev=True) +mount = fs.mount(volume.name, "./workspace") + +workspace = Path(mount.mountpoint) +(workspace / "hello.txt").write_text("hello from SmolFS\n") + +try: + fs.flush(volume.name) +finally: + fs.unmount(volume.name) +``` + +`dev=True` creates a local-only volume. It is the easiest way to test SmolFS on a +single machine before connecting shared metadata and object storage. + +## Cloud Volumes + +Cloud volumes use the same API with explicit metadata and object storage +settings: + +```python +from smolfs import SmolFS + +fs = SmolFS.from_env() +fs.ensure_volume( + "agent-workspace", + metadata="redis://localhost:6379/1", + storage="s3", + bucket="https://my-bucket.s3.us-east-2.amazonaws.com", +) +``` + +Keep storage credentials in the environment used by SmolFS. Do not print them in +logs or store them in source files. + +## API Overview + +- `doctor()` checks whether the machine can create and mount volumes. +- `SmolFS.from_env()` creates a client using `SMOLFS_HOME` and the current + environment. +- `ensure_volume(...)` creates a volume if it does not exist and returns the + existing volume if it does. +- `init(...)` creates a new volume. +- `mount(name, path)` mounts a volume at a local directory. +- `flush(name)` asks SmolFS to sync important writes. +- `unmount(name)` unmounts a mounted volume. +- `status(name=None)` lists known volumes and mountpoints. + +## Links + +- Repository: https://github.com/CelestoAI/smolfs +- Issues: https://github.com/CelestoAI/smolfs/issues +- CLI installer: https://raw.githubusercontent.com/CelestoAI/smolfs/main/scripts/install.sh diff --git a/bindings/python/pyproject.toml b/bindings/python/pyproject.toml index 6519069..894dc90 100644 --- a/bindings/python/pyproject.toml +++ b/bindings/python/pyproject.toml @@ -5,13 +5,24 @@ build-backend = "maturin" [project] name = "smolfs" version = "0.1.0" -description = "Python bindings for SmolFS" +description = "Durable workspace folders for Python agents" +readme = "README.md" requires-python = ">=3.9" license = "Apache-2.0" authors = [{ name = "Celesto AI" }] -keywords = ["agents", "filesystem", "object-storage", "smolfs"] +keywords = ["agents", "filesystem", "object-storage", "persistent-workspaces", "smolfs"] classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS", + "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Rust", "Topic :: System :: Filesystems", "Topic :: Software Development :: Libraries :: Python Modules",