From 4659e74c1d5bbd24b0f99b62a363063cd24a8655 Mon Sep 17 00:00:00 2001 From: CoprDistGit Date: Mon, 29 May 2023 11:27:58 +0000 Subject: automatic import of python-fastapi-etag --- .gitignore | 1 + python-fastapi-etag.spec | 441 +++++++++++++++++++++++++++++++++++++++++++++++ sources | 1 + 3 files changed, 443 insertions(+) create mode 100644 python-fastapi-etag.spec create mode 100644 sources diff --git a/.gitignore b/.gitignore index e69de29..b58e3b1 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/fastapi-etag-0.4.0.tar.gz diff --git a/python-fastapi-etag.spec b/python-fastapi-etag.spec new file mode 100644 index 0000000..ad266ed --- /dev/null +++ b/python-fastapi-etag.spec @@ -0,0 +1,441 @@ +%global _empty_manifest_terminate_build 0 +Name: python-fastapi-etag +Version: 0.4.0 +Release: 1 +Summary: Convenience library for working with etags in fastapi +License: MIT +URL: https://github.com/steinitzu/fastapi-etag +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/96/38/840966db80f5d8cd419754fad150edd16ed161ffb473379f0e7e0f7fad1f/fastapi-etag-0.4.0.tar.gz +BuildArch: noarch + + +%description +# fastapi-etag + +## Quickstart + +Basic etag support for FastAPI, allowing you to benefit from conditional caching in web browsers and reverse-proxy caching layers. + +This does not generate etags that are a hash of the response content, but instead lets you pass in a custom etag generating function per endpoint that is called before executing the route function. +This lets you bypass expensive API calls when client includes a matching etag in the `If-None-Match` header, in this case your endpoint is never called, instead returning a 304 response telling the client nothing has changed. + +The etag logis is implemented with a fastapi dependency that you can add to your routes or entire routers. + +Here's how you use it: + +```python3 +# app.py + +from fastapi import FastAPI +from starlette.requests import Request +from fastapi_etag import Etag, add_exception_handler + +app = FastAPI() +add_exception_handler(app) + + +async def get_hello_etag(request: Request): + return "etagfor" + request.path_params["name"] + + +@app.get("/hello/{name}", dependencies=[Depends(Etag(get_hello_etag))]) +async def hello(name: str): + return {"hello": name} + +``` + +Run this example with `uvicorn: uvicorn --port 8090 app:app` + +Let's break it down: + +```python3 +add_exception_handler(app) +``` + +The dependency raises a special `CacheHit` exception to exit early when there's a an etag match, this adds a standard exception handler to the app to generate a correct 304 response from the exception. + +```python3 +async def get_hello_etag(request: Request): + name = request.path_params.get("name") + return f"etagfor{name}" +``` + +This is the function that generates the etag for your endpoint. +It can do anything you want, it could for example return a hash of a last modified timestamp in your database. +It can be either a normal function or an async function. +Only requirement is that it accepts one argument (request) and that it returns either a string (the etag) or `None` (in which case no etag header is added) + + +```python3 +@app.get("/hello/{name}", dependencies=[Depends(Etag(get_hello_etag))]) +def hello(name: str): + ... +``` + +The `Etag` dependency is called like any fastapi dependency. +It always adds the etag returned by your etag gen function to the response. +If client passes a matching etag in the `If-None-Match` header, it will raise a `CacheHit` exception which triggers a 304 response before calling your endpoint. + + +Now try it with curl: + +``` +curl -i "http://localhost:8090/hello/bob" +HTTP/1.1 200 OK +date: Mon, 30 Dec 2019 21:55:43 GMT +server: uvicorn +content-length: 15 +content-type: application/json +etag: W/"etagforbob" + +{"hello":"bob"} +``` + +Etag header is added + +Now including the etag in `If-None-Match` header (mimicking a web browser): + +``` +curl -i -X GET "http://localhost:8090/hello/bob" -H "If-None-Match: W/\"etagforbob\"" +HTTP/1.1 304 Not Modified +date: Mon, 30 Dec 2019 21:57:37 GMT +server: uvicorn +etag: W/"etagforbob" +``` + +It now returns no content, only the 304 telling us nothing has changed. + +### Add response headers + +If you want to add some extra response headers to the 304 and regular response, +you can add the `extra_headers` argument with a dict of headers: + +``` +@app.get( + "/hello/{name}", + dependencies=[ + Depends( + Etag( + get_hello_etag, + extra_headers={"Cache-Control": "public, max-age: 30"}, + ) + ) + ], +) +def hello(name: str): + ... +``` + +This will add the `cache-control` header on all responses from the endpoint. + + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) + + + +%package -n python3-fastapi-etag +Summary: Convenience library for working with etags in fastapi +Provides: python-fastapi-etag +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-fastapi-etag +# fastapi-etag + +## Quickstart + +Basic etag support for FastAPI, allowing you to benefit from conditional caching in web browsers and reverse-proxy caching layers. + +This does not generate etags that are a hash of the response content, but instead lets you pass in a custom etag generating function per endpoint that is called before executing the route function. +This lets you bypass expensive API calls when client includes a matching etag in the `If-None-Match` header, in this case your endpoint is never called, instead returning a 304 response telling the client nothing has changed. + +The etag logis is implemented with a fastapi dependency that you can add to your routes or entire routers. + +Here's how you use it: + +```python3 +# app.py + +from fastapi import FastAPI +from starlette.requests import Request +from fastapi_etag import Etag, add_exception_handler + +app = FastAPI() +add_exception_handler(app) + + +async def get_hello_etag(request: Request): + return "etagfor" + request.path_params["name"] + + +@app.get("/hello/{name}", dependencies=[Depends(Etag(get_hello_etag))]) +async def hello(name: str): + return {"hello": name} + +``` + +Run this example with `uvicorn: uvicorn --port 8090 app:app` + +Let's break it down: + +```python3 +add_exception_handler(app) +``` + +The dependency raises a special `CacheHit` exception to exit early when there's a an etag match, this adds a standard exception handler to the app to generate a correct 304 response from the exception. + +```python3 +async def get_hello_etag(request: Request): + name = request.path_params.get("name") + return f"etagfor{name}" +``` + +This is the function that generates the etag for your endpoint. +It can do anything you want, it could for example return a hash of a last modified timestamp in your database. +It can be either a normal function or an async function. +Only requirement is that it accepts one argument (request) and that it returns either a string (the etag) or `None` (in which case no etag header is added) + + +```python3 +@app.get("/hello/{name}", dependencies=[Depends(Etag(get_hello_etag))]) +def hello(name: str): + ... +``` + +The `Etag` dependency is called like any fastapi dependency. +It always adds the etag returned by your etag gen function to the response. +If client passes a matching etag in the `If-None-Match` header, it will raise a `CacheHit` exception which triggers a 304 response before calling your endpoint. + + +Now try it with curl: + +``` +curl -i "http://localhost:8090/hello/bob" +HTTP/1.1 200 OK +date: Mon, 30 Dec 2019 21:55:43 GMT +server: uvicorn +content-length: 15 +content-type: application/json +etag: W/"etagforbob" + +{"hello":"bob"} +``` + +Etag header is added + +Now including the etag in `If-None-Match` header (mimicking a web browser): + +``` +curl -i -X GET "http://localhost:8090/hello/bob" -H "If-None-Match: W/\"etagforbob\"" +HTTP/1.1 304 Not Modified +date: Mon, 30 Dec 2019 21:57:37 GMT +server: uvicorn +etag: W/"etagforbob" +``` + +It now returns no content, only the 304 telling us nothing has changed. + +### Add response headers + +If you want to add some extra response headers to the 304 and regular response, +you can add the `extra_headers` argument with a dict of headers: + +``` +@app.get( + "/hello/{name}", + dependencies=[ + Depends( + Etag( + get_hello_etag, + extra_headers={"Cache-Control": "public, max-age: 30"}, + ) + ) + ], +) +def hello(name: str): + ... +``` + +This will add the `cache-control` header on all responses from the endpoint. + + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) + + + +%package help +Summary: Development documents and examples for fastapi-etag +Provides: python3-fastapi-etag-doc +%description help +# fastapi-etag + +## Quickstart + +Basic etag support for FastAPI, allowing you to benefit from conditional caching in web browsers and reverse-proxy caching layers. + +This does not generate etags that are a hash of the response content, but instead lets you pass in a custom etag generating function per endpoint that is called before executing the route function. +This lets you bypass expensive API calls when client includes a matching etag in the `If-None-Match` header, in this case your endpoint is never called, instead returning a 304 response telling the client nothing has changed. + +The etag logis is implemented with a fastapi dependency that you can add to your routes or entire routers. + +Here's how you use it: + +```python3 +# app.py + +from fastapi import FastAPI +from starlette.requests import Request +from fastapi_etag import Etag, add_exception_handler + +app = FastAPI() +add_exception_handler(app) + + +async def get_hello_etag(request: Request): + return "etagfor" + request.path_params["name"] + + +@app.get("/hello/{name}", dependencies=[Depends(Etag(get_hello_etag))]) +async def hello(name: str): + return {"hello": name} + +``` + +Run this example with `uvicorn: uvicorn --port 8090 app:app` + +Let's break it down: + +```python3 +add_exception_handler(app) +``` + +The dependency raises a special `CacheHit` exception to exit early when there's a an etag match, this adds a standard exception handler to the app to generate a correct 304 response from the exception. + +```python3 +async def get_hello_etag(request: Request): + name = request.path_params.get("name") + return f"etagfor{name}" +``` + +This is the function that generates the etag for your endpoint. +It can do anything you want, it could for example return a hash of a last modified timestamp in your database. +It can be either a normal function or an async function. +Only requirement is that it accepts one argument (request) and that it returns either a string (the etag) or `None` (in which case no etag header is added) + + +```python3 +@app.get("/hello/{name}", dependencies=[Depends(Etag(get_hello_etag))]) +def hello(name: str): + ... +``` + +The `Etag` dependency is called like any fastapi dependency. +It always adds the etag returned by your etag gen function to the response. +If client passes a matching etag in the `If-None-Match` header, it will raise a `CacheHit` exception which triggers a 304 response before calling your endpoint. + + +Now try it with curl: + +``` +curl -i "http://localhost:8090/hello/bob" +HTTP/1.1 200 OK +date: Mon, 30 Dec 2019 21:55:43 GMT +server: uvicorn +content-length: 15 +content-type: application/json +etag: W/"etagforbob" + +{"hello":"bob"} +``` + +Etag header is added + +Now including the etag in `If-None-Match` header (mimicking a web browser): + +``` +curl -i -X GET "http://localhost:8090/hello/bob" -H "If-None-Match: W/\"etagforbob\"" +HTTP/1.1 304 Not Modified +date: Mon, 30 Dec 2019 21:57:37 GMT +server: uvicorn +etag: W/"etagforbob" +``` + +It now returns no content, only the 304 telling us nothing has changed. + +### Add response headers + +If you want to add some extra response headers to the 304 and regular response, +you can add the `extra_headers` argument with a dict of headers: + +``` +@app.get( + "/hello/{name}", + dependencies=[ + Depends( + Etag( + get_hello_etag, + extra_headers={"Cache-Control": "public, max-age: 30"}, + ) + ) + ], +) +def hello(name: str): + ... +``` + +This will add the `cache-control` header on all responses from the endpoint. + + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) + + + +%prep +%autosetup -n fastapi-etag-0.4.0 + +%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-etag -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Mon May 29 2023 Python_Bot - 0.4.0-1 +- Package Spec generated diff --git a/sources b/sources new file mode 100644 index 0000000..9cca238 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +e5222da7a1d2021e81c9ea6313afdde1 fastapi-etag-0.4.0.tar.gz -- cgit v1.2.3