vybekiit 0.7.34 → 0.7.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/bin.js +520 -9
  2. package/dist/global-skills/eas-app-stores/SKILL.md +2 -2
  3. package/dist/global-skills/eas-hosting/SKILL.md +2 -2
  4. package/dist/global-skills/eas-observe/SKILL.md +7 -15
  5. package/dist/global-skills/eas-observe/references/queries.md +51 -10
  6. package/dist/global-skills/eas-observe/references/setup.md +60 -7
  7. package/dist/global-skills/eas-simulator/SKILL.md +2 -2
  8. package/dist/global-skills/eas-simulator/references/run-your-app.md +2 -0
  9. package/dist/global-skills/eas-update/SKILL.md +2 -2
  10. package/dist/global-skills/eas-update-insights/SKILL.md +2 -2
  11. package/dist/global-skills/eas-workflows/SKILL.md +2 -2
  12. package/dist/global-skills/expo-animation/SKILL.md +2 -2
  13. package/dist/global-skills/expo-app-clip/SKILL.md +2 -2
  14. package/dist/global-skills/expo-brownfield/SKILL.md +2 -2
  15. package/dist/global-skills/expo-data-fetching/SKILL.md +2 -2
  16. package/dist/global-skills/expo-design-system/SKILL.md +2 -2
  17. package/dist/global-skills/expo-dev-client/SKILL.md +4 -2
  18. package/dist/global-skills/expo-dom/SKILL.md +2 -2
  19. package/dist/global-skills/expo-examples/SKILL.md +2 -2
  20. package/dist/global-skills/expo-migrate-module/SKILL.md +2 -2
  21. package/dist/global-skills/expo-module/SKILL.md +2 -2
  22. package/dist/global-skills/expo-native-ui/SKILL.md +2 -2
  23. package/dist/global-skills/expo-overview/SKILL.md +9 -4
  24. package/dist/global-skills/expo-overview/references/launch-without-dev-menu.md +24 -0
  25. package/dist/global-skills/expo-project-structure/SKILL.md +2 -2
  26. package/dist/global-skills/expo-router/SKILL.md +2 -2
  27. package/dist/global-skills/expo-ui/SKILL.md +2 -2
  28. package/dist/global-skills/expo-upgrade/SKILL.md +2 -2
  29. package/dist/global-skills/expo-web-to-native/SKILL.md +2 -2
  30. package/dist/global-skills/expo-web-to-native/references/verify-on-device.md +1 -1
  31. package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +16 -3
  32. package/dist/global-skills/firebase-app-hosting-basics/references/cli_commands.md +10 -12
  33. package/dist/global-skills/firebase-app-hosting-basics/references/configuration.md +2 -1
  34. package/dist/global-skills/firebase-basics/SKILL.md +6 -4
  35. package/dist/global-skills/firebase-basics/references/web_setup.md +3 -3
  36. package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +81 -333
  37. package/dist/global-skills/instrument-feature-flags/references/android.md +19 -13
  38. package/dist/global-skills/instrument-feature-flags/references/api.md +17 -13
  39. package/dist/global-skills/instrument-feature-flags/references/best-practices.md +35 -35
  40. package/dist/global-skills/instrument-feature-flags/references/django.md +120 -72
  41. package/dist/global-skills/instrument-feature-flags/references/dotnet.md +48 -102
  42. package/dist/global-skills/instrument-feature-flags/references/elixir.md +4 -10
  43. package/dist/global-skills/instrument-feature-flags/references/flask.md +55 -39
  44. package/dist/global-skills/instrument-feature-flags/references/flutter.md +19 -13
  45. package/dist/global-skills/instrument-feature-flags/references/go.md +21 -13
  46. package/dist/global-skills/instrument-feature-flags/references/ios.md +19 -13
  47. package/dist/global-skills/instrument-feature-flags/references/java.md +4 -12
  48. package/dist/global-skills/instrument-feature-flags/references/laravel.md +18 -16
  49. package/dist/global-skills/instrument-feature-flags/references/next-js.md +44 -54
  50. package/dist/global-skills/instrument-feature-flags/references/nodejs.md +21 -13
  51. package/dist/global-skills/instrument-feature-flags/references/php.md +21 -13
  52. package/dist/global-skills/instrument-feature-flags/references/python.md +22 -14
  53. package/dist/global-skills/instrument-feature-flags/references/react-native.md +18 -13
  54. package/dist/global-skills/instrument-feature-flags/references/react.md +21 -14
  55. package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +31 -68
  56. package/dist/global-skills/instrument-feature-flags/references/ruby.md +21 -13
  57. package/dist/global-skills/instrument-feature-flags/references/rust.md +10 -34
  58. package/dist/global-skills/instrument-feature-flags/references/usage.md +94 -114
  59. package/dist/global-skills/instrument-feature-flags/references/web.md +21 -13
  60. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-android.md +7 -7
  61. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-expo.md +2 -2
  62. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +1 -1
  63. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +1 -1
  64. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-laravel.md +2 -2
  65. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-php.md +1 -1
  66. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-python.md +1 -1
  67. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby.md +1 -1
  68. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-swift.md +4 -4
  69. package/dist/global-skills/instrument-product-analytics/references/android.md +64 -109
  70. package/dist/global-skills/instrument-product-analytics/references/angular.md +32 -28
  71. package/dist/global-skills/instrument-product-analytics/references/astro.md +29 -34
  72. package/dist/global-skills/instrument-product-analytics/references/configuration.md +27 -42
  73. package/dist/global-skills/instrument-product-analytics/references/django.md +120 -72
  74. package/dist/global-skills/instrument-product-analytics/references/dotnet.md +48 -102
  75. package/dist/global-skills/instrument-product-analytics/references/elixir.md +25 -50
  76. package/dist/global-skills/instrument-product-analytics/references/flask.md +55 -39
  77. package/dist/global-skills/instrument-product-analytics/references/flutter.md +94 -96
  78. package/dist/global-skills/instrument-product-analytics/references/go.md +39 -77
  79. package/dist/global-skills/instrument-product-analytics/references/identify-users.md +24 -26
  80. package/dist/global-skills/instrument-product-analytics/references/ios.md +22 -22
  81. package/dist/global-skills/instrument-product-analytics/references/laravel.md +18 -16
  82. package/dist/global-skills/instrument-product-analytics/references/next-js.md +44 -54
  83. package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +32 -34
  84. package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +36 -36
  85. package/dist/global-skills/instrument-product-analytics/references/php.md +42 -87
  86. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +15 -12
  87. package/dist/global-skills/instrument-product-analytics/references/python.md +106 -154
  88. package/dist/global-skills/instrument-product-analytics/references/react-native.md +97 -176
  89. package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +29 -40
  90. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +29 -38
  91. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +29 -40
  92. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +32 -37
  93. package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +31 -68
  94. package/dist/global-skills/instrument-product-analytics/references/ruby.md +40 -96
  95. package/dist/global-skills/instrument-product-analytics/references/svelte.md +34 -34
  96. package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +19 -19
  97. package/dist/global-skills/instrument-product-analytics/references/usage.md +94 -114
  98. package/dist/global-skills/instrument-product-analytics/references/vue-js.md +33 -45
  99. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +40 -22
  100. package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +8 -2
  101. package/dist/global-skills/mongodb-search-and-ai/references/quick-start.md +725 -0
  102. package/dist/global-skills/mongodb-search-and-ai/scripts/quickstart_complete.py +386 -0
  103. package/dist/global-skills/neon/references/claimable-neon.md +2 -0
  104. package/dist/global-skills/neon-realtime/references/queries.md +2 -2
  105. package/dist/global-skills/resend/SKILL.md +1 -1
  106. package/dist/global-skills/resend/references/inboxes.md +49 -21
  107. package/dist/global-skills/resend/references/webhooks.md +1 -1
  108. package/dist/global-skills/stripe-best-practices/SKILL.md +1 -1
  109. package/dist/global-skills/stripe-best-practices/references/connect.md +1 -1
  110. package/dist/global-skills/stripe-best-practices/references/security.md +9 -9
  111. package/dist/global-skills/vybekiitReferences/backend/AGENTS.md +1 -1
  112. package/dist/global-skills/vybekiitReferences/backend/agent/goal-routes.json +303 -18
  113. package/dist/global-skills/vybekiitReferences/extension/AGENTS.md +1 -1
  114. package/dist/global-skills/vybekiitReferences/extension/agent/goal-routes.json +352 -18
  115. package/dist/global-skills/vybekiitReferences/mobile/AGENTS.md +1 -1
  116. package/dist/global-skills/vybekiitReferences/mobile/agent/goal-routes.json +413 -22
  117. package/dist/global-skills/vybekiitReferences/spa/AGENTS.md +1 -1
  118. package/dist/global-skills/vybekiitReferences/spa/agent/goal-routes.json +391 -21
  119. package/dist/global-skills/vybekiitReferences/web/AGENTS.md +14 -2
  120. package/dist/global-skills/vybekiitReferences/web/agent/goal-routes.json +490 -32
  121. package/package.json +8 -8
