{"id":27926026,"url":"https://github.com/cafetechne/flask_limiter_firestore","last_synced_at":"2026-05-13T20:32:26.721Z","repository":{"id":291506163,"uuid":"977824821","full_name":"cafeTechne/flask_limiter_firestore","owner":"cafeTechne","description":"A Firestore backend for Flask-Limiter that enables serverless, distributed rate limiting without Redis or Memcached.","archived":false,"fork":false,"pushed_at":"2025-05-13T20:03:13.000Z","size":16,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-15T18:53:52.321Z","etag":null,"topics":["backend","firestore","flask","rate-limiter","rate-limiting"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/flask-limiter-firestore/0.0.0/","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/cafeTechne.png","metadata":{"files":{"readme":"README.rst","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-05-05T02:58:41.000Z","updated_at":"2025-05-19T11:34:52.000Z","dependencies_parsed_at":"2025-05-05T04:22:32.269Z","dependency_job_id":"122a08e1-d667-4f3a-a358-d1e5971d4c24","html_url":"https://github.com/cafeTechne/flask_limiter_firestore","commit_stats":null,"previous_names":["cafetechne/flask_limiter_firestore"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cafeTechne/flask_limiter_firestore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cafeTechne%2Fflask_limiter_firestore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cafeTechne%2Fflask_limiter_firestore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cafeTechne%2Fflask_limiter_firestore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cafeTechne%2Fflask_limiter_firestore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cafeTechne","download_url":"https://codeload.github.com/cafeTechne/flask_limiter_firestore/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cafeTechne%2Fflask_limiter_firestore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275304914,"owners_count":25441168,"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-09-15T02:00:09.272Z","response_time":75,"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":["backend","firestore","flask","rate-limiter","rate-limiting"],"created_at":"2025-05-07T00:51:01.279Z","updated_at":"2025-09-15T18:53:53.626Z","avatar_url":"https://github.com/cafeTechne.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"🔧 Features\r\n-----------\r\n- ✅ Drop-in replacement for Redis/Memcached backends\r\n- ☁️ Firestore-compatible (GCP-managed, serverless, global scale)\r\n- 🧹 Built-in TTL auto-cleanup via `expires_at` field\r\n- 🔐 No extra infrastructure needed on Google App Engine/Cloud Run\r\n- 🧪 Fully compatible with Flask-Limiter ≥3.5+\r\n\r\n📦 Installation\r\n---------------\r\n    pip install Flask-Limiter-Firestore\r\n\r\n🚀 Usage\r\n--------\r\n    from flask import Flask, request\r\n    from flask_limiter import Limiter\r\n    from flask_limiter_firestore import FirestoreStorage\r\n\r\n    def get_client_ip():\r\n        xff = request.headers.get(\"X-Forwarded-For\", \"\")\r\n        return xff.split(\",\")[0].strip() if xff else request.remote_addr\r\n\r\n    app = Flask(__name__)\r\n    limiter = Limiter(\r\n        app=app,\r\n        key_func=get_client_ip,\r\n        storage=FirestoreStorage(collection_name=\"rate_limits\"),\r\n        default_limits=[\"10 per minute\"],\r\n    )\r\n\r\n🔐 Authentication\r\n-----------------\r\nIf you're running locally, authenticate with:\r\n    export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json\r\n\r\nOn GAE / Cloud Run / Cloud Functions: ADC is automatic.\r\n\r\n✅ Example Route\r\n----------------\r\n    @app.route(\"/api/data\")\r\n    @limiter.limit(\"5 per minute\")\r\n    def data():\r\n        return \"Rate limited!\"\r\n\r\n🧹 Cleanup Policy\r\n-----------------\r\nUse a TTL index on the `expires_at` field in Firestore for auto-deletion.\r\n\r\n🐛 Troubleshooting\r\n------------------\r\n- FirestoreStorage.incr() got unexpected keyword 'amount' → Upgrade Flask-Limiter ≥ 3.5\r\n- Invalid document key → Avoid slashes in limiter keys\r\n- 'wrap_exceptions' attribute missing → ensure base_exceptions property exists\r\n\r\n🔗 Links\r\n--------\r\n- Flask-Limiter: https://flask-limiter.readthedocs.io\r\n- Firestore: https://cloud.google.com/firestore\r\n- PyPI: https://pypi.org/project/Flask-Limiter-Firestore\r\n\r\n📄 License\r\n----------\r\nMIT License\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcafetechne%2Fflask_limiter_firestore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcafetechne%2Fflask_limiter_firestore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcafetechne%2Fflask_limiter_firestore/lists"}