Library to work with socket clients and servers.
Project description
PySockLib
Helper library to implement socket client and servers as well as services to process, store, or send data received or send trough sockets.
Installation
Create a virtual environment and activate it:
python3.11 -m venv venv
source venv/bin/activate
Install the latest version:
pip install pysocklib
Python module
The python module contains several classes to easily implement client and/or server programs. All available classes are listed below.
ServerReceiver
A server that receives messages from a single client.
Constructor
def __init__(
self,
address: tuple[str, int],
received: Optional[queue.Queue[bytes]] = None,
reconnect: bool = True,
timeout: Optional[float] = None,
stop: Optional[Callable[[], bool]] = None,
stop_reconnect: Optional[Callable[[], bool]] = None,
logger: Optional[logging.Logger] = None,
)
address
: A tuple representing the IP address and port number to bind the server to.received
: Optional queue to store received messages.reconnect
: If True, the server will attempt to reconnect after disconnection.timeout
: Optional timeout value for send and receive operations.stop
: A function that returns True to signal the server to stop.stop_reconnect
: A function that returns True to signal the reconnecting loop to stop. Won't have any effect if reconnect is set to False.logger
: Optional logger for logging server events.
Properties
ip
: The IP address component of the server's address.port
: The port number component of the server's address.received
: The queue containing received messages.
Methods
listen()
: Creates the socket and puts it in listen mode.accept_connection()
: Accepts a new connection.start()
: Starts the server in a new thread.join()
: Waits for the server thread to finish.shutdown()
: Signals the server to shut down gracefully.close_connection()
: Closes the client connection and the socket.__enter__()
: Context manager entry point.__exit__(...)
: Context manager exit point. Closes all sockets
ServerSender
Constructor
def __init__(
self,
address: tuple[str, int],
to_send: Optional[queue.Queue[str | bytes]] = None,
reconnect: bool = True,
timeout: Optional[float] = None,
stop: Optional[Callable[[], bool]] = None,
stop_reconnect: Optional[Callable[[], bool]] = None,
logger: Optional[logging.Logger] = None,
)
address
: A tuple representing the IP address and port number to bind the server to.to_send
: Optional queue to store messages that will be sent.reconnect
: If True, the server will attempt to reconnect after disconnection.timeout
: Optional timeout value for send and receive operations.stop
: A function that returns True to signal the server to stop.stop_reconnect
: A function that returns True to signal the reconnecting loop to stop. Won't have any effect if reconnect is set to False.logger
: Optional logger for logging server events.
Properties
ip
: The IP address component of the server's address.port
: The port number component of the server's address.to_send
: The queue containing messages to be sent.
Methods
listen()
: Creates the socket and puts it in listen mode.accept_connection()
: Accepts a new connection.start()
: Starts the server in a new thread.join()
: Waits for the server thread to finish.shutdown()
: Signals the server to shut down gracefully.close_connection()
: Closes the client connection and the socket.__enter__()
: Context manager entry point.__exit__(...)
: Context manager exit point. Closes all sockets
Server
A server that sends and receives messages to and from a single client. This server runs in two threads, one to send messages and another to receive messages.
def __init__(
self,
address: tuple[str, int],
received: Optional[queue.Queue[bytes]] = None,
to_send: Optional[queue.Queue[str | bytes]] = None,
reconnect: bool = True,
timeout: Optional[float] = None,
stop_receive: Optional[Callable[[], bool]] = None,
stop_send: Optional[Callable[[], bool]] = None,
stop_reconnect: Optional[Callable[[], bool]] = None,
logger: Optional[logging.Logger] = None,
)
address
: A tuple representing the IP address and port number to bind the server to.received
: Optional queue to store received messages.to_send
: Optional queue containing messages to be sent.reconnect
: If True, the server will attempt to reconnect after disconnection.timeout
: Optional timeout value for send and receive operations.stop_receive
: A function that returns True to signal the receiving loop to stop.stop_send
: A function that returns True to signal the sending loop to stop.stop_reconnect
: A function that returns True to signal the reconnecting loop to stop. Won't have any effect if reconnect is set to False.logger
: Optional logger for logging server events.
Properties
received
: The queue containing received messages.to_send
: The queue containing messages to be sent.send_thread
: The thread responsible for sending messages.receive_thread
: The thread responsible for receiving messages.
Methods
listen()
: Creates the socket and puts it in listen mode.accept_connection()
: Accepts a new connection.start()
: Starts the server in a new thread.join()
: Waits for both the sending and receiving threads to stop.shutdown()
: Signals the server to shut down gracefully.close_connection()
: Closes the client connection and the socket.__enter__()
: Context manager entry point.__exit__(...)
: Context manager exit point. Closes all sockets
ClientReceiver
A client that receives messages from a server.
Constructor
def __init__(
self,
address: tuple[str, int],
received: Optional[queue.Queue[bytes]] = None,
reconnect: bool = True,
timeout: Optional[float] = None,
stop: Optional[Callable[[], bool]] = None,
stop_reconnect: Optional[Callable[[], bool]] = None,
logger: Optional[logging.Logger] = None,
)
address
: A tuple representing the IP address and port number to connect to.received
: Optional queue to store received messages.reconnect
: If True, the client will attempt to reconnect after disconnection.timeout
: Optional timeout value for send and receive operations.stop
: A function that returns True to signal the client to stop.stop_reconnect
: A function that returns True to signal the reconnecting loop to stop. Won't have any effect if reconnect is set to False.logger
: Optional logger for logging client events.
Properties
ip
: The IP address component of the client's address.port
: The port number component of the client's address.received
: The queue containing received messages.
Methods
connect(timeout: Optional[float] = None)
: Connects to the server with an optional timeout.start()
: Starts the client in a new thread.join()
: Waits for the client thread to finish.shutdown()
: Signals the client to shut down gracefully.close_connection()
: Closes the socket connection.__enter__()
: Context manager entry point.__exit__(...)
: Context manager exit point.
ClientSender
def __init__(
self,
address: tuple[str, int],
to_send: Optional[queue.Queue[bytes | bytes]] = None,
reconnect: bool = True,
timeout: Optional[float] = None,
stop: Optional[Callable[[], bool]] = None,
stop_reconnect: Optional[Callable[[], bool]] = None,
logger: Optional[logging.Logger] = None,
)
address
: A tuple representing the IP address and port number to connect to.to_send
: Optional queue to store messages to be sent.reconnect
: If True, the client will attempt to reconnect after disconnection.timeout
: Optional timeout value for send and receive operations.stop
: A function that returns True to signal the client to stop.stop_reconnect
: A function that returns True to signal the reconnecting loop to stop. Won't have any effect if reconnect is set to False.logger
: Optional logger for logging client events.
Properties
ip
: The IP address component of the client's address.port
: The port number component of the client's address.to_send
: The queue containing messages to be sent.
Methods
connect(timeout: Optional[float] = None)
: Connects to the server with an optional timeout.start()
: Starts the client in a new thread.join()
: Waits for the client thread to finish.shutdown()
: Signals the client to shut down gracefully.close_connection()
: Closes the socket connection.__enter__()
: Context manager entry point.__exit__(...)
: Context manager exit point.
Client
A client that sends and receives messages to and from a server.
def __init__(
self,
address: tuple[str, int],
received: Optional[queue.Queue[bytes]] = None,
to_send: Optional[queue.Queue[str | bytes]] = None,
reconnect: bool = True,
timeout: Optional[float] = None,
stop_receive: Callable[[], bool] = None,
stop_send: Callable[[], bool] = None,
stop_reconnect: Optional[Callable[[], bool]] = None,
logger: Optional[logging.Logger] = None,
)
address
: A tuple representing the IP address and port number to connect to.received
: Optional queue to store received messages.to_send
: Optional queue containing messages to be sent.reconnect
: If True, the client will attempt to reconnect after disconnection.timeout
: Optional timeout value for send and receive operations.stop_receive
: A function that returns True to signal the receiving loop to stop.stop_send
: A function that returns True to signal the sending loop to stop.stop_reconnect
: A function that returns True to signal the reconnecting loop to stop. Won't have any effect if reconnect is set to False.logger
: Optional logger for logging client events.
Properties
ip
: The IP address component of the client's address.port
: The port number component of the client's address.received
: The queue containing received messages.to_send
: The queue containing messages to be sent.send_thread
: The thread responsible for sending messages.receive_thread
: The thread responsible for receiving messages.
Methods
connect(timeout: Optional[float] = None)
: Connects to the server with an optional timeout.start()
: Starts the client in a new thread.join()
: Waits for the client thread to finish.shutdown()
: Signals the client to shut down gracefully.close_connection()
: Closes the socket connection.__enter__()
: Context manager entry point.__exit__(...)
: Context manager exit point.
AbstractService
This abstract base class is a blueprint to easily create other services that communicate with each other trough queues. Very useful for processing, storing, etc. the data received trough sockets.
Abstract base class for all services.
To add a new service, implement the _handle_message
method.
A service consists of an input queue and an output queue. The purpose of a service is to apply some function to the inputs to obtain the outputs that can then be processed by another service or sent to a receptor.
Most services are meant to run indefinitely, and so they do not run in the main thread. However, a custom function to terminate the service when needed can be used, and the service can also run in the main thread if necessary.
Constructor
def __init__(
self,
in_queue: Optional[queue.Queue] = None,
out_queue: Optional[queue.Queue] = None,
stop: Optional[Callable[[], bool]] = None,
events: Optional[dict[str, threading.Event]] = None,
logger: Optional[logging.Logger] = None,
):
Parameters:
in_queue
(Optional[queue.Queue]): Input queue for receiving messages.out_queue
(Optional[queue.Queue]): Output queue for sending messages.stop
(Optional[Callable[[], bool]]): Custom stop function.events
(Optional[dict[str, threading.Event]]): Dictionary of events.logger
(Optional[logging.Logger]): Logger for logging events.
Examples
Sample usage of a client that sends receives data from a server. The client.py
program
will use a custom MessageLogger
service to log all the data it receives, while the
server.py
program whill use a service MessageGenerator
to generate messages continuously
and send them to the client.
# client.py
from socketlib import ClientReceiver
from socketlib.services.samples import MessageLogger
from socketlib.utils.logger import get_module_logger
if __name__ == "__main__":
address = ("localhost", 12345)
client = ClientReceiver(address, reconnect=True)
logger = get_module_logger(__name__, "dev")
msg_logger = MessageLogger(client.received, logger)
with client:
client.connect()
client.start()
msg_logger.start()
try:
client.join()
except KeyboardInterrupt:
client.shutdown()
msg_logger.shutdown()
# server.py
from socketlib import ServerSender, get_module_logger
from socketlib.services.samples import MessageGenerator
if __name__ == "__main__":
address = ("localhost", 12345)
server = ServerSender(address)
logger = get_module_logger(__name__, "dev", use_file_handler=False)
msg_gen = MessageGenerator(server.to_send, logger)
with server:
server.start()
msg_gen.start()
try:
server.join()
except KeyboardInterrupt:
server.shutdown()
msg_gen.shutdown()
Developing
Developed in Python 3.11.4
Installing the development environment:
git clone https://github.com/Daniel-Ibarrola/MServ
python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements/dev.txt
pip install -e .
License
pysocklib
was created by Daniel Ibarrola. It is licensed under the terms
of the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pysocklib-0.6.1.tar.gz
.
File metadata
- Download URL: pysocklib-0.6.1.tar.gz
- Upload date:
- Size: 15.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.18
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a5dffd36aa322f3dbdc8be29e106df9d791aefd497194f7f4ede5c465cbf8f89 |
|
MD5 | 9de68b8a0244792dcd08a315ee598d95 |
|
BLAKE2b-256 | 53343d6c5c354d2e0cffc3205538fd0d03decbcfed8c974eff738c10c8fa75f8 |
File details
Details for the file pysocklib-0.6.1-py3-none-any.whl
.
File metadata
- Download URL: pysocklib-0.6.1-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.18
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 540e01c910500bdeeb5d117d06e981723d549858db601e49f32b9b50d955772d |
|
MD5 | dc429959d16f8f405646b86409f840a9 |
|
BLAKE2b-256 | 303c634c3e5277fb9cadab24bda321133458c5ba2cbc3aa145ae68434884c9df |