Steerage
Pluggable async storage backends for Python projects.
This project implements the Repository Pattern for data access, using Pydantic 2.0 models for entity composition and decomposition.
Features
- One model, many possible storage backends: Start simple and add complexity as you need it.
- Use a fast, ephemeral in-memory database for tests, and a slow, reliable SQL database for production.
- One unified query interface: write most queries once, apply them to any backend.
- Simple environment-based configuration with Convoke
- 100% test coverage
Installation
With Pip:
pip install steerage
Example
Let's create a simple blog engine. First, we'll want a Pydantic entity model:
from uuid import UUID
from datetime import datetime
from pydantic import BaseModel, Field
from pydantic.types import AwareDatetime
class Entry(BaseModel):
id: UUID
path: str
title: str
body: str
created_at: AwareDatetime = Field(
default_factory=lambda: datetime.utcnow().replace(tzinfo=timezone.utc)
)
published_at: AwareDatetime | None = Field(default=None)
Models are all fine and good, but we need to be able to store it somewhere. Let's start simple, with an in-memory repository and a repository factory:
from steerage.repositories.memdb import AbstractInMemoryRepository
class InMemoryEntryRepository(AbstractInMemoryRepository):
table_name: str = "entries"
entity_class = Entry
def get_entry_repository():
return InMemoryEntityRepository()
Now, in the async request handler, we can easily create an entry:
async def create_entry(request: Request):
form = await EntryForm.from_request(request)
if form.is_valid():
repo = get_entry_repository()
entry = Entry.model_validate(form)
await repo.insert(entry)
return redirect('entry-admin')
... and retrieve an entry:
async def get_entry(request: Request, id: UUID):
repo = get_entry_repository()
entry = await repo.get(id)
return render('entry.html', {'entry': entry})
This is great, but whenever we restart the server, we lose all our data!
Let's go a step up and add a more durable disk-based repository:
from convoke.configs import BaseConfig
from steerage.repositories.shelvedb import ShelveInMemoryRepository
class ShelveEntryRepository(AbstractShelveRepository):
table_name: str = "entries"
entity_class = Entry
def get_entry_repository():
config = BaseConfig()
if config.TESTING:
return InMemoryEntityRepository()
else:
return ShelveEntityRepository()
Now we have a durable repository for development use, and an in-memory repository for our tests.
Contribute
- Source Code: https://github.com/eykd/steerage
- Issue Tracker: https://github.com/eykd/steerage/issues
License
The project is licensed under the BSD 3-clause license.
Metadata
Release files for steerage 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| steerage-2.0.0.tar.gz | 17.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| steerage-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.7 kB
Release files / steerage-2.0.0.tar.gz
| Download URL | steerage-2.0.0.tar.gz |
|---|---|
| Size | 17.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c1fc1061bc8ec6078280b6080ca289b86818ef51ebcd52e2183f0303db74bdca
|
|
BLAKE2b-256 checksum How to use checksums |
744c5f06056799aa0e33eb4aac8ec7d3329bedd818eee5b8523212cefb2a8777
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.7.1 CPython/3.11.8 Linux/6.2.0-1019-azure
|
Release files / steerage-2.0.0-py3-none-any.whl
| Download URL | steerage-2.0.0-py3-none-any.whl |
|---|---|
| Size | 23.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3e79cc7e1628a7cdae960ec3d00e3b3df89ce715e1a37710851f003cb7b522d2
|
|
BLAKE2b-256 checksum How to use checksums |
44842642071c1b91bc1fe63ad89a6153c739a383f7a5861e033eaecb78b65106
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.7.1 CPython/3.11.8 Linux/6.2.0-1019-azure
|
Security for steerage 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.