chatterflow package

Submodules

chatterflow.cli module

chatterflow.cli.main()[source]

chatterflow.client module

client.py

Run: python client.py

Terminal chat client. Supports login/register and commands:
  • /msg <user> <text> private message

  • /list

    list users

  • /help

    show help

  • /quit

    quit

chatterflow.client.main()[source]

The main entry point for the chat client.

This function establishes a connection to the server, handles the user authentication (login or register) process, and then starts the receiver thread. It then enters a loop to read user input for sending messages or executing commands.

chatterflow.client.print_help()[source]

Prints a list of available client-side commands to the console.

chatterflow.client.receiver_thread(conn: socket)[source]

Listens for incoming messages from the server and prints them to the console.

This function runs in a dedicated thread, continuously calling recv_json to wait for new messages. It handles different message types (system, broadcast, private, user list) and formats them for display. The thread terminates if the connection is lost.

Parameters:

conn (socket.socket) – The client’s socket connection to the server.

chatterflow.client.recv_json(conn: socket) Any[source]

Receive and deserialize a length-prefixed JSON object from a socket.

This function reads a 4-byte header to determine the incoming payload size, then reads that many bytes from the socket. The received bytes are decoded and parsed as a JSON object.

Parameters:

conn (socket.socket) – An active, connected socket object.

Returns:

The deserialized Python object, or None if the connection is

closed or an incomplete header is received.

Return type:

Any

Raises:
  • json.JSONDecodeError – If the received data is not valid JSON.

  • OSError – If the socket connection is broken during transmission.

chatterflow.client.send_json(conn: socket, obj: Any)[source]

Serialize and send a JSON object over a socket with a length-prefixed header.

This function first encodes the given Python object as a compact JSON string, then prefixes it with a 4-byte unsigned integer (big-endian) indicating the length of the serialized data. Both the header and JSON payload are sent using socket.sendall to ensure all bytes are transmitted.

Parameters:
  • conn (socket.socket) – An active, connected socket object.

  • obj (Any) – A JSON-serializable Python object (e.g., dict, list, str, int).

Raises:
  • TypeError – If obj cannot be serialized to JSON.

  • OSError – If the socket connection is broken during transmission.

chatterflow.server module

server.py

Run: python server.py

Multi-client chat server with user authentication. Users stored in users.json with PBKDF2 password hashing.

chatterflow.server.broadcast(sender: str, message: str)[source]

Broadcasts a message to all connected and authenticated clients.

If sending to a client fails, that client is removed from the pool.

Parameters:
  • sender (str) – The username of the message sender (or ‘SYS’ for system).

  • message (str) – The message text to broadcast.

chatterflow.server.handle_client(conn: socket, addr: tuple)[source]

Handles a single client connection from inception to termination.

This function manages the authentication process (register/login), then enters a loop to receive and process messages and commands from the client. It dispatches actions like broadcasting, private messaging, and user listing.

Parameters:
  • conn (socket.socket) – The client’s socket object.

  • addr (tuple) – The client’s address tuple (host, port).

chatterflow.server.hash_password(password: str, salt: str | None = None) tuple[str, str][source]

Hashes a password using PBKDF2-HMAC-SHA256.

If a salt is not provided, a new 16-byte salt is generated. The function uses 200,000 iterations.

Parameters:
  • password (str) – The password to hash.

  • salt (str, optional) – The salt to use, as a hex string. Defaults to None.

Returns:

A tuple containing the salt (hex) and the derived key (hex).

Return type:

tuple[str, str]

chatterflow.server.load_users() Dict[source]

Loads the user database from a JSON file.

If the user file does not exist, it returns an empty dictionary.

Returns:

A dictionary containing user data, with usernames as keys.

Return type:

dict

chatterflow.server.recv_json(conn: socket) Any[source]

Receive and deserialize a length-prefixed JSON object from a socket.

This function reads a 4-byte header to determine the incoming payload size, then reads that many bytes from the socket. The received bytes are decoded and parsed as a JSON object.

Parameters:

conn (socket.socket) – An active, connected socket object.

Returns:

The deserialized Python object, or None if the connection is

closed or an incomplete header is received.

Return type:

Any

Raises:
  • json.JSONDecodeError – If the received data is not valid JSON.

  • OSError – If the socket connection is broken during transmission.

chatterflow.server.remove_client(username: str)[source]

Removes a client from the global client and address dictionaries and closes the socket.

This function is thread-safe.

Parameters:

username (str) – The username of the client to remove.

chatterflow.server.save_users(users: Dict)[source]

Saves the user database to a JSON file.

Parameters:

users (dict) – A dictionary containing user data to be saved.

chatterflow.server.send_json(conn: socket, obj: Any)[source]

Serialize and send a JSON object over a socket with a length-prefixed header.

This function first encodes the given Python object as a compact JSON string, then prefixes it with a 4-byte unsigned integer (big-endian) indicating the length of the serialized data. Both the header and JSON payload are sent using socket.sendall to ensure all bytes are transmitted.

Parameters:
  • conn (socket.socket) – An active, connected socket object.

  • obj (Any) – A JSON-serializable Python object (e.g., dict, list, str, int).

Raises:
  • TypeError – If obj cannot be serialized to JSON.

  • OSError – If the socket connection is broken during transmission.

chatterflow.server.send_private(sender: str, target: str, message: str) bool[source]

Sends a private message to a single specified client.

Parameters:
  • sender (str) – The username of the message sender.

  • target (str) – The username of the recipient.

  • message (str) – The message text to send.

Returns:

True if the message was sent successfully, False if the target

user was not found or the connection failed.

Return type:

bool

chatterflow.server.send_system(conn: socket, text: str)[source]

Sends a system message to a single client.

Parameters:
  • conn (socket.socket) – The socket of the client to send the message to.

  • text (str) – The system message text.

chatterflow.server.start_server(host: str = '127.0.0.1', port: int = 9009)[source]

Starts the main chat server and listens for incoming connections.

The server binds to a host and port, and for each new connection, it spawns a new daemon thread running handle_client to manage that client independently.

Parameters:
  • host (str, optional) – The host address to bind to. Defaults to HOST.

  • port (int, optional) – The port to listen on. Defaults to PORT.

chatterflow.server.verify_password(password: str, salt: str, stored_hash: str) bool[source]

Verifies a password against a stored salt and hash.

Parameters:
  • password (str) – The password to verify.

  • salt (str) – The salt used during hashing (hex).

  • stored_hash (str) – The stored password hash to compare against (hex).

Returns:

True if the password is correct, False otherwise.

Return type:

bool

Module contents