### Complete Runnable Example: Async SQLAlchemy and awaitlet Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst A comprehensive example combining all components: asynchronous engine creation, ORM model definition, table setup, synchronous data manipulation, and execution via `awaitlet.async_def` within an asyncio application. ```python from __future__ import annotations import asyncio import datetime from typing import Optional import awaitlet from sqlalchemy.ext.asyncio import create_async_engine from sqlalchemy.orm import sessionmaker from sqlalchemy import ForeignKey from sqlalchemy import func from sqlalchemy import select from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import Mapped from sqlalchemy.orm import mapped_column class Base(DeclarativeBase): pass class A(Base): __tablename__ = "a" id: Mapped[int] = mapped_column(primary_key=True) data: Mapped[Optional[str]] create_date: Mapped[datetime.datetime] = mapped_column( server_default=func.now() ) async_engine = create_async_engine( "postgresql+asyncpg://scott:tiger@localhost/test", echo=True, ) engine = async_engine.engine sessionmaker = sessionmaker(async_engine.engine) def setup_tables(): with engine.begin() as conn: Base.metadata.drop_all(conn) Base.metadata.create_all(conn) def work_with_data(): with sessionmaker() as session: with session.begin(): session.add_all( [ A(data="a1"), A(data="a2"), A(data="a3"), ] ) stmt = select(A.data) result = session.scalars(stmt) return result.all() def call_async_db_code(): setup_tables() result = work_with_data() return result async def front_facing_asyncio_facade(): result = await awaitlet.async_def(call_async_db_code) print(f"Result: {result}") asyncio.run(front_facing_asyncio_facade()) ``` -------------------------------- ### Simplified async_def implementation Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst A simplified illustration of the `async_def` function, showing the core logic of starting a greenlet and switching context. ```python async def async_def( fn: Callable[..., _T], *args: Any, assert_await_occurs: bool = False, **kwargs: Any, ) -> _T: """Runs a sync function ``fn`` in a new greenlet.""" # make a greenlet.greenlet with the given function. # getcurrent() is the parent greenlet that is basically where we # are right now in the function context = _AsyncIoGreenlet(fn, greenlet.getcurrent()) # switch into the new greenlet (start the function) result = context.switch(*args, **kwargs) # ... continued ... ``` -------------------------------- ### Create Async SQLAlchemy Engine and Sessionmaker Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst Demonstrates how to create an asynchronous SQLAlchemy engine using `create_async_engine` and configure a sessionmaker for asynchronous operations. This is the initial setup for using SQLAlchemy with asyncio. ```python from sqlalchemy.ext.asyncio import create_async_engine from sqlalchemy.orm import sessionmaker async_engine = create_async_engine( "postgresql+asyncpg://scott:tiger@localhost/test", echo=True, ) sessionmaker = sessionmaker(async_engine.engine) ``` -------------------------------- ### Async SQLAlchemy Engine and Session Setup Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst Sets up an asynchronous SQLAlchemy engine using asyncpg and defines an asynchronous sessionmaker. This is a prerequisite for using SQLAlchemy's asyncio API. ```python from sqlalchemy.ext.asyncio import async_sessionmaker from sqlalchemy.ext.asyncio import create_async_engine async_engine = create_async_engine( "postgresql+asyncpg://scott:tiger@localhost/test", echo=True, ) async_session = async_sessionmaker(async_engine, expire_on_commit=False) ``` -------------------------------- ### Async SQLAlchemy Functions for Table Setup and Data Operations Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst Provides asynchronous functions to set up database tables and perform data insertion and retrieval using SQLAlchemy's asyncio API. These functions can be called from non-async contexts using awaitlet. ```python async def setup_tables(): async with async_engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) await conn.run_sync(Base.metadata.create_all) async def work_with_data(): async with async_session() as session: async with session.begin(): session.add_all( [ A(data="a1"), A(data="a2"), A(data="a3"), ] ) stmt = select(A.data) result = await session.scalars(stmt) return result.all() ``` -------------------------------- ### Basic awaitlet Usage Source: https://github.com/sqlalchemy/awaitlet/blob/main/README.rst Demonstrates how a non-async def can be invoked in an asyncio context and call awaitables directly. This example shows a simple function that uses asyncio.sleep and is run within an asyncio event loop using awaitlet. ```python import asyncio import awaitlet def asyncio_sleep(): return awaitlet.awaitlet(asyncio.sleep(5, result='hello')) print(asyncio.run(awaitlet.async_def(asyncio_sleep))) ``` -------------------------------- ### Synchronous DB Code Execution Wrapper Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst A helper function that encapsulates synchronous database operations like table setup and data work. This function is designed to be called by `awaitlet.async_def`. ```python def call_async_db_code(): setup_tables() result = work_with_data() return result ``` -------------------------------- ### SQLAlchemy ORM Model Definition Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst Defines a basic SQLAlchemy ORM model 'A' with an ID, optional data, and a creation timestamp. This model is used across various examples. ```python from __future__ import annotations import datetime from typing import Optional from sqlalchemy import ForeignKey from sqlalchemy import func from sqlalchemy import select from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import Mapped from sqlalchemy.orm import mapped_column class Base(DeclarativeBase): pass class A(Base): __tablename__ = "a" id: Mapped[int] = mapped_column(primary_key=True) data: Mapped[Optional[str]] create_date: Mapped[datetime.datetime] = mapped_column( server_default=func.now() ) ``` -------------------------------- ### Full async_def loop with return handling Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst The complete loop logic for `async_def`, including handling the final return value once the hosted function completes. ```python # switch into it (start the function) result = context.switch(*args, **kwargs) # loop for the function not done yet while not context.dead: # await on the result that we expect is awaitable value = await result result = context.switch(value) # no more awaits; so this is the result! return result ``` -------------------------------- ### Using async_def to run a synchronous function in a greenlet Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst Demonstrates how to use `async_def` to wrap a synchronous function (`send_receive_logic`) that can then `await` asynchronous operations. ```python async def some_function(): my_awaitable = awaitlet.async_def( send_receive_logic, msg, "tcpbin.com", 4242, adapt_async_implementation ) return await my_awaitable ``` -------------------------------- ### Core loop in async_def for handling awaits Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst Illustrates the main loop within `async_def` that handles awaiting results from the hosted function and passing control back. ```python # switch into the new greenlet (start the function) result = context.switch(*args, **kwargs) # loop for the function not done yet while not context.dead: # await on the result that we expect is awaitable value = await result # pass control back into the function, with the return value # of the awaitable result = context.switch(value) ``` -------------------------------- ### awaitlet Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/api.rst A utility for managing asynchronous operations. ```APIDOC ## awaitlet ### Description A utility for managing asynchronous operations. This function likely provides a way to await or manage the execution of coroutines. ### Method Function call ### Endpoint N/A ### Parameters This function's specific parameters are not detailed in the provided text. It is expected to take awaitable objects or related arguments. ### Request Example ```python # Assuming awaitlet takes an awaitable object await awaitlet(some_coroutine()) ``` ### Response #### Success Response Returns the result of the awaited asynchronous operation. #### Response Example ```json { "result": "" } ``` ``` -------------------------------- ### Calling Async SQLAlchemy from Non-Async Functions with Awaitlet Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst Demonstrates how to call asynchronous SQLAlchemy functions (setup_tables, work_with_data) from a regular blocking Python function using awaitlet.awaitlet. The overall program is run within an asyncio event loop. ```python import asyncio import awaitlet def call_async_db_code(): awaitlet.awaitlet(setup_tables()) result = awaitlet.awaitlet(work_with_data()) return result async def front_facing_asyncio_facade(): result = await awaitlet.async_def(call_async_db_code) print(f"Result: {result}") asyncio.run(front_facing_asyncio_facade()) ``` -------------------------------- ### Asyncio Facade with awaitlet Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst An asynchronous function that uses `awaitlet.async_def` to run the synchronous database code (`call_async_db_code`) within the asyncio event loop. It then prints the result. ```python async def front_facing_asyncio_facade(): result = await awaitlet.async_def(call_async_db_code) print(f"Result: {result}") asyncio.run(front_facing_asyncio_facade()) ``` -------------------------------- ### Blocking SQLAlchemy Functions for Sync API Usage Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/sqlalchemy.rst Illustrates traditional blocking SQLAlchemy functions for setting up tables and working with data using the sync API. This code is intended to be run within an asyncio program using an asyncio driver. ```python sessionmaker = sessionmaker(...) def setup_tables(): with engine.begin() as conn: Base.metadata.drop_all(conn) Base.metadata.create_all(conn) def work_with_data(): with sessionmaker() as session: with session.begin(): session.add_all( [ A(data="a1"), A(data="a2"), A(data="a3"), ] ) stmt = select(A.data) result = session.scalars(stmt) return result.all() ``` -------------------------------- ### awaitlet function implementation Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst The `awaitlet` function allows synchronous code within a greenlet to await Python awaitables by switching back to the parent greenlet. ```python def awaitlet(awaitable: Awaitable[_T]) -> _T: """Awaits an async function in a sync method.""" current = greenlet.getcurrent() return current.parent.switch(awaitable) ``` -------------------------------- ### Original Multithreaded Program Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst This is the initial multithreaded program that sends and receives messages from an echo server using Python's socket library and threading. ```python import socket import threading messages = [] def send_receive_implementation(host, port, message): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) sock.sendall(message.encode("ascii")) return sock.recv(1024).decode("utf-8") def send_receive_logic(msg, host, port, implementation): return implementation(host, port, f"message number {msg}\n") def send_receive_api(msg): messages.append( send_receive_logic(msg, "tcpbin.com", 4242, send_receive_implementation) ) def main(): threads = [ threading.Thread(target=send_receive_api, args=(msg,)) for msg in ["one", "two", "three", "four", "five"] ] for t in threads: t.start() for t in threads: t.join() for msg in messages: print(f"Got back echo response: {msg}") main() ``` -------------------------------- ### Refactored Program with awaitlet Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst This refactored program uses awaitlet to integrate asynchronous operations within a structure that still allows synchronous functions to coexist. The middle layer (send_receive_logic) remains unchanged. ```python import asyncio import awaitlet async def async_send_receive_implementation(host, port, message): reader, writer = await asyncio.open_connection(host, port) writer.write(message.encode("ascii")) await writer.drain() data = (await reader.read(1024)).decode("utf-8") return data def send_receive_logic(msg, host, port, implementation): return implementation(host, port, f"message number {msg}\n") async def send_receive_api(msg): def adapt_async_implementation(host, port, message): return awaitlet.awaitlet( async_send_receive_implementation(host, port, message) ) return await awaitlet.async_def( send_receive_logic, msg, "tcpbin.com", 4242, adapt_async_implementation ) async def main(): messages = await asyncio.gather( *[ send_receive_api(msg) for msg in ["one", "two", "three", "four", "five"] ] ) for msg in messages: print(f"Got back echo response: {msg}") asyncio.run(main()) ``` -------------------------------- ### async_def Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/api.rst Defines an asynchronous function. ```APIDOC ## async_def ### Description Defines an asynchronous function. This is a decorator that allows for the definition of asynchronous functions. ### Method Decorator ### Endpoint N/A ### Parameters This function does not take direct parameters in the traditional sense as it is a decorator. It modifies the behavior of the function it decorates. ### Request Example ```python @async_def def my_async_function(): pass ``` ### Response #### Success Response N/A (modifies function behavior) #### Response Example N/A ``` -------------------------------- ### Target Asynchronous API Structure Source: https://github.com/sqlalchemy/awaitlet/blob/main/docs/build/synopsis.rst This shows the desired structure of the asynchronous API, utilizing asyncio.gather for concurrent execution of message API calls. ```python async def main(): messages = await asyncio.gather( *[ message_api(msg) for msg in ["one", "two", "three", "four", "five"] ] ) for msg in messages: print(f"Got back echo response: {msg}") asyncio.run(main()) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.