Skip to main content

Pluggable async storage backends for Python projects

Project description

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

License

The project is licensed under the BSD 3-clause license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

steerage-2.0.0.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

steerage-2.0.0-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

File details

Details for the file steerage-2.0.0.tar.gz.

File metadata

  • Download URL: steerage-2.0.0.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.8 Linux/6.2.0-1019-azure

File hashes

Hashes for steerage-2.0.0.tar.gz
Algorithm Hash digest
SHA256 c1fc1061bc8ec6078280b6080ca289b86818ef51ebcd52e2183f0303db74bdca
MD5 09cc827afe9b2cb656c14bd41d57bf7b
BLAKE2b-256 744c5f06056799aa0e33eb4aac8ec7d3329bedd818eee5b8523212cefb2a8777

See more details on using hashes here.

File details

Details for the file steerage-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: steerage-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 23.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.8 Linux/6.2.0-1019-azure

File hashes

Hashes for steerage-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e79cc7e1628a7cdae960ec3d00e3b3df89ce715e1a37710851f003cb7b522d2
MD5 f6fca1a8c9b8a47da35665c338be9c93
BLAKE2b-256 44842642071c1b91bc1fe63ad89a6153c739a383f7a5861e033eaecb78b65106

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page