py3.12: more styling and linting

This commit is contained in:
Jörn-Michael Miehe 2023-10-17 14:55:38 +02:00
parent d193d07fd6
commit b0e95af44e
9 changed files with 43 additions and 76 deletions

View file

@ -9,9 +9,7 @@ from typing import Awaitable, Callable, TypeVar
RT = TypeVar("RT") RT = TypeVar("RT")
def run_in_executor( def run_in_executor(function: Callable[..., RT]) -> Callable[..., Awaitable[RT]]:
function: Callable[..., RT]
) -> Callable[..., Awaitable[RT]]:
""" """
Decorator to make blocking a function call asyncio compatible. Decorator to make blocking a function call asyncio compatible.
https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library/ https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library/

View file

@ -22,17 +22,6 @@ from .dav_common import caldav_principal
from .settings import SETTINGS from .settings import SETTINGS
_logger = getLogger(__name__) _logger = getLogger(__name__)
def _string_strip(in_str: str) -> str:
"""
Wrapper for str.strip().
Used to define `pydantic` validators.
"""
return in_str.strip()
StrippedStr = Annotated[str, AfterValidator(lambda s: s.strip())] StrippedStr = Annotated[str, AfterValidator(lambda s: s.strip())]

View file

@ -18,12 +18,14 @@ from . import __file__ as OVD_INIT
from .async_helpers import run_in_executor from .async_helpers import run_in_executor
from .settings import SETTINGS from .settings import SETTINGS
_WEBDAV_CLIENT = WebDAVclient({ _WEBDAV_CLIENT = WebDAVclient(
{
"webdav_hostname": SETTINGS.webdav.url, "webdav_hostname": SETTINGS.webdav.url,
"webdav_login": SETTINGS.webdav.username, "webdav_login": SETTINGS.webdav.username,
"webdav_password": SETTINGS.webdav.password, "webdav_password": SETTINGS.webdav.password,
"disable_check": SETTINGS.webdav_disable_check, "disable_check": SETTINGS.webdav_disable_check,
}) }
)
_logger = getLogger(__name__) _logger = getLogger(__name__)
@ -113,11 +115,13 @@ def webdav_ensure_files(remote_path: str, *file_names: str) -> None:
missing_files = ( missing_files = (
file_name file_name
for file_name in file_names for file_name in file_names
if not _WEBDAV_CLIENT.check(path.join( if not _WEBDAV_CLIENT.check(
path.join(
SETTINGS.webdav_prefix, SETTINGS.webdav_prefix,
remote_path, remote_path,
file_name, file_name,
)) )
)
) )
webdav_upload_skel( webdav_upload_skel(
@ -132,9 +136,7 @@ def webdav_resource(remote_path: Any) -> WebDAVResource:
Gets a resource using the main WebDAV client. Gets a resource using the main WebDAV client.
""" """
return _WEBDAV_CLIENT.resource( return _WEBDAV_CLIENT.resource(f"{SETTINGS.webdav_prefix}/{remote_path}")
f"{SETTINGS.webdav_prefix}/{remote_path}"
)
@run_in_executor @run_in_executor
@ -143,9 +145,7 @@ def webdav_list(remote_path: str) -> list[str]:
Asynchronously lists a WebDAV path using the main WebDAV client. Asynchronously lists a WebDAV path using the main WebDAV client.
""" """
return _WEBDAV_CLIENT.list( return _WEBDAV_CLIENT.list(f"{SETTINGS.webdav_prefix}/{remote_path}")
f"{SETTINGS.webdav_prefix}/{remote_path}"
)
_CALDAV_CLIENT = CalDAVclient( _CALDAV_CLIENT = CalDAVclient(
@ -169,7 +169,4 @@ def caldav_list() -> Iterator[str]:
Asynchronously lists all calendars using the main WebDAV client. Asynchronously lists all calendars using the main WebDAV client.
""" """
return ( return (str(cal.name) for cal in caldav_principal().calendars())
str(cal.name)
for cal in caldav_principal().calendars()
)

View file

@ -63,11 +63,7 @@ class FileNameLister:
try: try:
file_names = await webdav_list(await self.remote_path) file_names = await webdav_list(await self.remote_path)
return ( return (name for name in file_names if self.re.search(name))
name
for name in file_names
if self.re.search(name)
)
except RemoteResourceNotFound: except RemoteResourceNotFound:
_logger.error( _logger.error(
@ -115,8 +111,7 @@ class PrefixFinder:
return { return {
**_RESPONSE_OK, **_RESPONSE_OK,
status.HTTP_404_NOT_FOUND: { status.HTTP_404_NOT_FOUND: {
"description": "Failure in lister " + "description": f"Failure in lister {self.lister.__class__.__name__!r}",
repr(self.lister.__class__.__name__),
"content": None, "content": None,
}, },
} }

View file

@ -10,6 +10,7 @@ from logging import getLogger
from typing import Iterator from typing import Iterator
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from ovdashboard_api.config import Config from ovdashboard_api.config import Config
from ...dav_calendar import CalEvent, DavCalendar from ...dav_calendar import CalEvent, DavCalendar
@ -52,12 +53,13 @@ async def get_aggregate_calendar(
aggregate = cfg.calendar.aggregates[name] aggregate = cfg.calendar.aggregates[name]
calendars = ( calendars = (
DavCalendar(await calendar_unique(cal_prefix)) DavCalendar(await calendar_unique(cal_prefix)) for cal_prefix in aggregate
for cal_prefix in aggregate
) )
return sorted([ return sorted(
[
event event
async for calendar in calendars # type: ignore async for calendar in calendars # type: ignore
for event in (await calendar.events) for event in (await calendar.events)
]) ]
)

View file

@ -88,7 +88,5 @@ async def get_file(
return StreamingResponse( return StreamingResponse(
content=buffer, content=buffer,
media_type=mime, media_type=mime,
headers={ headers={"Content-Disposition": f"filename={prefix}"},
"Content-Disposition": f"filename={prefix}"
},
) )

View file

@ -83,11 +83,7 @@ async def get_image(
cfg = await Config.get() cfg = await Config.get()
dav_file = DavFile(f"{await image_lister.remote_path}/{name}") dav_file = DavFile(f"{await image_lister.remote_path}/{name}")
img = Image.open( img = Image.open(BytesIO(await dav_file.as_bytes)).convert(cfg.image.mode)
BytesIO(await dav_file.as_bytes)
).convert(
cfg.image.mode
)
img_buffer = BytesIO() img_buffer = BytesIO()
img.save(img_buffer, **cfg.image.save_params) img.save(img_buffer, **cfg.image.save_params)
@ -96,9 +92,7 @@ async def get_image(
return StreamingResponse( return StreamingResponse(
content=img_buffer, content=img_buffer,
media_type="image/jpeg", media_type="image/jpeg",
headers={ headers={"Content-Disposition": f"filename={prefix}.jpg"},
"Content-Disposition": f"filename={prefix}.jpg"
},
) )

View file

@ -42,11 +42,7 @@ async def get_ticker_lines() -> Iterator[str]:
f"{await text_lister.remote_path}/{file_name}", f"{await text_lister.remote_path}/{file_name}",
).as_string ).as_string
return ( return (line.strip() for line in ticker.split("\n") if line.strip())
line.strip()
for line in ticker.split("\n")
if line.strip()
)
async def get_ticker_content_lines( async def get_ticker_content_lines(
@ -55,9 +51,7 @@ async def get_ticker_content_lines(
cfg = await Config.get() cfg = await Config.get()
return ( return (
line line for line in ticker_lines if not line.startswith(cfg.ticker.comment_marker)
for line in ticker_lines
if not line.startswith(cfg.ticker.comment_marker)
) )

View file

@ -7,7 +7,7 @@ Converts per-run (environment) variables and config files into the
Pydantic models might have convenience methods attached. Pydantic models might have convenience methods attached.
""" """
from typing import Any, Optional from typing import Any
from pydantic import BaseModel, root_validator from pydantic import BaseModel, root_validator
from pydantic_settings import BaseSettings from pydantic_settings import BaseSettings
@ -18,11 +18,11 @@ class DavSettings(BaseModel):
Connection to a DAV server. Connection to a DAV server.
""" """
protocol: Optional[str] = None protocol: str | None = None
host: Optional[str] = None host: str | None = None
username: Optional[str] = None username: str | None = None
password: Optional[str] = None password: str | None = None
path: Optional[str] = None path: str | None = None
@property @property
def url(self) -> str: def url(self) -> str:
@ -57,8 +57,8 @@ class Settings(BaseSettings):
##### #####
openapi_url: str = "/openapi.json" openapi_url: str = "/openapi.json"
docs_url: Optional[str] = None if production_mode else "/docs" docs_url: str | None = None if production_mode else "/docs"
redoc_url: Optional[str] = None if production_mode else "/redoc" redoc_url: str | None = None if production_mode else "/redoc"
##### #####
# webdav settings # webdav settings