@@ -70,7 +70,11 @@ More examples [here](https://github.com/Krukov/cashews/tree/master/examples)
70
70
- [ Cache invalidation on code change] ( #cache-invalidation-on-code-change )
71
71
- [ Detect the source of a result] ( #detect-the-source-of-a-result )
72
72
- [ Middleware] ( #middleware )
73
+ - [ Callbacks] ( #callbacks )
73
74
- [ Transactional mode] ( #transactional )
75
+ - [ Contrib] ( #contrib )
76
+ - [ Fastapi] ( #fastapi )
77
+ - [ Prometheus] ( #prometheus )
74
78
75
79
### Configuration
76
80
@@ -891,6 +895,23 @@ async def logging_middleware(call, cmd: Command, backend: Backend, *args, **kwar
891
895
cache.setup(" mem://" , middlewares = (logging_middleware, ))
892
896
```
893
897
898
+ #### Callbacks
899
+
900
+ One of the middleware that is preinstalled in cache instance is ` CallbackMiddleware ` .
901
+ This middleware also add to a cache a new interface that allow to add a function that will be called before given command will be triggered
902
+
903
+ ``` python
904
+ from cashews import cache, Command
905
+
906
+
907
+ def callback (key , result ):
908
+ print (f " GET key= { key} " )
909
+
910
+ with cache.callback(callback, cmd = Command.GET ):
911
+ await cache.get(" test" ) # also will print "GET key=test"
912
+
913
+ ```
914
+
894
915
### Transactional
895
916
896
917
Applications are more often based on a database with transaction (OLTP) usage. Usually cache supports transactions poorly.
@@ -963,6 +984,74 @@ async def my_handler():
963
984
...
964
985
```
965
986
987
+ ### Contrib
988
+
989
+ This library is framework agnostic, but includes several "batteries" for most popular tools.
990
+
991
+ #### Fastapi
992
+
993
+ You may find a few middlewares useful that can help you to control a cache in you web application based on fastapi.
994
+
995
+ 1 . ` CacheEtagMiddleware ` - middleware add Etag and check 'If-None-Match' header based on Etag
996
+ 2 . ` CacheRequestControlMiddleware ` - middleware check and add ` Cache-Control ` header
997
+ 3 . ` CacheDeleteMiddleware ` - clear cache for an endpoint based on ` Clear-Site-Data ` header
998
+
999
+ Example:
1000
+
1001
+ ``` python
1002
+ from fastapi import FastAPI, Header, Query
1003
+ from fastapi.responses import StreamingResponse
1004
+
1005
+ from cashews import cache
1006
+ from cashews.contrib.fastapi import (
1007
+ CacheDeleteMiddleware,
1008
+ CacheEtagMiddleware,
1009
+ CacheRequestControlMiddleware,
1010
+ cache_control_ttl,
1011
+ )
1012
+
1013
+ app = FastAPI()
1014
+ app.add_middleware(CacheDeleteMiddleware)
1015
+ app.add_middleware(CacheEtagMiddleware)
1016
+ app.add_middleware(CacheRequestControlMiddleware)
1017
+ metrics_middleware = create_metrics_middleware()
1018
+ cache.setup(os.environ.get(" CACHE_URI" , " redis://" ))
1019
+
1020
+
1021
+
1022
+ @app.get (" /" )
1023
+ @cache.failover (ttl = " 1h" )
1024
+ @cache (ttl = cache_control_ttl(default = " 4m" ), key = " simple:{user_agent: hash} " , time_condition = " 1s" )
1025
+ async def simple (user_agent : str = Header(" No" )):
1026
+ ...
1027
+
1028
+
1029
+ @app.get (" /stream" )
1030
+ @cache (ttl = " 1m" , key = " stream:{file_path} " )
1031
+ async def stream (file_path : str = Query(__file__ )):
1032
+ return StreamingResponse(_read_file(file_path = file_path))
1033
+
1034
+
1035
+ async def _read_file (_read_file ):
1036
+ ...
1037
+
1038
+ ```
1039
+
1040
+ Also cashews can cache stream responses
1041
+
1042
+ #### Prometheus
1043
+
1044
+ You can easily provide metrics using the Prometheus middleware.
1045
+
1046
+ ``` python
1047
+ from cashews import cache
1048
+ from cashews.contrib.prometheus import create_metrics_middleware
1049
+
1050
+ metrics_middleware = create_metrics_middleware(with_tag = False )
1051
+ cache.setup(" redis://" , middlewares = (metrics_middleware,))
1052
+
1053
+ ```
1054
+
966
1055
## Development
967
1056
968
1057
### Setup
0 commit comments