Metadata-Version: 2.4
Name: baltimore-patapsco
Version: 0.2.0
Summary: Shared Django runtime foundations for Baltimore civic applications
Author: Mayor's Office of Performance and Innovation
License-Expression: MIT
License-File: LICENSE
Requires-Dist: django>=6.0,<7.0
Requires-Dist: djangorestframework>=3.16,<4.0
Requires-Dist: drf-spectacular>=0.28,<0.30
Requires-Dist: django-allauth[socialaccount]>=65.10,<66.0 ; extra == 'auth'
Requires-Dist: django-auditlog>=3.3,<4.0 ; extra == 'auth'
Requires-Dist: django-anymail[sendgrid]>=15.0,<16.0 ; extra == 'email'
Requires-Dist: sentry-sdk[django]>=2.64.0,<3.0 ; extra == 'observability'
Requires-Dist: dj-database-url>=3.0,<4.0 ; extra == 'runtime'
Requires-Dist: django-cors-headers>=4.9,<5.0 ; extra == 'runtime'
Requires-Dist: django-environ>=0.12,<0.14 ; extra == 'runtime'
Requires-Dist: whitenoise>=6.9,<7.0 ; extra == 'runtime'
Requires-Python: >=3.13
Provides-Extra: auth
Provides-Extra: email
Provides-Extra: observability
Provides-Extra: runtime
Description-Content-Type: text/markdown

# baltimore-patapsco (Python)

Reusable Django runtime primitives for Baltimore civic applications.

```python
INSTALLED_APPS += ["baltimore.patapsco"]
MIDDLEWARE += ["baltimore.patapsco.observability.RequestContextMiddleware"]

REST_FRAMEWORK = {
    "EXCEPTION_HANDLER": "baltimore.patapsco.api.exception_handler",
}

urlpatterns = [path("", include("baltimore.patapsco.urls"))]
```

## Stable health and readiness views

Applications that mount or extend the operational views directly use the public
facade:

```python
from baltimore.patapsco.api import HealthView, ReadinessView
```

`HealthView` is process-only liveness. `ReadinessView` runs the established
database check and returns its public-safe 200 or 503 status document. Both use
no authentication classes and `AllowAny`, and both remain ordinary DRF
`APIView` classes with `as_view()`.

An application may subclass either class, override `get()`, and call
`super().get(request)` before composing app-owned public-safe checks. The parent
response status, request ID, and database result remain the starting contract;
the application owns an explicit serializer and OpenAPI annotation for any
extended payload.

The previous `baltimore.patapsco.api.views` imports resolve to the same class
objects for compatibility. `DiagnosticsView` remains available only from that
module and through the packaged URL configuration; it is intentionally absent
from `baltimore.patapsco.api.__all__` because its staff/public policy is a
separate operational surface. The settings-free package root exports neither
view class.

`api_error_response()` and the DRF exception handler force every 5xx response to
the public `internal_error` code, generic message, and no details. Application
callers cannot opt a server failure out of that safety boundary.

Use `build_logging_config()` for the shared JSON/pretty log shape. Modules are
incrementally adoptable; installing the package does not enable auth, email, or
Sentry by itself.

## Sentry privacy defaults

Install the `observability` extra and call the shared initializer only when a DSN
is configured:

```python
from baltimore.patapsco.observability import configure_sentry

configure_sentry(
    environment="production",
    release="my-app@1.2.3",
    traces_sample_rate=0.1,
)
```

`configure_sentry()` is deny-by-default: it disables automatic PII, request-body
capture, and stack-frame local variables. Its event pipeline also removes request
cookies and query strings, strips query/fragment data from request URLs, and
recursively redacts Sentry's credential/session denylist plus common civic contact
and precise-location fields. Safe operational fields such as request IDs, routes,
and HTTP methods remain available.

Redaction is key-based. Applications must not attach sensitive values under
misleading keys or place resident data in exception messages. Product-specific
fields still require a privacy review before being added to Sentry context.
