### Install Project Dependencies Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Use Poetry to install all necessary development dependencies for the project. ```bash $ poetry install ``` -------------------------------- ### Install aioudp Source: https://github.com/thatxliner/aioudp/blob/main/docs/quickstart.md Install the aioudp library using pip. ```bash $ pip install aioudp ``` -------------------------------- ### Install AioUDP with Poetry Source: https://github.com/thatxliner/aioudp/blob/main/README.md Use this command to add the AioUDP library to your project if you are using Poetry for dependency management. ```bash $ poetry add aioudp ``` -------------------------------- ### AioUDP Echo Server Example Source: https://github.com/thatxliner/aioudp/blob/main/README.md This snippet demonstrates how to set up an echo server using AioUDP. It handles incoming messages and sends them back to the client. It also includes signal handling for graceful shutdown. ```Python import asyncio import signal import aioudp async def main(): async def handler(connection): async for message in connection: await connection.send(message) loop = asyncio.get_running_loop() stop = loop.create_future() # Optional. This is for properly exiting the server when Ctrl-C is pressed # or when the process is killed/terminated loop.add_signal_handler(signal.SIGTERM, stop.set_result, None) loop.add_signal_handler(signal.SIGINT, stop.set_result, None) # Serve the server async with aioudp.serve("localhost", 9999, handler): await stop # Serve forever if __name__ == '__main__': asyncio.run(main()) ``` -------------------------------- ### AioUDP Client Example Source: https://github.com/thatxliner/aioudp/blob/main/README.md This snippet shows how to create a UDP client using AioUDP. It connects to a server, sends a message, and asserts that the received message matches the sent message. ```Python import asyncio import aioudp async def main(): async with aioudp.connect("localhost", 9999) as connection: await connection.send(b"Hello world!") assert await connection.recv() == b"Hello world!" if __name__ == '__main__': asyncio.run(main()) ``` -------------------------------- ### aioudp.serve Source: https://github.com/thatxliner/aioudp/blob/main/docs/api_ref.md Run a UDP server. This function starts a UDP server on the specified host and port, and uses the provided handler to process incoming connections. ```APIDOC ## aioudp.serve Run a UDP server. See the docs for an example UDP echo server ### Method - **Parameters:** - **host** (str) – The host name/address to run the server on - **port** (int) – The port number to run the server on - **handler** (Callable[[Connection], Awaitable[None]]) – An asynchronous function to handle a request. It should accept an instance of `Connection` and doesn’t need to return anything. - **queue_size** (int | None) – The maximum size of the message queue used internally. Defaults to None, meaning an unlimited size. Unless you know for sure what you’re doing, there is no need to change this value. - **kwargs** – Additional keyword arguments to pass to loop.create_datagram_endpoint - **Returns:** An asynchronous iterator yielding None. - **SEE ALSO:** [`connect()`](#aioudp.connect) ``` -------------------------------- ### Run Project Tests with Pytest Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Alternatively, run the project's tests using Poetry and Pytest if Poe the poet is not installed. ```bash $ poetry run pytest ``` -------------------------------- ### Example of Test Class Structure Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Illustrates the recommended structure for test classes in Pytest. If a test class is the only one in a file, its tests should be unwrapped. ```python # test_connection.py class TestConnection: def test_can_con(self): ... def test_con_ends_gracefully(self):... ``` -------------------------------- ### Add Timeout to Async Function Source: https://github.com/thatxliner/aioudp/blob/main/docs/faq.md Use asyncio.wait_for to add a timeout to an asynchronous function. This is a general asyncio pattern, not specific to aioudp. The example demonstrates catching asyncio.TimeoutError. ```python try: await asyncio.wait_for(func(), timeout=0.01) except asyncio.TimeoutError: print("timeout!") ``` -------------------------------- ### Simple UDP Echo Server Source: https://github.com/thatxliner/aioudp/blob/main/docs/index.md Sets up a UDP echo server that listens on localhost:9999. It echoes back any received messages. The server runs indefinitely until interrupted. ```python import asyncio import aioudp async def main(): async def handler(connection): async for message in connection: await connection.send(message) async with aioudp.serve("localhost", 9999, handler): await asyncio.Future() # Serve forever if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Format Code with Poe Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Apply code formatting to the project using the 'poe format' command. ```bash $ poe format ``` -------------------------------- ### Run Project Tests Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Execute the project's test suite using the Poe the poet tool. ```bash $ poe test ``` -------------------------------- ### PA System Client Implementation Source: https://github.com/thatxliner/aioudp/blob/main/docs/quickstart.md This Python code implements the client side of a simple PA system using aioudp and PyAudio. It connects to a server, sends audio input, and handles server responses. ```python import asyncio import pyaudio import aioudp DECLINE = b"\x01" TERMINATOR = b"DONE" async def main() -> None: # Configuration for PyAudio CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100 # Let's connect to my Raspberry Pi on the local network async with aioudp.connect("raspberrypi", 9999) as connection: if await connection.recv() == DECLINE: print("Someone else is already using the PA system :(") return # Again, some PyAudio black magic. # This time set up for input p = pyaudio.PyAudio() stream = p.open( format=FORMAT, channels=CHANNELS, input=True, rate=RATE, frames_per_buffer=CHUNK, ) # Continue recording and stream recording # Until CTRL-C try: while True: await connection.send(stream.read(CHUNK)) except KeyboardInterrupt: await connection.send(TERMINATOR) # De-init PyAudio stream.stop_stream() stream.close() p.terminate() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### PA System Server Implementation Source: https://github.com/thatxliner/aioudp/blob/main/docs/quickstart.md This Python code implements the server side of a simple PA system using aioudp and PyAudio. It handles incoming connections, plays audio data, and ensures only one user can transmit at a time. ```python import asyncio import signal import pyaudio import aioudp # Doesn't have to be "\x00" and "\x01". Any unique value would do ACCEPT = b"\x00" DECLINE = b"\x01" TERMINATOR = b"DONE" # Could be anything that will never be audio data connections = set() async def main(): # Configuration for PyAudio CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100 async def handler(connection: aioudp.Connection) -> None: # Make sure only one person uses the PA at a time if connections: await connection.send(DECLINE) return await connection.send(ACCEPT) connections.add(None) # PyAudio initialization black magic p = pyaudio.PyAudio() stream = p.open( format=FORMAT, channels=CHANNELS, output=True, frames_per_buffer=CHUNK, rate=RATE, ) async for data in connection: # Until b"DONE" is recieved, play the data if data == TERMINATOR: break stream.write(data) # Uninitalize PyAudio stuff stream.stop_stream() stream.close() p.terminate() connections.remove(None) loop = asyncio.get_running_loop() stop = loop.create_future() # This way, we can CTRl-C it properly loop.add_signal_handler(signal.SIGINT, stop.set_result, None) # "0.0.0.0" to expose globally. Serve at port 9999 async with aioudp.serve("0.0.0.0", 9999, handler): await stop if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Simple UDP Client Source: https://github.com/thatxliner/aioudp/blob/main/docs/index.md A UDP client that connects to localhost:9999, sends a byte message, and asserts that the echoed response matches the sent message. Requires a running server. ```python import asyncio import aioudp async def main(): async with aioudp.connect("localhost", 9999) as connection: await connection.send(b"Hello world!") assert await connection.recv() == b"Hello world!" if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Format Code with Shed Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md An alternative command to format Python files using 'shed'. ```bash $ shed {{ cookiecutter.module_name }}/**.py ``` -------------------------------- ### Run Linters Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Execute the project's linters using the 'poe lint' command. ```bash $ poe lint ``` -------------------------------- ### aioudp.connect Source: https://github.com/thatxliner/aioudp/blob/main/docs/api_ref.md Connect to a UDP server. This function returns an asynchronous iterator that yields a connection object for interacting with the UDP server. ```APIDOC ## aioudp.connect Connect to a UDP server. ### Method - **Parameters:** - **host** (str) – The server’s host name/address. - **port** (int) – The server’s port number. - **queue_size** (int | None) – The maximum size of the message queue used internally. Defaults to None, meaning an unlimited size. Unless you know for sure what you’re doing, there is no need to change this value. - **kwargs** – Additional keyword arguments to pass to loop.create_datagram_endpoint - **Returns:** An asynchronous iterator yielding a connection to the UDP server. - **SEE ALSO:** [`serve()`](#aioudp.serve) ``` -------------------------------- ### aioudp.Connection Source: https://github.com/thatxliner/aioudp/blob/main/docs/api_ref.md Represents a server-client connection in aioudp. It provides methods to send and receive data, and properties to access local and remote addresses. Connections should not be instantiated manually. ```APIDOC ## aioudp.Connection Represents a server-client connection. Do not instantiate manually. ### Properties #### local_address - **Returns:** This is a tuple containing the hostname and port - **Return type:** tuple[str, int] #### remote_address - **Returns:** This is a tuple containing the hostname and port - **Return type:** tuple[str, int] ### Methods #### async recv() -> bytes Receives a message from the connection. - **Returns:** The received bytes. - **Return type:** bytes - **Raises:** - [exceptions.ConnectionClosedError](#aioudp.exceptions.ConnectionClosedError) – The connection is closed #### async send(data: bytes) -> None Send a message to the connection. The reason why this send function is async is due to API consistency. There is actually no underlying async call so feel free to just forgo the await. WARNING: Since this is UDP, there is no guarantee that the message will be sent. - **Parameters:** - **data** (bytes) – The message in bytes to send - **Raises:** - [exceptions.ConnectionClosedError](#aioudp.exceptions.ConnectionClosedError) – The connection is closed - ValueError – There is no data to send ``` -------------------------------- ### Unwrapped Test Functions Source: https://github.com/thatxliner/aioudp/blob/main/CONTRIBUTING.md Shows the unwrapped structure for test functions when a test class is not necessary. ```python # test_connection.py def test_can_con():... def test_con_ends_gracefully():... ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.