I have a function that makes an HTTP request and then returns the response. I'd like this function to be able to run in blocking or non-blocking mode depending on a parameter. Is this possible at all in Python? The pseudo-code I would imagine would be something like:
def maybe_async(asynchronous):
if asynchronous:
# We assume there's an event loop running and we can await
return await send_async_http_request()
else:
# Perform a normal synchronous call
return send_http_request()
This throws a SyntaxError and I'd like to find a way to rephrase it so that it rather throws RuntimeError: no running event loop at runtime if asynchronous=True but no event loop is running.
There's been two comments saying I just have to remove the await keyword from maybe_async, however I believe if we want to post-process the response then this is not relevant. Here is a more specific use case: say I want to hand to end-users a function that gathers all events IDs from the GitHub API, and that does so in a blocking or non-blocking mode depending on user input. Here's what I would like to do:
import aiohttp
import requests
async def get_async(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
def get_sync(url):
return requests.get(url).json()
def get(url, asynchronous):
if asynchronous:
return get_async(url) # This is the suggested edit where
# I removed the await keyword
else:
return get_sync(url)
def get_github_events_ids(asynchronous=False):
url = 'https://api.github.com/events'
body = get(url, asynchronous)
return [event['id'] for event in body]
But obviously running get_github_events_ids(True) raises TypeError: 'coroutine' object is not iterable.
My question is: is there any code design other than duplicating all functions that allows to choose between sync and async?