Skip to main content

HexCore PyPI Downloads

A reusable core for Python applications built on hexagonal architecture, DDD, CQRS and background tasks. HexCore ships the abstractions (entities, repositories, unit of work, buses) and the infrastructure every project otherwise rewrites: the SQL session layer, the FastAPI factories, the worker runner, the dynamic cron, identity, and the testing utilities.

The design goal is that the happy path takes zero configuration: create_app() with no arguments gives you a usable app, init_engine() with no arguments gives you a production-correct engine.

🇪🇸 ¿Preferís español? La documentación está completa en los dos idiomas: docs/es/.

# main.py — a complete HexCore app
from hexcore.fastapi import build_lifespan, create_app, SqlEngineStep

app = create_app(
    lifespan=build_lifespan(SqlEngineStep()),
    routers=[users_router, tickets_router],
)
# worker.py — the complete worker, with cron, mutual death and SIGTERM
import hexcore.cqrs as cqrs

await cqrs.run_procrastinate_worker(
    procrastinate_app,
    queues=["default", "reactive"],
    scheduler=cqrs.DynamicScheduler(repo, enqueuer, lock_provider=lock),
    on_startup=[lambda: cqrs.seed_cron_jobs(CRON_JOBS)],
)

📚 Documentation

docs/ — 🇬🇧 English · 🇪🇸 español

English Español
Installation and extras installation instalacion
Quickstart quickstart inicio-rapido
Configuration configuration configuracion
SQL layer sql sql
Repositories and entities repositories repositorios
FastAPI utilities fastapi fastapi
CQRS architecture cqrs cqrs
Queues and workers queues-and-workers colas-y-workers
Scheduled tasks cron cron
Event Sourcing event-sourcing event-sourcing
Testing testing testing
CLI cli cli
Darwin (identity) darwin/ darwin/
API reference reference referencia
Versions and migration versions-and-migration versiones-y-migracion
Typing typing tipado

Installation

pip install hexcore

Requires Python ≥ 3.12. HexCore pulls in no heavy dependencies: everything that is not the core lives in extras, and the modules that need them only import them when you use them.

pip install "hexcore[api,sql,procrastinate]"
pip install "hexcore[darwin-sqlalchemy]"
pip install "hexcore[all]"
Group Extras
Core api, sql, mongo, redis, rabbitmq, procrastinate, celery
Identity darwin, darwin-sqlalchemy, darwin-beanie, darwin-magic-link, darwin-two-factor, darwin-oauth, darwin-impersonate, darwin-passkey, darwin-organization
Everything all

The full table, with what each one enables, is in installation · instalación.

import hexcore.cqrs works with no extras at all: name resolution is lazy, so hexcore.cqrs.SqlAlchemyCronJobRepository only requires [sql] at the moment you ask for it.


The four imports

There is one facade module per task. They re-export the public surface without moving anything: the long paths keep resolving to the same object.

import hexcore.fastapi as hx     # create_app, build_lifespan, providers, middlewares, health
import hexcore.cqrs as cqrs      # Command, Query, handlers, decorators, buses, worker, cron
import hexcore.sql as sql        # init_engine, session_scope, uow_scope, Base, query DTOs
import hexcore.darwin as darwin  # IdentityConfig, configure_identity, build_identity_router

The facades expose only the canonical names. The historical I* aliases were removed in 7.0 — see Removed API.


What you get, at a glance

You need API Extra
A wired-up FastAPI app hx.create_app(), hx.AppFeatures api
Orchestrated startup and shutdown hx.build_lifespan() + steps api
SQL engine and sessions sql.init_engine(), sql.PoolSettings sql
A session or UoW outside a request sql.session_scope(), sql.uow_scope() sql
Health checks that actually probe hx.register_health_routes() api
Rate limiting hx.rate_limit() api
SSE / WebSocket / connection caps hx.sse_stream(), hx.connection_slot() api
Commands, queries and events cqrs.Command, cqrs.Query, cqrs.HandlerRegistry
Running work in the background cqrs.background_command, cqrs.background_task
The worker entrypoint cqrs.run_cqrs_worker(), cqrs.run_procrastinate_worker()
Cron you can edit without a restart cqrs.DynamicScheduler, cqrs.SqlAlchemyCronJobRepository sql
Distributed locks cqrs.RedisLockProvider, cqrs.PostgresLockProvider redis / sql
Identity and authentication darwin.configure_identity(), darwin.build_identity_router() darwin + storage
Testing all of the above hexcore.testing

Darwin: the identity module

Registration, email verification, sign-in, sessions with rotating refresh, revocation, audited impersonation, and a plugin system that adds second factor, OAuth, magic links, passkeys and organizations without the core knowing about them.

from hexcore.darwin import (
    IdentityConfig,
    build_identity_router,
    configure_identity,
    identity_startup_steps,
)
from hexcore.fastapi import AppFeatures, SqlEngineStep, build_lifespan, create_app

configure_identity(IdentityConfig())

app = create_app(
    features=AppFeatures(auth_context=True, csrf=True),
    lifespan=build_lifespan(SqlEngineStep(), *identity_startup_steps()),
    routers=[build_identity_router()],
)

⚠️ If you use SQL, the most important thing to read before deploying is the Alembic section: storage · almacenamiento. A plugin missing from your env.py makes alembic revision --autogenerate emit op.drop_table for its tables.


Project templates (CLI)

hexcore init my_project --template hexagonal
hexcore init my_project --template vertical-slice
  • hexagonalsrc/domain, src/application, src/infrastructure.
  • vertical-slicesrc/features, src/shared/{domain,application,infrastructure}.

