@amplitude/wizard 1.0.0-beta.2 → 1.0.0
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.
- package/README.md +171 -74
- package/dist/bin.js +338 -222
- package/dist/src/lib/agent-interface.js +64 -9
- package/dist/src/lib/agent-runner.js +1 -10
- package/dist/src/lib/api.d.ts +22 -4
- package/dist/src/lib/api.js +114 -12
- package/dist/src/lib/commandments.js +14 -1
- package/dist/src/lib/constants.d.ts +6 -5
- package/dist/src/lib/constants.js +13 -13
- package/dist/src/lib/credential-resolution.d.ts +45 -0
- package/dist/src/lib/credential-resolution.js +311 -0
- package/dist/src/lib/exit-codes.d.ts +10 -0
- package/dist/src/lib/exit-codes.js +12 -0
- package/dist/src/lib/health-checks/statuspage.d.ts +1 -0
- package/dist/src/lib/health-checks/statuspage.js +5 -1
- package/dist/src/lib/mode-config.d.ts +14 -0
- package/dist/src/lib/mode-config.js +14 -0
- package/dist/src/lib/session-checkpoint.d.ts +27 -0
- package/dist/src/lib/session-checkpoint.js +134 -0
- package/dist/src/lib/wizard-session.d.ts +44 -1
- package/dist/src/lib/wizard-session.js +70 -14
- package/dist/src/lib/wizard-tools.js +19 -4
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +3 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js +6 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +3 -1
- package/dist/src/ui/agent-ui.d.ts +91 -0
- package/dist/src/ui/agent-ui.js +277 -0
- package/dist/src/ui/logging-ui.js +1 -1
- package/dist/src/ui/tui/App.d.ts +12 -0
- package/dist/src/ui/tui/App.js +29 -18
- package/dist/src/ui/tui/components/AmplitudeLogo.js +16 -17
- package/dist/src/ui/tui/components/AmplitudeTextLogo.d.ts +0 -2
- package/dist/src/ui/tui/components/AmplitudeTextLogo.js +53 -18
- package/dist/src/ui/tui/components/BrailleSpinner.d.ts +8 -0
- package/dist/src/ui/tui/components/BrailleSpinner.js +15 -0
- package/dist/src/ui/tui/components/ConsoleView.d.ts +8 -11
- package/dist/src/ui/tui/components/ConsoleView.js +51 -34
- package/dist/src/ui/tui/components/HeaderBar.d.ts +12 -0
- package/dist/src/ui/tui/components/HeaderBar.js +17 -0
- package/dist/src/ui/tui/components/JourneyStepper.d.ts +16 -0
- package/dist/src/ui/tui/components/JourneyStepper.js +83 -0
- package/dist/src/ui/tui/components/KeyHintBar.d.ts +19 -0
- package/dist/src/ui/tui/components/KeyHintBar.js +20 -0
- package/dist/src/ui/tui/console-commands.d.ts +1 -2
- package/dist/src/ui/tui/console-commands.js +48 -7
- package/dist/src/ui/tui/flows.d.ts +1 -1
- package/dist/src/ui/tui/flows.js +1 -1
- package/dist/src/ui/tui/hooks/useAsyncEffect.d.ts +15 -0
- package/dist/src/ui/tui/hooks/useAsyncEffect.js +35 -0
- package/dist/src/ui/tui/hooks/useWizardStore.d.ts +9 -0
- package/dist/src/ui/tui/hooks/useWizardStore.js +11 -0
- package/dist/src/ui/tui/ink-ui.js +1 -1
- package/dist/src/ui/tui/primitives/DissolveTransition.js +4 -5
- package/dist/src/ui/tui/primitives/EventPlanViewer.d.ts +3 -1
- package/dist/src/ui/tui/primitives/EventPlanViewer.js +8 -3
- package/dist/src/ui/tui/primitives/ProgressList.js +1 -1
- package/dist/src/ui/tui/primitives/SlashCommandInput.js +19 -4
- package/dist/src/ui/tui/primitives/SplitView.d.ts +2 -1
- package/dist/src/ui/tui/primitives/SplitView.js +10 -2
- package/dist/src/ui/tui/primitives/TabContainer.js +10 -2
- package/dist/src/ui/tui/primitives/index.d.ts +0 -1
- package/dist/src/ui/tui/primitives/index.js +0 -1
- package/dist/src/ui/tui/router.js +1 -1
- package/dist/src/ui/tui/screen-registry.d.ts +0 -7
- package/dist/src/ui/tui/screen-registry.js +13 -4
- package/dist/src/ui/tui/screens/ActivationOptionsScreen.d.ts +2 -2
- package/dist/src/ui/tui/screens/ActivationOptionsScreen.js +8 -8
- package/dist/src/ui/tui/screens/AuthScreen.js +57 -27
- package/dist/src/ui/tui/screens/ChecklistScreen.d.ts +2 -12
- package/dist/src/ui/tui/screens/ChecklistScreen.js +22 -33
- package/dist/src/ui/tui/screens/DataIngestionCheckScreen.d.ts +3 -12
- package/dist/src/ui/tui/screens/DataIngestionCheckScreen.js +109 -39
- package/dist/src/ui/tui/screens/DataSetupScreen.d.ts +3 -3
- package/dist/src/ui/tui/screens/DataSetupScreen.js +17 -10
- package/dist/src/ui/tui/screens/IntroScreen.d.ts +5 -3
- package/dist/src/ui/tui/screens/IntroScreen.js +132 -41
- package/dist/src/ui/tui/screens/LoginScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/LoginScreen.js +4 -4
- package/dist/src/ui/tui/screens/LogoutScreen.d.ts +4 -2
- package/dist/src/ui/tui/screens/LogoutScreen.js +17 -5
- package/dist/src/ui/tui/screens/McpScreen.d.ts +4 -4
- package/dist/src/ui/tui/screens/McpScreen.js +25 -17
- package/dist/src/ui/tui/screens/OutageScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/OutageScreen.js +5 -5
- package/dist/src/ui/tui/screens/OutroScreen.d.ts +5 -0
- package/dist/src/ui/tui/screens/OutroScreen.js +21 -14
- package/dist/src/ui/tui/screens/RegionSelectScreen.js +15 -13
- package/dist/src/ui/tui/screens/RunScreen.d.ts +7 -5
- package/dist/src/ui/tui/screens/RunScreen.js +102 -157
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +6 -5
- package/dist/src/ui/tui/screens/SetupScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/SetupScreen.js +7 -7
- package/dist/src/ui/tui/screens/SlackScreen.d.ts +2 -2
- package/dist/src/ui/tui/screens/SlackScreen.js +60 -35
- package/dist/src/ui/tui/session-constants.d.ts +41 -0
- package/dist/src/ui/tui/session-constants.js +38 -0
- package/dist/src/ui/tui/start-tui.d.ts +3 -1
- package/dist/src/ui/tui/start-tui.js +14 -10
- package/dist/src/ui/tui/store.d.ts +2 -1
- package/dist/src/ui/tui/store.js +33 -7
- package/dist/src/ui/tui/styles.d.ts +75 -19
- package/dist/src/ui/tui/styles.js +101 -19
- package/dist/src/ui/tui/utils/classify-error.d.ts +14 -0
- package/dist/src/ui/tui/utils/classify-error.js +90 -0
- package/dist/src/ui/tui/utils/diagnostics.d.ts +21 -0
- package/dist/src/ui/tui/utils/diagnostics.js +72 -0
- package/dist/src/ui/tui/utils/with-retry.d.ts +12 -0
- package/dist/src/ui/tui/utils/with-retry.js +32 -0
- package/dist/src/ui/tui/utils/with-timeout.d.ts +10 -0
- package/dist/src/ui/tui/utils/with-timeout.js +24 -0
- package/dist/src/utils/ampli-settings.d.ts +1 -1
- package/dist/src/utils/ampli-settings.js +15 -5
- package/dist/src/utils/api-key-store.js +5 -5
- package/dist/src/utils/atomic-write.d.ts +15 -0
- package/dist/src/utils/atomic-write.js +34 -0
- package/dist/src/utils/setup-utils.js +2 -2
- package/dist/src/utils/token-refresh.d.ts +22 -0
- package/dist/src/utils/token-refresh.js +79 -0
- package/dist/src/utils/wizard-abort.js +6 -1
- package/package.json +6 -6
- package/skills/instrumentation/add-analytics-instrumentation/SKILL.md +142 -0
- package/skills/instrumentation/diff-intake/SKILL.md +128 -0
- package/skills/instrumentation/discover-analytics-patterns/SKILL.md +185 -0
- package/skills/instrumentation/discover-event-surfaces/SKILL.md +322 -0
- package/skills/instrumentation/discover-event-surfaces/references/best-practices.md +563 -0
- package/skills/instrumentation/instrument-events/SKILL.md +169 -0
- package/skills/instrumentation/instrument-events/references/best-practices.md +563 -0
- package/skills/integration/integration-android/SKILL.md +49 -0
- package/skills/integration/integration-android/references/EXAMPLE.md +1977 -0
- package/skills/integration/integration-android/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-android/references/analytics.md +1778 -0
- package/skills/integration/integration-android/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-android/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-android/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-android/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-angular/SKILL.md +49 -0
- package/skills/integration/integration-angular/references/EXAMPLE.md +899 -0
- package/skills/integration/integration-angular/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-angular/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-angular/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-angular/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-angular/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-angular/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-hybrid/SKILL.md +56 -0
- package/skills/integration/integration-astro-hybrid/references/EXAMPLE.md +1095 -0
- package/skills/integration/integration-astro-hybrid/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-hybrid/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-ssr/SKILL.md +52 -0
- package/skills/integration/integration-astro-ssr/references/EXAMPLE.md +1106 -0
- package/skills/integration/integration-astro-ssr/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-ssr/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-static/SKILL.md +49 -0
- package/skills/integration/integration-astro-static/references/EXAMPLE.md +910 -0
- package/skills/integration/integration-astro-static/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-static/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-view-transitions/SKILL.md +51 -0
- package/skills/integration/integration-astro-view-transitions/references/EXAMPLE.md +979 -0
- package/skills/integration/integration-astro-view-transitions/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-view-transitions/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-django/SKILL.md +57 -0
- package/skills/integration/integration-django/references/EXAMPLE.md +1005 -0
- package/skills/integration/integration-django/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-django/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-django/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-django/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-django/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-django/references/python.md +1424 -0
- package/skills/integration/integration-expo/SKILL.md +53 -0
- package/skills/integration/integration-expo/references/EXAMPLE.md +1291 -0
- package/skills/integration/integration-expo/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-expo/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-expo/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-expo/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-expo/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-expo/references/react-native-sdk.md +2819 -0
- package/skills/integration/integration-fastapi/SKILL.md +57 -0
- package/skills/integration/integration-fastapi/references/EXAMPLE.md +1389 -0
- package/skills/integration/integration-fastapi/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-fastapi/references/python.md +1424 -0
- package/skills/integration/integration-flask/SKILL.md +56 -0
- package/skills/integration/integration-flask/references/EXAMPLE.md +1130 -0
- package/skills/integration/integration-flask/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-flask/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-flask/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-flask/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-flask/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-flask/references/python.md +1424 -0
- package/skills/integration/integration-javascript_node/SKILL.md +54 -0
- package/skills/integration/integration-javascript_node/references/EXAMPLE.md +365 -0
- package/skills/integration/integration-javascript_node/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-javascript_node/references/analytics.md +1778 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-javascript_web/SKILL.md +58 -0
- package/skills/integration/integration-javascript_web/references/EXAMPLE.md +451 -0
- package/skills/integration/integration-javascript_web/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-javascript_web/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-laravel/SKILL.md +52 -0
- package/skills/integration/integration-laravel/references/EXAMPLE.md +2039 -0
- package/skills/integration/integration-laravel/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-laravel/references/analytics.md +1778 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nextjs-app-router/SKILL.md +54 -0
- package/skills/integration/integration-nextjs-app-router/references/EXAMPLE.md +673 -0
- package/skills/integration/integration-nextjs-app-router/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nextjs-app-router/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-nextjs-pages-router/SKILL.md +54 -0
- package/skills/integration/integration-nextjs-pages-router/references/EXAMPLE.md +735 -0
- package/skills/integration/integration-nextjs-pages-router/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nextjs-pages-router/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-nuxt-3.6/SKILL.md +46 -0
- package/skills/integration/integration-nuxt-3.6/references/EXAMPLE.md +8422 -0
- package/skills/integration/integration-nuxt-3.6/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nuxt-3.6/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-nuxt-4/SKILL.md +46 -0
- package/skills/integration/integration-nuxt-4/references/EXAMPLE.md +8670 -0
- package/skills/integration/integration-nuxt-4/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nuxt-4/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-python/SKILL.md +53 -0
- package/skills/integration/integration-python/references/EXAMPLE.md +445 -0
- package/skills/integration/integration-python/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-python/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-python/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-python/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-python/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-python/references/python.md +1424 -0
- package/skills/integration/integration-react-native/SKILL.md +49 -0
- package/skills/integration/integration-react-native/references/EXAMPLE.md +2253 -0
- package/skills/integration/integration-react-native/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-native/references/react-native-sdk.md +2819 -0
- package/skills/integration/integration-react-react-router-6/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-6/references/EXAMPLE.md +570 -0
- package/skills/integration/integration-react-react-router-6/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-6/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-react-router-7-data/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-7-data/references/EXAMPLE.md +830 -0
- package/skills/integration/integration-react-react-router-7-data/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-7-data/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-react-router-7-declarative/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/EXAMPLE.md +609 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-react-router-7-framework/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-7-framework/references/EXAMPLE.md +1081 -0
- package/skills/integration/integration-react-react-router-7-framework/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-7-framework/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-tanstack-router-code-based/SKILL.md +57 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/EXAMPLE.md +659 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-tanstack-router-file-based/SKILL.md +57 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/EXAMPLE.md +777 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-vite/SKILL.md +53 -0
- package/skills/integration/integration-react-vite/references/EXAMPLE.md +542 -0
- package/skills/integration/integration-react-vite/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-vite/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-ruby/SKILL.md +50 -0
- package/skills/integration/integration-ruby/references/EXAMPLE.md +420 -0
- package/skills/integration/integration-ruby/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-ruby/references/analytics.md +1778 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-ruby-on-rails/SKILL.md +55 -0
- package/skills/integration/integration-ruby-on-rails/references/EXAMPLE.md +1013 -0
- package/skills/integration/integration-ruby-on-rails/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-ruby-on-rails/references/analytics.md +1778 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-sveltekit/SKILL.md +47 -0
- package/skills/integration/integration-sveltekit/references/EXAMPLE.md +14121 -0
- package/skills/integration/integration-sveltekit/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-sveltekit/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-swift/SKILL.md +49 -0
- package/skills/integration/integration-swift/references/EXAMPLE.md +660 -0
- package/skills/integration/integration-swift/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-swift/references/analytics.md +1778 -0
- package/skills/integration/integration-swift/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-swift/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-swift/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-swift/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-tanstack-start/SKILL.md +58 -0
- package/skills/integration/integration-tanstack-start/references/EXAMPLE.md +998 -0
- package/skills/integration/integration-tanstack-start/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-tanstack-start/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-vue-3/SKILL.md +46 -0
- package/skills/integration/integration-vue-3/references/EXAMPLE.md +846 -0
- package/skills/integration/integration-vue-3/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-vue-3/references/browser-sdk-2.md +4680 -0
- package/skills/taxonomy/amplitude-quickstart-taxonomy-agent/SKILL.md +228 -0
- package/dist/src/ui/tui/components/TitleBar.d.ts +0 -8
- package/dist/src/ui/tui/components/TitleBar.js +0 -27
- package/dist/src/ui/tui/primitives/KagiSmallWebViewer.d.ts +0 -7
- package/dist/src/ui/tui/primitives/KagiSmallWebViewer.js +0 -101
- package/dist/src/utils/anthropic-status.d.ts +0 -17
- package/dist/src/utils/anthropic-status.js +0 -51
|
@@ -0,0 +1,1005 @@
|
|
|
1
|
+
# Amplitude Django Example Project
|
|
2
|
+
|
|
3
|
+
Repository: https://github.com/amplitude/context-hub
|
|
4
|
+
Path: basics/django
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## README.md
|
|
9
|
+
|
|
10
|
+
# Amplitude Django example
|
|
11
|
+
|
|
12
|
+
This is a [Django](https://djangoproject.com) example demonstrating Amplitude integration with product analytics and user identification.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Product analytics**: Track user events and behaviors
|
|
17
|
+
- **User identification**: Associate events with authenticated users
|
|
18
|
+
- **Server-side tracking**: All tracking happens server-side with the Python SDK
|
|
19
|
+
|
|
20
|
+
## Getting started
|
|
21
|
+
|
|
22
|
+
### 1. Install dependencies
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -r requirements.txt
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Configure environment variables
|
|
29
|
+
|
|
30
|
+
Create a `.env` file in the root directory:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
AMPLITUDE_API_KEY=your_amplitude_api_key
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Get your Amplitude API key from your [Amplitude project settings](https://app.amplitude.com).
|
|
37
|
+
|
|
38
|
+
### 3. Run migrations
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python manage.py migrate
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 4. Run the development server
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
python manage.py runserver
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Open [http://localhost:8000](http://localhost:8000) with your browser to see the app.
|
|
51
|
+
|
|
52
|
+
## Project structure
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
django/
|
|
56
|
+
├── manage.py # Django management script
|
|
57
|
+
├── requirements.txt # Python dependencies
|
|
58
|
+
├── .env.example # Environment variable template
|
|
59
|
+
├── .gitignore
|
|
60
|
+
├── amplitude_example/
|
|
61
|
+
│ ├── __init__.py
|
|
62
|
+
│ ├── settings.py # Django settings with Amplitude config
|
|
63
|
+
│ ├── urls.py # URL routing
|
|
64
|
+
│ ├── wsgi.py # WSGI application
|
|
65
|
+
│ └── asgi.py # ASGI application
|
|
66
|
+
└── core/
|
|
67
|
+
├── __init__.py
|
|
68
|
+
├── apps.py # AppConfig
|
|
69
|
+
├── views.py # Views with event tracking examples
|
|
70
|
+
├── urls.py # App URL patterns
|
|
71
|
+
└── templates/
|
|
72
|
+
└── core/
|
|
73
|
+
├── base.html # Base template
|
|
74
|
+
├── home.html # Home/login page
|
|
75
|
+
├── burrito.html # Burrito page with event tracking
|
|
76
|
+
├── dashboard.html # Dashboard page
|
|
77
|
+
└── profile.html # Profile page
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Key integration points
|
|
81
|
+
|
|
82
|
+
### Django settings configuration (settings.py)
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import os
|
|
86
|
+
|
|
87
|
+
AMPLITUDE_API_KEY = os.environ.get('AMPLITUDE_API_KEY', '')
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Amplitude client helper (core/views.py)
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from amplitude import Amplitude, BaseEvent, Identify
|
|
94
|
+
|
|
95
|
+
def get_amplitude_client():
|
|
96
|
+
api_key = getattr(settings, 'AMPLITUDE_API_KEY', '')
|
|
97
|
+
if not api_key:
|
|
98
|
+
return None
|
|
99
|
+
return Amplitude(api_key)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### User identification (core/views.py)
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
client = get_amplitude_client()
|
|
106
|
+
if client:
|
|
107
|
+
identify_obj = Identify()
|
|
108
|
+
identify_obj.set('email', user.email)
|
|
109
|
+
identify_obj.set('username', user.username)
|
|
110
|
+
client.identify(identify_obj, {"user_id": str(user.id)})
|
|
111
|
+
|
|
112
|
+
client.track(BaseEvent(
|
|
113
|
+
event_type='User Logged In',
|
|
114
|
+
user_id=str(user.id),
|
|
115
|
+
event_properties={'login_method': 'email'},
|
|
116
|
+
))
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Event tracking (core/views.py)
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
client = get_amplitude_client()
|
|
123
|
+
if client:
|
|
124
|
+
client.track(BaseEvent(
|
|
125
|
+
event_type='Burrito Considered',
|
|
126
|
+
user_id=user_id,
|
|
127
|
+
event_properties={'total_considerations': count},
|
|
128
|
+
))
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Learn more
|
|
132
|
+
|
|
133
|
+
- [Amplitude Python SDK Documentation](https://amplitude.com/docs/sdks/analytics/python)
|
|
134
|
+
- [Amplitude Quickstart](https://amplitude.com/docs/get-started/amplitude-quickstart)
|
|
135
|
+
- [Django documentation](https://docs.djangoproject.com/)
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## .env.example
|
|
140
|
+
|
|
141
|
+
```example
|
|
142
|
+
AMPLITUDE_API_KEY=
|
|
143
|
+
DJANGO_SECRET_KEY=your-secret-key-here
|
|
144
|
+
DEBUG=True
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## amplitude_example/__init__.py
|
|
151
|
+
|
|
152
|
+
```py
|
|
153
|
+
# Amplitude Django example project
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## amplitude_example/asgi.py
|
|
160
|
+
|
|
161
|
+
```py
|
|
162
|
+
"""
|
|
163
|
+
ASGI config for Amplitude example project
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
import os
|
|
167
|
+
|
|
168
|
+
from django.core.asgi import get_asgi_application
|
|
169
|
+
|
|
170
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'amplitude_example.settings')
|
|
171
|
+
|
|
172
|
+
application = get_asgi_application()
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## amplitude_example/settings.py
|
|
179
|
+
|
|
180
|
+
```py
|
|
181
|
+
"""Django settings for Amplitude example project"""
|
|
182
|
+
|
|
183
|
+
import os
|
|
184
|
+
from pathlib import Path
|
|
185
|
+
|
|
186
|
+
try:
|
|
187
|
+
from dotenv import load_dotenv
|
|
188
|
+
load_dotenv()
|
|
189
|
+
except ImportError:
|
|
190
|
+
pass
|
|
191
|
+
|
|
192
|
+
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
193
|
+
|
|
194
|
+
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'django-insecure-example-key-change-in-production')
|
|
195
|
+
|
|
196
|
+
DEBUG = os.environ.get('DEBUG', 'True').lower() == 'true'
|
|
197
|
+
|
|
198
|
+
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# Amplitude configuration
|
|
202
|
+
AMPLITUDE_API_KEY = os.environ.get('AMPLITUDE_API_KEY', '')
|
|
203
|
+
AMPLITUDE_DISABLED = os.environ.get('AMPLITUDE_DISABLED', 'False').lower() == 'true'
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
INSTALLED_APPS = [
|
|
207
|
+
'django.contrib.admin',
|
|
208
|
+
'django.contrib.auth',
|
|
209
|
+
'django.contrib.contenttypes',
|
|
210
|
+
'django.contrib.sessions',
|
|
211
|
+
'django.contrib.messages',
|
|
212
|
+
'django.contrib.staticfiles',
|
|
213
|
+
'core.apps.CoreConfig',
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
MIDDLEWARE = [
|
|
217
|
+
'django.middleware.security.SecurityMiddleware',
|
|
218
|
+
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
219
|
+
'django.middleware.common.CommonMiddleware',
|
|
220
|
+
'django.middleware.csrf.CsrfViewMiddleware',
|
|
221
|
+
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
222
|
+
'django.contrib.messages.middleware.MessageMiddleware',
|
|
223
|
+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
224
|
+
]
|
|
225
|
+
|
|
226
|
+
ROOT_URLCONF = 'amplitude_example.urls'
|
|
227
|
+
|
|
228
|
+
TEMPLATES = [
|
|
229
|
+
{
|
|
230
|
+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
231
|
+
'DIRS': [],
|
|
232
|
+
'APP_DIRS': True,
|
|
233
|
+
'OPTIONS': {
|
|
234
|
+
'context_processors': [
|
|
235
|
+
'django.template.context_processors.debug',
|
|
236
|
+
'django.template.context_processors.request',
|
|
237
|
+
'django.contrib.auth.context_processors.auth',
|
|
238
|
+
'django.contrib.messages.context_processors.messages',
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
WSGI_APPLICATION = 'amplitude_example.wsgi.application'
|
|
245
|
+
|
|
246
|
+
DATABASES = {
|
|
247
|
+
'default': {
|
|
248
|
+
'ENGINE': 'django.db.backends.sqlite3',
|
|
249
|
+
'NAME': BASE_DIR / 'db.sqlite3',
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
AUTH_PASSWORD_VALIDATORS = [
|
|
254
|
+
{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
|
|
255
|
+
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
|
|
256
|
+
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
|
|
257
|
+
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
|
|
258
|
+
]
|
|
259
|
+
|
|
260
|
+
LANGUAGE_CODE = 'en-us'
|
|
261
|
+
TIME_ZONE = 'UTC'
|
|
262
|
+
USE_I18N = True
|
|
263
|
+
USE_TZ = True
|
|
264
|
+
|
|
265
|
+
STATIC_URL = 'static/'
|
|
266
|
+
|
|
267
|
+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## amplitude_example/urls.py
|
|
274
|
+
|
|
275
|
+
```py
|
|
276
|
+
"""
|
|
277
|
+
URL configuration for Amplitude example project
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
from django.contrib import admin
|
|
281
|
+
from django.urls import path, include
|
|
282
|
+
|
|
283
|
+
urlpatterns = [
|
|
284
|
+
path('admin/', admin.site.urls),
|
|
285
|
+
# Include the core app URLs for Amplitude examples
|
|
286
|
+
path('', include('core.urls')),
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## amplitude_example/wsgi.py
|
|
294
|
+
|
|
295
|
+
```py
|
|
296
|
+
"""
|
|
297
|
+
WSGI config for Amplitude example project
|
|
298
|
+
"""
|
|
299
|
+
|
|
300
|
+
import os
|
|
301
|
+
|
|
302
|
+
from django.core.wsgi import get_wsgi_application
|
|
303
|
+
|
|
304
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'amplitude_example.settings')
|
|
305
|
+
|
|
306
|
+
application = get_wsgi_application()
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## core/__init__.py
|
|
313
|
+
|
|
314
|
+
```py
|
|
315
|
+
# Core app for Amplitude Django example
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## core/apps.py
|
|
322
|
+
|
|
323
|
+
```py
|
|
324
|
+
"""
|
|
325
|
+
Django AppConfig for the Amplitude example application.
|
|
326
|
+
|
|
327
|
+
This ensures the app is configured correctly when Django starts.
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
from django.apps import AppConfig
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
class CoreConfig(AppConfig):
|
|
334
|
+
default_auto_field = 'django.db.models.BigAutoField'
|
|
335
|
+
name = 'core'
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## core/templates/core/base.html
|
|
342
|
+
|
|
343
|
+
```html
|
|
344
|
+
<!DOCTYPE html>
|
|
345
|
+
<html lang="en">
|
|
346
|
+
<head>
|
|
347
|
+
<meta charset="UTF-8">
|
|
348
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
349
|
+
<title>{% block title %}Amplitude Django example{% endblock %}</title>
|
|
350
|
+
<style>
|
|
351
|
+
* {
|
|
352
|
+
box-sizing: border-box;
|
|
353
|
+
margin: 0;
|
|
354
|
+
padding: 0;
|
|
355
|
+
}
|
|
356
|
+
body {
|
|
357
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
|
358
|
+
line-height: 1.6;
|
|
359
|
+
background-color: #f5f5f5;
|
|
360
|
+
color: #333;
|
|
361
|
+
}
|
|
362
|
+
.container {
|
|
363
|
+
max-width: 800px;
|
|
364
|
+
margin: 0 auto;
|
|
365
|
+
padding: 20px;
|
|
366
|
+
}
|
|
367
|
+
nav {
|
|
368
|
+
background: #1d4ed8;
|
|
369
|
+
padding: 15px 20px;
|
|
370
|
+
margin-bottom: 30px;
|
|
371
|
+
}
|
|
372
|
+
nav a {
|
|
373
|
+
color: white;
|
|
374
|
+
text-decoration: none;
|
|
375
|
+
margin-right: 20px;
|
|
376
|
+
}
|
|
377
|
+
nav a:hover {
|
|
378
|
+
text-decoration: underline;
|
|
379
|
+
}
|
|
380
|
+
.card {
|
|
381
|
+
background: white;
|
|
382
|
+
border-radius: 8px;
|
|
383
|
+
padding: 20px;
|
|
384
|
+
margin-bottom: 20px;
|
|
385
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
386
|
+
}
|
|
387
|
+
h1, h2, h3 {
|
|
388
|
+
margin-bottom: 15px;
|
|
389
|
+
color: #1d4ed8;
|
|
390
|
+
}
|
|
391
|
+
button, .btn {
|
|
392
|
+
background: #1d4ed8;
|
|
393
|
+
color: white;
|
|
394
|
+
border: none;
|
|
395
|
+
padding: 10px 20px;
|
|
396
|
+
border-radius: 5px;
|
|
397
|
+
cursor: pointer;
|
|
398
|
+
font-size: 14px;
|
|
399
|
+
display: inline-block;
|
|
400
|
+
text-decoration: none;
|
|
401
|
+
}
|
|
402
|
+
button:hover, .btn:hover {
|
|
403
|
+
background: #1e40af;
|
|
404
|
+
}
|
|
405
|
+
button.danger {
|
|
406
|
+
background: #dc2626;
|
|
407
|
+
}
|
|
408
|
+
button.danger:hover {
|
|
409
|
+
background: #b91c1c;
|
|
410
|
+
}
|
|
411
|
+
input {
|
|
412
|
+
width: 100%;
|
|
413
|
+
padding: 10px;
|
|
414
|
+
margin-bottom: 15px;
|
|
415
|
+
border: 1px solid #ddd;
|
|
416
|
+
border-radius: 5px;
|
|
417
|
+
font-size: 14px;
|
|
418
|
+
}
|
|
419
|
+
.messages {
|
|
420
|
+
margin-bottom: 20px;
|
|
421
|
+
}
|
|
422
|
+
.message {
|
|
423
|
+
padding: 10px 15px;
|
|
424
|
+
border-radius: 5px;
|
|
425
|
+
margin-bottom: 10px;
|
|
426
|
+
}
|
|
427
|
+
.message.error {
|
|
428
|
+
background: #fee2e2;
|
|
429
|
+
color: #dc2626;
|
|
430
|
+
}
|
|
431
|
+
.message.success {
|
|
432
|
+
background: #d1fae5;
|
|
433
|
+
color: #059669;
|
|
434
|
+
}
|
|
435
|
+
code {
|
|
436
|
+
background: #f3f4f6;
|
|
437
|
+
padding: 2px 6px;
|
|
438
|
+
border-radius: 3px;
|
|
439
|
+
font-family: monospace;
|
|
440
|
+
}
|
|
441
|
+
.count {
|
|
442
|
+
font-size: 48px;
|
|
443
|
+
font-weight: bold;
|
|
444
|
+
color: #1d4ed8;
|
|
445
|
+
text-align: center;
|
|
446
|
+
padding: 20px;
|
|
447
|
+
}
|
|
448
|
+
</style>
|
|
449
|
+
</head>
|
|
450
|
+
<body>
|
|
451
|
+
{% if user.is_authenticated %}
|
|
452
|
+
<nav>
|
|
453
|
+
<a href="{% url 'dashboard' %}">Dashboard</a>
|
|
454
|
+
<a href="{% url 'burrito' %}">Burrito</a>
|
|
455
|
+
<a href="{% url 'profile' %}">Profile</a>
|
|
456
|
+
<a href="{% url 'logout' %}" style="float: right;">Logout ({{ user.username }})</a>
|
|
457
|
+
</nav>
|
|
458
|
+
{% endif %}
|
|
459
|
+
|
|
460
|
+
<div class="container">
|
|
461
|
+
{% if messages %}
|
|
462
|
+
<div class="messages">
|
|
463
|
+
{% for message in messages %}
|
|
464
|
+
<div class="message {{ message.tags }}">{{ message }}</div>
|
|
465
|
+
{% endfor %}
|
|
466
|
+
</div>
|
|
467
|
+
{% endif %}
|
|
468
|
+
|
|
469
|
+
{% block content %}{% endblock %}
|
|
470
|
+
</div>
|
|
471
|
+
|
|
472
|
+
{% block scripts %}{% endblock %}
|
|
473
|
+
</body>
|
|
474
|
+
</html>
|
|
475
|
+
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## core/templates/core/burrito.html
|
|
481
|
+
|
|
482
|
+
```html
|
|
483
|
+
{% extends 'core/base.html' %}
|
|
484
|
+
|
|
485
|
+
{% block title %}Burrito - Amplitude Django example{% endblock %}
|
|
486
|
+
|
|
487
|
+
{% block content %}
|
|
488
|
+
<div class="card">
|
|
489
|
+
<h1>Burrito consideration tracker</h1>
|
|
490
|
+
<p>This page demonstrates custom event tracking with Amplitude.</p>
|
|
491
|
+
</div>
|
|
492
|
+
|
|
493
|
+
<div class="card" style="text-align: center;">
|
|
494
|
+
<h2>Times considered</h2>
|
|
495
|
+
<div class="count" id="burrito-count">{{ burrito_count }}</div>
|
|
496
|
+
<button onclick="considerBurrito()" style="font-size: 18px; padding: 15px 30px;">
|
|
497
|
+
Consider a burrito
|
|
498
|
+
</button>
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
<div class="card">
|
|
502
|
+
<h3>How event tracking works</h3>
|
|
503
|
+
<p>Each time you click the button, a <code>Burrito Considered</code> event is sent to Amplitude:</p>
|
|
504
|
+
<pre style="background: #f3f4f6; padding: 15px; border-radius: 5px; overflow-x: auto; margin-top: 15px;"><code>from amplitude import Amplitude, BaseEvent
|
|
505
|
+
|
|
506
|
+
client = Amplitude(api_key)
|
|
507
|
+
client.track(BaseEvent(
|
|
508
|
+
event_type='Burrito Considered',
|
|
509
|
+
user_id=user_id,
|
|
510
|
+
event_properties={'total_considerations': count},
|
|
511
|
+
))</code></pre>
|
|
512
|
+
</div>
|
|
513
|
+
{% endblock %}
|
|
514
|
+
|
|
515
|
+
{% block scripts %}
|
|
516
|
+
<script>
|
|
517
|
+
async function considerBurrito() {
|
|
518
|
+
try {
|
|
519
|
+
const response = await fetch('{% url "consider_burrito" %}', {
|
|
520
|
+
method: 'POST',
|
|
521
|
+
headers: {
|
|
522
|
+
'X-CSRFToken': '{{ csrf_token }}',
|
|
523
|
+
'Content-Type': 'application/json',
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
const data = await response.json();
|
|
528
|
+
|
|
529
|
+
if (data.success) {
|
|
530
|
+
document.getElementById('burrito-count').textContent = data.count;
|
|
531
|
+
}
|
|
532
|
+
} catch (error) {
|
|
533
|
+
console.error('Error:', error);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
</script>
|
|
537
|
+
{% endblock %}
|
|
538
|
+
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
## core/templates/core/dashboard.html
|
|
544
|
+
|
|
545
|
+
```html
|
|
546
|
+
{% extends 'core/base.html' %}
|
|
547
|
+
|
|
548
|
+
{% block title %}Dashboard - Amplitude Django example{% endblock %}
|
|
549
|
+
|
|
550
|
+
{% block content %}
|
|
551
|
+
<div class="card">
|
|
552
|
+
<h1>Dashboard</h1>
|
|
553
|
+
<p>Welcome back, <strong>{{ user.username }}</strong>!</p>
|
|
554
|
+
</div>
|
|
555
|
+
|
|
556
|
+
<div class="card">
|
|
557
|
+
<h2>Analytics tracking</h2>
|
|
558
|
+
<p>This page view is tracked as a <code>Dashboard Viewed</code> event in Amplitude.</p>
|
|
559
|
+
<p style="margin-top: 10px; color: #666; font-size: 14px;">
|
|
560
|
+
Note: Feature flags are available via Amplitude Experiment (separate SDK).
|
|
561
|
+
</p>
|
|
562
|
+
</div>
|
|
563
|
+
|
|
564
|
+
<div class="card">
|
|
565
|
+
<h3>How event tracking works</h3>
|
|
566
|
+
<pre style="background: #f3f4f6; padding: 15px; border-radius: 5px; overflow-x: auto;"><code>from amplitude import Amplitude, BaseEvent
|
|
567
|
+
|
|
568
|
+
client = Amplitude(api_key)
|
|
569
|
+
client.track(BaseEvent(
|
|
570
|
+
event_type='Dashboard Viewed',
|
|
571
|
+
user_id=user_id,
|
|
572
|
+
event_properties={'is_staff': user.is_staff},
|
|
573
|
+
))</code></pre>
|
|
574
|
+
</div>
|
|
575
|
+
{% endblock %}
|
|
576
|
+
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## core/templates/core/home.html
|
|
582
|
+
|
|
583
|
+
```html
|
|
584
|
+
{% extends 'core/base.html' %}
|
|
585
|
+
|
|
586
|
+
{% block title %}Login - Amplitude Django example{% endblock %}
|
|
587
|
+
|
|
588
|
+
{% block content %}
|
|
589
|
+
<div class="card">
|
|
590
|
+
<h1>Amplitude Django example</h1>
|
|
591
|
+
<p>Welcome! This example demonstrates Amplitude integration with Django.</p>
|
|
592
|
+
</div>
|
|
593
|
+
|
|
594
|
+
<div class="card">
|
|
595
|
+
<h2>Login</h2>
|
|
596
|
+
<p>Login to see Amplitude analytics in action.</p>
|
|
597
|
+
|
|
598
|
+
<form method="post" style="margin-top: 20px;">
|
|
599
|
+
{% csrf_token %}
|
|
600
|
+
<input type="text" name="username" placeholder="Username" required>
|
|
601
|
+
<input type="password" name="password" placeholder="Password" required>
|
|
602
|
+
<button type="submit">Login</button>
|
|
603
|
+
</form>
|
|
604
|
+
|
|
605
|
+
<p style="margin-top: 15px; color: #666; font-size: 14px;">
|
|
606
|
+
Tip: Create a user with <code>python manage.py createsuperuser</code>
|
|
607
|
+
</p>
|
|
608
|
+
</div>
|
|
609
|
+
|
|
610
|
+
<div class="card">
|
|
611
|
+
<h3>What this example demonstrates</h3>
|
|
612
|
+
<ul style="padding-left: 20px;">
|
|
613
|
+
<li><strong>User identification</strong> - Users are identified with <code>client.identify()</code> on login</li>
|
|
614
|
+
<li><strong>Event tracking</strong> - Custom events captured with <code>client.track()</code></li>
|
|
615
|
+
<li><strong>Error tracking</strong> - Exceptions tracked as events</li>
|
|
616
|
+
</ul>
|
|
617
|
+
</div>
|
|
618
|
+
{% endblock %}
|
|
619
|
+
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## core/templates/core/profile.html
|
|
625
|
+
|
|
626
|
+
```html
|
|
627
|
+
{% extends 'core/base.html' %}
|
|
628
|
+
|
|
629
|
+
{% block title %}Profile - Amplitude Django example{% endblock %}
|
|
630
|
+
|
|
631
|
+
{% block content %}
|
|
632
|
+
<div class="card">
|
|
633
|
+
<h1>Profile</h1>
|
|
634
|
+
<p>This page demonstrates error tracking with Amplitude.</p>
|
|
635
|
+
</div>
|
|
636
|
+
|
|
637
|
+
<div class="card">
|
|
638
|
+
<h2>User information</h2>
|
|
639
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
640
|
+
<tr>
|
|
641
|
+
<td style="padding: 10px; border-bottom: 1px solid #eee;"><strong>Username:</strong></td>
|
|
642
|
+
<td style="padding: 10px; border-bottom: 1px solid #eee;">{{ user.username }}</td>
|
|
643
|
+
</tr>
|
|
644
|
+
<tr>
|
|
645
|
+
<td style="padding: 10px; border-bottom: 1px solid #eee;"><strong>Email:</strong></td>
|
|
646
|
+
<td style="padding: 10px; border-bottom: 1px solid #eee;">{{ user.email|default:"Not set" }}</td>
|
|
647
|
+
</tr>
|
|
648
|
+
<tr>
|
|
649
|
+
<td style="padding: 10px; border-bottom: 1px solid #eee;"><strong>Date Joined:</strong></td>
|
|
650
|
+
<td style="padding: 10px; border-bottom: 1px solid #eee;">{{ user.date_joined }}</td>
|
|
651
|
+
</tr>
|
|
652
|
+
<tr>
|
|
653
|
+
<td style="padding: 10px;"><strong>Staff Status:</strong></td>
|
|
654
|
+
<td style="padding: 10px;">{{ user.is_staff|yesno:"Yes,No" }}</td>
|
|
655
|
+
</tr>
|
|
656
|
+
</table>
|
|
657
|
+
</div>
|
|
658
|
+
|
|
659
|
+
<div class="card">
|
|
660
|
+
<h2>Error tracking demo</h2>
|
|
661
|
+
<p>Click the buttons below to trigger different types of errors. These errors are tracked and sent to Amplitude.</p>
|
|
662
|
+
|
|
663
|
+
<div style="margin-top: 20px;">
|
|
664
|
+
<button class="danger" onclick="triggerError('value')">
|
|
665
|
+
Trigger ValueError
|
|
666
|
+
</button>
|
|
667
|
+
<button class="danger" onclick="triggerError('key')" style="margin-left: 10px;">
|
|
668
|
+
Trigger KeyError
|
|
669
|
+
</button>
|
|
670
|
+
<button class="danger" onclick="triggerError('generic')" style="margin-left: 10px;">
|
|
671
|
+
Trigger Generic Error
|
|
672
|
+
</button>
|
|
673
|
+
</div>
|
|
674
|
+
|
|
675
|
+
<div id="error-result" style="margin-top: 20px; display: none;"></div>
|
|
676
|
+
</div>
|
|
677
|
+
|
|
678
|
+
<div class="card">
|
|
679
|
+
<h3>How error tracking works</h3>
|
|
680
|
+
<pre style="background: #f3f4f6; padding: 15px; border-radius: 5px; overflow-x: auto;"><code>from amplitude import Amplitude, BaseEvent
|
|
681
|
+
|
|
682
|
+
client = Amplitude(api_key)
|
|
683
|
+
try:
|
|
684
|
+
risky_operation()
|
|
685
|
+
except Exception as e:
|
|
686
|
+
client.track(BaseEvent(
|
|
687
|
+
event_type='Error Triggered',
|
|
688
|
+
user_id=user_id,
|
|
689
|
+
event_properties={'error_message': str(e)},
|
|
690
|
+
))</code></pre>
|
|
691
|
+
</div>
|
|
692
|
+
{% endblock %}
|
|
693
|
+
|
|
694
|
+
{% block scripts %}
|
|
695
|
+
<script>
|
|
696
|
+
async function triggerError(errorType) {
|
|
697
|
+
const resultDiv = document.getElementById('error-result');
|
|
698
|
+
|
|
699
|
+
try {
|
|
700
|
+
const response = await fetch('{% url "trigger_error" %}', {
|
|
701
|
+
method: 'POST',
|
|
702
|
+
headers: {
|
|
703
|
+
'X-CSRFToken': '{{ csrf_token }}',
|
|
704
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
705
|
+
},
|
|
706
|
+
body: 'error_type=' + errorType,
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
const data = await response.json();
|
|
710
|
+
|
|
711
|
+
resultDiv.style.display = 'block';
|
|
712
|
+
if (data.success) {
|
|
713
|
+
resultDiv.innerHTML = '<div class="message success">No error occurred</div>';
|
|
714
|
+
} else {
|
|
715
|
+
resultDiv.innerHTML = `
|
|
716
|
+
<div class="message error">
|
|
717
|
+
<strong>Error captured:</strong> ${data.error}<br>
|
|
718
|
+
<small>${data.message}</small>
|
|
719
|
+
</div>
|
|
720
|
+
`;
|
|
721
|
+
}
|
|
722
|
+
} catch (error) {
|
|
723
|
+
resultDiv.style.display = 'block';
|
|
724
|
+
resultDiv.innerHTML = `<div class="message error">Request failed: ${error}</div>`;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
</script>
|
|
728
|
+
{% endblock %}
|
|
729
|
+
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
## core/urls.py
|
|
735
|
+
|
|
736
|
+
```py
|
|
737
|
+
"""
|
|
738
|
+
URL configuration for the core app.
|
|
739
|
+
|
|
740
|
+
This module defines all the URL patterns for the Amplitude example views.
|
|
741
|
+
"""
|
|
742
|
+
|
|
743
|
+
from django.urls import path
|
|
744
|
+
from . import views
|
|
745
|
+
|
|
746
|
+
urlpatterns = [
|
|
747
|
+
# Home login page
|
|
748
|
+
path('', views.home_view, name='home'),
|
|
749
|
+
|
|
750
|
+
# Authentication
|
|
751
|
+
path('logout/', views.logout_view, name='logout'),
|
|
752
|
+
|
|
753
|
+
# Dashboard
|
|
754
|
+
path('dashboard/', views.dashboard_view, name='dashboard'),
|
|
755
|
+
|
|
756
|
+
# Burrito example for event tracking
|
|
757
|
+
path('burrito/', views.burrito_view, name='burrito'),
|
|
758
|
+
path('api/burrito/consider/', views.consider_burrito_view, name='consider_burrito'),
|
|
759
|
+
|
|
760
|
+
# Profile with error tracking
|
|
761
|
+
path('profile/', views.profile_view, name='profile'),
|
|
762
|
+
path('api/trigger-error/', views.trigger_error_view, name='trigger_error'),
|
|
763
|
+
]
|
|
764
|
+
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
## core/views.py
|
|
770
|
+
|
|
771
|
+
```py
|
|
772
|
+
"""Django views demonstrating Amplitude integration patterns"""
|
|
773
|
+
|
|
774
|
+
from amplitude import Amplitude, BaseEvent, Identify
|
|
775
|
+
from django.shortcuts import render, redirect
|
|
776
|
+
from django.contrib.auth import authenticate, login, logout
|
|
777
|
+
from django.contrib.auth.decorators import login_required
|
|
778
|
+
from django.contrib import messages
|
|
779
|
+
from django.http import JsonResponse
|
|
780
|
+
from django.views.decorators.http import require_POST
|
|
781
|
+
from django.conf import settings
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
def get_amplitude_client():
|
|
785
|
+
"""Get the Amplitude client instance."""
|
|
786
|
+
api_key = getattr(settings, 'AMPLITUDE_API_KEY', '')
|
|
787
|
+
if not api_key:
|
|
788
|
+
return None
|
|
789
|
+
return Amplitude(api_key)
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
def home_view(request):
|
|
793
|
+
"""Home page with login functionality"""
|
|
794
|
+
if request.user.is_authenticated:
|
|
795
|
+
return redirect('dashboard')
|
|
796
|
+
|
|
797
|
+
if request.method == 'POST':
|
|
798
|
+
username = request.POST.get('username')
|
|
799
|
+
password = request.POST.get('password')
|
|
800
|
+
|
|
801
|
+
user = authenticate(request, username=username, password=password)
|
|
802
|
+
|
|
803
|
+
if user is not None:
|
|
804
|
+
login(request, user)
|
|
805
|
+
|
|
806
|
+
# Amplitude: Identify user and capture login event
|
|
807
|
+
client = get_amplitude_client()
|
|
808
|
+
if client:
|
|
809
|
+
identify_obj = Identify()
|
|
810
|
+
identify_obj.set('email', user.email)
|
|
811
|
+
identify_obj.set('username', user.username)
|
|
812
|
+
identify_obj.set('name', user.get_full_name() or user.username)
|
|
813
|
+
identify_obj.set('is_staff', user.is_staff)
|
|
814
|
+
identify_obj.set('date_joined', user.date_joined.isoformat())
|
|
815
|
+
client.identify(identify_obj, {"user_id": str(user.id)})
|
|
816
|
+
|
|
817
|
+
client.track(BaseEvent(
|
|
818
|
+
event_type='User Logged In',
|
|
819
|
+
user_id=str(user.id),
|
|
820
|
+
event_properties={'login_method': 'email'},
|
|
821
|
+
))
|
|
822
|
+
|
|
823
|
+
return redirect('dashboard')
|
|
824
|
+
else:
|
|
825
|
+
messages.error(request, 'Invalid username or password')
|
|
826
|
+
|
|
827
|
+
return render(request, 'core/home.html')
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
def logout_view(request):
|
|
831
|
+
"""Logout the current user"""
|
|
832
|
+
if request.user.is_authenticated:
|
|
833
|
+
user_id = str(request.user.id)
|
|
834
|
+
|
|
835
|
+
# Amplitude: Track logout before session ends
|
|
836
|
+
client = get_amplitude_client()
|
|
837
|
+
if client:
|
|
838
|
+
client.track(BaseEvent(
|
|
839
|
+
event_type='User Logged Out',
|
|
840
|
+
user_id=user_id,
|
|
841
|
+
))
|
|
842
|
+
|
|
843
|
+
logout(request)
|
|
844
|
+
|
|
845
|
+
return redirect('home')
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
@login_required
|
|
849
|
+
def dashboard_view(request):
|
|
850
|
+
"""Dashboard page"""
|
|
851
|
+
user_id = str(request.user.id)
|
|
852
|
+
|
|
853
|
+
# Amplitude: Track dashboard view
|
|
854
|
+
client = get_amplitude_client()
|
|
855
|
+
if client:
|
|
856
|
+
client.track(BaseEvent(
|
|
857
|
+
event_type='Dashboard Viewed',
|
|
858
|
+
user_id=user_id,
|
|
859
|
+
event_properties={'is_staff': request.user.is_staff},
|
|
860
|
+
))
|
|
861
|
+
|
|
862
|
+
# TODO: Use Amplitude Experiment for feature flags
|
|
863
|
+
# Feature flags are handled by Amplitude Experiment (separate SDK)
|
|
864
|
+
context = {}
|
|
865
|
+
|
|
866
|
+
return render(request, 'core/dashboard.html', context)
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
@login_required
|
|
870
|
+
def burrito_view(request):
|
|
871
|
+
"""Example page demonstrating event tracking"""
|
|
872
|
+
count = request.session.get('burrito_count', 0)
|
|
873
|
+
|
|
874
|
+
context = {
|
|
875
|
+
'burrito_count': count,
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
return render(request, 'core/burrito.html', context)
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
@login_required
|
|
882
|
+
@require_POST
|
|
883
|
+
def consider_burrito_view(request):
|
|
884
|
+
"""API endpoint for tracking burrito considerations"""
|
|
885
|
+
count = request.session.get('burrito_count', 0) + 1
|
|
886
|
+
request.session['burrito_count'] = count
|
|
887
|
+
|
|
888
|
+
user_id = str(request.user.id)
|
|
889
|
+
|
|
890
|
+
# Amplitude: Track custom event
|
|
891
|
+
client = get_amplitude_client()
|
|
892
|
+
if client:
|
|
893
|
+
client.track(BaseEvent(
|
|
894
|
+
event_type='Burrito Considered',
|
|
895
|
+
user_id=user_id,
|
|
896
|
+
event_properties={'total_considerations': count},
|
|
897
|
+
))
|
|
898
|
+
|
|
899
|
+
return JsonResponse({
|
|
900
|
+
'success': True,
|
|
901
|
+
'count': count,
|
|
902
|
+
})
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
@login_required
|
|
906
|
+
def profile_view(request):
|
|
907
|
+
"""Profile page"""
|
|
908
|
+
user_id = str(request.user.id)
|
|
909
|
+
|
|
910
|
+
# Amplitude: Track profile view
|
|
911
|
+
client = get_amplitude_client()
|
|
912
|
+
if client:
|
|
913
|
+
client.track(BaseEvent(
|
|
914
|
+
event_type='Profile Viewed',
|
|
915
|
+
user_id=user_id,
|
|
916
|
+
))
|
|
917
|
+
|
|
918
|
+
context = {
|
|
919
|
+
'user': request.user,
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
return render(request, 'core/profile.html', context)
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
@login_required
|
|
926
|
+
@require_POST
|
|
927
|
+
def trigger_error_view(request):
|
|
928
|
+
"""API endpoint that demonstrates error tracking"""
|
|
929
|
+
try:
|
|
930
|
+
error_type = request.POST.get('error_type', 'generic')
|
|
931
|
+
|
|
932
|
+
if error_type == 'value':
|
|
933
|
+
raise ValueError("Invalid value provided by user")
|
|
934
|
+
elif error_type == 'key':
|
|
935
|
+
data = {}
|
|
936
|
+
_ = data['nonexistent_key']
|
|
937
|
+
else:
|
|
938
|
+
raise Exception("Something went wrong!")
|
|
939
|
+
|
|
940
|
+
except Exception as e:
|
|
941
|
+
# Amplitude: Track error event
|
|
942
|
+
client = get_amplitude_client()
|
|
943
|
+
if client:
|
|
944
|
+
client.track(BaseEvent(
|
|
945
|
+
event_type='Error Triggered',
|
|
946
|
+
user_id=str(request.user.id),
|
|
947
|
+
event_properties={
|
|
948
|
+
'error_type': error_type,
|
|
949
|
+
'error_message': str(e),
|
|
950
|
+
},
|
|
951
|
+
))
|
|
952
|
+
|
|
953
|
+
return JsonResponse({
|
|
954
|
+
'success': False,
|
|
955
|
+
'error': str(e),
|
|
956
|
+
'message': 'Error has been tracked by Amplitude',
|
|
957
|
+
}, status=400)
|
|
958
|
+
|
|
959
|
+
return JsonResponse({'success': True})
|
|
960
|
+
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
---
|
|
964
|
+
|
|
965
|
+
## manage.py
|
|
966
|
+
|
|
967
|
+
```py
|
|
968
|
+
#!/usr/bin/env python
|
|
969
|
+
"""Django's command-line utility for administrative tasks."""
|
|
970
|
+
import os
|
|
971
|
+
import sys
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
def main():
|
|
975
|
+
"""Run administrative tasks."""
|
|
976
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'amplitude_example.settings')
|
|
977
|
+
try:
|
|
978
|
+
from django.core.management import execute_from_command_line
|
|
979
|
+
except ImportError as exc:
|
|
980
|
+
raise ImportError(
|
|
981
|
+
"Couldn't import Django. Are you sure it's installed and "
|
|
982
|
+
"available on your PYTHONPATH environment variable? Did you "
|
|
983
|
+
"forget to activate a virtual environment?"
|
|
984
|
+
) from exc
|
|
985
|
+
execute_from_command_line(sys.argv)
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
if __name__ == '__main__':
|
|
989
|
+
main()
|
|
990
|
+
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
---
|
|
994
|
+
|
|
995
|
+
## requirements.txt
|
|
996
|
+
|
|
997
|
+
```txt
|
|
998
|
+
Django>=4.2,<5.0
|
|
999
|
+
amplitude-analytics # Always use latest version
|
|
1000
|
+
python-dotenv>=1.0.0
|
|
1001
|
+
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
---
|
|
1005
|
+
|