diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-15 06:26:26 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-15 06:26:26 +0000 |
commit | 563eca9af65b4c52f37d1b9e1fa9b3c2d50ad60d (patch) | |
tree | db461db70f0d41b7aba1a5f83a35d585ed6b2f9a | |
parent | 8f193a2b3d8296d6bdce9132aa2fc0cf3b5481a7 (diff) |
automatic import of python-fastapi-limiter
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-fastapi-limiter.spec | 578 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 580 insertions, 0 deletions
@@ -0,0 +1 @@ +/fastapi-limiter-0.1.5.tar.gz diff --git a/python-fastapi-limiter.spec b/python-fastapi-limiter.spec new file mode 100644 index 0000000..5343b62 --- /dev/null +++ b/python-fastapi-limiter.spec @@ -0,0 +1,578 @@ +%global _empty_manifest_terminate_build 0 +Name: python-fastapi-limiter +Version: 0.1.5 +Release: 1 +Summary: A request rate limiter for fastapi +License: Apache2.0 +URL: https://github.com/long2ice/fastapi-limiter +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/19/8a/fd3d43632cb8e009c5ec8cda84e9d213f5c484cd14de99ecbabdc173c935/fastapi-limiter-0.1.5.tar.gz +BuildArch: noarch + +Requires: python3-fastapi +Requires: python3-redis + +%description +# fastapi-limiter + +[](https://pypi.python.org/pypi/fastapi-limiter) +[](https://github.com/long2ice/fastapi-limiter/blob/master/LICENCE) +[](https://github.com/long2ice/fastapi-limiter/actions?query=workflow:pypi) +[](https://github.com/long2ice/fastapi-limiter/actions?query=workflow:ci) + +## Introduction + +FastAPI-Limiter is a rate limiting tool for [fastapi](https://github.com/tiangolo/fastapi) routes with lua script. + +## Requirements + +- [redis](https://redis.io/) + +## Install + +Just install from pypi + +```shell script +> pip install fastapi-limiter +``` + +## Quick Start + +FastAPI-Limiter is simple to use, which just provide a dependency `RateLimiter`, the following example allow `2` times +request per `5` seconds in route `/`. + +```py +import redis.asyncio as redis +import uvicorn +from fastapi import Depends, FastAPI + +from fastapi_limiter import FastAPILimiter +from fastapi_limiter.depends import RateLimiter + +app = FastAPI() + + +@app.on_event("startup") +async def startup(): + redis = redis.from_url("redis://localhost", encoding="utf-8", decode_responses=True) + await FastAPILimiter.init(redis) + + +@app.get("/", dependencies=[Depends(RateLimiter(times=2, seconds=5))]) +async def index(): + return {"msg": "Hello World"} + + +if __name__ == "__main__": + uvicorn.run("main:app", debug=True, reload=True) +``` + +## Usage + +There are some config in `FastAPILimiter.init`. + +### redis + +The `redis` instance of `aioredis`. + +### prefix + +Prefix of redis key. + +### identifier + +Identifier of route limit, default is `ip`, you can override it such as `userid` and so on. + +```py +async def default_identifier(request: Request): + forwarded = request.headers.get("X-Forwarded-For") + if forwarded: + return forwarded.split(",")[0] + return request.client.host + ":" + request.scope["path"] +``` + +### callback + +Callback when access is forbidden, default is raise `HTTPException` with `429` status code. + +```py +async def default_callback(request: Request, response: Response, pexpire: int): + """ + default callback when too many requests + :param request: + :param pexpire: The remaining milliseconds + :param response: + :return: + """ + expire = ceil(pexpire / 1000) + + raise HTTPException( + HTTP_429_TOO_MANY_REQUESTS, "Too Many Requests", headers={"Retry-After": str(expire)} + ) +``` + +## Multiple limiters + +You can use multiple limiters in one route. + +```py +@app.get( + "/multiple", + dependencies=[ + Depends(RateLimiter(times=1, seconds=5)), + Depends(RateLimiter(times=2, seconds=15)), + ], +) +async def multiple(): + return {"msg": "Hello World"} +``` + +Not that you should note the dependencies orders, keep lower of result of `seconds/times` at the first. + +## Rate limiting within a websocket. + +While the above examples work with rest requests, FastAPI also allows easy usage +of websockets, which require a slightly different approach. + +Because websockets are likely to be long lived, you may want to rate limit in +response to data sent over the socket. + +You can do this by rate limiting within the body of the websocket handler: + +```py +@app.websocket("/ws") +async def websocket_endpoint(websocket: WebSocket): + await websocket.accept() + ratelimit = WebSocketRateLimiter(times=1, seconds=5) + while True: + try: + data = await websocket.receive_text() + await ratelimit(websocket, context_key=data) # NB: context_key is optional + await websocket.send_text(f"Hello, world") + except WebSocketRateLimitException: # Thrown when rate limit exceeded. + await websocket.send_text(f"Hello again") +``` + +## Lua script + +The lua script used. + +```lua +local key = KEYS[1] +local limit = tonumber(ARGV[1]) +local expire_time = ARGV[2] + +local current = tonumber(redis.call('get', key) or "0") +if current > 0 then + if current + 1 > limit then + return redis.call("PTTL", key) + else + redis.call("INCR", key) + return 0 + end +else + redis.call("SET", key, 1, "px", expire_time) + return 0 +end +``` + +## License + +This project is licensed under the +[Apache-2.0](https://github.com/long2ice/fastapi-limiter/blob/master/LICENCE) License. + + + +%package -n python3-fastapi-limiter +Summary: A request rate limiter for fastapi +Provides: python-fastapi-limiter +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-fastapi-limiter +# fastapi-limiter + +[](https://pypi.python.org/pypi/fastapi-limiter) +[](https://github.com/long2ice/fastapi-limiter/blob/master/LICENCE) +[](https://github.com/long2ice/fastapi-limiter/actions?query=workflow:pypi) +[](https://github.com/long2ice/fastapi-limiter/actions?query=workflow:ci) + +## Introduction + +FastAPI-Limiter is a rate limiting tool for [fastapi](https://github.com/tiangolo/fastapi) routes with lua script. + +## Requirements + +- [redis](https://redis.io/) + +## Install + +Just install from pypi + +```shell script +> pip install fastapi-limiter +``` + +## Quick Start + +FastAPI-Limiter is simple to use, which just provide a dependency `RateLimiter`, the following example allow `2` times +request per `5` seconds in route `/`. + +```py +import redis.asyncio as redis +import uvicorn +from fastapi import Depends, FastAPI + +from fastapi_limiter import FastAPILimiter +from fastapi_limiter.depends import RateLimiter + +app = FastAPI() + + +@app.on_event("startup") +async def startup(): + redis = redis.from_url("redis://localhost", encoding="utf-8", decode_responses=True) + await FastAPILimiter.init(redis) + + +@app.get("/", dependencies=[Depends(RateLimiter(times=2, seconds=5))]) +async def index(): + return {"msg": "Hello World"} + + +if __name__ == "__main__": + uvicorn.run("main:app", debug=True, reload=True) +``` + +## Usage + +There are some config in `FastAPILimiter.init`. + +### redis + +The `redis` instance of `aioredis`. + +### prefix + +Prefix of redis key. + +### identifier + +Identifier of route limit, default is `ip`, you can override it such as `userid` and so on. + +```py +async def default_identifier(request: Request): + forwarded = request.headers.get("X-Forwarded-For") + if forwarded: + return forwarded.split(",")[0] + return request.client.host + ":" + request.scope["path"] +``` + +### callback + +Callback when access is forbidden, default is raise `HTTPException` with `429` status code. + +```py +async def default_callback(request: Request, response: Response, pexpire: int): + """ + default callback when too many requests + :param request: + :param pexpire: The remaining milliseconds + :param response: + :return: + """ + expire = ceil(pexpire / 1000) + + raise HTTPException( + HTTP_429_TOO_MANY_REQUESTS, "Too Many Requests", headers={"Retry-After": str(expire)} + ) +``` + +## Multiple limiters + +You can use multiple limiters in one route. + +```py +@app.get( + "/multiple", + dependencies=[ + Depends(RateLimiter(times=1, seconds=5)), + Depends(RateLimiter(times=2, seconds=15)), + ], +) +async def multiple(): + return {"msg": "Hello World"} +``` + +Not that you should note the dependencies orders, keep lower of result of `seconds/times` at the first. + +## Rate limiting within a websocket. + +While the above examples work with rest requests, FastAPI also allows easy usage +of websockets, which require a slightly different approach. + +Because websockets are likely to be long lived, you may want to rate limit in +response to data sent over the socket. + +You can do this by rate limiting within the body of the websocket handler: + +```py +@app.websocket("/ws") +async def websocket_endpoint(websocket: WebSocket): + await websocket.accept() + ratelimit = WebSocketRateLimiter(times=1, seconds=5) + while True: + try: + data = await websocket.receive_text() + await ratelimit(websocket, context_key=data) # NB: context_key is optional + await websocket.send_text(f"Hello, world") + except WebSocketRateLimitException: # Thrown when rate limit exceeded. + await websocket.send_text(f"Hello again") +``` + +## Lua script + +The lua script used. + +```lua +local key = KEYS[1] +local limit = tonumber(ARGV[1]) +local expire_time = ARGV[2] + +local current = tonumber(redis.call('get', key) or "0") +if current > 0 then + if current + 1 > limit then + return redis.call("PTTL", key) + else + redis.call("INCR", key) + return 0 + end +else + redis.call("SET", key, 1, "px", expire_time) + return 0 +end +``` + +## License + +This project is licensed under the +[Apache-2.0](https://github.com/long2ice/fastapi-limiter/blob/master/LICENCE) License. + + + +%package help +Summary: Development documents and examples for fastapi-limiter +Provides: python3-fastapi-limiter-doc +%description help +# fastapi-limiter + +[](https://pypi.python.org/pypi/fastapi-limiter) +[](https://github.com/long2ice/fastapi-limiter/blob/master/LICENCE) +[](https://github.com/long2ice/fastapi-limiter/actions?query=workflow:pypi) +[](https://github.com/long2ice/fastapi-limiter/actions?query=workflow:ci) + +## Introduction + +FastAPI-Limiter is a rate limiting tool for [fastapi](https://github.com/tiangolo/fastapi) routes with lua script. + +## Requirements + +- [redis](https://redis.io/) + +## Install + +Just install from pypi + +```shell script +> pip install fastapi-limiter +``` + +## Quick Start + +FastAPI-Limiter is simple to use, which just provide a dependency `RateLimiter`, the following example allow `2` times +request per `5` seconds in route `/`. + +```py +import redis.asyncio as redis +import uvicorn +from fastapi import Depends, FastAPI + +from fastapi_limiter import FastAPILimiter +from fastapi_limiter.depends import RateLimiter + +app = FastAPI() + + +@app.on_event("startup") +async def startup(): + redis = redis.from_url("redis://localhost", encoding="utf-8", decode_responses=True) + await FastAPILimiter.init(redis) + + +@app.get("/", dependencies=[Depends(RateLimiter(times=2, seconds=5))]) +async def index(): + return {"msg": "Hello World"} + + +if __name__ == "__main__": + uvicorn.run("main:app", debug=True, reload=True) +``` + +## Usage + +There are some config in `FastAPILimiter.init`. + +### redis + +The `redis` instance of `aioredis`. + +### prefix + +Prefix of redis key. + +### identifier + +Identifier of route limit, default is `ip`, you can override it such as `userid` and so on. + +```py +async def default_identifier(request: Request): + forwarded = request.headers.get("X-Forwarded-For") + if forwarded: + return forwarded.split(",")[0] + return request.client.host + ":" + request.scope["path"] +``` + +### callback + +Callback when access is forbidden, default is raise `HTTPException` with `429` status code. + +```py +async def default_callback(request: Request, response: Response, pexpire: int): + """ + default callback when too many requests + :param request: + :param pexpire: The remaining milliseconds + :param response: + :return: + """ + expire = ceil(pexpire / 1000) + + raise HTTPException( + HTTP_429_TOO_MANY_REQUESTS, "Too Many Requests", headers={"Retry-After": str(expire)} + ) +``` + +## Multiple limiters + +You can use multiple limiters in one route. + +```py +@app.get( + "/multiple", + dependencies=[ + Depends(RateLimiter(times=1, seconds=5)), + Depends(RateLimiter(times=2, seconds=15)), + ], +) +async def multiple(): + return {"msg": "Hello World"} +``` + +Not that you should note the dependencies orders, keep lower of result of `seconds/times` at the first. + +## Rate limiting within a websocket. + +While the above examples work with rest requests, FastAPI also allows easy usage +of websockets, which require a slightly different approach. + +Because websockets are likely to be long lived, you may want to rate limit in +response to data sent over the socket. + +You can do this by rate limiting within the body of the websocket handler: + +```py +@app.websocket("/ws") +async def websocket_endpoint(websocket: WebSocket): + await websocket.accept() + ratelimit = WebSocketRateLimiter(times=1, seconds=5) + while True: + try: + data = await websocket.receive_text() + await ratelimit(websocket, context_key=data) # NB: context_key is optional + await websocket.send_text(f"Hello, world") + except WebSocketRateLimitException: # Thrown when rate limit exceeded. + await websocket.send_text(f"Hello again") +``` + +## Lua script + +The lua script used. + +```lua +local key = KEYS[1] +local limit = tonumber(ARGV[1]) +local expire_time = ARGV[2] + +local current = tonumber(redis.call('get', key) or "0") +if current > 0 then + if current + 1 > limit then + return redis.call("PTTL", key) + else + redis.call("INCR", key) + return 0 + end +else + redis.call("SET", key, 1, "px", expire_time) + return 0 +end +``` + +## License + +This project is licensed under the +[Apache-2.0](https://github.com/long2ice/fastapi-limiter/blob/master/LICENCE) License. + + + +%prep +%autosetup -n fastapi-limiter-0.1.5 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-fastapi-limiter -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Mon May 15 2023 Python_Bot <Python_Bot@openeuler.org> - 0.1.5-1 +- Package Spec generated @@ -0,0 +1 @@ +bdbbc849d1c6fb665b46bc1fc31f51ff fastapi-limiter-0.1.5.tar.gz |