Basically I have synchronous code something similar to this:
def f(.):
...
def call(.):
..Some sync code..
try:
resp = f(..)
...some more transformations of resp...
return ..
except:
..Some error handling..
async def af(.):
...
Basically I want to dynamically alter the code of call
so that it can call and await af
function instead of f
. Is there a way around this? I have found syncit
on github, but it doesn't seem to be a solution to me as you have to rewerite the code to async first and then downgrade it to sync. Any help will be appreciated.
Convert Synchronous to Asynchronous The typical way to make a synchronous function asynchronous is to execute the function in a separate thread. Notice how SyncToAsync finishes and returns control to the program immediately, while SyncMethod executes asynchronously in the background.
Async/await statements are syntactic sugar created on top of JavaScript Promises. They allow us to write Promise-based code as if it were synchronous, but without blocking the main thread.
Sync is blocking — it will only send the server one request at a time and will wait for that request to be answered by the server. Async increases throughput because multiple operations can run at the same time. Sync is slower and more methodical.
Async functions can directly call sync functions, and if that sync function blocks, then so does the async function calling it.
Here are two options mixing synchronous and asynchronous code.
Given
import asyncio
import trio
from unsync import unsync
Code
Option 1 - trio
Given sync code (call
), call an async function via trio
(async_div
):
# Sync code
def call(x, y):
"""Return an awaited result."""
try:
resp = async_div(x, y)
except ZeroDivisionError:
return "Caught an exception."
return resp
# Wrapper
def async_div(*args):
"""Return results from an async function."""
return trio.run(_async_div, *args)
# Async code
async def _async_div(x, y):
"""Return an async result."""
await trio.sleep(3)
return x / y
Option 2 - unsync
Decorate the async code with @unsync
and call the result()
:
# Sync code
def call(x, y):
"""Return an awaited result."""
try:
resp = async_div(x, y).result()
except ZeroDivisionError:
return "Caught an exception."
return resp
# Async code
@unsync
async def async_div(x, y):
"""Return an async result."""
await asyncio.sleep(3)
return x / y
Demo
After the prescribed delay (3 secs), the results are the same:
call(0, 1)
# 0.0
call(1, 0)
# 'Caught an exception.'
See Also
Some additional resources:
trio
trio
creator N. Smith for more details and his philosophy on asynchronous programming.unsync
detailsunsync
to speed up requestsIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With