mirror of
https://github.com/long2ice/fastapi-cache.git
synced 2026-03-25 13:07:53 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15576b482a | ||
|
|
f80bfdb18d | ||
|
|
aaed438d8f | ||
|
|
d6c52408d2 | ||
|
|
8c92cc59ae | ||
|
|
824e2e145f | ||
|
|
7fa54d311f | ||
|
|
9582e04d43 | ||
|
|
fd8cf2da11 | ||
|
|
2f1b1409b9 | ||
|
|
269c1ca616 |
@@ -2,6 +2,10 @@
|
||||
|
||||
## 0.1
|
||||
|
||||
### 0.1.9
|
||||
|
||||
- Replace `aioredis` with `redis-py`.
|
||||
|
||||
### 0.1.8
|
||||
|
||||
- Support `dynamodb` backend.
|
||||
|
||||
1
Makefile
1
Makefile
@@ -14,7 +14,6 @@ style: deps
|
||||
check: deps
|
||||
@poetry run black $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
|
||||
@poetry run flake8 $(checkfiles)
|
||||
@poetry run bandit -r $(checkfiles)
|
||||
|
||||
test: deps
|
||||
$(py_warn) poetry run pytest
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from datetime import date, datetime
|
||||
import time
|
||||
|
||||
import aioredis
|
||||
import redis.asyncio as redis
|
||||
import uvicorn
|
||||
from fastapi import FastAPI
|
||||
from redis.asyncio.connection import ConnectionPool
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response
|
||||
|
||||
@@ -39,6 +41,13 @@ async def get_data(request: Request, response: Response):
|
||||
return date.today()
|
||||
|
||||
|
||||
@app.get("/blocking")
|
||||
@cache(namespace="test", expire=20)
|
||||
def blocking(request: Request, response: Response):
|
||||
time.sleep(5)
|
||||
return dict(ret=get_ret())
|
||||
|
||||
|
||||
@app.get("/datetime")
|
||||
@cache(namespace="test", expire=20)
|
||||
async def get_datetime(request: Request, response: Response):
|
||||
@@ -47,8 +56,9 @@ async def get_datetime(request: Request, response: Response):
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup():
|
||||
redis = aioredis.from_url(url="redis://localhost")
|
||||
FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")
|
||||
pool = ConnectionPool.from_url(url="redis://localhost")
|
||||
r = redis.Redis(connection_pool=pool)
|
||||
FastAPICache.init(RedisBackend(r), prefix="fastapi-cache")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -43,7 +43,7 @@ class InMemoryBackend(Backend):
|
||||
|
||||
async def set(self, key: str, value: str, expire: int = None):
|
||||
async with self._lock:
|
||||
self._store[key] = Value(value, self._now + expire or 0)
|
||||
self._store[key] = Value(value, self._now + (expire or 0))
|
||||
|
||||
async def clear(self, namespace: str = None, key: str = None) -> int:
|
||||
count = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Tuple
|
||||
|
||||
from aioredis import Redis
|
||||
from redis.asyncio.client import Redis
|
||||
|
||||
from fastapi_cache.backends import Backend
|
||||
|
||||
|
||||
@@ -64,4 +64,4 @@ class PickleCoder(Coder):
|
||||
|
||||
@classmethod
|
||||
def decode(cls, value: Any):
|
||||
return pickle.loads(value) # nosec:B403
|
||||
return pickle.loads(value) # nosec:B403,B301
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
from functools import wraps
|
||||
from typing import Callable, Optional, Type
|
||||
import asyncio
|
||||
from functools import wraps, partial
|
||||
import inspect
|
||||
from typing import TYPE_CHECKING, Callable, Optional, Type
|
||||
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.coder import Coder
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import concurrent.futures
|
||||
|
||||
|
||||
def cache(
|
||||
expire: int = None,
|
||||
coder: Type[Coder] = None,
|
||||
key_builder: Callable = None,
|
||||
namespace: Optional[str] = "",
|
||||
executor: Optional["concurrent.futures.Executor"] = None,
|
||||
):
|
||||
"""
|
||||
cache all function
|
||||
@@ -17,6 +23,8 @@ def cache(
|
||||
:param expire:
|
||||
:param coder:
|
||||
:param key_builder:
|
||||
:param executor:
|
||||
|
||||
:return:
|
||||
"""
|
||||
|
||||
@@ -63,7 +71,12 @@ def cache(
|
||||
response.headers["ETag"] = etag
|
||||
return coder.decode(ret)
|
||||
|
||||
if inspect.iscoroutinefunction(func):
|
||||
ret = await func(*args, **kwargs)
|
||||
else:
|
||||
loop = asyncio.get_event_loop()
|
||||
ret = await loop.run_in_executor(executor, partial(func, *args, **kwargs))
|
||||
|
||||
await backend.set(cache_key, coder.encode(ret), expire or FastAPICache.get_expire())
|
||||
return ret
|
||||
|
||||
|
||||
1181
poetry.lock
generated
1181
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "fastapi-cache2"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
description = "Cache for FastAPI"
|
||||
authors = ["long2ice <long2ice@gmail.com>"]
|
||||
license = "Apache-2.0"
|
||||
@@ -18,27 +18,26 @@ include = ["LICENSE", "README.md"]
|
||||
python = "^3.7"
|
||||
fastapi = "*"
|
||||
uvicorn = "*"
|
||||
aioredis = {version = "^2.0", optional = true}
|
||||
aiomcache = {version = "*", optional = true}
|
||||
redis = { version = "^4.2.0rc1", optional = true }
|
||||
aiomcache = { version = "*", optional = true }
|
||||
pendulum = "*"
|
||||
aiobotocore = {version = "^1.4.1", optional = true}
|
||||
aiobotocore = { version = "^1.4.1", optional = true }
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
flake8 = "*"
|
||||
isort = "*"
|
||||
black = "*"
|
||||
pytest = "*"
|
||||
bandit = "*"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
build-backend = "poetry.masonry.api"
|
||||
|
||||
[tool.poetry.extras]
|
||||
redis = ["aioredis"]
|
||||
redis = ["redis"]
|
||||
memcache = ["aiomcache"]
|
||||
dynamodb = ["aiobotocore"]
|
||||
all = ["aioredis","aiomcache"]
|
||||
all = ["redis", "aiomcache", "aiobotocore"]
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
|
||||
Reference in New Issue
Block a user