### Running picows Benchmark Examples Source: https://github.com/tarasko/picows/blob/master/README.rst Starts the picows echo server example and then executes the echo client benchmark script. These commands run the example applications to measure performance. Requires the examples to be built and available. ```Shell python -m examples.echo_server python -m examples.echo_client_benchmark ``` -------------------------------- ### Installing picows Python library Source: https://github.com/tarasko/picows/blob/master/README.rst Provides the command-line instruction to install the picows library using pip. ```Shell pip install picows ``` -------------------------------- ### Building picows Documentation using Make Source: https://github.com/tarasko/picows/blob/master/README.rst Navigates to the 'docs' directory and executes the 'make' command to clean previous builds and generate the HTML documentation. Requires Make and the documentation build dependencies installed via 'docs/requirements.txt'. ```Shell make -C docs clean html ``` -------------------------------- ### Installing picows Development Dependencies with pip Source: https://github.com/tarasko/picows/blob/master/README.rst Installs various sets of development dependencies required for testing, benchmarking, and building documentation using pip and the specified requirements files. This should be done within the activated virtual environment. Requires pip and the respective requirements files to be present. ```Shell pip install -r requirements-test.txt ``` ```Shell pip install -r requirements-benchmark.txt ``` ```Shell pip install -r docs/requirements.txt ``` -------------------------------- ### Building picows and Running Pytest Source: https://github.com/tarasko/picows/blob/master/README.rst Sets an environment variable to include examples during the build process, builds the picows Cython extensions inplace, and then runs the project's tests using pytest with verbose output and disabled output capture. Requires pytest and the necessary build tools (like a C compiler). ```Shell export PICOWS_BUILD_EXAMPLES=1 python setup.py build_ext --inplace pytest -s -v ``` -------------------------------- ### Setting up picows WebSocket Server in Python Source: https://github.com/tarasko/picows/blob/master/README.rst Defines a factory function for creating client listeners, initializes an asynchronous WebSocket server bound to localhost on port 9001, prints the server's socket address, and starts the server to run indefinitely. This requires the asyncio library and the picows server components. ```Python def listener_factory(r: WSUpgradeRequest): # Routing can be implemented here by analyzing request content return ServerClientListener() server: asyncio.Server = await ws_create_server(listener_factory, "127.0.0.1", 9001) for s in server.sockets: print(f"Server started on {s.getsockname()}") await server.serve_forever() if __name__ == '__main__': asyncio.run(main()) ``` -------------------------------- ### Cloning picows Repository using Git Source: https://github.com/tarasko/picows/blob/master/README.rst Clones the picows repository from GitHub via SSH into the current directory and then changes the current directory to the newly created 'picows' folder. Requires Git to be installed and configured for SSH access to GitHub. ```Shell git clone git@github.com:tarasko/picows.git cd picows ``` -------------------------------- ### Creating and Activating Python Virtual Environment Source: https://github.com/tarasko/picows/blob/master/README.rst Creates a isolated Python virtual environment named 'picows-dev' using the built-in 'venv' module and then activates it. This ensures project dependencies are installed separately from the system Python environment. Requires Python 3 with the venv module. ```Shell python3 -m venv picows-dev source picows-dev/bin/activate ``` -------------------------------- ### Implementing Async WebSocket Message Processing with asyncio.Queue in Python Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This Python example shows how to create an async interface on top of the non-async `picows.WSListener` using `asyncio.Queue`. The `on_ws_frame` method puts received messages into a queue, which can then be consumed asynchronously by another function. ```python class ClientListener(picows.WSListener): def __init__(self): self.msg_queue = asyncio.Queue() ... def on_ws_frame(transport: picows.WSTransport, frame: picows.WSFrame): if frame.msg_type == picows.WSMsgType.TEXT: obj = json.loads(frame.get_payload_as_utf8_text()) self.msg_queue.put_nowait(obj) def on_ws_disconnected(transport: picows.WSTransport): # Push None to indicate the end of the stream self.msg_queue.put_nowait(None) async def some_async_function(): transport, listener = await ws_connect(ClientListener, ...) while True: msg = await listener.msg_queue.get() listener.msg_queue.task_done() if msg is None: # client disconnected :else # Otherwise process message in async context ``` -------------------------------- ### Processing WebSocket Messages Asynchronously with asyncio.create_task in Python Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This Python example demonstrates another method for handling WebSocket messages asynchronously from a non-async `picows.WSListener`. It uses `asyncio.get_running_loop().create_task()` to schedule an async function (`process_message`) to process each incoming message. ```python async def process_message(msg): ... class ClientListener(picows.WSListener): def on_ws_frame(transport: picows.WSTransport, frame: picows.WSFrame): if frame.msg_type == picows.WSMsgType.TEXT: msg = json.loads(frame.get_payload_as_utf8_text()) asyncio.get_running_loop().create_task(process_message(msg)) ``` -------------------------------- ### Illustrating WSFrame fin Attribute Usage (Python) Source: https://github.com/tarasko/picows/blob/master/docs/source/reference.rst These examples show how the `fin` attribute of a `WSFrame` indicates whether a frame is the last one in a message. The first example shows an unfragmented message, while the second shows a sequence of frames for a fragmented message, ending with `fin=True`. ```Python WSFrame(msg_type=WSMsgType., fin=True) ``` ```Python WSFrame(msg_type=WSMsgType., fin=False) WSFrame(msg_type=WSMsgType.CONTINUATION, fin=False) ... # the last frame of the message WSFrame(msg_type=WSMsgType.CONTINUATION, fin=True) ``` -------------------------------- ### Creating a picows Echo WebSocket Server in Python Source: https://github.com/tarasko/picows/blob/master/docs/source/introduction.rst This snippet shows how to set up a basic WebSocket server using picows. It listens on a specified address and port, handles incoming connections, responds to PING frames with PONG, echoes other message types, and handles CLOSE frames. ```python import asyncio import uvloop from picows import ws_create_server, WSFrame, WSTransport, WSListener, WSMsgType, WSUpgradeRequest class ServerClientListener(WSListener): def on_ws_connected(self, transport: WSTransport): print("New client connected") def on_ws_frame(self, transport: WSTransport, frame: WSFrame): if frame.msg_type == WSMsgType.PING: transport.send_pong(frame.get_payload_as_bytes()) elif frame.msg_type == WSMsgType.CLOSE: transport.send_close(frame.get_close_code(), frame.get_close_message()) transport.disconnect() else: transport.send(frame.msg_type, frame.get_payload_as_bytes()) async def main(): def listener_factory(r: WSUpgradeRequest): # Routing can be implemented here by analyzing request content return ServerClientListener() server: asyncio.Server = await ws_create_server(listener_factory, "127.0.0.1", 9001) for s in server.sockets: print(f"Server started on {s.getsockname()}") await server.serve_forever() if __name__ == '__main__': asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) asyncio.run(main()) ``` -------------------------------- ### Creating a picows Echo WebSocket Client in Python Source: https://github.com/tarasko/picows/blob/master/docs/source/introduction.rst This snippet demonstrates how to create a basic WebSocket client using picows. It connects to a specified URL, sends a 'Hello world' message upon connection, prints the received echo reply, and then closes the connection gracefully. ```python import asyncio import uvloop from picows import ws_connect, WSFrame, WSTransport, WSListener, WSMsgType, WSCloseCode class ClientListener(WSListener): def on_ws_connected(self, transport: WSTransport): self.transport = transport transport.send(WSMsgType.TEXT, b"Hello world") def on_ws_frame(self, transport: WSTransport, frame: WSFrame): print(f"Echo reply: {frame.get_payload_as_ascii_text()}") transport.send_close(WSCloseCode.OK) transport.disconnect() async def main(url): (_, client) = await ws_connect(ClientListener, url) await client.transport.wait_disconnected() if __name__ == '__main__': asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) asyncio.run(main("ws://127.0.0.1:9001")) ``` -------------------------------- ### Implementing a picows Echo Client Source: https://github.com/tarasko/picows/blob/master/README.rst Demonstrates how to create a WebSocket client using picows that connects to an echo server, sends a message, prints the reply, and disconnects. It defines a custom WSListener class to handle connection and frame events. ```Python import asyncio from picows import ws_connect, WSFrame, WSTransport, WSListener, WSMsgType, WSCloseCode class ClientListener(WSListener): def on_ws_connected(self, transport: WSTransport): transport.send(WSMsgType.TEXT, b"Hello world") def on_ws_frame(self, transport: WSTransport, frame: WSFrame): print(f"Echo reply: {frame.get_payload_as_ascii_text()}") transport.send_close(WSCloseCode.OK) transport.disconnect() async def main(url): transport, client = await ws_connect(ClientListener, url) await transport.wait_disconnected() if __name__ == '__main__': asyncio.run(main("ws://127.0.0.1:9001")) ``` -------------------------------- ### Implementing a picows Echo Server Source: https://github.com/tarasko/picows/blob/master/README.rst Shows how to create a basic WebSocket server using picows that listens for connections and echoes received messages back to the client. It defines a custom WSListener to handle client connections and frame events, including handling close frames. ```Python import asyncio from picows import ws_create_server, WSFrame, WSTransport, WSListener, WSMsgType, WSUpgradeRequest class ServerClientListener(WSListener): def on_ws_connected(self, transport: WSTransport): print("New client connected") def on_ws_frame(self, transport: WSTransport, frame: WSFrame): if frame.msg_type == WSMsgType.CLOSE: transport.send_close(frame.get_close_code(), frame.get_close_message()) transport.disconnect() else: transport.send(frame.msg_type, frame.get_payload_as_bytes()) async def main(): ``` -------------------------------- ### Output of the picows Echo Client Source: https://github.com/tarasko/picows/blob/master/README.rst Shows the expected output when running the picows echo client script, demonstrating the received message from the echo server. ```Text Echo reply: Hello world ``` -------------------------------- ### Customizing Ping/Pong with JSON TEXT Frames and Efficient Handling in picows Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This snippet illustrates customizing ping/pong using TEXT frames with JSON payloads. It highlights the inefficiency of parsing JSON in the fast `is_user_specific_pong` method and shows the recommended approach: returning `False` in `is_user_specific_pong` and handling the pong detection after parsing the payload in the `on_ws_frame` method, notifying the transport upon receiving a valid pong. ```python class ClientListener(picows.WSListener): ... def send_user_specific_ping(transport: picows.WSTransport): transport.send(picows.WSMsgType.TEXT, b'{"op":"ping"}') def is_user_specific_pong(frame: picows.WSFrame): # It is inefficient to do json.loads(frame.get_payload_as_utf8_text()) here. # Because we would have to do it again in on_ws_frame return False def on_ws_frame(transport: picows.WSTransport, frame: picows.WSFrame): if frame.msg_type == picows.WSMsgType.TEXT: obj = json.loads(frame.get_payload_as_utf8()) if obj["op"] == "pong": # Notify transport that pong reply has been received transport.notify_user_specific_pong_received() return # Process other operations ... ``` -------------------------------- ### Configuring picows Debug Logging (Python) Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This snippet demonstrates two methods for enabling debug logging for the picows library using Python's standard logging module. It shows how to either set the global log level or specifically target the 'picows' logger to the debug level (PICOWS_DEBUG_LL). ```python # Either set global log level logging.basicConfig(level=picows.PICOWS_DEBUG_LL) # Or set picows logger log level only logging.basicConfig(level=logging.INFO) logging.getLogger("picows").setLevel(picows.PICOWS_DEBUG_LL) ``` -------------------------------- ### Configuring Auto Ping in picows Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This snippet demonstrates how to enable and configure the automatic ping mechanism when establishing a WebSocket connection using `picows.ws_connect`. It shows the parameters to control whether auto-ping is active, the inactivity timeout before sending a ping, and the timeout for expecting a pong reply. ```python await ws_connect(..., enable_auto_ping=True, # disabled by default auto_ping_idle_timeout=2, # send ping after 2 seconds of inactivity auto_ping_reply_timeout=1 # expect pong reply within 1 second ) ``` -------------------------------- ### Customizing Ping/Pong with TEXT Frames in picows Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This snippet shows how to customize the auto-ping/pong behavior by overriding `send_user_specific_ping` and `is_user_specific_pong` methods in a `picows.WSListener` subclass. It demonstrates sending and checking for TEXT frames with 'ping' and 'pong' payloads instead of the default PING/PONG control frames. ```python class ClientListener(picows.WSListener): ... def send_user_specific_ping(transport: picows.WSTransport): transport.send(picows.WSMsgType.TEXT, b"ping") # default implementation does: # transport.send_ping() def is_user_specific_pong(frame: picows.WSFrame): return frame.msg_type == picows.WSMsgType.TEXT and frame.get_payload_as_memoryview() == b"pong" # default implementation does: # return frame.msg_type == picows.WSMsgType.PONG ``` -------------------------------- ### Project Dependency List (Python) Source: https://github.com/tarasko/picows/blob/master/requirements-test.txt Specifies the required Python packages and their minimum versions for the project. Includes conditional dependency for uvloop based on the operating system. ```Python setuptools >= 61.0 Cython >= 3.0 multidict pytest pytest-asyncio async_timeout uvloop; sys_platform != 'win32' ``` -------------------------------- ### Handling Manual Pong Response in picows Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This snippet demonstrates how to manually respond to incoming PING messages when the `enable_auto_pong` setting is disabled. It shows a `WSListener` subclass implementing the `on_ws_frame` method to detect PING frames and explicitly send a PONG response using `transport.send_pong` with the original payload. ```python class ClientListener(picows.WSListener): ... def on_ws_frame(transport: picows.WSTransport, frame: picows.WSFrame): if frame.msg_type == picows.WSMsgType.PING: transport.send_pong(frame.get_payload_as_bytes()) ... ``` -------------------------------- ### Implementing WebSocket Message Concatenation in Python Source: https://github.com/tarasko/picows/blob/master/docs/source/guides.rst This Python class `ClientListener` demonstrates a naive approach to concatenating fragmented WebSocket messages received via `picows`. It accumulates payload from multiple frames until the final fragment (`fin=True`) is received, then calls a handler for the complete message. ```python class ClientListener(picows.WSListener): def __init__(self): self._full_msg == bytearray() self._full_msg_type = picows.WSMsgType.TEXT def on_ws_frame(transport: picows.WSTransport, frame: picows.WSFrame): ... # Handle PING/PONG/CLOSE control frames first if frame.fin: if self._full_msg: # This is the last fragment of the message because fin is set # and there were previous fragments assert frame.msg_type == picows.WSMsgType.CONTINUATION self._full_msg += frame.get_payload_as_memoryview() self.on_concatenated_message(transport, self._full_msg_type, self._full_msg) self._full_msg.clear() else: # This is the only fragment of the message because fin is set # and there was not previous fragments self.on_unfragmented_message(transport, frame) else: if not self._full_msg: # First fragment determine the whole message type self._full_msg_type == frame.msg_type # Accumulate payload from multiple fragments self._full_msg += frame.get_payload_as_memoryview() return def on_unfragmented_message(self, transport: picows.WSTransport, frame: picows.WSFrame): # Called for the simple case when a frame is a whole message pass def on_concatenated_message(self, transport: picows.WSTransport, msg_type: picows.WSMsgType, payload: bytearray): # Called after concatenating a message from multiple frames pass ``` -------------------------------- ### Running Specific Pytest with Debug Logging Source: https://github.com/tarasko/picows/blob/master/README.rst Executes a specific pytest test identified by a keyword expression ('test_client_handshake_timeout[uvloop-plain]') with verbose output, disabled output capture, and sets the command-line logging level to 9 for detailed debug output. Useful for debugging individual test failures. Requires pytest. ```Shell pytest -s -v -k test_client_handshake_timeout[uvloop-plain] --log-cli-level 9 ``` -------------------------------- ### Defining WSTransport send_reuse_external_buffer Method (Cython) Source: https://github.com/tarasko/picows/blob/master/docs/source/reference.rst This Cython method signature for `WSTransport.send_reuse_external_buffer` shows how to send a websocket frame using an external buffer. It requires a pointer to the message payload (`msg_ptr`) and its size (`msg_size`), along with message type and optional flags. ```Cython send_reuse_external_buffer(WSMsgType msg_type, char* msg_ptr, size_t msg_size, bint fin=True, bint rsv1=False) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.