{"id":17132192,"url":"https://github.com/bitsofinfo/mock-rate-limiting-endpoint","last_synced_at":"2025-10-07T18:50:43.702Z","repository":{"id":146759245,"uuid":"160711277","full_name":"bitsofinfo/mock-rate-limiting-endpoint","owner":"bitsofinfo","description":"Mock endpoint to mimics a rate limiting service that returns customizable status code and retry header; i.e. 429 Retry-After","archived":false,"fork":false,"pushed_at":"2018-12-06T22:05:08.000Z","size":10,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T04:47:25.246Z","etag":null,"topics":["apis","mock","rate-limiting","testing"],"latest_commit_sha":null,"homepage":"https://bitsofinfo.wordpress.com/2018/12/20/mocking-a-rate-limiting-endpoint-429/","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/bitsofinfo.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}},"created_at":"2018-12-06T17:51:54.000Z","updated_at":"2024-07-10T16:49:46.000Z","dependencies_parsed_at":"2023-03-31T16:47:00.302Z","dependency_job_id":null,"html_url":"https://github.com/bitsofinfo/mock-rate-limiting-endpoint","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bitsofinfo/mock-rate-limiting-endpoint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fmock-rate-limiting-endpoint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fmock-rate-limiting-endpoint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fmock-rate-limiting-endpoint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fmock-rate-limiting-endpoint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitsofinfo","download_url":"https://codeload.github.com/bitsofinfo/mock-rate-limiting-endpoint/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fmock-rate-limiting-endpoint/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266985867,"owners_count":24017007,"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-07-25T02:00:09.625Z","response_time":70,"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":["apis","mock","rate-limiting","testing"],"created_at":"2024-10-14T19:26:19.750Z","updated_at":"2025-10-07T18:50:38.665Z","avatar_url":"https://github.com/bitsofinfo.png","language":"Python","readme":"# mock-rate-limiting-endpoint\n\nSimple mock endpoint that simulates a rate limiting endpoint. Useful for testing\nclients and how they interact with a rate limited API.\n\nPython 3+, and `pip install twisted ratelimit`\n\nCustomizable: See usage and examples below for details.\n\n## Docker file\n\n```\ndocker build -t mock-rate-limiting-endpoint:latest .\n\ndocker run -p 8081:8081 mock-rate-limiting-endpoint:latest endpoint.py\n```\n\n## Usage\n```\n$\u003e python3 endpoint.py -h\n\nusage: endpoint.py [-h] [-p LISTEN_PORT] [-m MAX_CALLS] [-P PERIOD_SECONDS]\n                   [-r RETRY_IN_SECONDS] [-c LIMIT_HIT_RESPONSE_CODE]\n                   [-a RETRY_AFTER_HEADER_NAME]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -p LISTEN_PORT, --listen-port LISTEN_PORT\n                        Port to listen on, default 8081\n  -m MAX_CALLS, --max-calls MAX_CALLS\n                        Max calls for the rate limiter over the specified\n                        --period-seconds, Default 1\n  -P PERIOD_SECONDS, --period-seconds PERIOD_SECONDS\n                        Period in seconds that the --max-calls will apply for,\n                        Default 10\n  -r RETRY_IN_SECONDS, --retry-in-seconds RETRY_IN_SECONDS\n                        Value for the --retry-after-header-name argument which\n                        is returned when the rate limit has been reached,\n                        default 10\n  -c LIMIT_HIT_RESPONSE_CODE, --limit-hit-response-code LIMIT_HIT_RESPONSE_CODE\n                        Default 429\n  -a RETRY_AFTER_HEADER_NAME, --retry-after-header-name RETRY_AFTER_HEADER_NAME\n                        Default Retry-After\n\n```\n\n## Examples\n\nStart in a shell, logs to stdout\n```\n./python3 endpoint.py\n\n2018-12-06 19:33:07,535 - root - DEBUG - Starting with config: {\"listen_port\": 8081, \"max_calls\": 1, \"period_seconds\": 10, \"retry_in_seconds\": 10, \"limit_hit_response_code\": 429, \"retry_after_header_name\": \"Retry-After\"}\n...\n2018-12-06 19:53:08,561 - root - DEBUG - GET / : {\"path\": \"/\", \"status_code\": 200, \"msg\": \"OK\", \"total_reqs\": 1, \"total_ok\": 1, \"total_limit_hits\": 0}\n2018-12-06 19:53:09,339 - root - DEBUG - GET / : {\"path\": \"/\", \"status_code\": 429, \"msg\": \"429: rate limit hit max_calls:1 period_seconds:10\", \"retry_in_seconds\":\n10, \"retry_after_header_name\": \"Retry-After\", \"total_reqs\": 2, \"total_ok\": 1, \"total_limit_hits\": 1}\n```\n\nIn another shell make a request\n```\nbash-4.4$ curl http://localhost:8081\n{\n  \"path\": \"/\",\n  \"status_code\": 200,\n  \"msg\": \"OK\",\n  \"total_reqs\": 1,\n  \"total_ok\": 1,\n  \"total_limit_hits\": 0\n}\n```\n\nMake a 2nd request\n```\nbash-4.4$ curl -v  http://127.0.0.1:8081\n* ...\n\u003e\n\u003c HTTP/1.1 429 Unknown Status\n\u003c Server: TwistedWeb/18.9.0\n\u003c Date: Thu, 06 Dec 2018 19:41:06 GMT\n\u003c Retry-After: 10\n\u003c Content-Length: 232\n\u003c Content-Type: text/html\n\u003c\n{\n  \"path\": \"/\",\n  \"status_code\": 429,\n  \"msg\": \"429: rate limit hit max_calls:1 period_seconds:10\",\n  \"retry_in_seconds\": 10,\n  \"retry_after_header_name\": \"Retry-After\",\n  \"total_reqs\": 3,\n  \"total_ok\": 2,\n  \"total_limit_hits\": 1\n}\n```\n\nWait 10s for 3rd request:\n```\nbash-4.4$ curl http://localhost:8081\n{\n  \"path\": \"/\",\n  \"status_code\": 200,\n  \"msg\": \"OK\",\n  \"total_reqs\": 3,\n  \"total_ok\": 2,\n  \"total_limit_hits\": 1\n}\n```\n\nYou can send any args for tracking i.e:\n```\nbash-4.4$ curl http://localhost:8081?callerid=99191\n{\n  \"path\": \"/\",\n  \"status_code\": 200,\n  \"msg\": \"OK\",\n  \"total_reqs\": 5,\n  \"total_ok\": 4,\n  \"total_limit_hits\": 1,\n  \"args\": [\n    {\n      \"callerid\": \"99191\"\n    }\n  ]\n}\n```\n\n...Or override the the rate limit hit status code and response header:\n```\nbash-4.4$ curl -v http://localhost:8081?limit_hit_response_code=999\\\u0026retry_after_header_name=X-Custom-Retry\n...\n\u003e\n\u003c HTTP/1.1 999 Unknown Status\n\u003c Server: TwistedWeb/18.9.0\n\u003c Date: Thu, 06 Dec 2018 19:50:01 GMT\n\u003c X-Custom-Retry: 10\n\u003c Content-Length: 366\n\u003c Content-Type: text/html\n\u003c\n{\n  \"path\": \"/\",\n  \"status_code\": 999,\n  \"msg\": \"999: rate limit hit max_calls:1 period_seconds:10\",\n  \"retry_in_seconds\": 10,\n  \"retry_after_header_name\": \"X-Custom-Retry\",\n  \"total_reqs\": 5,\n  \"total_ok\": 2,\n  \"total_limit_hits\": 3,\n  \"args\": [\n    {\n      \"limit_hit_response_code\": \"999\"\n    },\n    {\n      \"retry_after_header_name\": \"X-Custom-Retry\"\n    }\n  ]\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsofinfo%2Fmock-rate-limiting-endpoint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitsofinfo%2Fmock-rate-limiting-endpoint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsofinfo%2Fmock-rate-limiting-endpoint/lists"}