繁体   English   中英

装饰的异步方法返回 None

[英]Decorated async method returns None

我有以下 Yodel 类,它从官方 Yodel API 获取数据。 为了使它更快,我使用 aiohttp 和 asyncio 但我想让它在用户实例化对象并调用其方法时看起来同步。 为了实现这一点,我创建了一个装饰器,以便将tracking作为同步方法调用。

import aiohttp
import asyncio
import time

class Yodel:
    API_BASE_URL = "api.yodel.co.uk"

    CLIENT_ID = "..."
    CLIENT_SECRET = "..."

    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.loop.run_until_complete(self.auth())

    async def auth(self):
        self.session = aiohttp.ClientSession()
        url = f"https://{Yodel.API_BASE_URL}/tracking/v1.0/oauth2/token"

        payload = f"grant_type=client_credentials&client_id={Yodel.CLIENT_ID}&client_secret={Yodel.CLIENT_SECRET}&scope=tracking"
        headers = {
            "Accept": "application/json",
            "content-type": "application/x-www-form-urlencoded"
        }

        response = await self.session.request("POST", url=url, data=payload, headers=headers)

        response = await response.json()

        self.session = aiohttp.ClientSession(
            headers = {
                "Accept": "*/*",
                "Authorization": f"Bearer {response['access_token']}",
                "x-ibm-client-id": Yodel.CLIENT_ID,
            }
        )

    async def fetch_data(self, url, **kwargs):
        response = await self.session.request("GET", url=url, **kwargs)
        response = await response.json()

        return response
    
    def async_loop(f):
        def decorated(self, *args, **kwargs):
            self.loop.run_until_complete(f(self, *args, **kwargs))
        return decorated

    @async_loop
    async def tracking(self, trackingIds: list, **kwargs):
        tasks = []

        for trackingId in trackingIds:
            endpoint = f"/tracking/v1.0/parcel-tracking/{trackingId}"
            url = f"https://{Yodel.API_BASE_URL}{endpoint}"
            tasks.append(self.fetch_data(url, **kwargs))
        
        trackings = await asyncio.gather(*tasks, return_exceptions=True)

        # I see trackings as json when inspecting variables, however...
        return trackings # Returns None


if __name__ == "__main__":
    yodel = Yodel()
    trackings = yodel.tracking([
        "JJD0002247772000106",
        "JJD0002247772000107",
        "JJD0002247772000108"
    ])

退货

None

哦,它只是失踪了

def async_loop(f):
    def decorated(self, *args, **kwargs):
        response = self.loop.run_until_complete(f(self, *args, **kwargs))
        return response
    return decorated

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM