wip/experiments

This commit is contained in:
Jörn-Michael Miehe 2022-09-03 15:40:46 +00:00
parent 37b1a1ee68
commit 5034115281
3 changed files with 37 additions and 31 deletions

View file

@ -1,3 +1,4 @@
import asyncio
import functools
from typing import Any
@ -13,11 +14,29 @@ _WEBDAV_CLIENT = WebDAVclient.Client({
})
def run_in_executor(f):
"""
Decorator to make blocking function call asyncio compatible
https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library/
"""
@functools.wraps(f)
def inner(*args, **kwargs):
loop = asyncio.get_running_loop()
return loop.run_in_executor(
None,
functools.partial(f, *args, **kwargs),
)
return inner
@functools.lru_cache
def webdav_resource(remote_path: Any) -> WebDAVclient.Resource:
return _WEBDAV_CLIENT.resource(remote_path)
@run_in_executor
def webdav_list(remote_path: str) -> list:
return _WEBDAV_CLIENT.list(remote_path)

View file

@ -1,5 +1,3 @@
import asyncio
import functools
import logging
import time
from io import BytesIO
@ -8,28 +6,11 @@ from typing import Any, Optional
from async_lru import alru_cache
from webdav3.client import Resource
from . import webdav_resource
from . import run_in_executor, webdav_resource
_logger = logging.getLogger(__name__)
def _run_in_executor(f):
"""
Decorator to make blocking function call asyncio compatible
https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library/
"""
@functools.wraps(f)
def inner(*args, **kwargs):
loop = asyncio.get_running_loop()
return loop.run_in_executor(
None,
functools.partial(f, *args, **kwargs),
)
return inner
def _get_ttl_hash(seconds: int = 20) -> int:
"""
Return the same value within `seconds` time period
@ -45,7 +26,7 @@ async def _get_buffer(
) -> BytesIO:
del ttl_hash
@_run_in_executor
@run_in_executor
def buffer_inner(resource: Resource) -> BytesIO:
_logger.info(f"updating {resource}")
print(f"updating {resource}")

View file

@ -1,6 +1,6 @@
import re
from dataclasses import dataclass
from typing import Iterator
from typing import Iterator, Protocol
from fastapi import HTTPException, status
from webdav3.exceptions import RemoteResourceNotFound
@ -9,14 +9,20 @@ from .. import webdav_list
from ..dav_file import DavFile
@dataclass(frozen=True)
class NameLister(Protocol):
def __call__(self) -> Iterator[str]:
...
@dataclass(frozen=True)
class FileNameLister:
remote_path: str
re: re.Pattern[str]
def __call__(self) -> Iterator[str]:
async def __call__(self) -> Iterator[str]:
try:
file_names = webdav_list(self.remote_path)
file_names = await webdav_list(self.remote_path)
return (
name
@ -29,20 +35,20 @@ class FileNameLister:
@dataclass(frozen=True)
class FilePrefixFinder:
lister: FileNameLister
class PrefixFinder:
lister: NameLister
def __call__(self, prefix: str) -> Iterator[str]:
async def __call__(self, prefix: str) -> Iterator[str]:
return (
file_name
for file_name in self.lister()
for file_name in (await self.lister())
if file_name.lower().startswith(prefix.lower())
)
@dataclass(frozen=True)
class FilePrefixLoader:
finder: FilePrefixFinder
finder: PrefixFinder
@property
def responses(self) -> dict:
@ -62,8 +68,8 @@ class FilePrefixLoader:
},
}
def __call__(self, prefix: str) -> DavFile:
file_names = list(self.finder(prefix))
async def __call__(self, prefix: str) -> DavFile:
file_names = list(await self.finder(prefix))
if not (file_names):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)