@@ -2,18 +2,29 @@
2
2
 
3
3
  # Django
4
4
 
5
+ Canonical URL: https://posthog.com/docs/libraries/django
6
+
7
+ > **Cloud region:** This page uses US Cloud hosts. For an EU Cloud project, use `https://eu.i.posthog.com` instead of `https://us.i.posthog.com` (ingestion host), and use `https://eu.posthog.com` instead of `https://app.posthog.com` (app host for links).
8
+
9
+ ## On this page
10
+
11
+ - [Beta: integration via LLM](#beta-integration-via-llm)
12
+ - [Installation](#installation)
13
+ - [Identifying users](#identifying-users)
14
+ - [Django contexts middleware](#django-contexts-middleware)
15
+ - [Next steps](#next-steps)
16
+ - [Supported versions](#supported-versions)
17
+
5
18
  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.
6
19
 
7
- This guide walks you through integrating PostHog into your Django app using the [Python SDK](/docs/libraries/python.md).
20
+ This guide walks you through integrating PostHog into your Django app using the [Python SDK](https://posthog.com/docs/libraries/python.md).
8
21
 
9
22
  ## Beta: integration via LLM
10
23
 
11
- Install PostHog for Django in seconds with our wizard by running this prompt with [LLM coding agents](/blog/envoy-wizard-llm-agent.md) like Cursor and Bolt, or by running it in your terminal.
24
+ Install PostHog for Django in seconds with our wizard by running this prompt with [LLM coding agents](https://posthog.com/blog/envoy-wizard-llm-agent.md) like Cursor and Bolt, or by running it in your terminal.
12
25
 
13
26
  `npx @posthog/wizard`
14
27
 
15
- [Learn more](/wizard.md)
16
-
17
28
  Or, to integrate manually, continue with the rest of this guide.
18
29
 
19
30
  > These docs cover version `7.x` of the Python SDK, which requires Python 3.10 or higher. On Python 3.9? See [supported versions](#supported-versions).
@@ -53,8 +64,6 @@ You can find your project token and instance address in [your project settings](
53
64
 
54
65
  To capture events from any file, import `posthog` and call the method you need. For example:
55
66
 
56
- Python
57
-
58
67
  ```python
59
68
  import posthog
60
69
  from posthog import identify_context
@@ -69,7 +78,7 @@ def some_request(request):
69
78
  posthog.capture('event_name')
70
79
  ```
71
80
 
72
- Events captured without a context or explicit `distinct_id` are sent as [anonymous events](/docs/data/anonymous-vs-identified-events.md) with an auto-generated `distinct_id`. See the [Python SDK docs](/docs/libraries/python.md#person-profiles-and-properties) for more details.
81
+ Events captured without a context or explicit `distinct_id` are sent as [anonymous events](https://posthog.com/docs/data/anonymous-vs-identified-events.md) with an auto-generated `distinct_id`. See the [Python SDK docs](https://posthog.com/docs/libraries/python.md#person-profiles-and-properties) for more details.
73
82
 
74
83
  ## Identifying users
75
84
 
@@ -77,8 +86,6 @@ Events captured without a context or explicit `distinct_id` are sent as [anonymo
77
86
  >
78
87
  > In Python, you can do this through a context. All event captures in the same context will be tagged automatically with the correct `distinct_id`. Typically, you would set a fresh context and identify at the top of each route.
79
88
  >
80
- > Python
81
- >
82
89
  > ```python
83
90
  > from posthog import new_context, identify_context, capture
84
91
  >
@@ -94,18 +101,16 @@ Events captured without a context or explicit `distinct_id` are sent as [anonymo
94
101
 
95
102
  ## Django contexts middleware
96
103
 
97
- The Python SDK provides a Django middleware that automatically wraps all requests with a [context](/docs/libraries/python.md#contexts). This middleware extracts session and user information from each request and tags all events captured during that request with relevant metadata.
104
+ The Python SDK provides a Django middleware that automatically wraps all requests with a [context](https://posthog.com/docs/libraries/python.md#contexts). This middleware extracts session and user information from each request and adds relevant properties to events captured during that request.
98
105
 
99
106
  ### Basic setup
100
107
 
101
108
  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.
102
109
 
103
- Python
104
-
105
110
  ```python
106
111
  MIDDLEWARE = [
107
112
  # ... other middleware
108
- 'posthog.integrations.django.PosthogContextMiddleware',
113
+ "posthog.integrations.django.PosthogContextMiddleware",
109
114
  # ... other middleware
110
115
  ]
111
116
  ```
@@ -114,8 +119,8 @@ The middleware uses the globally configured `posthog` client by default, so you
114
119
 
115
120
  The middleware automatically extracts and uses:
116
121
 
117
- - **Session ID** from the `X-POSTHOG-SESSION-ID` header, if present
118
- - **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)
122
+ - **Session ID** from the `X-POSTHOG-SESSION-ID` header when you enable `POSTHOG_MW_TRUST_TRACING_HEADERS`
123
+ - **Distinct ID** from the authenticated Django user's `pk` (Django's primary-key alias, which works with custom user models), or from the `X-POSTHOG-DISTINCT-ID` header when you enable `POSTHOG_MW_TRUST_TRACING_HEADERS`
119
124
  - **User email** from the authenticated Django user's `email` as `email`
120
125
  - **Current URL** as `$current_url`
121
126
  - **Request method** as `$request_method`
@@ -123,7 +128,14 @@ The middleware automatically extracts and uses:
123
128
  - **Forwarded IP address** from `X-Forwarded-For` as `$ip`
124
129
  - **User agent** from `User-Agent` as `$user_agent`
125
130
 
126
- 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.
131
+ The middleware ignores the session and distinct ID headers by default because clients can control them. To use them as analytics context, enable them in your Django settings:
132
+
133
+ ```python
134
+ # settings.py
135
+ POSTHOG_MW_TRUST_TRACING_HEADERS = True
136
+ ```
137
+
138
+ Don't use these headers for authentication or authorization. The middleware sanitizes trusted header values before use. It ignores empty values, removes control characters, trims values, and caps them at 1000 characters.
127
139
 
128
140
  All events captured during the request (including exceptions) include these properties and are associated with the extracted session and distinct ID.
129
141
 
@@ -133,8 +145,6 @@ The middleware reads `request.user` once, before your view runs. On a login or s
133
145
 
134
146
  Identify the context from inside the request once you know who the user is. Django's auth signals are the natural place:
135
147
 
136
- Python
137
-
138
148
  ```python
139
149
  from django.contrib.auth.signals import user_logged_in
140
150
  from django.dispatch import receiver
@@ -147,7 +157,7 @@ def identify_posthog_user(sender, request, user, **kwargs):
147
157
 
148
158
  Every capture later in that request is then attributed to the user who just logged in. Requests made after login don't need this. The middleware sees the authenticated user from the start.
149
159
 
150
- If you're using [PostHog JavaScript Web](/docs/libraries/js.md) on the frontend, configure [`tracing_headers`](/docs/libraries/js/config.md#tracing-headers) for your Django backend hostname so browser requests include the session and distinct ID headers.
160
+ If you're using [PostHog JavaScript Web](https://posthog.com/docs/libraries/js.md) on the frontend, configure [`tracing_headers`](https://posthog.com/docs/libraries/js/config.md#tracing-headers) for your Django backend hostname so browser requests include the session and distinct ID headers. You must also set `POSTHOG_MW_TRUST_TRACING_HEADERS = True` in Django to accept them.
151
161
 
152
162
  ### Exception capture
153
163
 
@@ -155,120 +165,166 @@ By default, the middleware captures exceptions and sends them to PostHog's error
155
165
 
156
166
  Disable this by setting:
157
167
 
158
- Python
159
-
160
168
  ```python
161
169
  # settings.py
162
170
  POSTHOG_MW_CAPTURE_EXCEPTIONS = False
163
171
  ```
164
172
 
165
- ### Adding custom tags
173
+ Set `POSTHOG_MW_CAPTURE_EXCEPTIONS = None` to inherit the global client's `enable_exception_autocapture` setting. When you omit `POSTHOG_MW_CAPTURE_EXCEPTIONS`, the middleware preserves the existing Django default and captures exceptions.
174
+
175
+ ### Capture Django REST Framework exceptions
166
176
 
167
- Use `POSTHOG_MW_EXTRA_TAGS` to add custom properties to all requests:
177
+ This integration requires version `7.69.0` or later of the Python SDK.
168
178
 
169
- Python
179
+ Django REST Framework (DRF) converts many exceptions into responses before Django middleware can observe them. Add PostHog's DRF exception handler to capture these handled errors:
170
180
 
171
181
  ```python
172
182
  # settings.py
173
- def add_user_tags(request):
183
+ REST_FRAMEWORK = {
184
+ # ... other DRF settings
185
+ "EXCEPTION_HANDLER": "posthog.integrations.drf.exception_handler",
186
+ }
187
+ ```
188
+
189
+ Keep `PosthogContextMiddleware` enabled. The middleware adds request properties and identity to the active context, while the DRF handler captures handled API exceptions. The handler captures responses with a `5xx` status by default and ignores expected `4xx` responses. If DRF doesn't handle an exception, Django re-raises it and the middleware captures it instead.
190
+
191
+ If you already use a custom DRF exception handler, wrap it in an application module:
192
+
193
+ ```python
194
+ # your_app/exception_handlers.py
195
+ from posthog.integrations.drf import create_exception_handler
196
+ from your_app.api import existing_exception_handler
197
+
198
+ exception_handler = create_exception_handler(existing_exception_handler)
199
+ ```
200
+
201
+ Then point DRF to the wrapper:
202
+
203
+ ```python
204
+ # settings.py
205
+ REST_FRAMEWORK = {
206
+ "EXCEPTION_HANDLER": "your_app.exception_handlers.exception_handler",
207
+ }
208
+ ```
209
+
210
+ To capture selected `4xx` responses, create a handler with `capture_4xx=True` and an exception filter:
211
+
212
+ ```python
213
+ # your_app/exception_handlers.py
214
+ from posthog.integrations.drf import create_exception_handler
215
+
216
+
217
+ def capture_auth_errors(exception, response, context):
218
+ return response.status_code >= 500 or response.status_code in {401, 403}
219
+
220
+
221
+ exception_handler = create_exception_handler(
222
+ capture_4xx=True,
223
+ exception_filter=capture_auth_errors,
224
+ )
225
+ ```
226
+
227
+ The DRF handler follows `POSTHOG_MW_CAPTURE_EXCEPTIONS` and `POSTHOG_MW_REQUEST_FILTER`. You can also pass `capture_exceptions=True` or `capture_exceptions=False` to `create_exception_handler()` to override the middleware setting.
228
+
229
+ ### Add custom properties
230
+
231
+ Use `POSTHOG_MW_EXTRA_PROPERTIES` to add custom properties to all requests:
232
+
233
+ ```python
234
+ # settings.py
235
+ def add_user_properties(request):
174
236
  # type: (HttpRequest) -> Dict[str, Any]
175
- tags = {}
176
- if hasattr(request, 'user') and request.user.is_authenticated:
237
+ properties = {}
238
+ if hasattr(request, "user") and request.user.is_authenticated:
177
239
  # Use pk instead of id so this works with custom User primary keys.
178
- tags['user_id'] = str(request.user.pk)
179
- tags['email'] = request.user.email
180
- return tags
240
+ properties["user_id"] = str(request.user.pk)
241
+ properties["email"] = request.user.email
242
+ return properties
181
243
 
182
- POSTHOG_MW_EXTRA_TAGS = add_user_tags
244
+ POSTHOG_MW_EXTRA_PROPERTIES = add_user_properties
183
245
  ```
184
246
 
185
- #### Filtering requests
247
+ ### Filter requests
186
248
 
187
249
  Skip tracking for certain requests using `POSTHOG_MW_REQUEST_FILTER`:
188
250
 
189
- Python
190
-
191
251
  ```python
192
252
  # settings.py
193
253
  def should_track_request(request):
194
254
  # type: (HttpRequest) -> bool
195
255
  # Don't track health checks or admin requests
196
- if request.path.startswith('/health') or request.path.startswith('/admin'):
256
+ if request.path.startswith("/health") or request.path.startswith("/admin"):
197
257
  return False
198
258
  return True
199
259
 
200
260
  POSTHOG_MW_REQUEST_FILTER = should_track_request
201
261
  ```
202
262
 
203
- ### Modifying default tags
263
+ ### Modify default properties
204
264
 
205
- Use `POSTHOG_MW_TAG_MAP` to modify or remove default tags:
206
-
207
- Python
265
+ Use `POSTHOG_MW_PROPERTIES_MAP` to modify or remove default properties:
208
266
 
209
267
  ```python
210
268
  # settings.py
211
- def customize_tags(tags):
269
+ def customize_properties(properties):
212
270
  # type: (Dict[str, Any]) -> Dict[str, Any]
213
271
  # Remove URL for privacy
214
- tags.pop('$current_url', None)
272
+ properties.pop("$current_url", None)
215
273
  # Add custom prefix to method
216
- if '$request_method' in tags:
217
- tags['http_method'] = tags.pop('$request_method')
218
- return tags
274
+ if "$request_method" in properties:
275
+ properties["http_method"] = properties.pop("$request_method")
276
+ return properties
219
277
 
220
- POSTHOG_MW_TAG_MAP = customize_tags
278
+ POSTHOG_MW_PROPERTIES_MAP = customize_properties
221
279
  ```
222
280
 
223
281
  ### Complete configuration example
224
282
 
225
- Python
226
-
227
283
  ```python
228
284
  # settings.py
229
285
  def add_request_context(request):
230
286
  # type: (HttpRequest) -> Dict[str, Any]
231
- tags = {}
232
- if hasattr(request, 'user') and request.user.is_authenticated:
233
- tags['user_type'] = 'authenticated'
287
+ properties = {}
288
+ if hasattr(request, "user") and request.user.is_authenticated:
289
+ properties["user_type"] = "authenticated"
234
290
  # Use pk instead of id so this works with custom User primary keys.
235
- tags['user_id'] = str(request.user.pk)
291
+ properties["user_id"] = str(request.user.pk)
236
292
  else:
237
- tags['user_type'] = 'anonymous'
293
+ properties["user_type"] = "anonymous"
238
294
 
239
295
  # Add request info
240
- tags['user_agent'] = request.META.get('HTTP_USER_AGENT', '')
241
- return tags
296
+ properties["user_agent"] = request.META.get("HTTP_USER_AGENT", "")
297
+ return properties
242
298
 
243
299
  def filter_tracking(request):
244
300
  # type: (HttpRequest) -> bool
245
301
  # Skip internal endpoints
246
- return not request.path.startswith(('/health', '/metrics', '/admin'))
302
+ return not request.path.startswith(("/health", "/metrics", "/admin"))
247
303
 
248
- def clean_tags(tags):
304
+ def clean_properties(properties):
249
305
  # type: (Dict[str, Any]) -> Dict[str, Any]
250
306
  # Remove sensitive data
251
- tags.pop('user_agent', None)
252
- return tags
307
+ properties.pop("user_agent", None)
308
+ return properties
253
309
 
254
- POSTHOG_MW_EXTRA_TAGS = add_request_context
310
+ POSTHOG_MW_EXTRA_PROPERTIES = add_request_context
255
311
  POSTHOG_MW_REQUEST_FILTER = filter_tracking
256
- POSTHOG_MW_TAG_MAP = clean_tags
312
+ POSTHOG_MW_PROPERTIES_MAP = clean_properties
257
313
  POSTHOG_MW_CAPTURE_EXCEPTIONS = True
258
314
  ```
259
315
 
260
- 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.
316
+ All events captured within the request context automatically include the configured properties. They use the authenticated Django user as the distinct ID, or the session and distinct ID from request headers when you enable `POSTHOG_MW_TRUST_TRACING_HEADERS`.
261
317
 
262
318
  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.
263
319
 
264
320
  ## Next steps
265
321
 
266
- For any technical questions for how to integrate specific PostHog features into Django (such as analytics, feature flags, A/B testing, etc.), have a look at our [Python SDK docs](/docs/libraries/python.md).
322
+ For any technical questions for how to integrate specific PostHog features into Django (such as analytics, feature flags, A/B testing, etc.), have a look at our [Python SDK docs](https://posthog.com/docs/libraries/python.md).
267
323
 
268
324
  Alternatively, the following tutorials can help you get started:
269
325
 
270
- - [Setting up Django analytics, feature flags, and more](/tutorials/django-analytics.md)
271
- - [How to set up A/B tests in Django](/tutorials/django-ab-tests.md)
326
+ - [Setting up Django analytics, feature flags, and more](https://posthog.com/tutorials/django-analytics.md)
327
+ - [How to set up A/B tests in Django](https://posthog.com/tutorials/django-ab-tests.md)
272
328
 
273
329
  ## Supported versions
274
330
 
@@ -277,11 +333,3 @@ These docs cover version `7.x` of the PostHog Python SDK, which requires Python
277
333
  Everything on this page works the same way on `6.9.3`. Event capture, the context API (`new_context`, `identify_context`, `set_context_session`), and `PosthogContextMiddleware` are identical on `6.9.3` and `7.0.0` — `7.0.0` only dropped Python 3.9 and bumped the optional LLM provider SDKs. That includes the middleware identifying the request context from the `X-POSTHOG-DISTINCT-ID` header and falling back to the authenticated user, which behaves the same across both lines.
278
334
 
279
335
  Later `7.x` releases add what the 6.x line does not receive, such as the Celery integration, tracing header sanitization, and `set_context_device_id`. They also changed the middleware's own captured properties: `7.x` sends the request IP as `$ip`, where `6.9.3` sends it as `$ip_address`, and `7.x` additionally captures `$request_path`, `$raw_user_agent`, and the authenticated user's `email`.
280
-
281
- ### Still have questions?
282
-
283
- Ask PostHog AI
284
-
285
- ### Was this page useful?
286
-
287
- HelpfulCould be better