Generate a random integer between min and max
Generating a random float between min and max
Reverse the order of digits in a number
Format large numbers with comma separators
Convert a number to a byte array
Calculate Exponents
Strings
The modern Python regular expressions cheat sheet
The modern Python strings cheat sheet
Find the length of a string
String slicing
Ways to format a string
Remove leading/trailing whitespaces
Reverse a string
Check if a string contains a substring
Concatenate strings
Convert a string to lowercase/uppercase
Convert a string into a list
Declare a multiline string
Capitalize the first letter of each word in a string
Count the number of words in a string
Check if a string is empty
String replace() method
Raw strings
Compare 2 strings ignoring case sensitivity
Remove one or many substrings from a string
Remove all non-alphanumeric characters from a string
Convert a string to a URL slug
Convert a string to bytes and vice versa
Convert a string to integer char codes
Remove consecutive spaces
Convert a string to binary codes
Get the size of a string in bytes
Convert a character to a code point and vice versa
Base64 encode/decode a string in Python
Add leading zeros to a string
Check if a string is a valid URL
Extract all URLs from text
Get the filename and the file extension from a URL
Get hostname, domain, and protocol from a URL
Align a string
Reverse the order of wrods in a string
Get a list of unique words from a string
Replace unwanted words in a string with asterisks
Convert a string to a hexadecimal value
Ways to generate random strings
Count the frequency of each word in a string
Generate random color codes
Validate phone numbers
Remove HTML tags from a string
Unescape HTML entities from a string
Remove empty lines from a string
Validate an email address
Control flow
for loop
While loop
Conditional expression
The WITH statement
Try, except, else, finally
The match/case statement
Return multiple results from a function
Keyword & positional arguments
Lists
Create a list
List comprehension
Access elements in a list
Iterate through a list
Count elements in a list
Check whether a list is empty
Replace/update elements in a list
Combine lists
Select random elements from a list
Remove elements from a list
Find all occurrences of a value in a list
Reverse a list
Find min and max in a numeric list
Find the sum of a list
Calculate the average of a numeric list
List insert() method
Sorting lists
Create nested lists
Flatten a nested list
Clone a list
Remove duplicates from a list
Filter a list
reduce() function
Find common elements in 2 lists
Swap 2 elements in a list
Compare 2 lists
Check if a list contains an element
Shuffle a list
Calculate the product of a numeric list
Count the occurrences of elements in a list
Iterate over 2 lists in parallel
The map() function
Divide a list into equally sized chunks
Declaring lists with type hints
Passing a list to a function as multiple arguments
Generate a dummy list with N random elements
List element-wise operations in Python
IndexError: List index out of range
Network & JSON
Parsing JSON data
Create JSON Data from a Dictionary
Convert a list to JSON
Send GET requests with aiohttp
aiohttp POST requests
Set timeouts when using aiohttp
Download files with aiohttp streams
aiohttp upload files
aiohttp - send multiple requests concurrently
Create a simple web server with aiohttp
Use aiohttp to crawl webpages asynchronously
Convert a dictionary to a query string
Best open-source libraries to make HTTP requests
System & File I/O
File modes
Date and Time
Convert Datetime to Timestamp and vice versa
Comparing 2 Dates
Convert Date Strings into Date Objects
Format Date and Time
Check if a date string is valid
Get the Current Date and Time with Timezone
Get a list of dates between 2 dates
Async & Await
An introduction to coroutines and event loops
asyncio.run()
Async/await and loops
asyncio.sleep() function
asycnio.create_task() function
asyncio.wait_for() function
asyncio.gather() function
async/await & timeouts
loop.run_until_complete()
Define and call async functions
Handle exceptions
Use the result returned by an async function
asyncio.Runner() context manager
asyncio.Semaphore class
Running a function periodically with asyncio
asyncio.wait() function
asyncio.Queue class
asyncio.as_completed() function
Async generators (with "yield")
run_coroutine_threadsafe()
Using async/await with class methods
Define a class with an async constructor
asyncio.loop.run_in_executor()
Run a task at a certain time time every day
loop.create_server() method
Add a coroutine to an already running event loop
RuntimeWarning: Coroutine was never awaited
CancelledError exception
SyntaxError: 'await' outside async function
Dataclasses
Introduction to dataclass
Defining Fields in Dataclass
Using Dataclass Methods
Using Inheritance with Dataclass
How to Validate Data in Dataclass
Set Default Values in Dataclass
Using Class Decorators with Dataclass
Fun Examples
Get all links from a webpage with Beautiful Soup
Extract plain text from a webpage
Extract and download all images from a webpage
3 ways to hash a password
Check System RAM/CPU/Disk Usage
Schedule events with sched.scheduler class
When and when NOT to use asyncio.run_coroutine_threadsafe()
The
asyncio.run_coroutine_threadsafe()
function is really helpful in some situations:
When you are introducing
asyncio
into an existing large program (likely an old one) that uses threads and blocking calls and cannot be converted to asyncio all at once.
When you need to call blocking functions that have no async equivalent from
asyncio
, e.g. CPU-bound functions, legacy database drivers, and something like that.
If you’re starting a new project (that doesn’t involve blocking functions without async equivalent), there is no reason to use the
asyncio.run_coroutine_threadsafe()
function. Instead, it’s better to write the code entirely using asyncio features, such as coroutines, tasks, futures, and
async/await
syntax.
At this point, you might get bored with concepts and boring words. It’s time to get our hands dirty with code.
Examples
Example 1: Welcome to Sling Academy (basic)
This simple example shows you how to use the
asyncio.run_coroutine_threadsafe()
function to print “Welcome to Sling Academy!” from a coroutine in another thread:
# SlingAcademy.com
# This code uses Python 3.11.4
import asyncio
import threading
# Define a coroutine
async def welcome():
await asyncio.sleep(2)
print("Welcome to Sling Academy!")
return "This is the result of the coroutine."
# Define a function that runs the coroutine in a thread
def run_in_thread(loop):
# Submit the coroutine to the loop
future = asyncio.run_coroutine_threadsafe(welcome(), loop)
# Wait for the result
print(f"Result: {future.result()}")
if __name__ == "__main__":
# Get the main event loop
loop = asyncio.get_event_loop()
# Create a thread that runs the coroutine
thread = threading.Thread(target=run_in_thread, args=(loop,))
# Start the thread
thread.start()
# Run the loop forever
loop.run_forever()
Output:
Welcome to Sling Academy!
Result: This is the result of the coroutine.
Example 2: Fetching URLs (intermediate)
In this example, we’ll use the
asyncio.run_coroutine_threadsafe()
function to fetch multiple URLs concurrently from a coroutine in another thread. We’ll use a library named
requests
to make network requests. You can install it by running:
pip install requests
The code:
# SlingAcademy.com
# This code uses Python 3.11.4
import asyncio
import requests
import threading
async def fetch_url(url):
# Use requests library to get the content of the url
response = requests.get(url)
return response.content
def run_in_thread(loop):
# A list of urls to fetch
urls = [
"https://api.slingacademy.com",
"https://api.slingacademy.com/v1/sample-data/photos",
"https://api.slingacademy.com/v1/sample-data/users",
# A list of futures to store the results
futures = []
# Submit each coroutine to the loop
for url in urls:
future = asyncio.run_coroutine_threadsafe(fetch_url(url), loop)
futures.append(future)
# Wait for all futures to complete
for future in futures:
# Print the length of each content
print(len(future.result()))
if __name__ == "__main__":
# Get the main event loop
loop = asyncio.get_event_loop()
# Create a thread that runs the coroutine
thread = threading.Thread(target=run_in_thread, args=(loop,))
# Start the thread
thread.start()
# Run the loop forever
loop.run_forever()
Output:
Example 3: Calling CPU-bound functions (advanced)
This example demonstrates how to use the
asyncio.run_coroutine_threadsafe()
function to call a CPU-bound function (factorial) from a coroutine in another thread:
# SlingAcademy.com
# This code uses Python 3.11.4
import asyncio
import concurrent.futures
import math
import threading
async def factorial(n):
# Use concurrent.futures module to run the math.factorial function in a separate process
with concurrent.futures.ProcessPoolExecutor() as pool:
result = await loop.run_in_executor(pool, math.factorial, n)
return result
def run_in_thread(loop):
# A list of numbers to calculate the factorial
numbers = [5, 10, 20, 30]
# A list of futures to store the results
futures = []
# Submit each coroutine to the loop
for n in numbers:
future = asyncio.run_coroutine_threadsafe(factorial(n), loop)
futures.append(future)
# Wait for all futures to complete
for future in futures:
# Print the result of each factorial
print(future.result())
if __name__ == "__main__":
# Get the main event loop
loop = asyncio.get_event_loop()
# Create a thread that runs the coroutine
thread = threading.Thread(target=run_in_thread, args=(loop,))
# Start the thread
thread.start()
# Run the loop forever
loop.run_forever()
Output:
3628800
2432902008176640000
265252859812191058636308480000000
In this case, the
asyncio.run_coroutine_threadsafe()
function helps us perform a computation-intensive task that would block the event loop if done in the same thread.
Afterword
You’ve learned the fundamentals of the
asyncio.run_coroutine_threadsafe()
function in Python and seen its helpfulness in certain situations. Try to run all of the examples on your machine, modify some lines of code, and see what happens. This is a nice way to learn new things.
This tutorial ends here. If you find something outdated or incorrect, please let me know by leaving a comment. Happy coding & have a nice day!
Next Article:
Python async/await and timeouts (with examples)
Previous Article:
Python asyncio.create_task() function (with examples)
Series:
Python Asynchronous Programming Tutorials