Skip to main content

DealerTower Python Framework (dtpyfw)

Python Version Code Style Type Checked License

DealerTower Python Framework (dtpyfw) is a production-ready internal framework providing reusable building blocks for DealerTower microservices. It covers API development, database orchestration, caching, event streaming, object storage, task scheduling, and structured logging — all with full type safety and consistent interfaces.

PEP 561 typed package — py.typed marker is shipped so mypy/pyright narrow types in consumer services automatically.


Installation

Requires Python 3.13 or newer.

Base

pip install dtpyfw

Includes dtpyfw.core (env, retry, hashing, chunking, validation, …) and dtpyfw.log (structured logging).

dtpyfw @ git+https://github.com/datgate/dtpyfw.git@v1.0

Development

poetry install -E all

Check installed version

import dtpyfw
print(dtpyfw.__version__)  # "1.0"

Optional extras

Extras can be combined: pip install dtpyfw[api,db,redis].

Extra Key dependencies Install
api FastAPI, Uvicorn, Gunicorn pip install dtpyfw[api]
db SQLAlchemy 2, asyncpg, psycopg2 pip install dtpyfw[db]
db-mysql PyMySQL, aiomysql pip install dtpyfw[db-mysql]
bucket boto3 pip install dtpyfw[bucket]
redis redis-py + hiredis pip install dtpyfw[redis]
redis_streamer redis-py pip install dtpyfw[redis_streamer]
worker Celery, celery-redbeat, celery_once pip install dtpyfw[worker]
kafka kafka-python pip install dtpyfw[kafka]
opensearch opensearch-py pip install dtpyfw[opensearch]
ftp paramiko pip install dtpyfw[ftp]
encrypt python-jose, passlib, bcrypt pip install dtpyfw[encrypt]
all Everything above pip install dtpyfw[all]

Common profiles:

pip install dtpyfw[api,db,redis]        # API microservice
pip install dtpyfw[worker,db,redis]     # Celery worker service
pip install dtpyfw[api,db,opensearch,redis]  # Search-enabled service
pip install dtpyfw[bucket,db,ftp]       # Data processing service

Documentation


Quick start examples

FastAPI application

from dtpyfw.api import Application
from dtpyfw.api.routes import Router, Route, RouteMethod
from dtpyfw.api.routes.authentication import Auth, AuthType
from dtpyfw.core.env import Env

gateway_auth = Auth.from_env(
    auth_type=AuthType.HEADER,
    header_key="x-gateway-key",
    env_var="gateway_key",
)

router = Router(prefix="/health", tags=["health"])
router.add_route(Route(
    method=RouteMethod.GET,
    path="/",
    endpoint=lambda: {"status": "ok"},
))

app = Application(
    title="My Microservice",
    version="1.0",
    routers=[router],
    auth=gateway_auth,
).get_app()

Database

from dtpyfw.db.config import DatabaseConfig
from dtpyfw.db.database import DatabaseInstance

db_config = DatabaseConfig.from_env()   # reads db_host, db_port, db_user, …
db = DatabaseInstance(db_config)

with db.get_db_cm_sync() as session:
    result = session.execute(select(User)).scalars().all()

Structured logging

from dtpyfw.log.config import LogConfig
from dtpyfw.log.initializer import log_initializer

log_config = LogConfig.from_env()   # reads logging_ms_url, log_level, …
log_initializer(config=log_config)

# Inside any function:
from dtpyfw.log import footprint

footprint.leave(
    log_type="info",
    controller=f"{__name__}.my_func",
    subject="Task started",
    message="Processing item.",
    payload={"item_id": item_id},
)

Redis caching

from dtpyfw.redis.config import RedisConfig
from dtpyfw.redis.connection import RedisInstance

redis = RedisInstance(RedisConfig.from_env())   # reads redis_url / redis_host, …

from dtpyfw.redis.caching import cache_function

@cache_function(redis_instance=redis, expire_time=3600)
def get_dealer(dealer_id: str) -> dict:
    ...

S3-compatible storage

from dtpyfw.bucket.bucket import Bucket

bucket = Bucket.from_env()          # reads s3_bucket_name, s3_access_key, …
bucket = Bucket.from_env("media_s3_")  # custom prefix

url = bucket.upload("path/to/file.pdf", "dealers/123/file.pdf")
bucket.download("dealers/123/file.pdf", "/tmp/file.pdf")
exists = bucket.exists("dealers/123/file.pdf")

