{"id":30593371,"url":"https://github.com/techwithty/plausible","last_synced_at":"2025-10-06T23:25:22.950Z","repository":{"id":309613141,"uuid":"1036942664","full_name":"TechWithTy/plausible","owner":"TechWithTy","description":"Plausible Analytics Python SDK and FastAPI API routes (stats, events, sites). Typed models, retries, rate limiting, and tests for production-ready integration.","archived":false,"fork":false,"pushed_at":"2025-08-12T20:18:23.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-12T22:15:08.295Z","etag":null,"topics":["analytics","events","fastapi","plausible","python","rate-limiting","retries","sdk","sites","stats","testing","typed-models"],"latest_commit_sha":null,"homepage":"https://www.cybershoptech.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TechWithTy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-12T20:18:11.000Z","updated_at":"2025-08-12T20:18:27.000Z","dependencies_parsed_at":"2025-08-12T22:16:23.056Z","dependency_job_id":"33acbc09-3db8-41ed-915a-768ce9058a89","html_url":"https://github.com/TechWithTy/plausible","commit_stats":null,"previous_names":["techwithty/plausible"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/TechWithTy/plausible","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fplausible","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fplausible/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fplausible/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fplausible/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TechWithTy","download_url":"https://codeload.github.com/TechWithTy/plausible/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fplausible/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272735316,"owners_count":24984283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","events","fastapi","plausible","python","rate-limiting","retries","sdk","sites","stats","testing","typed-models"],"created_at":"2025-08-29T18:13:42.289Z","updated_at":"2025-10-06T23:25:22.858Z","avatar_url":"https://github.com/TechWithTy.png","language":"Python","readme":"# Plausible Analytics SDK (Internal)\n\nLocation: `backend/app/core/landing_page/plausible/`\n\nThis is a lightweight Python SDK for Plausible Analytics covering:\n\n- Stats API v2: `POST /api/v2/query`\n- Events API: `POST /api/event`\n- Sites API v1: manage sites, goals, guests, and shared links\n\n## Install/use\n\nThis SDK is part of the backend codebase. Import from the package:\n\n```python\nfrom backend.app.core.landing_page.plausible import PlausibleClient, PlausibleAPIError\n```\n\n## Environment variables\n\n- `PLAUSIBLE_STATS_API_KEY` — key with Stats scope\n- `PLAUSIBLE_SITES_API_KEY` — key with Sites scope (for provisioning)\n\nYou can also pass keys directly to `PlausibleClient(...)`.\n\n## Quick start\n\n```python\nfrom backend.app.core.landing_page.plausible import PlausibleClient\n\nclient = PlausibleClient()  # reads keys from env\n\n# Stats: last 7 days visitors + pageviews\nstats = client.query_stats({\n    \"site_id\": \"dummy.site\",\n    \"metrics\": [\"visitors\", \"pageviews\"],\n    \"date_range\": \"7d\",\n})\nprint(stats)\n\n# Events: record a server-side pageview\nclient.send_event(\n    domain=\"dummy.site\",\n    name=\"pageview\",\n    url=\"https://dummy.site/login\",\n    user_agent=\"Mozilla/5.0 ...\",    # REQUIRED\n    client_ip=\"203.0.113.10\",        # Recommended when sending from backend\n    props={\"logged_in\": \"false\"},\n)\n\n# Sites: list sites\nsites = client.list_sites()\nprint(sites)\n```\n\n## Notes\n\n- Rate limiting: a simple token-bucket limiter is applied (default 600 req/hour). Adjust with `rate_limit_per_hour`.\n- Retries: HTTP 429/5xx are retried with exponential backoff.\n- Errors: raises `PlausibleAuthError`, `PlausibleRateLimitError`, or `PlausibleAPIError`.\n\n## Common patterns\n\n- Do not mix session metrics (e.g., `bounce_rate`, `visit_duration`, `views_per_visit`) with event dimensions (`event:*`).\n- Use `date_range` for time selection; time dimensions (`time:*`) are not usable in filters.\n- For time-series charts, include `dimensions=[\"time:day\"]` (or hour/month) and optionally `include={\"time_labels\": true}`.\n\n## Examples\n\n### Country/City breakdown ordered by visitors\n```python\nresp = client.query_stats({\n    \"site_id\": \"dummy.site\",\n    \"metrics\": [\"visitors\", \"pageviews\"],\n    \"date_range\": [\"2024-01-01\", \"2024-07-01\"],\n    \"dimensions\": [\"visit:country_name\", \"visit:city_name\"],\n    \"filters\": [[\"is_not\", \"visit:country_name\", [\"\"]]],\n    \"order_by\": [[\"visitors\", \"desc\"]],\n})\n```\n\n### Time-series last 28 days with labels\n```python\nresp = client.query_stats({\n    \"site_id\": \"dummy.site\",\n    \"metrics\": [\"visitors\", \"pageviews\"],\n    \"date_range\": \"28d\",\n    \"dimensions\": [\"time:day\"],\n    \"include\": {\"time_labels\": True, \"total_rows\": True},\n})\n```\n\n### Create a site and a goal\n```python\nsite = client.create_site(domain=\"test-domain.com\", timezone=\"Europe/London\")\ngoal = client.put_goal(site_id=\"test-domain.com\", goal_type=\"event\", event_name=\"Signup\")\n```\n\n## Testing\n\n- Unit tests can mock `requests.Session` to ensure correct method, headers, and body are used.\n- For integration, set real API keys and a test domain, then run simple smoke tests for each endpoint.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechwithty%2Fplausible","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechwithty%2Fplausible","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechwithty%2Fplausible/lists"}