Merge branch 'develop' into feature/remove-svg-rect
This commit is contained in:
commit
194a7bb0db
7 changed files with 20 additions and 21 deletions
|
@ -4,7 +4,7 @@
|
||||||
"name": "Advent22 API",
|
"name": "Advent22 API",
|
||||||
"dockerComposeFile": "docker-compose.yml",
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
"service": "api",
|
"service": "api",
|
||||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
"workspaceFolder": "/workspaces/advent22/${localWorkspaceFolderBasename}",
|
||||||
// Configure tool-specific properties.
|
// Configure tool-specific properties.
|
||||||
"customizations": {
|
"customizations": {
|
||||||
// Configure properties specific to VS Code.
|
// Configure properties specific to VS Code.
|
||||||
|
|
|
@ -16,7 +16,7 @@ services:
|
||||||
TZ: "Europe/Berlin"
|
TZ: "Europe/Berlin"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- "../..:/workspaces:cached"
|
- "../..:/workspaces/advent22:cached"
|
||||||
|
|
||||||
# Overrides default command so things don't shut down after the process ends.
|
# Overrides default command so things don't shut down after the process ends.
|
||||||
command: "sleep infinity"
|
command: "sleep infinity"
|
||||||
|
|
1
api/.env
Normal file
1
api/.env
Normal file
|
@ -0,0 +1 @@
|
||||||
|
COMPOSE_PROJECT_NAME="advent22_api"
|
1
api/.gitignore
vendored
1
api/.gitignore
vendored
|
@ -152,3 +152,4 @@ cython_debug/
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
|
api.conf
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from json import JSONDecodeError
|
from json import JSONDecodeError
|
||||||
|
from typing import Callable, Hashable
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from cachetools.keys import hashkey
|
from cachetools.keys import hashkey
|
||||||
|
@ -8,11 +9,17 @@ from redis.typing import EncodableT
|
||||||
from webdav3.client import Client as __WebDAVclient
|
from webdav3.client import Client as __WebDAVclient
|
||||||
|
|
||||||
|
|
||||||
def davkey(name, _, *args, **kwargs):
|
def davkey(
|
||||||
"""Return a cache key for use with cached methods."""
|
name: str,
|
||||||
|
slice: slice = slice(1, None),
|
||||||
|
) -> Callable[..., tuple[Hashable, ...]]:
|
||||||
|
def func(*args, **kwargs) -> tuple[Hashable, ...]:
|
||||||
|
"""Return a cache key for use with cached methods."""
|
||||||
|
|
||||||
key = hashkey(name, *args, **kwargs)
|
key = hashkey(name, *args[slice], **kwargs)
|
||||||
return hashkey(*(str(key_item) for key_item in key))
|
return hashkey(*(str(key_item) for key_item in key))
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
|
||||||
class WebDAVclient(__WebDAVclient):
|
class WebDAVclient(__WebDAVclient):
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import functools
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
@ -34,10 +33,7 @@ class WebDAV:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@asyncify
|
@asyncify
|
||||||
@cachedmethod(
|
@cachedmethod(cache=lambda cls: cls._cache, key=davkey("list_files"))
|
||||||
cache=lambda cls: cls._cache,
|
|
||||||
key=functools.partial(davkey, "list_files"),
|
|
||||||
)
|
|
||||||
def list_files(
|
def list_files(
|
||||||
cls,
|
cls,
|
||||||
directory: str = "",
|
directory: str = "",
|
||||||
|
@ -55,10 +51,7 @@ class WebDAV:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@asyncify
|
@asyncify
|
||||||
@cachedmethod(
|
@cachedmethod(cache=lambda cls: cls._cache, key=davkey("exists"))
|
||||||
cache=lambda cls: cls._cache,
|
|
||||||
key=functools.partial(davkey, "exists"),
|
|
||||||
)
|
|
||||||
def exists(cls, path: str) -> bool:
|
def exists(cls, path: str) -> bool:
|
||||||
"""
|
"""
|
||||||
`True` iff there is a WebDAV resource at `path`
|
`True` iff there is a WebDAV resource at `path`
|
||||||
|
@ -69,10 +62,7 @@ class WebDAV:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@asyncify
|
@asyncify
|
||||||
@cachedmethod(
|
@cachedmethod(cache=lambda cls: cls._cache, key=davkey("read_bytes"))
|
||||||
cache=lambda cls: cls._cache,
|
|
||||||
key=functools.partial(davkey, "read_bytes"),
|
|
||||||
)
|
|
||||||
def read_bytes(cls, path: str) -> bytes:
|
def read_bytes(cls, path: str) -> bytes:
|
||||||
"""
|
"""
|
||||||
Load WebDAV file from `path` as bytes
|
Load WebDAV file from `path` as bytes
|
||||||
|
@ -105,7 +95,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(davkey("read_bytes", None, path))
|
cls._cache.pop(davkey("read_bytes")(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:
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Settings(BaseSettings):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model_config = SettingsConfigDict(
|
model_config = SettingsConfigDict(
|
||||||
env_file=".env",
|
env_file="api.conf",
|
||||||
env_file_encoding="utf-8",
|
env_file_encoding="utf-8",
|
||||||
env_nested_delimiter="__",
|
env_nested_delimiter="__",
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue