Skip to main content

A minimal, contract-tested UserStore implementation and GitHub template for building custom UserHarbor storage integrations.

Project description

userharbor

GitHub License Tests Codecov PyPI - Python Version PyPI - Version uv Pytest

userharbor-inmemory is a minimal, contract-tested UserStore implementation for UserHarbor. It can be installed directly for tests and examples or used as a GitHub template when building a custom storage integration.

[!WARNING] All data is process-local and is lost when the store instance is discarded. This package is not a persistent database and is not intended for production storage.

Installation

pip install userharbor-inmemory

The package depends on userharbor and has no database or framework dependencies.

Usage

from userharbor import UserHarbor
from userharbor_inmemory import InMemoryUserStore


store = InMemoryUserStore()

harbor = UserHarbor(
    secret_key="your-secret-key",
    store=store,
    email_sender=email_sender,
)

Each InMemoryUserStore instance starts empty and keeps its data for the lifetime of that instance.

The store implements the complete UserHarbor persistence contract:

  • users and password hashes
  • email verification and password reset tokens
  • sessions and session refresh
  • roles and permissions
  • user-role and role-permission assignments
  • commit, rollback, and nested transaction behavior

Each user has at most one active email verification token and one active password reset token. Storing a replacement invalidates the previous token. Users may have multiple active sessions.

Use as an integration template

Select Use this template on GitHub and create a new repository. The generated repository starts with a complete implementation and a passing contract suite, so backend code can be replaced incrementally while the tests continue to verify UserStore behavior.

GitHub copies files without replacing project-specific names. After creating a repository:

  1. Rename the distribution in pyproject.toml.
  2. Rename the userharbor_inmemory package and InMemoryUserStore class.
  3. Update project metadata, links, badges, and this README.
  4. Replace the in-memory dictionaries and snapshot transaction with the target backend.
  5. Adapt the user_store fixture in tests/conftest.py to create and clean up the backend.
  6. Keep backend-specific tests separate from the shared contract suite.
  7. Run the complete test suite before publishing.

The contract tests stay intentionally small in this repository:

# tests/test_user_store_contract.py

from userharbor.testing.user_store_contract import *  # noqa: F403
# tests/conftest.py

import pytest

from userharbor_inmemory import InMemoryUserStore


@pytest.fixture
def user_store() -> InMemoryUserStore:
    return InMemoryUserStore()

See the UserStore contract testing guide and custom integrations guide for the complete behavioral requirements.

Development

Install the project and run its tests:

uv sync
uv run pytest

The suite imports the shared contract distributed with UserHarbor. Tests specific to this package remain in tests/test_public_api.py.

To develop against an unpublished local UserHarbor checkout, keep both repositories in the same parent directory and run:

uv run --with-editable ../userharbor pytest

Limitations

InMemoryUserStore is deliberately small. It does not provide persistence across process restarts, cross-process sharing, durable transactions, or concurrency guarantees. Its snapshot-based transaction implementation exists to reproduce the atomic behavior required by UserHarbor in tests and examples.

License

UserHarbor In-Memory is licensed under the MIT License. See LICENSE for details.

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

userharbor_inmemory-0.1.0.tar.gz (4.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

userharbor_inmemory-0.1.0-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

Details for the file userharbor_inmemory-0.1.0.tar.gz.

File metadata

  • Download URL: userharbor_inmemory-0.1.0.tar.gz
  • Upload date:
  • Size: 4.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for userharbor_inmemory-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d0ecb220c41ffe34eece0a92078831c68585d5c8221d7de9aa0815a3d2db6f58
MD5 dc329bc828b81ec27eebe1c97d5ab42f
BLAKE2b-256 8c541d42885a1c4c2ef87f731fd7b8d9fa08c2c403efa8b6b726e28306b70c30

See more details on using hashes here.

File details

Details for the file userharbor_inmemory-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: userharbor_inmemory-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for userharbor_inmemory-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a23b6f4f2567d3f06f5ebc0a70ba87b595465e1a84aea45d58a61e12e757e8f
MD5 2ab9673019ee91cbb1f227b4f931a5dd
BLAKE2b-256 a6367deb3576b9eaa1a58971b379f8d50281ac3e0dc36657777fe867cf267c27

See more details on using hashes here.

Supported by

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