Skip to content

Commit

Permalink
improve the documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmad88me committed Aug 14, 2024
1 parent 2f578e1 commit d40eccc
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 22 deletions.
111 changes: 111 additions & 0 deletions README-pypi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@

![stiqueue](https://github.com/ahmad88me/stiqueue/raw/main/stiqueue.png)


# stiqueue


Stands for stick queue which is a simple messaging queue. It is developed with simplicity and flexibility in mind.


## Guide

### SQServer
You can run the SQServer directly without the need to write any piece of code.
The server will handle the messaging queue. Once the code is downloaded, you can run it as follows:
```
python src/stiqueue/sqserver.py --host 0.0.0.0 --port 1234 --debug
```
It is recommended to use the `--debug` if you are running it for the first time to
see when the server is getting a message or once a message is leaving the queue.

#### Usage
The following is the command line options
```
usage: StiQueue Server [-h] [--debug] [--host HOST] [--port PORT] [--buff-size BUFF_SIZE]
A message queue server
options:
-h, --help show this help message and exit
--debug Showing debug messages
--host HOST The host address of the server
--port PORT The port to listen on
--buff-size BUFF_SIZE
The size of the buffer
```

### SQClient
The client is meant to be used inside your code. Once you install the `stiqueue` package
inside your python project, you can use the client to send and receive messages from the
messaging queue. But make sure that the client host and port matches your SQServer.

#### Client Code Sample
1. Import and initiate
```
from stiqueue.sqclient import SQClient
c = SQClient()
```
2. Send a message
```
c.enq("Hello World!")
```
3. Fetch the message
```
hello_msg = c.deq()
```

Note that often the client that is sending the messages is different than the one receiving them.
For example, one client (or app) might be sending the requests and the second client is
fetching these messages/requests once a resource becomes available.

#### Methods
The followings are a set of methods supported by stiqueue
* **enq**: to add to the queue (enqueue).
* **deq**: to get a value from the queue (dequeue).
* **cnt**: number of items in the queue.

### Examples

#### Client example

```
from stiqueue.sqclient import SQClient
c = SQClient()
c.enq(b"This is message one")
c.enq(b"This is message two")
c.enq(b"This is message three")
msg = c.deq().decode()
print("msg1: ")
print(msg)
msg = c.deq().decode()
print("msg2: ")
print(msg)
msg = c.deq().decode()
print("msg3: ")
print(msg)
```
Note that the reason that `decode` is used because the `deq` returns `bytes`.

#### Server example
In case you want to extend the server code or want to use it, you can use the following code.
```
from stiqueue.sqserver import SQServer
server = SQServer()
server.listen()
```
Note that in most cases you do not want to call the server from your code. You can just run the
server script as explained in the guide.

### Extend
In most cases, you won't need to extend any of the classes, but in case you want to do so,
we provide two samples extending stiqueue with more functionality (optional). [examples](https://github.com/ahmad88me/stiqueue/tree/main/example)


## Run tests
```python -m unittest discover```




73 changes: 57 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,58 @@
Stands for stick queue which is a simple messaging queue. It is developed with simplicity and flexibility in mind.


## Usage
## Guide

### Methods
### SQServer
You can run the SQServer directly without the need to write any piece of code.
The server will handle the messaging queue. Once the code is downloaded, you can run it as follows:
```
python src/stiqueue/sqserver.py --host 0.0.0.0 --port 1234 --debug
```
It is recommended to use the `--debug` if you are running it for the first time to
see when the server is getting a message or once a message is leaving the queue.

#### Usage
The following is the command line options
```
usage: StiQueue Server [-h] [--debug] [--host HOST] [--port PORT] [--buff-size BUFF_SIZE]
A message queue server
options:
-h, --help show this help message and exit
--debug Showing debug messages
--host HOST The host address of the server
--port PORT The port to listen on
--buff-size BUFF_SIZE
The size of the buffer
```

### SQClient
The client is meant to be used inside your code. Once you install the `stiqueue` package
inside your python project, you can use the client to send and receive messages from the
messaging queue. But make sure that the client host and port matches your SQServer.

#### Client Code Sample
1. Import and initiate
```
from stiqueue.sqclient import SQClient
c = SQClient()
```
2. Send a message
```
c.enq("Hello World!")
```
3. Fetch the message
```
hello_msg = c.deq()
```

Note that often the client that is sending the messages is different than the one receiving them.
For example, one client (or app) might be sending the requests and the second client is
fetching these messages/requests once a resource becomes available.

#### Methods
The followings are a set of methods supported by stiqueue
* **enq**: to add to the queue (enqueue).
* **deq**: to get a value from the queue (dequeue).
Expand All @@ -25,7 +74,6 @@ The followings are a set of methods supported by stiqueue

```
from stiqueue.sqclient import SQClient
c = SQClient()
c.enq(b"This is message one")
c.enq(b"This is message two")
Expand All @@ -40,30 +88,23 @@ msg = c.deq().decode()
print("msg3: ")
print(msg)
```
Note that the reason that `decode` is used because the `deq` returns `bytes`.

#### Server example
In case you want to extend the server code or want to use it, you can use the following code.
```
from stiqueue.sqserver import SQServer
server = SQServer()
server.listen()
```
Note that in most cases you do not want to call the server from your code. You can just run the
server script as explained in the guide.

### Extend
We provide two samples extending stiqueue with more functionality. [examples](https://github.com/ahmad88me/stiqueue/tree/main/example)

### Server
You can run the server `sqserver.py` as is.
```
python src/stiqueue/sqserver --host 0.0.0.0 --port 1234
```
You can also change the port to any of your choice.
The default one used in Docker is `27017`. You can also
extend the server and add additional methods to meet your needs.
In most cases, you won't need to extend any of the classes, but in case you want to do so,
we provide two samples extending stiqueue with more functionality (optional). [examples](https://github.com/ahmad88me/stiqueue/tree/main/example)

### Client
Most probably you want to extend the class `SQClient`, located in `stiqueue/sqclient.py`.
You can see an example of this in `example.client.py`.

## Run tests
```python -m unittest discover```
Expand Down
62 changes: 61 additions & 1 deletion src/stiqueue/sqclient.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
"""
This module implements a simple client for interacting with a message queue server.
Classes:
SQClient: A client that connects to the message queue server to enqueue, dequeue, and check the count of messages.
"""

import socket
import sys
import time
import logging
import os
from sys import getsizeof


class SQClient:
"""
A client that connects to a message queue server for enqueuing, dequeuing, and retrieving the count of messages.
Attributes:
host (str): The server's host address.
port (int): The port number to connect to the server.
socket (socket.socket): The client socket to communicate with the server.
buff_size (int): Buffer size for sending and receiving messages.
logger (logging.Logger): Logger for printing messages.
"""

def __init__(self, host="127.0.0.1", port=1234, logger=None, buff_size=None):
"""
Initializes the SQClient with the specified parameters.
Args:
host (str): The server's host address. Defaults to "127.0.0.1".
port (int): The port number to connect to the server. Defaults to 1234.
logger (logging.Logger, optional): Logger for logging messages. If None, a default logger is created.
buff_size (int, optional): Buffer size for sending and receiving messages. Defaults to None.
"""
self.host = host
self.port = port
if host is None:
Expand All @@ -24,6 +49,9 @@ def __init__(self, host="127.0.0.1", port=1234, logger=None, buff_size=None):
self.logger = logger

def connect(self):
"""
Establishes a connection to the messaging queue server.
"""
self.logger.debug("Connecting to %s %d" % (self.host, self.port))
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if self.buff_size:
Expand All @@ -34,6 +62,17 @@ def connect(self):
self.socket.connect((self.host, self.port))

def send_with_action(self, msg, action, recv=False):
"""
Sends a message with a specified action to the server.
Args:
msg (bytes or str): The message to send. If not in bytes, it will be encoded.
action (bytes): The action command (e.g., "enq", "deq", "cnt").
recv (bool): Whether to expect a response from the server. Defaults to False.
Returns:
bytes: The server's response if recv is True, otherwise None.
"""
total_ret_val = None
if not isinstance(msg, bytes):
msg = msg.encode()
Expand All @@ -56,15 +95,36 @@ def send_with_action(self, msg, action, recv=False):
return total_ret_val

def enq(self, msg):
"""
Sends an "enqueue" request to the server.
Args:
msg (bytes or str): The message to enqueue. If not in bytes, it will be encoded.
"""
self.send_with_action(msg, b"enq")

def deq(self):
"""
Sends a "dequeue" request to the server and receives the dequeued message.
Returns:
bytes: The dequeued message from the server.
"""
return self.send_with_action(b"", b"deq", recv=True)

def cnt(self):
"""
Sends a "count" request to the server and receives the count of messages in the queue.
Returns:
bytes: The count of messages in the queue.
"""
return self.send_with_action(b"", b"cnt", recv=True)

def disconnect(self):
"""
Closes the connection to the server.
"""
self.socket.close()


Expand Down
Loading

0 comments on commit d40eccc

Please sign in to comment.