Skip to main content
userharbor

GitHub License Tests Codecov PyPI - Python Version PyPI - Version Code style: black Linting: Ruff uv Pytest Zensical

UserHarbor is a framework-agnostic Python library for user account management.

Its goal is to provide a simple, stable, and framework-independent interface for common user-related operations:

  • user registration
  • email verification
  • login
  • session management
  • logout from one or all sessions
  • password change
  • password reset
  • account deletion
  • role and permission checks

UserHarbor is not a web framework. It does not provide routers, views, or HTTP endpoints. Instead, it exposes a simple domain-level API that can be integrated with FastAPI, Flask, Django, Litestar, CLI applications, or any other environment.

Like UserHarbor? Give it a star.

Installation

Install the core package if you want to provide your own UserStore and EmailSender implementations:

pip install userharbor

Install the core package with the official SQLAlchemy, SMTP, and FastAPI adapters:

pip install "userharbor[sqlalchemy,smtp,fastapi]"

Or install all official integrations at once:

pip install "userharbor[all]"

The official adapters are documented in the integrations documentation:

Quick example

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from userharbor import UserHarbor
from userharbor_sqlalchemy import SQLAlchemyUserStore
from userharbor_smtp import SMTPEmailSender

engine = create_engine("sqlite:///users.db")
SessionLocal = sessionmaker(bind=engine)

store = SQLAlchemyUserStore(SessionLocal)
store.metadata.create_all(engine)

email_sender = SMTPEmailSender(
    host="smtp.example.com",
    port=587,
    username="smtp-user",
    password="smtp-password",
    from_email="noreply@example.com",
)

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

# Register a user
harbor.register(
    username="jane",
    email="jane@example.com",
    password="StrongPassword123!",
)

# Verify email address
harbor.verify_email("verification-token-from-email")

# Login
session_token = harbor.login(
    username="jane",
    password="StrongPassword123!",
)

# Verify session
if harbor.verify_session(session_token):
    print("User is logged in")

# Get current user
current_user = harbor.get_current_user(session_token)
print(current_user.username)

# Create roles and permissions
harbor.roles.create("admin")
harbor.permissions.create("users.delete")
harbor.roles.grant_permission("admin", "users.delete")
harbor.grant_role("jane", "admin")

# Check access
if harbor.has_permission(session_token, "users.delete"):
    print("User can delete users")

current_admin = harbor.require_role(session_token, "admin")
print(current_admin.username)

# Logout
harbor.logout(session_token)

# Change password
session_token = harbor.login(
    username="jane",
    password="StrongPassword123!",
)
harbor.change_password(
    old_password="StrongPassword123!",
    new_password="EvenStrongerPassword123!",
    session_token=session_token,
)

# Send password reset email
harbor.send_password_reset("jane@example.com")

# Reset password
harbor.reset_password(
    new_password="NewStrongPassword123!",
    reset_token="reset-token-from-email",
)

# Delete account
session_token = harbor.login(
    username="jane",
    password="NewStrongPassword123!",
)
harbor.delete_account(
    password="NewStrongPassword123!",
    session_token=session_token,
)

Full FastAPI example with official integrations

Install all official integrations:

pip install "userharbor[all]"

Then create a FastAPI application with SQLAlchemy storage, SMTP email delivery, and the FastAPI router adapter:

import os

from fastapi import FastAPI
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from userharbor import UserHarbor
from userharbor_fastapi import UserHarborFastAPI
from userharbor_smtp import SMTPEmailSender
from userharbor_sqlalchemy import SQLAlchemyUserStore

engine = create_engine("sqlite:///users.db")
SessionLocal = sessionmaker(bind=engine)

store = SQLAlchemyUserStore(SessionLocal)
store.metadata.create_all(engine)

email_sender = SMTPEmailSender(
    host=os.getenv("HOST", "smtp.example.com"),
    port=int(os.getenv("PORT", 587)),
    username=os.getenv("USERNAME"),
    password=os.getenv("PASSWORD"),
    from_email=os.getenv("USERNAME", ""),
)

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

auth = UserHarborFastAPI(harbor)

app = FastAPI()
app.include_router(auth.router, prefix="/auth", tags=["auth"])


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000)

Documentation

The full documentation is available at userharbor.github.io.

Useful pages:

Architecture