Both generate a root config.py and leave Alembic configured. See CLI · CLI.


Versions and support

Series Status What it means
9.x Active The only supported one. Receives features and fixes. Adds the event store and Event Sourcing, and leaves a single event bus port.
8.x Deprecated Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn.
7.x Deprecated Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on master.
6.x Deprecated No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present.
5.x Deprecated Same API surface as 6.x.
4.x Deprecated Partial application: missing the Celery event-loop fix, the facades, and the aligned documentation.
3.x Deprecated Partial application: has the P0/P1 fixes but none of the FastAPI factories.
2.x Deprecated Contains silent bugs fixed in 5.x: the worker re-enqueued instead of executing, the cron skipped or duplicated runs, and a Redis outage switched off the entire cron.
1.x Deprecated No support of any kind.

Everything before 9.0 is deprecated. Migrate to 9.x. The detail of each series, the silent 2.x bugs and the step-by-step guides are in versions and migration · versiones y migración.

Removed API and its replacement

The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — and were removed in 7.0. The replacement is mechanical: they are renames, not behavior changes.

Removed in 7.0 (was v1/v2) Use instead
ICommandBus, IQueryBus, IEventBus AbstractCommandBus, AbstractQueryBus, AbstractEventBus
ICommandHandler, IQueryHandler AbstractCommandHandler, AbstractQueryHandler
IMiddleware AbstractMiddleware
ISerializer AbstractSerializer
IEventDispatcher EventBus
EventBus.register() / .dispatch() EventBus.subscribe() / .publish()
ServerConfig.event_dispatcher ServerConfig.event_bus
SQLAlchemyCommonImplementationsRepo SqlAlchemyRepository
BeanieODMCommonImplementationsRepo BeanieRepository
NoSqlUnitOfWork BeanieUnitOfWork
reset_sqlalchemy_engine() dispose_engine()
MiddlewareConfig Removed in 3.0. It was dead code: never read.

Passing event_dispatcher= to ServerConfig fails with an error that says what to use, rather than being silently ignored: pydantic discards keyword arguments it does not know, and keeping the default bus without noticing would surface much later as "my events never arrive".

If you are still on 6.x, run your tests with warnings visible to see what you have left to migrate:

python -m pytest -W "default::DeprecationWarning"

Contributing

  1. Code of conduct — read the Code of Conduct before interacting.

  2. Branches — fork and create a branch (feat/name, fix/name, docs/name).

  3. Tests — every fix lands with at least one test that fails before and passes after:

    uv sync --extra all --group dev
    uv run python -m pytest -q
    

    CI fails if any test is skipped: a skip means an extra is missing, and we would be reporting green without having run half the suite.

  4. Typecheckuv run pyright hexcore. The verdict comes from the ratchet, not the exit code: see typing · tipado.

  5. StylePEP8. Comment the why, not the what.

  6. CommitsCommitizen: feat:, fix:, docs:, refactor:, and ! for breaking changes. The version bump and the CHANGELOG are automatic on merge to master.

  7. PRs — describe the problem, the reproduction, the solution and why that option.

Full detail in CONTRIBUTING.md.

Project skills

There is a set of skills for extending HexCore in VS Code and compatible environments: HexCore Skills repository.


References

Download files

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

Source Distribution

hexcore-9.0.1.tar.gz (766.4 kB view details)

Uploaded Source

Built Distribution

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

hexcore-9.0.1-py3-none-any.whl (619.8 kB view details)

Uploaded Python 3

File details

Details for the file hexcore-9.0.1.tar.gz.

File metadata

  • Download URL: hexcore-9.0.1.tar.gz
  • Upload date:
  • Size: 766.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for hexcore-9.0.1.tar.gz
Algorithm Hash digest
SHA256 265bf0f22734a990184a9b0eb1bf6c0b2908ee8d1f4a3cd7ef8ddfe956ab819d
MD5 99311524b6b21b4b59579580d88ef5e2
BLAKE2b-256 50aa70be741a33332e16a5a9546d497d828b8ded2368ff015cdce2a9631600ed

See more details on using hashes here.

File details

Details for the file hexcore-9.0.1-py3-none-any.whl.

File metadata

  • Download URL: hexcore-9.0.1-py3-none-any.whl
  • Upload date:
  • Size: 619.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for hexcore-9.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 82faa5ece34ec3da7695973f01c1517944a09d7ab820a2c5d4d9a6718fc1c052
MD5 94fea7b71bd99cef2dc0596d33749011
BLAKE2b-256 2f9816c96cb40c03c5147da851937955042be2ea04abacc71f78478845786015

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

9.0.1 This release

2 files

9.0.0

2 files

8.0.0

2 files

7.0.0

2 files

6.2.1

2 files

6.2.0

2 files

6.1.0

2 files

6.0.2

2 files

6.0.1

2 files

6.0.0

2 files

5.0.0

2 files

4.0.0

2 files

3.0.0

2 files

2.5.0

2 files

2.4.0

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.6

2 files

2.0.5

2 files

2.0.4

2 files

2.0.3

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.8.0

2 files

1.7.0

2 files

1.6.8

2 files

1.6.7

2 files

1.6.6

2 files

1.6.5

2 files

1.6.4

2 files

1.6.3

2 files

1.6.2

2 files

1.6.1

2 files

1.6.0

2 files

1.5.1

2 files

1.5.0

2 files

1.4.2

2 files

1.4.1

2 files

1.4.0

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 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