Metadata-Version: 2.4
Name: dataframer-journey
Version: 0.1.0
Summary: Automatic journey_id propagation for DataFramer — inbound extraction, outbound header injection, Langfuse trace stamping
Project-URL: Repository, https://github.com/aimonlabs/dataframer-journey-py
License: Copyright (c) 2026 AIMon Labs, Inc. All rights reserved.
        
        Permission is granted to use this software solely for the purpose of
        integrating with and sending data to the DataFramer service, whether
        directly or as part of a licensed application.
        
        Redistribution, resale, sublicensing, reverse engineering, or creation
        of derivative works based on this software, in whole or in part, is
        not permitted without the prior written permission of AIMon Labs, Inc.,
        except as expressly permitted under a separate written agreement.
License-File: LICENSE
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# dataframer-journey

Automatic `journey_id` propagation for [DataFramer](https://dataframer.ai) user-signal stitching. One line per service; after that the journey id flows browser → service → service → trace without anyone threading it by hand.

## Install

```
pip install dataframer-journey
```

Zero runtime dependencies. Patches apply only to libraries you already have (`requests`, `httpx`, `langfuse`).

## Usage

**FastAPI / Starlette:**

```python
from dataframer_journey import instrument

app = FastAPI()
instrument(app)
```

**Django** — call `instrument()` at the end of `settings.py` and add the middleware:

```python
MIDDLEWARE = [
    ...,
    'dataframer_journey.django.JourneyIdMiddleware',
]

import dataframer_journey
dataframer_journey.instrument()
```

That's it. From then on:

- **Inbound**: the journey id is read off each incoming request (`baggage` header → `X-Journey-Id` header → `df_journey_id` cookie set by `@dataframer/signals`) into request-scoped context.
- **Outbound**: every outgoing `requests`/`httpx` call automatically carries it to the next service (both `X-Journey-Id` and W3C `baggage`, so it also rides existing OpenTelemetry propagation). Explicitly-set headers are never overwritten.
- **Traces**: every Langfuse trace created during the request gets `metadata.journey_id` (and a `journey:<id>` tag) stamped automatically. Explicit metadata wins; the stamp is merge-if-absent.

**Non-HTTP entry points** (queue consumers, scheduled jobs): take the id from the payload yourself —

```python
from dataframer_journey import with_journey, get_journey_id

with with_journey(payload["journey_id"]):
    ...  # traces created here are stamped; outbound calls carry the id
```

## Notes

- Langfuse SDK v2 is supported; v3 (OpenTelemetry-based) stamping is not implemented yet and logs a warning.
- The browser side is [`@dataframer/signals`](https://www.npmjs.com/package/@dataframer/signals), which generates the journey id and sends it on requests to your API.
- CORS: if your frontend and API are on different origins, allow the `X-Journey-Id` (or `baggage`) request header in your API's CORS config. Same-site setups need nothing — the cookie carries it.
