Async Functions in
Python and Their
Relation to
Structured
Programming
Efficient Programming with Asynchronous Paradigms
GROUP 8 Presentaion
Members
AUL/CMP/22/092 GRAHAM EGWUANUMKU
AUL/CMP/22/072 ISRAEL OLUNIYI
AUL/CMP/22/096 PENUEL OLUWADARE
AUL/CMP/22/123 JEGEDE JOSEPH
AUL/CMP/22/103 OKOLI PROMISE
AUL/CMP/ 22/099 ORIZU HENRY
Async Functions
Definition
An Async function is a function in programming, particularly in asynchronous
programming, that allows non-blocking operations to be handled in a way that appears
synchronous. Async functions are integral in modern programming languages for handling
tasks that would otherwise take a long time to complete, such as reading from files,
making network requests, or interacting with databases. They enable a program to remain
responsive while waiting for time-consuming tasks to finish, instead of blocking the entire
execution flow.
An async function is a function in programming that enables asynchronous, non-blocking
execution of code. When a function is declared as async, it allows for the use of the await
keyword inside it, which pauses the function’s execution until a promise is resolved or rejected,
without blocking the entire program.
Key points about async functions:
1. Returns a Promise: An async function always returns a Promise, which can resolve
to a value or reject with an error.
2. Allows await: Inside an async function, the await keyword can be used to pause
execution until a Promise is resolved, making asynchronous code look and behave
more like synchronous code.
3. Error Handling: Async functions support try-catch for error handling, making it
easier to manage errors.
TYPES OF ASYNC FUNCTIONS IN PYTHON.
Async functions in Python are a powerful feature that allows for asynchronous
programming, enabling concurrent execution of coroutines. Let's explore the various types
of async functions in Python:
1. Basic Async Functions
Basic async functions are defined using the async def syntax. They can contain
asynchronous operations and yield control back to the event loop when an await
expression is encountered.
These functions can be called using the await keyword within other coroutines or using
asyncio.run().
2. Coroutines
Coroutines are special types of functions that can suspend their execution at specific
points (using yield expressions) and resume from where they left off later. They are the
building blocks of async programming in Python.
Coroutines can be used as async functions or returned from other coroutines.
3. Async Context Managers
Async context managers allow for asynchronous resource management using the async
with statement. They are particularly useful for managing database connections or file
operations in an asynchronous environment.
4. Async Generators
Async generators are coroutines that yield values asynchronously. They can be used to
implement asynchronous iterators.
5. Async Class Methods
Async class methods can be defined using the @classmethod decorator combined with
async def. These methods can be called without creating an instance of the class.
6. Async Static Methods
Similar to async class methods, static async methods can be defined using
@staticmethod combined with async def. These methods belong to the class itself rather
than instances.
7. Async Property Decorators
While not directly related to functions, async property decorators (@property,
@classmethod, @staticmethod) can be used to define asynchronous properties on
classes.
Applications of async functions
Web Applications:
FastAPI and Sanic are modern web frameworks that utilize async functions to manage
multiple HTTP requests at the same time, enhancing the throughput and responsiveness of
web applications.
Real-time Communication:
Async is particularly well-suited for WebSocket-based interactions, such as chat
applications, enabling multiple users to send and receive messages simultaneously.
Network Programming:
Asynchronous APIs: When retrieving data from APIs, such as making several API calls or
requests to external services, async functions facilitate parallel requests, which
accelerates the overall process.
Web Scraping: In the realm of web scraping, libraries like aiohttp leverage async functions to
request multiple web pages at once instead of one after the other, significantly boosting
efficiency.
Database Access:
Libraries such as asyncpg for PostgreSQL and aiomysql for MySQL employ async functions to
execute database queries concurrently, minimizing the wait time for responses in high-
traffic applications.
File I/O Operations:
Async is advantageous for handling large files or for reading and writing files at the same
time. Libraries like aiofiles are utilized to perform file operations asynchronously,
particularly in applications that require batch processing of files.
Concurrency in Scripts:
Async functions are widely used to run parallel tasks in scripts that involve fetching data
from multiple sources, sending multiple emails, or handling multiple tasks in general.
Uses of Async functions
Non-blocking Operations:
Async functions are great since they allow the program to keep working on other things
while a particular time-feature like an API request or a file read waits for the resource to be
free. The program will not remain idle; it can continue performing other tasks.
Concurrency:
It is possible to utilize several Async functions to interact with several APIs or databases
simultaneously, this leads to significant performance improvement of I/O processes
without the use of threads or multiprocessing.
Efficient Resource Management:
While async functions wait for resources such as file and network connections, they
enable other parts of the program to execute. This results in efficient utilization of system
resources such as CPU and memory.
Better Scalability:
For web servers or applications that perform a high volume of I/O operations, there may be
multiple users interacting with the web server at the same time. Asynchronous code is
more scalable for such cases.
Event Loop Management:
Async functions are effective while dealing with event loops, for example, when using
async.io frameworks, one can easily respond to a number of events such as a number of
network sockets anytime without blocking.
Advantages of Async Functions
1) Non-blocking Execution: Async functions allow for non-blocking execution. While
waiting for a time-consuming task (like I/O operations, network requests, or file
handling), other tasks can continue to run in the background. This helps in utilizing
system resources more efficiently.
2) Improved Performance: Asynchronous code allows for better performance in
applications that require high concurrency, such as web servers or APIs. Multiple
operations can be executed concurrently, which improves throughput and reduces
waiting time.
3) Scalability: Async functions make it easier to scale applications. This is particularly
useful for server-side applications, where handling many simultaneous requests
without blocking the main thread is essential for maintaining scalability and
responsiveness.
4) Simpler Code with async/await: Unlike traditional callback-based approaches (like
Promises or event listeners), using async and await provides a cleaner and more
readable syntax, similar to synchronous code. It reduces the callback hell and
makes error handling more intuitive.
5) Better Resource Utilization: Async functions help in optimizing CPU and memory
usage. Instead of idling while waiting for I/O operations to complete, the program
can perform other tasks, making better use of the available resources.
Disadvantages of Async Functions
1) Complex Debugging and Error Handling: Debugging asynchronous code can be
harder, as it involves different execution contexts. Errors may occur in different
parts of the program, which might be harder to trace and handle. Proper error
handling requires extra care when using async functions.
2) Callback Hell in Some Cases: While async/await helps avoid traditional callback
hell, improperly structured async code can still become complex and difficult to
follow, especially when chaining multiple asynchronous tasks.
3) Not Suitable for All Tasks: Async functions are great for I/O-bound operations, but
for CPU-bound tasks (like heavy computations), they don’t offer much benefit. In
fact, they can even introduce overhead due to the context switching between
threads.
4) Potential for Race Conditions: Since async functions allow multiple operations to
run concurrently, there's a potential for race conditions if shared resources are
accessed by multiple async tasks at the same time. Careful synchronization is
needed to avoid these issues.
5) Increased Complexity in Maintenance: While async functions are great for
concurrency, they may introduce complexity in the long run, especially in large
applications. Managing multiple async operations, timeouts, and dependencies
can become tricky, leading to difficulties in maintaining the codebase.
Importance of asynchronous functions
1. Improve responsiveness: Allow your program to respond to user input or other events
while performing time-consuming tasks in the background.
2. Enhance scalability: Enable your program to handle multiple tasks concurrently,
increasing overall throughput and efficiency.
3. Reduce latency: Permit your program to initiate time-consuming tasks without waiting
for them to complete, reducing the delay between user input and response.
4. Simplify code: Allow for more straightforward code structure, as asynchronous
functions can be written to appear synchronous.
5. Increase concurrency: Enable your program to perform multiple tasks simultaneously,
taking full advantage of multi-core processors.
6. Better error handling: Provide a clearer and more straightforward way to handle errors,
as asynchronous functions can explicitly handle errors.
7. Easier debugging: Make debugging easier, as asynchronous functions provide a clear
and concise way to trace program execution.
8. Improved user experience: Allow for a more responsive and engaging user interface, as
your program can continue to interact with the user while performing tasks in the
background.
9. Enable parallel processing: Allow your program to take full advantage of multi-core
processors, significantly improving performance.
10. Future-proofing: Asynchronous functions are essential for modern programming, and
understanding them will prepare you for future development.
Case Study: Building a Real-Time Weather Monitoring System
Scenario
A weather monitoring company needs to build a Python-based application that:
1. Fetches live weather data from multiple APIs concurrently.
2. Processes and stores the data in a database.
3. Generates reports or alerts in real time if specific conditions (e.g., storms or high
temperatures) are detected.
This project requires asynchronous programming to handle multiple I/O-bound operations
efficiently. At the same time, it should adhere to structured programming principles like
sequence, selection, and iteration for maintainability and clarity.
Step 1: Structured Program Design
The system follows structured programming principles:
1. Sequence: Each step of the process (fetch, process, store) occurs in a defined
order.
2. Selection: Decision-making logic determines if an alert should be generated based
on weather conditions.
3. Iteration: Processes data for multiple locations concurrently.
Step 2: Using Async Functions
Python’s async functions are used to achieve concurrency and handle high-latency
operations (e.g., API calls).
Implementation
1. Fetching Weather Data
Use asynchronous functions to fetch data from multiple weather APIs.
2. Processing the Data
Once the data is fetched, process it to detect extreme weather conditions.
python
3. Storing the Data
Store the processed data in a database using an async database library (e.g., aiomysql).
4. Running the Full Workflow
Integrate all functions to execute the workflow in a structured sequence.
Step 3: Analysis of the Case Study
Structured Programming Principles in Action
1. Sequence:
o The workflow follows a linear process: Fetch -> Process -> Store.
o Each task is clearly defined and executed in order.
2. Selection:
o Decisions (e.g., generating alerts for high temperatures) are made using
control flow constructs like if-else.
3. Iteration:
o Data for multiple locations is processed using a for loop.
o The asyncio.gather() method handles concurrent execution efficiently.
Benefits of Async Functions
Efficiency: Multiple API calls and database operations are handled without
blocking the program.
Scalability: Adding more locations or APIs doesn't significantly increase execution
time.
Clarity: The use of async functions maintains the readability and structure of the
code.
Conclusion
This case study demonstrates how async functions integrate seamlessly with structured
programming principles in Python. By leveraging async capabilities, the application becomes
more efficient and scalable while retaining clarity and modularity in its design.