2026-07-16 16:57:04 +03:00
2026-07-16 16:57:04 +03:00
2026-09-09 18:01:48 +03:00
2026-09-15 17:04:24 +03:00
2026-09-15 17:04:24 +03:00
2026-08-12 18:36:56 +03:00
2026-07-16 16:31:36 +03:00
2026-09-15 23:20:30 +03:00
2026-09-06 15:40:08 +03:00
2026-08-18 19:33:41 +03:00
2026-09-15 23:20:30 +03:00

The_DisExcel_project

A FastAPI project combining Excel and digital data ("The Great Excel project that is going to be built from Excel and digital projects").

Stack

  • Python >= 3.13
  • FastAPI + Uvicorn / Gunicorn
  • SQLAlchemy 2.0 (async) + Alembic (migrations)
  • PostgreSQL (asyncpg, psycopg2)
  • Pydantic 2 / Pydantic Settings
  • Poetry — dependency management
  • Redis — caching, rate limiting, token revocation
  • RabbitMQ (aio-pika) — background email workers
  • Jinja2 — HTML email templates
  • Docker, Ansible — deployment

Architecture

src/
├── cache/       # Redis client, rate limiting
├── daemons/     # background worker entrypoints (BaseDaemon, registry)
├── database/    # DB CRUD operations
├── errors/      # HTTP errors
├── logging/     # queue-based logging infra + HTTP middleware
├── messaging/   # RabbitMQ client, producers, consumers, topology
├── migrations/  # Alembic migrations
├── models/      # Pydantic and SQLAlchemy models, configs, RabbitMQ topology
├── reports/     # reports
├── service/     # business logic (auth, users_crud, email sending)
└── web/         # routes (protected_routes)

Layers are connected top to bottom: web → service → database → models.

Background workers (RabbitMQ)

Email sending (welcome / password-reset) runs as separate daemon processes, decoupled from the web API via a RabbitMQ topic exchange:

main.py / daemon_run.py → apply_topology() → RabbitMQ ("email" exchange)
                                                   ├── queue_welcome_email → WelcomeEmailConsumer
                                                   └── queue_reset_email  → ResetEmailConsumer

Each queue has a matching dead-letter queue for messages that fail permanently (bad data, non-retryable errors) instead of retrying forever. Run a worker locally with:

python daemon_run.py welcome_email   # single daemon
python daemon_run.py --all           # all daemons enabled in configs/daemons.json

Authentication

  • JWT access + refresh tokens
  • Refresh token is stored in the DB as a SHA256 hash, with rotation and revocation support
  • Passwords are hashed with bcrypt
  • RBAC: direct user permissions + permissions via groups, checked through require_permissions()

Testing

tests/
├── unit/
├── integrated/
└── e2e/

Uses pytest, pytest-asyncio, pytest-cov, pytest-mock, allure-pytest.

Allure report

make allure needs the Allure command-line tool (Java-based, not a pip package) — allure-pytest only writes raw result files, the CLI turns them into an HTML report.

  1. Download Allure 2.44.0 from github.com/allure-framework/allure2/releases.
  2. Extract it into .venv/allure-2.44.0/ so that .venv/allure-2.44.0/bin/allure exists — this matches the ALLURE variable already set in makefile.
  3. If you install it somewhere else (or on Windows), update the ALLURE variable at the top of makefile to point to your actual allure binary path — the Windows path is already there, commented out.
make test     # runs pytest, writes results to tests/allure-results/reports
make allure   # builds tests/allure-results/html/index.html from those results

Installation

Requires Poetry itself to be installed first (it's a global tool, not a project dependency). Recommended via pipx:

pipx install poetry

or via the official installer:

curl -sSL https://install.python-poetry.org | python3 -

Then install the project dependencies:

poetry install

Running migrations

alembic upgrade head

CI/CD

Pipeline is set up via Gitea Actions (.gitea/workflows/ci.yml).

Deployment

The repository includes ready-made docker/ and ansible/ configs for containerization and deployment.

License

MH.Dmitrii's project

S
Description
No description provided
Readme
314 KiB
Languages
Python 94.1%
HTML 3.4%
Makefile 1.5%
Shell 0.6%
Mako 0.4%