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.61

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.61
File Size Uploaded
dtpyfw-1.61.tar.gz 360.6 kB Details

Built distribution (wheel)

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

Total release size: 787.0 kB

Release files / dtpyfw-1.61.tar.gz

Download URL dtpyfw-1.61.tar.gz
Size 360.6 kB
Tags Source
SHA-256 checksum
How to use checksums
fdefa71d05566bbce54a45a2f2782e31a4ef2563618b410278f686808039f23e
BLAKE2b-256 checksum
How to use checksums
d02ae4895927a03356f976d2269c69e5aff4ed10453fd91eb3f2e71e987f33ea
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 Oct 11, 2026.

Transparency log

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

Download URL dtpyfw-1.61-py3-none-any.whl
Size 426.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2db07afe0d67b60e02c3fcd71d4af8d3eaaae3cc0007714c6b060f4a4063742f
BLAKE2b-256 checksum
How to use checksums
ce1f98cc2897597c5bb0736c64c8ce7d9962be3b78056e1f781a6947fd9a70c2
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 Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

1.64

2 release files

1.63

2 release files

1.62

2 release files

This release

1.61 This release

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

1.39

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