Celery worker

from dtpyfw.worker.task import Task
from dtpyfw.worker.worker import Worker
from dtpyfw.redis.config import RedisConfig
from dtpyfw.redis.connection import RedisInstance

task = Task()
task.register("myapp.tasks.process_data", queue="default")
task.add_periodic("myapp.tasks.cleanup", crontab(hour=0, minute=0))

redis = RedisInstance(RedisConfig.from_env())
worker = Worker()
worker.set_name("my_worker").set_redis(redis).set_task(task)
celery_app = worker.get_celery()

Startup diagnostics report

Emit a structured boot-time snapshot (environment variables, dependency health, process metadata) to stdout and footprint. All dependency probes run concurrently; the function never raises regardless of which probes fail.

from dtpyfw.diagnostics import emit_startup_report

# Minimal (process info + env snapshot, no dependency probes)
emit_startup_report(service_name="my-service", process_role="api")

# With dependencies
from app.config.database import database
from app.config.redis import redis_instance, redis_queue_instance
from app.config.log import log_config

emit_startup_report(
    service_name="my-service",
    process_role="api",
    service_version="1.4.2",
    database=database,
    redis=[redis_instance, redis_queue_instance],
    log_config=log_config,
    probe_timeout_seconds=3.0,
)

# Collect without emitting
from dtpyfw.diagnostics import collect_startup_report
import json

report = collect_startup_report(service_name="my-service", process_role="script")
print(json.dumps(report, indent=2, default=str))

The returned dict always has schema_version=1 and the following top-level keys: status ("ok" / "degraded" / "down"), process, environment, logging, dependencies, extras, notes.


Redis Streams (event bus)

from dtpyfw.redis.config import RedisConfig
from dtpyfw.redis.connection import RedisInstance
from dtpyfw.redis_streamer.synchronize import RedisStreamer
from dtpyfw.redis_streamer.message import Message

redis = RedisInstance(RedisConfig.from_env("redis_queue_"))
streamer = RedisStreamer(redis_instance=redis, consumer_name="my_service")

streamer.register_channel("my_service_events")
streamer.subscribe("dealer_updated")
streamer.register_handler("dealer_updated", handle_dealer_updated)

# Publish
streamer.send_message("my_service_events", Message(name="event_name", body=payload))

# Consume (blocking)
streamer.persist_consume()

Module reference

Module Extra Docs
dtpyfw.core base docs/core/
dtpyfw.log base docs/log/
dtpyfw.api api docs/api/
dtpyfw.db db docs/db/
dtpyfw.bucket bucket docs/bucket/
dtpyfw.redis redis docs/redis/
dtpyfw.redis_streamer redis_streamer docs/redis_streamer/
dtpyfw.worker worker docs/worker/
dtpyfw.kafka kafka docs/kafka/
dtpyfw.mongo mongo —
dtpyfw.opensearch opensearch docs/opensearch/
dtpyfw.ftp ftp docs/ftp/
dtpyfw.encrypt encrypt docs/encrypt/
dtpyfw.mcp mcp docs/mcp/
dtpyfw.diagnostics base —

Development

# Install all dependencies
poetry install -E all

# Run tests
pytest

# Format
black .

# Lint
ruff check . --fix

# Type check
mypy dtpyfw

Version history

Current version: see CHANGELOG.md for full history and UPGRADE.md for migration guides.

Releases are version-driven: bump [tool.poetry] version in pyproject.toml in your PR and merge to main. CI then runs two jobs in publish.yml — release (creates the v<version> tag + GitHub Release if the version is new), then publish (OIDC-publishes to PyPI via Trusted Publishing). The flow is idempotent; re-publishing is just re-running the workflow run. See docs/RELEASING.md for the flow and the one-time PyPI setup.


License

DealerTower Python Framework is proprietary software. See LICENSE for complete terms and conditions.


Resources

Metadata

Release files for dtpyfw 1.39

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

Source distribution (sdist)

Source distribution for dtpyfw 1.39
File Size Uploaded
dtpyfw-1.39.tar.gz 245.0 kB Details

Built distribution (wheel)

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

Total release size: 549.1 kB

Release files / dtpyfw-1.39.tar.gz

Download URL dtpyfw-1.39.tar.gz
Size 245.0 kB
Tags Source
SHA-256 checksum
How to use checksums
98dd84aa9d7cf7aa6e43354e61d1444852dff8a1818addb041287a4275b08820
BLAKE2b-256 checksum
How to use checksums
ba3dc638aec7d7f7e53caabcb320cfcec9e3ac0adb6fa446ee202abae6263add
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release files / dtpyfw-1.39-py3-none-any.whl

