IOStream
class to stream both input and output using websockets. The use of
websockets allows you to build web clients that are more responsive than
the one using web methods. The main difference is that the webosockets
allows you to push data while you need to poll the server for new
response using web methods.
In this guide, we explore the capabilities of the
IOStream
class. It is specifically designed to enhance the development of clients
such as web clients which use websockets for streaming both input and
output. The
IOStream
stands out by enabling a more dynamic and interactive user experience
for web applications.
Websockets technology is at the core of this functionality, offering a
significant advancement over traditional web methods by allowing data to
be “pushed” to the client in real-time. This is a departure from the
conventional approach where clients must repeatedly “poll” the server to
check for any new responses. By employing the underlining
websockets library, the IOStream
class facilitates a continuous, two-way communication channel between
the server and client. This ensures that updates are received instantly,
without the need for constant polling, thereby making web clients more
efficient and responsive.
The real power of websockets, leveraged through the
IOStream
class, lies in its ability to create highly responsive web clients. This
responsiveness is critical for applications requiring real-time data
updates such as chat applications. By integrating the
IOStream
class into your web application, you not only enhance user experience
through immediate data transmission but also reduce the load on your
server by eliminating unnecessary polling.
In essence, the transition to using websockets through the
IOStream
class marks a significant enhancement in web client development. This
approach not only streamlines the data exchange process between clients
and servers but also opens up new possibilities for creating more
interactive and engaging web applications. By following this guide,
developers can harness the full potential of websockets and the
IOStream
class to push the boundaries of what is possible with web client
responsiveness and interactivity.
Requirements
Some extra dependencies are needed for this notebook, which can be installed via pip:
Note: If you have been usingFor more information, please refer to the installation guide.autogenorag2, all you need to do is upgrade it using:orasautogen, andag2are aliases for the same PyPI package.
Set your API Endpoint
Theconfig_list_from_json
function loads a list of configurations from an environment variable or
a json file.
Defining on_connect function
An on_connect function is a crucial part of applications that utilize
websockets, acting as an event handler that is called whenever a new
client connection is established. This function is designed to initiate
any necessary setup, communication protocols, or data exchange
procedures specific to the newly connected client. Essentially, it lays
the groundwork for the interactive session that follows, configuring how
the server and the client will communicate and what initial actions are
to be taken once a connection is made. Now, let’s delve into the details
of how to define this function, especially in the context of using the
AG2 framework with websockets.
Upon a client’s connection to the websocket server, the server
automatically initiates a new instance of the
IOWebsockets
class. This instance is crucial for managing the data flow between the
server and the client. The on_connect function leverages this instance
to set up the communication protocol, define interaction rules, and
initiate any preliminary data exchanges or configurations required for
the client-server interaction to proceed smoothly.
on_connect function such as the
one in the example above is defined:
- Receive Initial Message: Immediately after establishing a connection, receive an initial message from the client. This step is crucial for understanding the client’s request or initiating the conversation flow.
-
Instantiate ConversableAgent: Create an instance of
ConversableAgent with a specific system message and the LLM
configuration. If you need more than one agent, make sure they don’t
share the same
llm_configas adding a function to one of them will also attempt to add it to another. -
Instantiate UserProxyAgent: Similarly, create a UserProxyAgent
instance, defining its termination condition, human input mode, and
other relevant parameters. There is no need to define
llm_configas the UserProxyAgent does not use LLM. - Define Agent-specific Functions: If your conversable agent requires executing specific tasks, such as fetching a weather forecast in the example above, define these functions within the on_connect scope. Decorate these functions accordingly to link them with your agents.
-
Initiate Conversation: Finally, use the
initiate_chatmethod of yourUserProxyAgentto start the interaction with the conversable agent, passing the initial message and a cache mechanism for efficiency.
Testing websockets server with Python client
Testing anon_connect function with a Python client involves
simulating a client-server interaction to ensure the setup, data
exchange, and communication protocols function as intended. Here’s a
brief explanation on how to conduct this test using a Python client:
-
Start the Websocket Server: Use the
IOWebsockets.run_server_in_thread methodto start the server in a separate thread, specifying the on_connect function and the port. This method returns the URI of the running websocket server. - Connect to the Server: Open a connection to the server using the returned URI. This simulates a client initiating a connection to your websocket server.
- Send a Message to the Server: Once connected, send a message from the client to the server. This tests the server’s ability to receive messages through the established websocket connection.
- Receive and Process Messages: Implement a loop to continuously receive messages from the server. Decode the messages if necessary, and process them accordingly. This step verifies the server’s ability to respond back to the client’s request.
on_connect function, by simulating a
realistic message exchange. It ensures that the server can handle
incoming connections, process messages, and communicate responses back
to the client, all critical functionalities for a robust websocket-based
application.
Testing websockets server running inside FastAPI server with HTML/JS client
The code snippets below outlines an approach for testing anon_connect
function in a web environment using
FastAPI to serve a simple interactive
HTML page. This method allows users to send messages through a web
interface, which are then processed by the server running the AG2
framework via websockets. Here’s a step-by-step explanation:
- FastAPI Application Setup: The code initiates by importing necessary libraries and setting up a FastAPI application. FastAPI is a modern, fast web framework for building APIs with Python 3.7+ based on standard Python type hints.
- HTML Template for User Interaction: An HTML template is defined as a multi-line Python string, which includes a basic form for message input and a script for managing websocket communication. This template creates a user interface where messages can be sent to the server and responses are displayed dynamically.
-
Running the Websocket Server: The
run_websocket_serverasync context manager starts the websocket server usingIOWebsockets.run_server_in_threadwith the specifiedon_connectfunction and port. This server listens for incoming websocket connections. -
FastAPI Route for Serving HTML Page: A FastAPI route
(
@app.get("/")) is defined to serve the HTML page to users. When a user accesses the root URL, the HTML content for the websocket chat is returned, allowing them to interact with the websocket server. - Starting the FastAPI Application: Lastly, the FastAPI application is started using Uvicorn, an ASGI server, configured with the app and additional parameters as needed. The server is then launched to serve the FastAPI application, making the interactive HTML page accessible to users.
Testing websockets server with HTML/JS client
The provided code snippet below is an example of how to create an interactive testing environment for anon_connect function using
Python’s built-in http.server module. This setup allows for real-time
interaction within a web browser, enabling developers to test the
websocket functionality in a more user-friendly and practical manner.
Here’s a breakdown of how this code operates and its potential
applications:
- Serving a Simple HTML Page: The code starts by defining an HTML page that includes a form for sending messages and a list to display incoming messages. JavaScript is used to handle the form submission and websocket communication.
- Temporary Directory for HTML File: A temporary directory is created to store the HTML file. This approach ensures that the testing environment is clean and isolated, minimizing conflicts with existing files or configurations.
-
Custom HTTP Request Handler: A custom subclass of
SimpleHTTPRequestHandleris defined to serve the HTML file. This handler overrides the do_GET method to redirect the root path (/) to thechat.htmlpage, ensuring that visitors to the server’s root URL are immediately presented with the chat interface. -
Starting the Websocket Server: Concurrently, a websocket server
is started on a different port using the
IOWebsockets.run_server_in_threadmethod, with the previously definedon_connectfunction as the callback for new connections. - HTTP Server for the HTML Interface: An HTTP server is instantiated to serve the HTML chat interface, enabling users to interact with the websocket server through a web browser.