async context manager for WebDAV.read_buffer

This commit is contained in:
Jörn-Michael Miehe 2023-09-08 15:30:52 +00:00
parent 6ac19ee866
commit d27d952d38
2 changed files with 64 additions and 9 deletions

View file

@ -1,7 +1,7 @@
import re
from contextlib import contextmanager
from contextlib import asynccontextmanager
from io import BytesIO, TextIOWrapper
from typing import ContextManager, Iterator
from typing import AsyncContextManager, AsyncIterator
from cache import AsyncTTL
from webdav3.client import Client as WebDAVclient
@ -44,18 +44,21 @@ class WebDAV:
return cls._webdav_client.check(path)
@AsyncTTL(time_to_live=SETTINGS.cache_ttl)
@classmethod
async def read_buffer(cls, path: str) -> ContextManager[BytesIO]:
async def read_buffer(cls, path: str) -> AsyncContextManager[BytesIO]:
"""
Datei aus Pfad `path` in einen `BytesIO` Puffer laden
"""
@AsyncTTL(time_to_live=SETTINGS.cache_ttl)
async def inner() -> BytesIO:
buffer = BytesIO()
cls._webdav_client.resource(path).write_to(buffer)
return buffer
@contextmanager
def ctx() -> Iterator[BytesIO]:
@asynccontextmanager
async def ctx() -> AsyncIterator[BytesIO]:
buffer = await inner()
buffer.seek(0)
yield buffer
@ -68,7 +71,7 @@ class WebDAV:
Datei aus Pfad `path` als string zurückgeben
"""
with await cls.read_buffer(path) as buffer:
async with await cls.read_buffer(path) as buffer:
tio = TextIOWrapper(buffer, encoding=encoding)
tio.seek(0)

View file

@ -0,0 +1,52 @@
import asyncio
import functools
from contextlib import asynccontextmanager, contextmanager
from io import BytesIO
from typing import AsyncContextManager, AsyncIterator, ContextManager, Iterator
def get_buf_sync() -> ContextManager[BytesIO]:
@functools.lru_cache
def inner() -> BytesIO:
with open(__file__, "rb") as file:
return BytesIO(file.readline())
@contextmanager
def ctx() -> Iterator[BytesIO]:
buf = inner()
buf.seek(0)
yield buf
return ctx()
def main_sync() -> None:
for _ in range(2):
with get_buf_sync() as buffer:
print(buffer.read())
async def get_buf_async() -> AsyncContextManager[BytesIO]:
@functools.lru_cache
async def inner() -> BytesIO:
with open(__file__, "rb") as file:
return BytesIO(file.readline())
@asynccontextmanager
async def ctx() -> AsyncIterator[BytesIO]:
buf = await inner()
buf.seek(0)
yield buf
return ctx()
async def main_async() -> None:
for _ in range(2):
async with await get_buf_async() as buffer:
print(buffer.read())
if __name__ == "__main__":
main_sync()
asyncio.run(main_async())