Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions contents/docs/libraries/django.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ platformLogo: django

import AgentIntegrationSection from "../components/AgentIntegrationSection.mdx"

PostHog makes it easy to get data about traffic and usage of your Django app. Integrating PostHog enables analytics, custom events capture, feature flags, and more.
PostHog makes it easy to get data about traffic and usage of your Django app. Integrating PostHog enables analytics, custom events capture, feature flags, error tracking, and more.

This guide walks you through integrating PostHog into your Django app using the [Python SDK](/docs/libraries/python).

Expand All @@ -15,41 +15,51 @@ This guide walks you through integrating PostHog into your Django app using the

To start, run `pip install posthog` to install PostHog’s Python SDK.

Then, set the PostHog API key and host in your `AppConfig` in your `your_app/apps.py` so that's it's available everywhere:
> **Note:** Version `7.x` of the PostHog Python SDK requires Python 3.10 or higher.

Then, configure PostHog in your app config so it's initialized when Django starts:

```python file=your_app/apps.py
from django.apps import AppConfig
import posthog

class YourAppConfig(AppConfig):
name = "your_app_name"
name = 'your_app_name'

def ready(self):
posthog.api_key = '<ph_project_token>'
posthog.host = '<ph_client_api_host>'
```

You can find your project token and instance address in [your project settings](https://us.posthog.com/project/settings).

Next, if you haven't done so already, make sure you add your `AppConfig` to your `settings.py` under `INSTALLED_APPS`:
Next, if you haven't done so already, add your `AppConfig` to `INSTALLED_APPS` in `settings.py`:

```python file=settings.py
INSTALLED_APPS = [
# other apps
'your_app_name.apps.MyAppConfig', # Add your app config
# ... other apps
'your_app_name.apps.YourAppConfig',
]
```

Lastly, to access PostHog in any file, simply `import posthog` and call the method you'd like. For example, to capture an event:
You can find your project token and instance address in [your project settings](https://app.posthog.com/project/settings).

To capture events from any file, import `posthog` and call the method you need. For example:

```python
import posthog
from posthog import identify_context

def some_request(request):
with posthog.new_context():
posthog.identify_context(request.user.id)
# Django includes request.user for anonymous visitors too. Only identify
# the context when the visitor is logged in.
if request.user.is_authenticated:
identify_context(str(request.user.pk))

posthog.capture('event_name')
```

Events captured without a context or explicit `distinct_id` are sent as [anonymous events](/docs/data/anonymous-vs-identified-events) with an auto-generated `distinct_id`. See the [Python SDK docs](/docs/libraries/python#person-profiles-and-properties) for more details.

## Identifying users

import IdentifyBackendCallout from '../_snippets/identify-backend-callout.mdx'
Expand Down
48 changes: 40 additions & 8 deletions contents/docs/libraries/flask.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,76 @@ title: Flask
platformLogo: flask
---

PostHog makes it easy to get data about traffic and usage of your Flask app. Integrating PostHog enables analytics, custom events capture, feature flags, and more.
PostHog makes it easy to get data about traffic and usage of your Flask app. Integrating PostHog enables analytics, custom events capture, feature flags, error tracking, and more.

This guide walks you through integrating PostHog into your Flask app using the [Python SDK](/docs/libraries/python).

## Installation

To start, run `pip install posthog` to install PostHog’s Python SDK.

> **Note:** Version `7.x` of the PostHog Python SDK requires Python 3.10 or higher.

Then, initialize PostHog where you'd like to use it. For example, here's how to capture an event in a simple route:

```python file=app.py
package main
from flask import Flask, render_template, request, redirect, session, url_for
from flask import Flask
from posthog import Posthog

app = Flask(__name__)

posthog = Posthog(
'<ph_project_token>',
host='<ph_client_api_host>'
'<ph_project_token>',
host='<ph_client_api_host>',
)

@app.route('/api/dashboard', methods=['POST'])
def api_dashboard():
posthog.capture(
'dashboard_api_called'
'dashboard_api_called',
distinct_id='distinct_id_of_your_user',
)
return '', 204

```

You can find your project token and instance address in [your project settings](https://us.posthog.com/project/settings).
You can find your project token and instance address in [your project settings](https://app.posthog.com/project/settings).

## Identifying users

import IdentifyBackendCallout from '../_snippets/identify-backend-callout.mdx'

<IdentifyBackendCallout />

## Request contexts

Use [contexts](/docs/libraries/python#contexts) to share identity, session IDs, and tags across multiple captures during a request:

```python
from flask import request, session
from posthog import identify_context, set_context_session, tag

@app.route('/api/dashboard', methods=['POST'])
def api_dashboard():
with posthog.new_context():
distinct_id = request.headers.get('X-POSTHOG-DISTINCT-ID') or session.get('user_id')
if distinct_id:
identify_context(str(distinct_id))

session_id = request.headers.get('X-POSTHOG-SESSION-ID')
if session_id:
set_context_session(session_id)

tag('$current_url', request.url)
tag('$request_method', request.method)
tag('$request_path', request.path)

posthog.capture('dashboard_api_called')

return '', 204
```

Events captured without a context or explicit `distinct_id` are sent as [anonymous events](/docs/data/anonymous-vs-identified-events) with an auto-generated `distinct_id`. See the [Python SDK docs](/docs/libraries/python#person-profiles-and-properties) for more details.

## Error tracking

import PythonFlaskExceptionAutocapture from './python/_snippets/python-flask-exception-autocapture.mdx'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
The Python SDK provides a Django middleware that automatically wraps all requests with a [context](/docs/libraries/python#contexts). This middleware extracts session and user information from request headers and tags all events captured during the request with relevant metadata.
The Python SDK provides a Django middleware that automatically wraps all requests with a [context](/docs/libraries/python#contexts). This middleware extracts session and user information from each request and tags all events captured during that request with relevant metadata.

### Basic setup

Add the middleware to your Django settings:
Add the middleware to your Django settings. If your app uses Django authentication, place it after `django.contrib.auth.middleware.AuthenticationMiddleware` so the middleware can use the authenticated Django user as a distinct ID fallback and capture the user's email.

```python
MIDDLEWARE = [
Expand All @@ -12,14 +12,22 @@ MIDDLEWARE = [
]
```

The middleware uses the globally configured `posthog` client by default, so you don't need to create or pass it a separate client instance.

The middleware automatically extracts and uses:

- **Session ID** from the `X-POSTHOG-SESSION-ID` header, if present
- **Distinct ID** from the `X-POSTHOG-DISTINCT-ID` header, if present
- **Distinct ID** from the `X-POSTHOG-DISTINCT-ID` header, if present, falling back to the authenticated Django user's `pk` (Django's primary-key alias, which works with custom user models)
- **User email** from the authenticated Django user's `email` as `email`
- **Current URL** as `$current_url`
- **Request method** as `$request_method`
- **Request path** as `$request_path`
- **Forwarded IP address** from `X-Forwarded-For` as `$ip`
- **User agent** from `User-Agent` as `$user_agent`

The session and distinct ID headers are sanitized before use. Empty values are ignored, control characters are removed, values are trimmed, and values are capped at 1000 characters.

All events captured during the request (including exceptions) will include these properties and be associated with the extracted session and distinct ID.
All events captured during the request (including exceptions) include these properties and are associated with the extracted session and distinct ID.

If you are using PostHog on your frontend, the JavaScript Web SDK will add the session and distinct ID headers automatically if you enable tracing headers.

Expand All @@ -31,7 +39,9 @@ posthog.init('<ph_project_token>', {

### Exception capture

By default, the middleware captures exceptions and sends them to PostHog's error tracking. Disable this by setting:
By default, the middleware captures exceptions and sends them to PostHog's error tracking using the globally configured `posthog` client. This includes Django view exceptions that Django converts into error responses.

Disable this by setting:

```python
# settings.py
Expand All @@ -48,7 +58,8 @@ def add_user_tags(request):
# type: (HttpRequest) -> Dict[str, Any]
tags = {}
if hasattr(request, 'user') and request.user.is_authenticated:
tags['user_id'] = request.user.id
# Use pk instead of id so this works with custom User primary keys.
tags['user_id'] = str(request.user.pk)
tags['email'] = request.user.email
return tags

Expand Down Expand Up @@ -98,7 +109,8 @@ def add_request_context(request):
tags = {}
if hasattr(request, 'user') and request.user.is_authenticated:
tags['user_type'] = 'authenticated'
tags['user_id'] = str(request.user.id)
# Use pk instead of id so this works with custom User primary keys.
tags['user_id'] = str(request.user.pk)
else:
tags['user_type'] = 'anonymous'

Expand All @@ -123,4 +135,6 @@ POSTHOG_MW_TAG_MAP = clean_tags
POSTHOG_MW_CAPTURE_EXCEPTIONS = True
```

All events captured within the request context automatically include the configured tags and are associated with the session and user identified from the request headers.
All events captured within the request context automatically include the configured tags and are associated with the session and user identified from the request headers or Django authentication.

The middleware supports both sync (WSGI) and async (ASGI) Django applications. In async mode, it uses Django's `request.auser()` API when available to avoid synchronous user access.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from flask import Flask, jsonify
from posthog import Posthog

app = Flask(__name__)
posthog = Posthog('<ph_project_token>', host='<ph_client_api_host>')

@app.errorhandler(Exception)
Expand Down
Loading