refactor main __init__

This commit is contained in:
Jörn-Michael Miehe 2022-09-04 22:30:40 +00:00
parent 105ca9d1bd
commit 77ee7c22e3
6 changed files with 85 additions and 80 deletions

View file

@ -1,76 +0,0 @@
import asyncio
import functools
import time
from typing import Any
import caldav
from async_lru import alru_cache
from webdav3 import client as WebDAVclient
from .settings import SETTINGS
_WEBDAV_CLIENT = WebDAVclient.Client({
"webdav_hostname": SETTINGS.webdav_url,
"webdav_login": SETTINGS.dav_username,
"webdav_password": SETTINGS.dav_password,
})
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
https://stackoverflow.com/a/55900800
"""
return round(time.time() / seconds)
def timed_alru_cache(**decorator_kwargs):
def decorate(f):
@alru_cache(**decorator_kwargs)
@functools.wraps(f)
async def wrapper(ttl_hash: int, *args, **kwargs):
del ttl_hash
return await f(*args, **kwargs)
return wrapper
return decorate
@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)
_CALDAV_CLIENT = caldav.DAVClient(
url=SETTINGS.caldav_url,
username=SETTINGS.dav_username,
password=SETTINGS.dav_password,
)
def caldav_principal() -> caldav.Principal:
return _CALDAV_CLIENT.principal()

View file

@ -0,0 +1,44 @@
from asyncio import get_running_loop
from functools import partial, wraps
from time import time
from async_lru import alru_cache
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/
"""
@wraps(f)
def inner(*args, **kwargs):
loop = get_running_loop()
return loop.run_in_executor(
None,
partial(f, *args, **kwargs),
)
return inner
def get_ttl_hash(seconds: int = 20) -> int:
"""
Return the same value within `seconds` time period
https://stackoverflow.com/a/55900800
"""
return round(time() / seconds)
def timed_alru_cache(**decorator_kwargs):
def decorate(f):
@alru_cache(**decorator_kwargs)
@wraps(f)
async def wrapper(ttl_hash: int, *args, **kwargs):
del ttl_hash
return await f(*args, **kwargs)
return wrapper
return decorate

View file

@ -9,7 +9,8 @@ from caldav.lib.error import ReportError
from pydantic import BaseModel, validator from pydantic import BaseModel, validator
from vobject.icalendar import VEvent from vobject.icalendar import VEvent
from . import caldav_principal, get_ttl_hash, run_in_executor, timed_alru_cache from .async_helpers import get_ttl_hash, run_in_executor, timed_alru_cache
from .dav_common import caldav_principal
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)

View file

@ -0,0 +1,35 @@
from functools import lru_cache
from typing import Any
import caldav
from webdav3 import client as WebDAVclient
from .async_helpers import run_in_executor
from .settings import SETTINGS
_WEBDAV_CLIENT = WebDAVclient.Client({
"webdav_hostname": SETTINGS.webdav_url,
"webdav_login": SETTINGS.dav_username,
"webdav_password": SETTINGS.dav_password,
})
@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)
_CALDAV_CLIENT = caldav.DAVClient(
url=SETTINGS.caldav_url,
username=SETTINGS.dav_username,
password=SETTINGS.dav_password,
)
def caldav_principal() -> caldav.Principal:
return _CALDAV_CLIENT.principal()

View file

@ -5,7 +5,8 @@ from typing import Any
from webdav3.client import Resource from webdav3.client import Resource
from . import get_ttl_hash, run_in_executor, timed_alru_cache, webdav_resource from .async_helpers import get_ttl_hash, run_in_executor, timed_alru_cache
from .dav_common import webdav_resource
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -34,7 +35,7 @@ class DavFile:
@property @property
async def __buffer(self) -> BytesIO: async def __buffer(self) -> BytesIO:
return await _get_buffer( return await _get_buffer(
ttl_hash=get_ttl_hash(), ttl_hash=get_ttl_hash(20),
remote_path=self.remote_path, remote_path=self.remote_path,
) )

View file

@ -5,7 +5,7 @@ from typing import Iterator, Protocol
from fastapi import HTTPException, status from fastapi import HTTPException, status
from webdav3.exceptions import RemoteResourceNotFound from webdav3.exceptions import RemoteResourceNotFound
from .. import caldav_principal, webdav_list from ..dav_common import caldav_principal, webdav_list
@dataclass(frozen=True) @dataclass(frozen=True)