# Python client and application examples The synchronous client uses Python 3 and its standard library. Add `clients/python` to your application's Python module search path or copy `ratdb.py` alongside your code. Start RatDB, then try this in Python. ```python from getpass import getpass from ratdb import Client with Client("admin", getpass()) as db: db.select_warren("garage") db.select_den("cars") db.put("car:001", {"make": "Ford"}) print(db.get("car:001")) page = db.find("make", "Ford") print(page["documents"], page["possibly_truncated"]) db.delete("car:001") ``` Every client authenticates once and keeps its navigation state on one socket. Give each worker its own client and close it with a context manager. Supply a numeric loopback address and port to connect through a local SSH tunnel. Connection failures during a mutation can leave its outcome uncertain. Reconnect, select the namespace again, and read the record before deciding whether to retry. `get` returns a dictionary or `None`. `put` inserts or replaces a document. `scan` and `find` return the server's bounded results and truncation metadata. Use insert for ID uniqueness, update for atomic top-level field changes, and page for ordered batches. Pass next_after back with the same filter until it is null. A server rejection raises `RatDBError` with a `code` attribute. A transport failure closes the session. Run both application examples, restart the server, and verify persisted records with a disposable database using the following commands from the workspace root. ```sh cargo build --release --workspace --locked python -B scripts/python_client_test.py target/release/ratdb ``` On Windows, pass `target/release/ratdb.exe`. The script generates its own administrator credential. The website example stores an application user with a salted scrypt password verifier, preferences, and an expiring session indexed by the digest of a random token. An application must check expiration, handle revocation, and protect browser cookies. The administrator account and website users serve different purposes. The CRM example creates five dens, updates a contact, filters it by stage, adds a note, lists activities and deletes an activity. It calls update to change one field atomically and uses a one-record page to walk activities. Each completed write is a separate commit. The website uses the canonical username as the document ID and calls insert to reject duplicates atomically. Applications own reference checks across dens and uniqueness of fields other than IDs. See [the application examples](../examples/python/workloads.py) and [the wire protocol](PROTOCOL.md). The optional `timeout` argument defaults to 30 seconds and bounds reads across the entire response frame, including its four-byte length header. Incomplete frames, malformed JSON, and over-limit lengths close the session. `get_versioned(id)` and `transaction(expected_generation, changes)` support [conditional atomic server writes](SERVER_TRANSACTIONS.md) in the development checkout. A generation_conflict leaves the connection available for a fresh read.