# Python quickstart
This is a ~60-second round-trip with **no cloud account and no setup**: snapshot
a directory, push it to a **local** `file://` store, pull it back somewhere else,
and confirm the snapshot ID matches. Snapshot IDs are 64-character lowercase hex
BLAKE3 digests, computed by the same Rust core the CLI uses — so the ID you get
in Python is bit-identical to the CLI and every other binding.
## 1. Install
Install the prebuilt wheel from PyPI (see [Install](/install/python/) for
platform detail):
```sh
pip install snapdir
```
## 2. Snapshot + push
All I/O-bound operations are `async`. Compute the content-addressed ID for a
directory with `id` (no store I/O), then `push` it to a local `file://` store,
which stages the snapshot and uploads it, returning the same 64-hex ID:
```python
import asyncio
import os
import snapdir
from snapdir import StoreUri
async def main() -> None:
src = "./demo"
store = StoreUri(f"file://{os.getcwd()}/store")
snap_id = await snapdir.id(src)
print(snap_id) # 64-char lowercase hex, e.g.
pushed = await snapdir.push(src, store)
print(pushed) # identical to snap_id above
asyncio.run(main())
```
The store URI is always an argument, never an environment variable. For a local
round-trip use `file://$PWD/store`; swap it for a `gs://bucket/prefix` URI to
publish to Google Cloud with no other changes.
## 3. Pull it back
Pull the snapshot into a fresh directory. `pull` fetches every object from the
store, re-hashes it, and materialises the files — then `id` on the restored
directory prints the same ID, proving a byte-for-byte identical restore:
```python
import asyncio
import os
import snapdir
from snapdir import SnapshotId, StoreUri
async def main() -> None:
store = StoreUri(f"file://{os.getcwd()}/store")
snap_id = "" # the 64-hex id from step 2
await snapdir.pull(SnapshotId(snap_id), store, "./restored")
restored = await snapdir.id("./restored")
assert restored == snap_id # same id — restore verified
asyncio.run(main())
```
That is the exact same snapshot ID the CLI's `snapdir id` and `snapdir push`
produce for the same content — the binding and the command-line tool are
interchangeable.