Download URL dtpyfw-1.39-py3-none-any.whl
Size 304.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
25890efe1e6175b4209327eb6e2b87cb609d01066fc8ebbcc535383c7dd7e9a5
BLAKE2b-256 checksum
How to use checksums
6f5365322dd0aaa90c5357973ff269b870b64f3f9bd392cb581c038bab28ddd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release history Release notifications | RSS feed

1.64

2 release files

1.63

2 release files

1.62

2 release files

1.61

2 release files

1.60

2 release files

1.59

2 release files

1.58

2 release files

1.56

2 release files

1.55

2 release files

1.54

2 release files

1.53

2 release files

1.52

2 release files

1.50

2 release files

1.49

2 release files

1.48

2 release files

1.47

2 release files

1.46

2 release files

1.45

2 release files

1.44

2 release files

1.43

2 release files

1.42

2 release files

1.41

2 release files

1.40

2 release files

This release

1.39 This release

2 release files

1.38

2 release files

1.37

2 release files

1.36

2 release files

1.35

2 release files

1.34

2 release files

1.33

2 release files

1.32

2 release files

1.31

2 release files

1.30

2 release files

1.29

2 release files

1.28

2 release files

1.27

2 release files

1.26

2 release files

1.25

2 release files

1.24

2 release files

1.23

2 release files

1.22

2 release files

1.21

2 release files

1.20

2 release files

1.19

2 release files

1.18

2 release files

1.17

2 release files

1.16

2 release files

1.15

2 release files

1.14

2 release files

1.13

2 release files

1.12

2 release files

1.11

2 release files

1.10

2 release files

1.9

2 release files

1.8

2 release files

1.7

2 release files

1.6

2 release files

1.5

2 release files

1.4

2 release files

1.3

2 release files

1.2

2 release files

1.1

2 release files

1.0

2 release files

0.6.43

2 release files

0.6.42

2 release files

0.6.41

2 release files

0.6.40

2 release files

0.6.39

2 release files

0.6.38

2 release files

0.6.37

2 release files

0.6.36

2 release files

0.6.35

2 release files

0.6.34

2 release files

0.6.33

2 release files

0.6.32

2 release files

0.6.31

2 release files

0.6.30

2 release files

0.6.29

2 release files

0.6.28

2 release files

0.6.24

2 release files

0.6.23

2 release files

0.6.22

2 release files

0.6.20

2 release files

0.6.19

2 release files

0.6.18

2 release files

0.6.17

2 release files

0.6.16

2 release files

0.6.15

2 release files

0.6.14

2 release files

0.6.13

2 release files

0.6.12

2 release files

0.6.11

2 release files

0.6.10

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.26

2 release files

0.5.25

2 release files

0.5.24

2 release files

0.5.23

2 release files

0.5.22

2 release files

0.5.21

2 release files

0.5.20

2 release files

0.5.19

2 release files

0.5.18

2 release files

0.5.17

2 release files

0.5.16

2 release files

0.5.15

2 release files

0.5.13

2 release files

0.5.12

2 release files

0.5.11

2 release files

0.5.10

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.13

2 release files

0.4.12

2 release files

0.4.11

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.2.76

2 release files

0.2.75

2 release files

0.2.74

2 release files

0.2.73

2 release files

0.2.72

2 release files

0.2.71

2 release files

0.2.70

2 release files

0.2.69

2 release files

0.2.68

2 release files

0.2.67

2 release files

0.2.66

2 release files

0.2.65

2 release files

0.2.64

2 release files

0.2.62

2 release files

0.2.56

2 release files

0.2.55

2 release files

0.2.54

2 release files

0.2.53

2 release files

0.2.52

2 release files

0.2.51

2 release files

0.2.50

2 release files

0.2.49

2 release files

0.2.48

2 release files

0.2.47

2 release files

0.2.46

2 release files

0.2.45

2 release files

0.2.44

2 release files

0.2.43

2 release files

0.2.42

2 release files

0.2.41

2 release files

0.2.40

2 release files

0.2.39

2 release files

0.2.38

2 release files

0.2.37

2 release files

0.2.36

2 release files

0.2.35

2 release files

0.2.34

2 release files

0.2.33

2 release files

0.2.32

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.9

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

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