UserHarbor consists of three main parts:

UserHarbor core
    ├── registration logic
    ├── login logic
    ├── session logic
    ├── password reset logic
    ├── role and permission checks
    ├── data validation
    ├── token generation
    └── password and token hashing

UserStore
    └── any implementation responsible for storing users, sessions, tokens, roles, and permissions

EmailSender
    └── any implementation responsible for sending email messages

The main userharbor package does not contain a concrete database implementation or email delivery implementation.

Instead, it relies on two protocols:

  • UserStore
  • EmailSender

This allows you to use official adapters or build your own integration.

Official integrations

UserHarbor core does not include database or email-provider implementations. Those responsibilities are handled by adapters that implement the core UserStore and EmailSender protocols.

Official integrations:

See the integrations documentation for detailed setup instructions.

Design principles

UserHarbor should remain simple, predictable, and easy to integrate.

1. Core should only do what is necessary

The main library is responsible for basic user account operations:

  • registration
  • email verification
  • login
  • session management
  • logout
  • password reset
  • password change
  • user deletion
  • simple role-based access control

Unusual business-specific cases should be implemented outside the library.

UserHarbor does not try to solve every identity-related problem.

The following are outside the scope of the core library:

  • OAuth
  • OpenID Connect
  • social login
  • 2FA/MFA
  • ACL
  • organizations and teams
  • ownership and resource policies
  • policy engines
  • admin panels
  • ready-made HTTP endpoints
  • ready-made HTML views
  • integrations with specific frameworks

Such features may be created as separate libraries or integrations, but they should not complicate the core project.

UserHarbor should not become an application framework.

2. Framework-agnostic before framework integrations

The main library should not depend on FastAPI, Django, Flask, Litestar, or any other framework.

Framework integrations should be created as separate libraries.

3. UserStore and EmailSender are dependencies

UserHarbor does not assume where users are stored.

UserHarbor does not assume how email messages are sent.

These responsibilities belong to adapters compatible with the UserStore and EmailSender interfaces.

4. Adapters should live outside the core

Integrations with databases, ORMs, email services, queues, frameworks, and providers should be developed as separate packages.

5. Stability is more important than feature count

Core development should focus mainly on:

  • improving security
  • improving reliability
  • improving performance
  • maintaining compatibility

New features should be added carefully.

6. Simple things should remain simple

The library should be easy to use in small projects, while still being possible to extend in larger applications.

Changelog

Changes for each release are documented in the GitHub release notes.

Contributing

The most welcome areas of contribution are:

  • security improvements
  • tests
  • documentation
  • UserStore implementations
  • EmailSender implementations
  • framework integrations as separate packages

Before starting work on a storage, email, or framework integration, read the integrations documentation and review the official adapters:

Local development

We use uv to manage the development environment. After installing uv, run these commands from the repository root:

uv sync                       # Create .venv and install development dependencies
uv run pytest                 # Run tests
uv run zensical build --clean # Build documentation in site/
uv run zensical serve         # Preview documentation locally

License

UserHarbor is released under the MIT License.

Metadata

Release files for userharbor 0.9.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for userharbor 0.9.1
File Size Uploaded
userharbor-0.9.1.tar.gz 13.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for userharbor 0.9.1
File Interpreter ABI Platform
userharbor-0.9.1-py3-none-any.whl Python 3 none any Details

Total release size: 32.2 kB

Release files / userharbor-0.9.1.tar.gz

Download URL userharbor-0.9.1.tar.gz
Size 13.3 kB
Tags Source
SHA-256 checksum
How to use checksums
ab8521566904566d76bd9e4d3629bb4dfc2c84eb917466c6858e2a61e27aaf04
BLAKE2b-256 checksum
How to use checksums
9291cec54231e12feab1c17bf9f691efaba88c915522aa24c6839a22205e5c61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}

Release files / userharbor-0.9.1-py3-none-any.whl

Download URL userharbor-0.9.1-py3-none-any.whl
Size 18.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b7f1c68aef6fcdc92eaacf7636c4a631049acf3f40f4e475bdc41c0d360d9188
BLAKE2b-256 checksum
How to use checksums
e31f2a94cf8cd741748e17ce330ab8aef40a22ba196662119297947c637f1a71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}

Release history Release notifications | RSS feed

This release

0.9.1 This release

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page