'Python annotations for decorated async functions

I have difficulties with annotations for my coroutines which are decorated to prevent aiohttp errors. There are my two functions:

from typing import Callable, Awaitable, Optional
from os import sep
import aiofiles
import aiohttp
from asyncio.exceptions import TimeoutError
from aiohttp.client_exceptions import ClientError


def catch_aiohttp_errors(func: Callable[..., Awaitable]) -> Callable[..., Awaitable]:
    async def wrapper(*args):
        try:
            return await func(*args)
        except (TimeoutError, ClientError):
            return None
    return wrapper


@catch_aiohttp_errors
async def download(url: str, download_path: str, filename: str, suffix: str) -> Optional[str]:
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            async with aiofiles.open(download_path + sep + filename + '.' + suffix, 'wb') as file:
                async for chunk in response.content.iter_chunked(1024):
                    await file.write(chunk) if chunk else await file.write(b'')
    return download_path + sep + filename + '.' + suffix

The main reason to make decorator function is that i have several async functions using aiohttp, and i don't want to write try/except statements in every similar function.

The problem i faced is correct annotation for my second function.
As you can see, it returns str. But if there will be errors, it will return None according to try/except part of the decorator function. Is it correct to annotate such function with Optional[str]?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source