analytics / README.md
nanye's picture
track location and timezone
a10ad9b
|
Raw History Blame Contribute Delete
5 kB
metadata
title: HF Space Analytics
emoji: πŸ“Š
colorFrom: yellow
colorTo: indigo
sdk: docker
pinned: false
license: mit

HF Space Analytics β€” Gradio Edition

A small Gradio Space that tracks page views across your other Hugging Face Spaces. Gradio provides the dashboard, while an embedded FastAPI application provides the tracking endpoints.

Features

  • Gradio dashboard at /
  • POST /track β€” record a page-view event
  • GET /stats β€” aggregated visit counts
  • GET /events β€” recent raw events
  • GET /tracker.js β€” reusable browser tracker
  • GET /health β€” health and storage check
  • Daily JSONL storage in an attached Hugging Face Storage Bucket

1. Create the analytics Space

  1. Create a new Hugging Face Space.
  2. Select Gradio as the SDK.
  3. Select ZeroGPU hardware. Dashboard refreshes use a one-second ZeroGPU allocation; tracking and API requests remain CPU-only.
  4. Upload every file in this project, or push the repository with Git.
  5. In the Space settings, attach a Hugging Face Storage Bucket as a read-write volume mounted at /data.
  6. Add the optional variables and secrets below.
Name Type Purpose
TRACKING_KEY Secret Required in tracking requests when set
ADMIN_KEY Secret Protects /stats, /events, and the dashboard when set
ALLOWED_ORIGINS Variable Comma-separated CORS origins; default *
DATA_DIR Variable Storage path; default /data/visits
HASH_SALT Secret Salt used to hash browser visitor IDs
GEOIP_DB_PATH Variable Path to a MaxMind GeoLite2 City database; default /data/GeoLite2-City.mmdb

The top-level app.py starts the mounted Gradio/FastAPI application on port 7860, the standard port for Gradio Spaces. Do not configure a PORT variable for this Space; that generic variable may be used by another process in the runtime.

2. Add tracking to another Space

Static HTML or a custom frontend

Add this before </body>:

<script
  src="https://YOUR-ANALYTICS-SPACE.hf.space/tracker.js"
  data-endpoint="https://YOUR-ANALYTICS-SPACE.hf.space/track"
  data-space="YOUR_USERNAME/YOUR_SPACE"
  data-key="YOUR_TRACKING_KEY"
  defer>
</script>

Omit data-key when TRACKING_KEY is not configured.

Another Gradio Space

See examples/gradio_example.py. It injects the same tracker through gr.Blocks(head=...).

Direct JavaScript

fetch("https://YOUR-ANALYTICS-SPACE.hf.space/track", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Tracking-Key": "YOUR_TRACKING_KEY"
  },
  body: JSON.stringify({
    space: "YOUR_USERNAME/YOUR_SPACE",
    path: location.pathname,
    referrer: document.referrer || null,
    visitor_id: localStorage.getItem("hf_analytics_visitor")
  }),
  keepalive: true
});

3. Read statistics

Open the analytics Space to use the Gradio dashboard, or call the API directly:

curl "https://YOUR-ANALYTICS-SPACE.hf.space/stats?days=30"

With an admin key:

curl -H "X-Admin-Key: YOUR_ADMIN_KEY" \
  "https://YOUR-ANALYTICS-SPACE.hf.space/stats?days=30"

Storage

The default layout is:

/data/visits/
β”œβ”€β”€ 2026-08-06.jsonl
β”œβ”€β”€ 2026-08-07.jsonl
└── ...

Without a bucket mounted at /data, files are written to the Space filesystem and may disappear after a restart or rebuild.

IP-based location

To store approximate IP-based location, provide a licensed MaxMind GeoLite2 City database at GEOIP_DB_PATH (the default is /data/GeoLite2-City.mmdb). Each event stores only the available coarse fields under location: country code, country, region, and city. The raw IP is never stored. If the database is absent or cannot identify an address, location is null and tracking continues normally.

Privacy and security

  • A salted hash of the connecting IP address is stored as ip_hash; raw IP addresses are not stored.
  • Approximate IP-based location is stored only when a GeoLite2 database is configured.
  • The recorded address may be the Hugging Face proxy address rather than the visitor's original IP.
  • The tracker stores the browser-reported timezone and language as coarse location hints; it does not collect GPS coordinates.
  • Browser visitor IDs are salted and hashed before storage.
  • Paths and referrers may contain sensitive information; omit them when unnecessary.
  • TRACKING_KEY is visible to visitors when included in browser JavaScript. Treat it only as a low-value anti-spam key, never as a Hugging Face access token.
  • Set an ADMIN_KEY before exposing raw events or private analytics.
  • Publish an appropriate privacy notice for your users and jurisdiction.

Local development

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
DATA_DIR=./local-data python app.py

Then open http://localhost:7860.

Run tests:

pip install -r requirements-dev.txt
pytest