sentinelhub-py icon indicating copy to clipboard operation
sentinelhub-py copied to clipboard

[FEAT] python async support

Open cmcconomyfwig opened this issue 2 years ago • 5 comments

What is the problem? Please describe.

I wish to be able to interact with sentinelhub via the python libraries asynchronously

Here's the solution

I've written up an async harness I have been using to work with the SentinelHub classes, maybe it can provide some inspiration.

from sentinelhub import SHConfig
from cache import AsyncTTL
import httpx
from urllib.parse import urlencode

@AsyncTTL(time_to_live=60*45)  # 45m in sec
async def get_sentinel_token(config: SHConfig) -> str:
    params = urlencode({
        'grant_type':'client_credentials',
        'client_id': config.sh_client_id,
        'client_secret': config.sh_client_secret,
    })
    url = f'{config.sh_auth_base_url}/oauth/token?{params}'
    headers = {
        "content-type": "application/x-www-form-urlencoded"
    }

    async with httpx.AsyncClient() as client:
    r = await client.post(url, headers=headers, timeout=10.0)
        r.raise_for_status()
        output = r.json()

    return output.get('access_token')

async def sentinel_request_async(request: SentinelHubRequest, config: SHConfig) -> Union[dict, bytes]:
    request.create_request()  # populate the download list.
    dl = request.download_list[0]
    headers = dl.headers

    async with httpx.AsyncClient() as client:
        access_token = await get_sentinel_token(config, client)
        headers['Authorization'] = f"Bearer {access_token}"
        r = await client.post(dl.url, headers=headers, json=dl.post_values, timeout=30.0)
        r.raise_for_status()

        if r.headers.get('content-type') == 'application/json':
            return r.json()
        elif r.headers.get('content-type') == 'image/tiff':
            return tiff.imread(BytesIO(r.read()))
        else:
            return r.read()  # bytes

The important thing is to ensure any I/O in the chain is performed in an async context, including things like token retrieval or any other network I/O.

Hope this helps.

cmcconomyfwig avatar Jan 25 '23 14:01 cmcconomyfwig

Hi @cmcconomyfwig thank you for the suggestion. Supporting async has been on our radar a couple of times in the past years. But since async is a rather all-or-nothing approach in Python, we never had the time to fully commit to it. We hope to be able to include async support in a future version, but cannot promise anything at this point.

zigaLuksic avatar Jan 25 '23 14:01 zigaLuksic

Thanks for the reply, I understand that what I have above doesn't cover all the batch downloading capabilities you've built into the sync client, and it looks like quite the undertaking.

Whenever it is released, I look forward to transitioning to official APIs. In the meantime, I hope that others who are looking for any way to hook asynchronous calling into SentinelHub can make use of the snippet above.

cmcconomyfwig avatar Jan 26 '23 02:01 cmcconomyfwig

Hi @zigaLuksic , I have been working with HTTPX Async for few months now, I'd be happy to work on this task if needed

krishnaglodha avatar Jul 12 '23 12:07 krishnaglodha

Hi @zigaLuksic , I have been working with HTTPX Async for few months now, I'd be happy to work on this task if needed

we very much appreciate the offer. but the current issue is that the structure of the sh-py is hard to adapt for such large changes. We do have a larger refactoring planned, and hopefully after that we would be able to start with async.

zigaLuksic avatar Jul 24 '23 06:07 zigaLuksic

Hi @zigaLuksic , I have been working with HTTPX Async for few months now, I'd be happy to work on this task if needed

we very much appreciate the offer. but the current issue is that the structure of the sh-py is hard to adapt for such large changes. We do have a larger refactoring planned, and hopefully after that we would be able to start with async.

Thanks a lot for getting back, let me know if you need me on any other task, I'm available for contribution on GIS | Python | Documentation

krishnaglodha avatar Jul 24 '23 06:07 krishnaglodha