use Redis to cache WebDAV results
This commit is contained in:
parent
bf6d72147e
commit
b206b472bc
11 changed files with 235 additions and 50 deletions
|
@ -1,11 +0,0 @@
|
||||||
from . import advent_image, calendar_config, config, depends, helpers, settings, webdav
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"advent_image",
|
|
||||||
"calendar_config",
|
|
||||||
"config",
|
|
||||||
"depends",
|
|
||||||
"helpers",
|
|
||||||
"settings",
|
|
||||||
"webdav",
|
|
||||||
]
|
|
|
@ -6,7 +6,7 @@ from fastapi import Depends
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from .config import Config, get_config
|
from .config import Config, get_config
|
||||||
from .webdav import WebDAV
|
from .dav.webdav import WebDAV
|
||||||
|
|
||||||
|
|
||||||
class DoorSaved(BaseModel):
|
class DoorSaved(BaseModel):
|
||||||
|
|
|
@ -5,8 +5,8 @@ from random import Random
|
||||||
|
|
||||||
from pydantic import BaseModel, field_validator
|
from pydantic import BaseModel, field_validator
|
||||||
|
|
||||||
|
from .dav.webdav import WebDAV
|
||||||
from .settings import SETTINGS
|
from .settings import SETTINGS
|
||||||
from .webdav import WebDAV
|
|
||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
class User(BaseModel):
|
||||||
|
|
0
api/advent22_api/core/dav/__init__.py
Normal file
0
api/advent22_api/core/dav/__init__.py
Normal file
54
api/advent22_api/core/dav/helpers.py
Normal file
54
api/advent22_api/core/dav/helpers.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
from json import JSONDecodeError
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from cachetools.keys import hashkey
|
||||||
|
from CacheToolsUtils import RedisCache as __RedisCache
|
||||||
|
from redis.commands.core import ResponseT
|
||||||
|
from redis.typing import EncodableT
|
||||||
|
from webdav3.client import Client as __WebDAVclient
|
||||||
|
|
||||||
|
|
||||||
|
def davkey(name, _, *args, **kwargs):
|
||||||
|
"""Return a cache key for use with cached methods."""
|
||||||
|
|
||||||
|
key = hashkey(name, *args, **kwargs)
|
||||||
|
return hashkey(*(str(key_item) for key_item in key))
|
||||||
|
|
||||||
|
|
||||||
|
class WebDAVclient(__WebDAVclient):
|
||||||
|
def execute_request(
|
||||||
|
self,
|
||||||
|
action,
|
||||||
|
path,
|
||||||
|
data=None,
|
||||||
|
headers_ext=None,
|
||||||
|
) -> requests.Response:
|
||||||
|
res = super().execute_request(action, path, data, headers_ext)
|
||||||
|
|
||||||
|
# the "Content-Length" header can randomly be missing on txt files,
|
||||||
|
# this should fix that (probably serverside bug)
|
||||||
|
if action == "download" and "Content-Length" not in res.headers:
|
||||||
|
res.headers["Content-Length"] = str(len(res.text))
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
class RedisCache(__RedisCache):
|
||||||
|
"""
|
||||||
|
Redis handles <bytes>, so ...
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _serialize(self, s) -> EncodableT:
|
||||||
|
if isinstance(s, bytes):
|
||||||
|
return s
|
||||||
|
|
||||||
|
else:
|
||||||
|
return super()._serialize(s)
|
||||||
|
|
||||||
|
def _deserialize(self, s: ResponseT):
|
||||||
|
try:
|
||||||
|
return super()._deserialize(s)
|
||||||
|
|
||||||
|
except (UnicodeDecodeError, JSONDecodeError):
|
||||||
|
assert isinstance(s, bytes)
|
||||||
|
return s
|
|
@ -3,42 +3,18 @@ import logging
|
||||||
import re
|
import re
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import requests
|
|
||||||
from asyncify import asyncify
|
from asyncify import asyncify
|
||||||
from cachetools import TTLCache, cachedmethod
|
from cachetools import cachedmethod
|
||||||
from cachetools.keys import hashkey
|
from redis import Redis
|
||||||
from webdav3.client import Client as WebDAVclient
|
|
||||||
|
|
||||||
from .settings import SETTINGS
|
from ..settings import SETTINGS
|
||||||
|
from .helpers import RedisCache, WebDAVclient, davkey
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def davkey(name, _, *args, **kwargs):
|
|
||||||
"""Return a cache key for use with cached methods."""
|
|
||||||
|
|
||||||
return hashkey(name, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class WebDAV:
|
class WebDAV:
|
||||||
class __WebDAVclient(WebDAVclient):
|
_webdav_client = WebDAVclient(
|
||||||
def execute_request(
|
|
||||||
self,
|
|
||||||
action,
|
|
||||||
path,
|
|
||||||
data=None,
|
|
||||||
headers_ext=None,
|
|
||||||
) -> requests.Response:
|
|
||||||
res = super().execute_request(action, path, data, headers_ext)
|
|
||||||
|
|
||||||
# the "Content-Length" header can randomly be missing on txt files,
|
|
||||||
# this should fix that (probably serverside bug)
|
|
||||||
if action == "download" and "Content-Length" not in res.headers:
|
|
||||||
res.headers["Content-Length"] = str(len(res.text))
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
_webdav_client = __WebDAVclient(
|
|
||||||
{
|
{
|
||||||
"webdav_hostname": SETTINGS.webdav.url,
|
"webdav_hostname": SETTINGS.webdav.url,
|
||||||
"webdav_login": SETTINGS.webdav.username,
|
"webdav_login": SETTINGS.webdav.username,
|
||||||
|
@ -46,9 +22,14 @@ class WebDAV:
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
_cache = TTLCache(
|
_cache = RedisCache(
|
||||||
|
cache=Redis(
|
||||||
|
host=SETTINGS.redis.host,
|
||||||
|
port=SETTINGS.redis.port,
|
||||||
|
db=SETTINGS.redis.db,
|
||||||
|
protocol=SETTINGS.redis.protocol,
|
||||||
|
),
|
||||||
ttl=SETTINGS.webdav.cache_ttl,
|
ttl=SETTINGS.webdav.cache_ttl,
|
||||||
maxsize=SETTINGS.webdav.cache_size,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -124,7 +105,7 @@ class WebDAV:
|
||||||
cls._webdav_client.upload_to(buffer, path)
|
cls._webdav_client.upload_to(buffer, path)
|
||||||
|
|
||||||
# invalidate cache entry
|
# invalidate cache entry
|
||||||
cls._cache.pop(hashkey("read_bytes", path))
|
cls._cache.pop(davkey("read_bytes", None, path))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def write_str(cls, path: str, content: str, encoding="utf-8") -> None:
|
async def write_str(cls, path: str, content: str, encoding="utf-8") -> None:
|
|
@ -8,8 +8,8 @@ from PIL import Image, ImageFont
|
||||||
from .advent_image import _XY, AdventImage
|
from .advent_image import _XY, AdventImage
|
||||||
from .calendar_config import CalendarConfig, get_calendar_config
|
from .calendar_config import CalendarConfig, get_calendar_config
|
||||||
from .config import Config, get_config
|
from .config import Config, get_config
|
||||||
|
from .dav.webdav import WebDAV
|
||||||
from .helpers import EventDates, Random, list_images_auto, load_image, set_len
|
from .helpers import EventDates, Random, list_images_auto, load_image, set_len
|
||||||
from .webdav import WebDAV
|
|
||||||
|
|
||||||
|
|
||||||
async def get_all_sorted_days(
|
async def get_all_sorted_days(
|
||||||
|
|
|
@ -9,7 +9,7 @@ from fastapi.responses import StreamingResponse
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .config import get_config
|
from .config import get_config
|
||||||
from .webdav import WebDAV
|
from .dav.webdav import WebDAV
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,7 @@ class DavSettings(BaseModel):
|
||||||
username: str = "advent22_user"
|
username: str = "advent22_user"
|
||||||
password: str = "password"
|
password: str = "password"
|
||||||
|
|
||||||
cache_ttl: int = 60 * 30
|
cache_ttl: int = 60 * 10
|
||||||
cache_size: int = 1024
|
|
||||||
config_filename: str = "config.toml"
|
config_filename: str = "config.toml"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -32,6 +31,17 @@ class DavSettings(BaseModel):
|
||||||
return f"{self.protocol}://{self.host}{self.path}{self.prefix}"
|
return f"{self.protocol}://{self.host}{self.path}{self.prefix}"
|
||||||
|
|
||||||
|
|
||||||
|
class RedisSettings(BaseModel):
|
||||||
|
"""
|
||||||
|
Connection to a redis server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
host: str = "redis"
|
||||||
|
port: int = 6379
|
||||||
|
db: int = 0
|
||||||
|
protocol: int = 3
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
"""
|
"""
|
||||||
Per-run settings.
|
Per-run settings.
|
||||||
|
@ -77,6 +87,7 @@ class Settings(BaseSettings):
|
||||||
#####
|
#####
|
||||||
|
|
||||||
webdav: DavSettings = DavSettings()
|
webdav: DavSettings = DavSettings()
|
||||||
|
redis: RedisSettings = RedisSettings()
|
||||||
|
|
||||||
|
|
||||||
SETTINGS = Settings()
|
SETTINGS = Settings()
|
||||||
|
|
150
api/poetry.lock
generated
150
api/poetry.lock
generated
|
@ -31,6 +31,17 @@ doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-
|
||||||
test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
||||||
trio = ["trio (<0.22)"]
|
trio = ["trio (<0.22)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-timeout"
|
||||||
|
version = "4.0.3"
|
||||||
|
description = "Timeout context manager for asyncio programs"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
|
||||||
|
{file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asyncify"
|
name = "asyncify"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
|
@ -97,6 +108,26 @@ files = [
|
||||||
{file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"},
|
{file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cachetoolsutils"
|
||||||
|
version = "8.2"
|
||||||
|
description = "Cachetools Utilities"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10"
|
||||||
|
files = [
|
||||||
|
{file = "CacheToolsUtils-8.2-py3-none-any.whl", hash = "sha256:721cd4d63477f4de3ba2108f6b8e5b1a9708075eeb72e4770e814f4826815846"},
|
||||||
|
{file = "CacheToolsUtils-8.2.tar.gz", hash = "sha256:a8ece7af5fcc221dfec747dffce4bbfd7e6b45ef315c3aefedb844790c9d1f59"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
cachetools = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["black", "coverage", "flake8", "mypy", "pymarkdownlnt", "pytest", "types-cachetools", "types-redis"]
|
||||||
|
doc = ["myst-parser", "sphinx", "sphinx-autoapi", "sphinx-lint", "sphinx-rtd-theme"]
|
||||||
|
pub = ["build", "twine", "wheel"]
|
||||||
|
tests = ["pymemcache", "redis"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
version = "2023.7.22"
|
version = "2023.7.22"
|
||||||
|
@ -275,6 +306,104 @@ files = [
|
||||||
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hiredis"
|
||||||
|
version = "2.2.3"
|
||||||
|
description = "Python wrapper for hiredis"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:9a1a80a8fa767f2fdc3870316a54b84fe9fc09fa6ab6a2686783de6a228a4604"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3f006c28c885deb99b670a5a66f367a175ab8955b0374029bad7111f5357dcd4"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffaf841546905d90ff189de7397aa56413b1ce5e54547f17a98f0ebf3a3b0a3b"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cadb0ac7ba3babfd804e425946bec9717b320564a1390f163a54af9365a720a"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33bc4721632ef9708fa44e5df0066053fccc8e65410a2c48573192517a533b48"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:227c5b4bcb60f89008c275d596e4a7b6625a6b3c827b8a66ae582eace7051f71"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61995eb826009d99ed8590747bc0da683a5f4fbb4faa8788166bf3810845cd5c"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f969edc851efe23010e0f53a64269f2629a9364135e9ec81c842e8b2277d0c1"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d27e560eefb57914d742a837f1da98d3b29cb22eff013c8023b7cf52ae6e051d"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3759f4789ae1913b7df278dfc9e8749205b7a106f888cd2903d19461e24a7697"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c6cb613148422c523945cdb8b6bed617856f2602fd8750e33773ede2616e55d5"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:1d274d5c511dfc03f83f997d3238eaa9b6ee3f982640979f509373cced891e98"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3b7fe075e91b9d9cff40eba4fb6a8eff74964d3979a39be9a9ef58b1b4cb3604"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-win32.whl", hash = "sha256:77924b0d32fd1f493d3df15d9609ddf9d94c31a364022a6bf6b525ce9da75bea"},
|
||||||
|
{file = "hiredis-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:dcb0569dd5bfe6004658cd0f229efa699a3169dcb4f77bd72e188adda302063d"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:d115790f18daa99b5c11a506e48923b630ef712e9e4b40482af942c3d40638b8"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c3b8be557e08b234774925622e196f0ee36fe4eab66cd19df934d3efd8f3743"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f5446068197b35a11ccc697720c41879c8657e2e761aaa8311783aac84cef20"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa17a3b22b3726d54d7af20394f65d4a1735a842a4e0f557dc67a90f6965c4bc"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7df645b6b7800e8b748c217fbd6a4ca8361bcb9a1ae6206cc02377833ec8a1aa"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fb9300959a0048138791f3d68359d61a788574ec9556bddf1fec07f2dbc5320"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d7e459fe7313925f395148d36d9b7f4f8dac65be06e45d7af356b187cef65fc"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8eceffca3941775b646cd585cd19b275d382de43cc3327d22f7c75d7b003d481"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b17baf702c6e5b4bb66e1281a3efbb1d749c9d06cdb92b665ad81e03118f78fc"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e43e2b5acaad09cf48c032f7e4926392bb3a3f01854416cf6d82ebff94d5467"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a7205497d7276a81fe92951a29616ef96562ed2f91a02066f72b6f93cb34b40e"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:126623b03c31cb6ac3e0d138feb6fcc36dd43dd34fc7da7b7a0c38b5d75bc896"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:071c5814b850574036506a8118034f97c3cbf2fe9947ff45a27b07a48da56240"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-win32.whl", hash = "sha256:d1be9e30e675f5bc1cb534633324578f6f0944a1bcffe53242cf632f554f83b6"},
|
||||||
|
{file = "hiredis-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9a7c987e161e3c58f992c63b7e26fea7fe0777f3b975799d23d65bbb8cb5899"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:f2dcb8389fa3d453927b1299f46bdb38473c293c8269d5c777d33ea0e526b610"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2df98f5e071320c7d84e8bd07c0542acdd0a7519307fc31774d60e4b842ec4f"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61a72e4a523cdfc521762137559c08dfa360a3caef63620be58c699d1717dac1"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9b9e5bde7030cae83aa900b5bd660decc65afd2db8c400f3c568c815a47ca2a"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd2614f17e261f72efc2f19f5e5ff2ee19e2296570c0dcf33409e22be30710de"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46525fbd84523cac75af5bf524bc74aaac848beaf31b142d2df8a787d9b4bbc4"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1a4ce40ba11da9382c14da31f4f9e88c18f7d294f523decd0fadfb81f51ad18"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cda592405bbd29d53942e0389dc3fa77b49c362640210d7e94a10c14a677d4d"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5e6674a017629284ef373b50496d9fb1a89b85a20a7fa100ecd109484ec748e5"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:e62ec131816c6120eff40dffe43424e140264a15fa4ab88c301bd6a595913af3"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17e938d9d3ee92e1adbff361706f1c36cc60eeb3e3eeca7a3a353eae344f4c91"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-win32.whl", hash = "sha256:95d2305fd2a7b179cacb48b10f618872fc565c175f9f62b854e8d1acac3e8a9e"},
|
||||||
|
{file = "hiredis-2.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8f9dbe12f011a9b784f58faecc171d22465bb532c310bd588d769ba79a59ef5a"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:5a4bcef114fc071d5f52c386c47f35aae0a5b43673197b9288a15b584da8fa3a"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:232d0a70519865741ba56e1dfefd160a580ae78c30a1517bad47b3cf95a3bc7d"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9076ce8429785c85f824650735791738de7143f61f43ae9ed83e163c0ca0fa44"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec58fb7c2062f835595c12f0f02dcda76d0eb0831423cc191d1e18c9276648de"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f2b34a6444b8f9c1e9f84bd2c639388e5d14f128afd14a869dfb3d9af893aa2"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:818dfd310aa1020a13cd08ee48e116dd8c3bb2e23b8161f8ac4df587dd5093d7"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96d9ea6c8d4cbdeee2e0d43379ce2881e4af0454b00570677c59f33f2531cd38"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1eadbcd3de55ac42310ff82550d3302cb4efcd4e17d76646a17b6e7004bb42b"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:477c34c4489666dc73cb5e89dafe2617c3e13da1298917f73d55aac4696bd793"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:14824e457e4f5cda685c3345d125da13949bcf3bb1c88eb5d248c8d2c3dee08f"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9cd32326dfa6ce87edf754153b0105aca64486bebe93b9600ccff74fa0b224df"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:51341e70b467004dcbec3a6ce8c478d2d6241e0f6b01e4c56764afd5022e1e9d"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2443659c76b226267e2a04dbbb21bc2a3f91aa53bdc0c22964632753ae43a247"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-win32.whl", hash = "sha256:4e3e3e31423f888d396b1fc1f936936e52af868ac1ec17dd15e3eeba9dd4de24"},
|
||||||
|
{file = "hiredis-2.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:20f509e3a1a20d6e5f5794fc37ceb21f70f409101fcfe7a8bde783894d51b369"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:d20891e3f33803b26d54c77fd5745878497091e33f4bbbdd454cf6e71aee8890"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:50171f985e17970f87d5a29e16603d1e5b03bdbf5c2691a37e6c912942a6b657"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9944a2cac25ffe049a7e89f306e11b900640837d1ef38d9be0eaa4a4e2b73a52"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a5c8019ff94988d56eb49b15de76fe83f6b42536d76edeb6565dbf7fe14b973"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a286ded34eb16501002e3713b3130c987366eee2ba0d58c33c72f27778e31676"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b3e974ad15eb32b1f537730dea70b93a4c3db7b026de3ad2b59da49c6f7454d"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08415ea74c1c29b9d6a4ca3dd0e810dc1af343c1d1d442e15ba133b11ab5be6a"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e17d04ea58ab8cf3f2dc52e875db16077c6357846006780086fff3189fb199d"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6ccdcb635dae85b006592f78e32d97f4bc7541cb27829d505f9c7fefcef48298"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69536b821dd1bc78058a6e7541743f8d82bf2d981b91280b14c4daa6cdc7faba"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:3753df5f873d473f055e1f8837bfad0bd3b277c86f3c9bf058c58f14204cd901"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6f88cafe46612b6fa68e6dea49e25bebf160598bba00101caa51cc8c1f18d597"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33ee3ea5cad3a8cb339352cd230b411eb437a2e75d7736c4899acab32056ccdb"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-win32.whl", hash = "sha256:b4f3d06dc16671b88a13ae85d8ca92534c0b637d59e49f0558d040a691246422"},
|
||||||
|
{file = "hiredis-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4f674e309cd055ee7a48304ceb8cf43265d859faf4d7d01d270ce45e976ae9d3"},
|
||||||
|
{file = "hiredis-2.2.3-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:8f280ab4e043b089777b43b4227bdc2035f88da5072ab36588e0ccf77d45d058"},
|
||||||
|
{file = "hiredis-2.2.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15c2a551f3b8a26f7940d6ee10b837810201754b8d7e6f6b1391655370882c5a"},
|
||||||
|
{file = "hiredis-2.2.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c4e3c258eafaab21b174b17270a0cc093718d61cdbde8c03f85ec4bf835343"},
|
||||||
|
{file = "hiredis-2.2.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc36a9dded458d4e37492fe3e619c6c83caae794d26ad925adbce61d592f8428"},
|
||||||
|
{file = "hiredis-2.2.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:4ed68a3b1ccb4313d2a42546fd7e7439ad4745918a48b6c9bcaa61e1e3e42634"},
|
||||||
|
{file = "hiredis-2.2.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3bf4b5bae472630c229518e4a814b1b68f10a3d9b00aeaec45f1a330f03a0251"},
|
||||||
|
{file = "hiredis-2.2.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33a94d264e6e12a79d9bb8af333b01dc286b9f39c99072ab5fef94ce1f018e17"},
|
||||||
|
{file = "hiredis-2.2.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fa6811a618653164f918b891a0fa07052bd71a799defa5c44d167cac5557b26"},
|
||||||
|
{file = "hiredis-2.2.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af33f370be90b48bbaf0dab32decbdcc522b1fa95d109020a963282086518a8e"},
|
||||||
|
{file = "hiredis-2.2.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b9953d87418ac228f508d93898ab572775e4d3b0eeb886a1a7734553bcdaf291"},
|
||||||
|
{file = "hiredis-2.2.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5e7bb4dd524f50b71c20ef5a12bd61da9b463f8894b18a06130942fe31509881"},
|
||||||
|
{file = "hiredis-2.2.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89a258424158eb8b3ed9f65548d68998da334ef155d09488c5637723eb1cd697"},
|
||||||
|
{file = "hiredis-2.2.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f4a65276f6ecdebe75f2a53f578fbc40e8d2860658420d5e0611c56bbf5054c"},
|
||||||
|
{file = "hiredis-2.2.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:334f2738700b20faa04a0d813366fb16ed17287430a6b50584161d5ad31ca6d7"},
|
||||||
|
{file = "hiredis-2.2.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d194decd9608f11c777946f596f31d5aacad13972a0a87829ae1e6f2d26c1885"},
|
||||||
|
{file = "hiredis-2.2.3.tar.gz", hash = "sha256:e75163773a309e56a9b58165cf5a50e0f84b755f6ff863b2c01a38918fe92daa"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httptools"
|
name = "httptools"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -914,6 +1043,25 @@ files = [
|
||||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redis"
|
||||||
|
version = "5.0.1"
|
||||||
|
description = "Python client for Redis database and key-value store"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"},
|
||||||
|
{file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""}
|
||||||
|
hiredis = {version = ">=1.0.0", optional = true, markers = "extra == \"hiredis\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
hiredis = ["hiredis (>=1.0.0)"]
|
||||||
|
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.31.0"
|
version = "2.31.0"
|
||||||
|
@ -1228,4 +1376,4 @@ typing-extensions = ">=4.4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.11,<3.13"
|
python-versions = ">=3.11,<3.13"
|
||||||
content-hash = "d41bba37f8ede7b450ab7acddd349299aab31fc2b9bb0bdb725571624dba29ce"
|
content-hash = "e97f2ab7e4314a0b6ce3725b8068a147a06e5ac5c9ee8e5406ca546dac3075cd"
|
||||||
|
|
|
@ -12,10 +12,12 @@ version = "0.1.0"
|
||||||
Pillow = "^10.0.1"
|
Pillow = "^10.0.1"
|
||||||
asyncify = "^0.9.2"
|
asyncify = "^0.9.2"
|
||||||
cachetools = "^5.3.2"
|
cachetools = "^5.3.2"
|
||||||
|
cachetoolsutils = "^8.2"
|
||||||
fastapi = "^0.103.1"
|
fastapi = "^0.103.1"
|
||||||
numpy = "^1.26.0"
|
numpy = "^1.26.0"
|
||||||
pydantic-settings = "^2.0.3"
|
pydantic-settings = "^2.0.3"
|
||||||
python = ">=3.11,<3.13"
|
python = ">=3.11,<3.13"
|
||||||
|
redis = {extras = ["hiredis"], version = "^5.0.1"}
|
||||||
tomli-w = "^1.0.0"
|
tomli-w = "^1.0.0"
|
||||||
uvicorn = {extras = ["standard"], version = "^0.23.2"}
|
uvicorn = {extras = ["standard"], version = "^0.23.2"}
|
||||||
webdavclient3 = "^3.14.6"
|
webdavclient3 = "^3.14.6"
|
||||||
|
|
Loading…
Reference in a new issue