#python #compsci #software Used for [[Asynchronous programming|asynchronous programming]] ## High-level APIs ### Runners "Runners" are high-level asyncio primitives that are used to run asyncio code. They are built on top of an event loop with the aid to simplify async code usage for common wide-spread scenarios. ![[Pasted image 20250802182307.png]] ([[Coroutine]]) ![[Pasted image 20250802182943.png]] Methods: ![[Pasted image 20250802183032.png]] ### Coroutines and Tasks #### Coroutines Coroutines declared with the **async/await** syntax is the preferred way of writing asyncio applications.: ![[Pasted image 20250802183212.png]] To actually run a coroutine, asyncio provides the following mechanisms: ![[Pasted image 20250802183244.png]] with the `asyncio.create_task()` function you can run coroutines concurrently (not really - we're not multithreading, BUT in here "concurrently" means that if one of the tasks waits or idles, the other task starts) as asyncio Tasks. Using the previous example: ![[Pasted image 20250802183327.png]] The `asyncio.TaskGroup` class provides a more modern alternative to `create_task()`: ![[Pasted image 20250802183403.png]] ^256deb #### Awaitables We say that an object is an **awaitable** object if it can be used in an `await` expression, which itself can only be used INSIDE a coroutine (async function). 3 types of awaitable objects: - coroutines - Tasks - Futures ![[Pasted image 20250802183539.png]] ![[Pasted image 20250802183559.png]] ![[Pasted image 20250802183611.png]] #### Creating Tasks ![[Pasted image 20250802185054.png]] #### Task Cancellation ![[Pasted image 20250802185127.png]] #### Task Groups ![[Pasted image 20250802185219.png]] ![[Pasted image 20250802185344.png]] ![[Pasted image 20250802185431.png]] ![[Pasted image 20250802185514.png]] ![[Pasted image 20250802190049.png]] #### Sleeping ![[Pasted image 20250802190412.png]] #### Running Tasks Concurrently ![[Pasted image 20250802190510.png]] ![[Pasted image 20250802190554.png]] #### Eager Task Factory Eager Task Execution = tasks start as soon as they are called ![[Pasted image 20250802190739.png]] ![[Pasted image 20250802190904.png]] #### Shielding from cancellation ![[Pasted image 20250802191015.png]] #### Timeouts ![[Pasted image 20250802191136.png]] ![[Pasted image 20250802191219.png]] ![[Pasted image 20250802191231.png]] ![[Pasted image 20250802191305.png]] #### Waiting Primitives ![[Pasted image 20250802191404.png]] ![[Pasted image 20250802191504.png]] #### Running in Threads ![[Pasted image 20250802191540.png]] #### Scheduling from other Threads ![[Pasted image 20250802191723.png]] #### Introspection ![[Pasted image 20250802191907.png]] #### Task Object ![[Pasted image 20250802193027.png]] Methods: ![[Pasted image 20250802193604.png]] ![[Pasted image 20250802193613.png]] ![[Pasted image 20250802193624.png]] ![[Pasted image 20250802193704.png]] ![[Pasted image 20250802194410.png]] ![[Pasted image 20250802194612.png]] ![[Pasted image 20250802194620.png]] ### Streams Streams are high-level async/await-ready primitives to work with network connections. Streams allow sending and receiving data without using callbacks or low-level protocols and transports. #### Stream Functions ![[Pasted image 20250802223844.png]] ![[Pasted image 20250802223854.png]] ![[Pasted image 20250802223904.png]] #### Stream Reader ![[Pasted image 20250802223950.png]] ![[Pasted image 20250802224001.png]] #### StreamWriter ![[Pasted image 20250802224019.png]] ![[Pasted image 20250802224039.png]] ![[Pasted image 20250802224102.png]] #### Examples ![[Pasted image 20250802224144.png]] ![[Pasted image 20250802224157.png]] ![[Pasted image 20250802224215.png]] ![[Pasted image 20250802224227.png]] (uses [[socket module]]) ### Syncronization primitives ![[Pasted image 20250802225153.png]] asyncio has the following basic synchronization primitives: - Lock - Event - Condition - Semaphore - BoundedSemaphore - Barrier #### Lock ![[Pasted image 20250802225255.png]] (thread-safe = will work even if many threads are executing it simultaneously) ![[Pasted image 20250802225343.png]] essentially everything inside the lock context manager must be executed before anything else. ![[Pasted image 20250802225710.png]] ![[Pasted image 20250802225759.png]] ![[Pasted image 20250802225839.png]]![[Pasted image 20250802230005.png]] ![[Pasted image 20250802230047.png]] #### Semaphore ![[Pasted image 20250802230214.png]] ![[Pasted image 20250802230226.png]] #### Barrier ![[Pasted image 20250802230331.png]] ![[Pasted image 20250802230347.png]] ![[Pasted image 20250802230431.png]]