pysmq 1.0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pysmq-1.0.7/PKG-INFO +262 -0
- pysmq-1.0.7/README.md +234 -0
- pysmq-1.0.7/examples/publish_example.py +56 -0
- pysmq-1.0.7/examples/secure_connection_example.py +105 -0
- pysmq-1.0.7/examples/subscribe_example.py +122 -0
- pysmq-1.0.7/pyproject.toml +55 -0
- pysmq-1.0.7/pysmq/__init__.py +37 -0
- pysmq-1.0.7/pysmq/_version.py +21 -0
- pysmq-1.0.7/pysmq/client.py +429 -0
- pysmq-1.0.7/pysmq/config.py +41 -0
- pysmq-1.0.7/pysmq/exceptions.py +84 -0
- pysmq-1.0.7/pysmq/proto/__init__.py +8 -0
- pysmq-1.0.7/pysmq/proto/smq_pb2.py +71 -0
- pysmq-1.0.7/pysmq/proto/smq_pb2_grpc.py +486 -0
- pysmq-1.0.7/pysmq.egg-info/PKG-INFO +262 -0
- pysmq-1.0.7/pysmq.egg-info/SOURCES.txt +20 -0
- pysmq-1.0.7/pysmq.egg-info/dependency_links.txt +1 -0
- pysmq-1.0.7/pysmq.egg-info/requires.txt +9 -0
- pysmq-1.0.7/pysmq.egg-info/top_level.txt +1 -0
- pysmq-1.0.7/setup.cfg +4 -0
- pysmq-1.0.7/tests/__init__.py +0 -0
- pysmq-1.0.7/tests/test_client.py +149 -0
pysmq-1.0.7/PKG-INFO
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pysmq
|
|
3
|
+
Version: 1.0.7
|
|
4
|
+
Summary: Python client for SuhaibMessageQueue
|
|
5
|
+
Author-email: Suhaib MessageQueue <example@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Classifier: Topic :: System :: Networking
|
|
18
|
+
Requires-Python: >=3.7
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: grpcio>=1.50.0
|
|
21
|
+
Requires-Dist: protobuf>=4.21.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: grpcio-tools>=1.50.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
25
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: isort>=5.10.0; extra == "dev"
|
|
27
|
+
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
28
|
+
|
|
29
|
+
# PySMQ: Python Client for SuhaibMessageQueue
|
|
30
|
+
|
|
31
|
+
This package provides a Python client for interacting with [SuhaibMessageQueue](https://github.com/Suhaibinator/SuhaibMessageQueue), a simple and efficient message queue service.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# From PyPI (once published)
|
|
37
|
+
pip install pysmq
|
|
38
|
+
|
|
39
|
+
# From source
|
|
40
|
+
git clone https://github.com/Suhaibinator/SuhaibMessageQueue.git
|
|
41
|
+
cd SuhaibMessageQueue
|
|
42
|
+
pip install -e ./pysmq
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Dependencies
|
|
46
|
+
|
|
47
|
+
- Python 3.7+
|
|
48
|
+
- grpcio
|
|
49
|
+
- protobuf
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
### Creating a client and publishing messages
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from pysmq.client import Client
|
|
57
|
+
|
|
58
|
+
# Create a client
|
|
59
|
+
with Client(host="localhost", port=8097) as client:
|
|
60
|
+
# Create a topic
|
|
61
|
+
client.create_topic("my-topic")
|
|
62
|
+
|
|
63
|
+
# Publish a message
|
|
64
|
+
offset = client.produce("my-topic", b"Hello, SMQ!")
|
|
65
|
+
print(f"Message published at offset {offset}")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Consuming messages
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from pysmq.client import Client
|
|
72
|
+
|
|
73
|
+
# Create a client
|
|
74
|
+
with Client(host="localhost", port=8097) as client:
|
|
75
|
+
# Consume the latest message
|
|
76
|
+
message, offset = client.consume_latest("my-topic")
|
|
77
|
+
print(f"Latest message: {message.decode('utf-8')}, offset: {offset}")
|
|
78
|
+
|
|
79
|
+
# Consume the earliest message
|
|
80
|
+
message, offset = client.consume_earliest("my-topic")
|
|
81
|
+
print(f"Earliest message: {message.decode('utf-8')}, offset: {offset}")
|
|
82
|
+
|
|
83
|
+
# Consume a specific message
|
|
84
|
+
message, offset = client.consume("my-topic", 5) # offset 5
|
|
85
|
+
print(f"Message at offset 5: {message.decode('utf-8')}")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Streaming messages
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from pysmq.client import Client
|
|
92
|
+
|
|
93
|
+
# Create a client
|
|
94
|
+
with Client(host="localhost", port=8097) as client:
|
|
95
|
+
# Stream produce messages
|
|
96
|
+
messages = [b"Message 1", b"Message 2", b"Message 3"]
|
|
97
|
+
last_offset = client.stream_produce("my-topic", messages)
|
|
98
|
+
print(f"Last message published at offset {last_offset}")
|
|
99
|
+
|
|
100
|
+
# Stream consume messages (continuous)
|
|
101
|
+
for message, offset in client.stream_consume("my-topic", 0):
|
|
102
|
+
print(f"Received message: {message.decode('utf-8')}, offset: {offset}")
|
|
103
|
+
# Break the loop when needed
|
|
104
|
+
if offset >= 10:
|
|
105
|
+
break
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Secure Connection (mTLS)
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from pysmq.client import Client
|
|
112
|
+
from pysmq.config import ClientTLSConfig
|
|
113
|
+
|
|
114
|
+
# Create TLS configuration
|
|
115
|
+
tls_config = ClientTLSConfig(
|
|
116
|
+
cert_file="/path/to/client.crt",
|
|
117
|
+
key_file="/path/to/client.key",
|
|
118
|
+
ca_file="/path/to/ca.crt"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Create a secure client
|
|
122
|
+
with Client(host="localhost", port=8097, tls_config=tls_config) as client:
|
|
123
|
+
# Use the client as normal
|
|
124
|
+
client.create_topic("secure-topic")
|
|
125
|
+
offset = client.produce("secure-topic", b"Secure message")
|
|
126
|
+
print(f"Secure message published at offset {offset}")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## API Overview
|
|
130
|
+
|
|
131
|
+
### Client
|
|
132
|
+
|
|
133
|
+
The `Client` class provides methods for interacting with the SMQ server.
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
# Constructor
|
|
137
|
+
client = Client(
|
|
138
|
+
host="localhost",
|
|
139
|
+
port=8097,
|
|
140
|
+
tls_config=None, # Optional: ClientTLSConfig for secure connections
|
|
141
|
+
max_send_message_size_mb=1024, # Optional: Maximum size of messages to send
|
|
142
|
+
max_receive_message_size_mb=1024 # Optional: Maximum size of messages to receive
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Topic Management
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
# Create a topic
|
|
150
|
+
client.create_topic(topic)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Message Production
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
# Produce a single message
|
|
157
|
+
offset = client.produce(topic, message_bytes)
|
|
158
|
+
|
|
159
|
+
# Produce a stream of messages
|
|
160
|
+
last_offset = client.stream_produce(topic, messages_iterable)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Message Consumption
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# Consume a single message at a specific offset
|
|
167
|
+
message, offset = client.consume(topic, offset)
|
|
168
|
+
|
|
169
|
+
# Consume the earliest available message
|
|
170
|
+
message, offset = client.consume_earliest(topic)
|
|
171
|
+
|
|
172
|
+
# Consume the latest message
|
|
173
|
+
message, offset = client.consume_latest(topic)
|
|
174
|
+
|
|
175
|
+
# Stream consume messages (returns an iterator)
|
|
176
|
+
for message, offset in client.stream_consume(topic, start_offset):
|
|
177
|
+
# Process each message
|
|
178
|
+
pass
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Offset Management
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
# Get the latest offset for a topic
|
|
185
|
+
latest_offset = client.get_latest_offset(topic)
|
|
186
|
+
|
|
187
|
+
# Get the earliest available offset for a topic
|
|
188
|
+
earliest_offset = client.get_earliest_offset(topic)
|
|
189
|
+
|
|
190
|
+
# Delete all messages up to and including the specified offset
|
|
191
|
+
client.delete_until_offset(topic, offset)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Bulk Operations
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
# Retrieve a batch of messages
|
|
198
|
+
response = client.bulk_retrieve(topic, start_offset, limit)
|
|
199
|
+
for message in response.messages:
|
|
200
|
+
# Process each message
|
|
201
|
+
message_bytes = message.message
|
|
202
|
+
message_offset = message.offset
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Connection Management
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
# Connect to the server (optional, happens automatically on first operation)
|
|
209
|
+
client.connect()
|
|
210
|
+
|
|
211
|
+
# Close the connection (or use 'with' statement)
|
|
212
|
+
client.close()
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Exception Handling
|
|
216
|
+
|
|
217
|
+
The client throws specific exceptions for different types of errors:
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
from pysmq.exceptions import (
|
|
221
|
+
SMQException, # Base exception for all SMQ errors
|
|
222
|
+
SMQConnectionError, # Connection issues
|
|
223
|
+
SMQAuthenticationError, # TLS/authentication issues
|
|
224
|
+
SMQProduceError, # Issues with producing messages
|
|
225
|
+
SMQConsumeError, # Issues with consuming messages
|
|
226
|
+
SMQTopicCreationError, # Issues with creating topics
|
|
227
|
+
SMQOffsetError, # Issues with offsets
|
|
228
|
+
SMQTimeoutError, # Timeout errors
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
try:
|
|
232
|
+
client.produce("my-topic", b"Hello")
|
|
233
|
+
except SMQProduceError as e:
|
|
234
|
+
print(f"Failed to produce message: {e}")
|
|
235
|
+
# Access the original error if needed
|
|
236
|
+
original_error = e.original_error
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Configuration
|
|
240
|
+
|
|
241
|
+
The client supports various configuration options:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
from pysmq.config import ClientTLSConfig, ClientConfig
|
|
245
|
+
|
|
246
|
+
# Default timeout values can be accessed or modified
|
|
247
|
+
ClientConfig.DEFAULT_TIMEOUT = 60.0 # Default timeout for most operations
|
|
248
|
+
ClientConfig.DEFAULT_TOPIC_TIMEOUT = 2.0 # Default timeout for topic creation
|
|
249
|
+
ClientConfig.DEFAULT_DELETE_TIMEOUT = 2.0 # Default timeout for deletion operations
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Examples
|
|
253
|
+
|
|
254
|
+
For more detailed examples, see the [examples](examples/) directory:
|
|
255
|
+
|
|
256
|
+
- [Basic Publishing](examples/publish_example.py)
|
|
257
|
+
- [Message Consumption](examples/subscribe_example.py)
|
|
258
|
+
- [Secure Connection](examples/secure_connection_example.py)
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
pysmq-1.0.7/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# PySMQ: Python Client for SuhaibMessageQueue
|
|
2
|
+
|
|
3
|
+
This package provides a Python client for interacting with [SuhaibMessageQueue](https://github.com/Suhaibinator/SuhaibMessageQueue), a simple and efficient message queue service.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# From PyPI (once published)
|
|
9
|
+
pip install pysmq
|
|
10
|
+
|
|
11
|
+
# From source
|
|
12
|
+
git clone https://github.com/Suhaibinator/SuhaibMessageQueue.git
|
|
13
|
+
cd SuhaibMessageQueue
|
|
14
|
+
pip install -e ./pysmq
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Dependencies
|
|
18
|
+
|
|
19
|
+
- Python 3.7+
|
|
20
|
+
- grpcio
|
|
21
|
+
- protobuf
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Creating a client and publishing messages
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from pysmq.client import Client
|
|
29
|
+
|
|
30
|
+
# Create a client
|
|
31
|
+
with Client(host="localhost", port=8097) as client:
|
|
32
|
+
# Create a topic
|
|
33
|
+
client.create_topic("my-topic")
|
|
34
|
+
|
|
35
|
+
# Publish a message
|
|
36
|
+
offset = client.produce("my-topic", b"Hello, SMQ!")
|
|
37
|
+
print(f"Message published at offset {offset}")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Consuming messages
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from pysmq.client import Client
|
|
44
|
+
|
|
45
|
+
# Create a client
|
|
46
|
+
with Client(host="localhost", port=8097) as client:
|
|
47
|
+
# Consume the latest message
|
|
48
|
+
message, offset = client.consume_latest("my-topic")
|
|
49
|
+
print(f"Latest message: {message.decode('utf-8')}, offset: {offset}")
|
|
50
|
+
|
|
51
|
+
# Consume the earliest message
|
|
52
|
+
message, offset = client.consume_earliest("my-topic")
|
|
53
|
+
print(f"Earliest message: {message.decode('utf-8')}, offset: {offset}")
|
|
54
|
+
|
|
55
|
+
# Consume a specific message
|
|
56
|
+
message, offset = client.consume("my-topic", 5) # offset 5
|
|
57
|
+
print(f"Message at offset 5: {message.decode('utf-8')}")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Streaming messages
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from pysmq.client import Client
|
|
64
|
+
|
|
65
|
+
# Create a client
|
|
66
|
+
with Client(host="localhost", port=8097) as client:
|
|
67
|
+
# Stream produce messages
|
|
68
|
+
messages = [b"Message 1", b"Message 2", b"Message 3"]
|
|
69
|
+
last_offset = client.stream_produce("my-topic", messages)
|
|
70
|
+
print(f"Last message published at offset {last_offset}")
|
|
71
|
+
|
|
72
|
+
# Stream consume messages (continuous)
|
|
73
|
+
for message, offset in client.stream_consume("my-topic", 0):
|
|
74
|
+
print(f"Received message: {message.decode('utf-8')}, offset: {offset}")
|
|
75
|
+
# Break the loop when needed
|
|
76
|
+
if offset >= 10:
|
|
77
|
+
break
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Secure Connection (mTLS)
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from pysmq.client import Client
|
|
84
|
+
from pysmq.config import ClientTLSConfig
|
|
85
|
+
|
|
86
|
+
# Create TLS configuration
|
|
87
|
+
tls_config = ClientTLSConfig(
|
|
88
|
+
cert_file="/path/to/client.crt",
|
|
89
|
+
key_file="/path/to/client.key",
|
|
90
|
+
ca_file="/path/to/ca.crt"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Create a secure client
|
|
94
|
+
with Client(host="localhost", port=8097, tls_config=tls_config) as client:
|
|
95
|
+
# Use the client as normal
|
|
96
|
+
client.create_topic("secure-topic")
|
|
97
|
+
offset = client.produce("secure-topic", b"Secure message")
|
|
98
|
+
print(f"Secure message published at offset {offset}")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## API Overview
|
|
102
|
+
|
|
103
|
+
### Client
|
|
104
|
+
|
|
105
|
+
The `Client` class provides methods for interacting with the SMQ server.
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
# Constructor
|
|
109
|
+
client = Client(
|
|
110
|
+
host="localhost",
|
|
111
|
+
port=8097,
|
|
112
|
+
tls_config=None, # Optional: ClientTLSConfig for secure connections
|
|
113
|
+
max_send_message_size_mb=1024, # Optional: Maximum size of messages to send
|
|
114
|
+
max_receive_message_size_mb=1024 # Optional: Maximum size of messages to receive
|
|
115
|
+
)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Topic Management
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# Create a topic
|
|
122
|
+
client.create_topic(topic)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Message Production
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
# Produce a single message
|
|
129
|
+
offset = client.produce(topic, message_bytes)
|
|
130
|
+
|
|
131
|
+
# Produce a stream of messages
|
|
132
|
+
last_offset = client.stream_produce(topic, messages_iterable)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Message Consumption
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
# Consume a single message at a specific offset
|
|
139
|
+
message, offset = client.consume(topic, offset)
|
|
140
|
+
|
|
141
|
+
# Consume the earliest available message
|
|
142
|
+
message, offset = client.consume_earliest(topic)
|
|
143
|
+
|
|
144
|
+
# Consume the latest message
|
|
145
|
+
message, offset = client.consume_latest(topic)
|
|
146
|
+
|
|
147
|
+
# Stream consume messages (returns an iterator)
|
|
148
|
+
for message, offset in client.stream_consume(topic, start_offset):
|
|
149
|
+
# Process each message
|
|
150
|
+
pass
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Offset Management
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
# Get the latest offset for a topic
|
|
157
|
+
latest_offset = client.get_latest_offset(topic)
|
|
158
|
+
|
|
159
|
+
# Get the earliest available offset for a topic
|
|
160
|
+
earliest_offset = client.get_earliest_offset(topic)
|
|
161
|
+
|
|
162
|
+
# Delete all messages up to and including the specified offset
|
|
163
|
+
client.delete_until_offset(topic, offset)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Bulk Operations
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
# Retrieve a batch of messages
|
|
170
|
+
response = client.bulk_retrieve(topic, start_offset, limit)
|
|
171
|
+
for message in response.messages:
|
|
172
|
+
# Process each message
|
|
173
|
+
message_bytes = message.message
|
|
174
|
+
message_offset = message.offset
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Connection Management
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Connect to the server (optional, happens automatically on first operation)
|
|
181
|
+
client.connect()
|
|
182
|
+
|
|
183
|
+
# Close the connection (or use 'with' statement)
|
|
184
|
+
client.close()
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Exception Handling
|
|
188
|
+
|
|
189
|
+
The client throws specific exceptions for different types of errors:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from pysmq.exceptions import (
|
|
193
|
+
SMQException, # Base exception for all SMQ errors
|
|
194
|
+
SMQConnectionError, # Connection issues
|
|
195
|
+
SMQAuthenticationError, # TLS/authentication issues
|
|
196
|
+
SMQProduceError, # Issues with producing messages
|
|
197
|
+
SMQConsumeError, # Issues with consuming messages
|
|
198
|
+
SMQTopicCreationError, # Issues with creating topics
|
|
199
|
+
SMQOffsetError, # Issues with offsets
|
|
200
|
+
SMQTimeoutError, # Timeout errors
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
client.produce("my-topic", b"Hello")
|
|
205
|
+
except SMQProduceError as e:
|
|
206
|
+
print(f"Failed to produce message: {e}")
|
|
207
|
+
# Access the original error if needed
|
|
208
|
+
original_error = e.original_error
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Configuration
|
|
212
|
+
|
|
213
|
+
The client supports various configuration options:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from pysmq.config import ClientTLSConfig, ClientConfig
|
|
217
|
+
|
|
218
|
+
# Default timeout values can be accessed or modified
|
|
219
|
+
ClientConfig.DEFAULT_TIMEOUT = 60.0 # Default timeout for most operations
|
|
220
|
+
ClientConfig.DEFAULT_TOPIC_TIMEOUT = 2.0 # Default timeout for topic creation
|
|
221
|
+
ClientConfig.DEFAULT_DELETE_TIMEOUT = 2.0 # Default timeout for deletion operations
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Examples
|
|
225
|
+
|
|
226
|
+
For more detailed examples, see the [examples](examples/) directory:
|
|
227
|
+
|
|
228
|
+
- [Basic Publishing](examples/publish_example.py)
|
|
229
|
+
- [Message Consumption](examples/subscribe_example.py)
|
|
230
|
+
- [Secure Connection](examples/secure_connection_example.py)
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Example showing how to publish messages to SMQ using the Python client.
|
|
4
|
+
"""
|
|
5
|
+
import time
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from pysmq.client import Client
|
|
9
|
+
from pysmq.config import ClientTLSConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main():
|
|
13
|
+
# Replace with actual server details
|
|
14
|
+
host = "localhost"
|
|
15
|
+
port = 8097
|
|
16
|
+
|
|
17
|
+
# Create a client with default settings (insecure connection)
|
|
18
|
+
with Client(host=host, port=port) as client:
|
|
19
|
+
# Connect to the server (this is optional but a good test)
|
|
20
|
+
print("Connecting to SMQ server...")
|
|
21
|
+
client.connect()
|
|
22
|
+
print("Connected!")
|
|
23
|
+
|
|
24
|
+
# Create a topic if it doesn't exist
|
|
25
|
+
topic = "example-topic"
|
|
26
|
+
try:
|
|
27
|
+
print(f"Creating topic '{topic}'...")
|
|
28
|
+
client.create_topic(topic)
|
|
29
|
+
print(f"Topic '{topic}' created successfully!")
|
|
30
|
+
except Exception as e:
|
|
31
|
+
# Topic may already exist, which is okay
|
|
32
|
+
print(f"Note: {e}")
|
|
33
|
+
|
|
34
|
+
# Publish a few messages
|
|
35
|
+
for i in range(5):
|
|
36
|
+
# Create a sample message (convert to bytes)
|
|
37
|
+
message = {
|
|
38
|
+
"id": i,
|
|
39
|
+
"timestamp": time.time(),
|
|
40
|
+
"content": f"Message #{i}",
|
|
41
|
+
}
|
|
42
|
+
message_bytes = json.dumps(message).encode('utf-8')
|
|
43
|
+
|
|
44
|
+
# Publish the message
|
|
45
|
+
print(f"Publishing message {i}...")
|
|
46
|
+
offset = client.produce(topic, message_bytes)
|
|
47
|
+
print(f"Message published at offset {offset}")
|
|
48
|
+
|
|
49
|
+
# Small delay between messages for demonstration
|
|
50
|
+
time.sleep(0.5)
|
|
51
|
+
|
|
52
|
+
print("All messages published successfully!")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
main()
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Example showing how to establish a secure connection to the SMQ server using mTLS.
|
|
4
|
+
"""
|
|
5
|
+
import json
|
|
6
|
+
import time
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from pysmq.client import Client
|
|
10
|
+
from pysmq.config import ClientTLSConfig
|
|
11
|
+
from pysmq.exceptions import SMQAuthenticationError, SMQConnectionError
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
# Replace with actual server details
|
|
16
|
+
host = "localhost"
|
|
17
|
+
port = 8097
|
|
18
|
+
|
|
19
|
+
# Replace with actual paths to your TLS certificate files
|
|
20
|
+
# These paths should point to your client certificate, client key,
|
|
21
|
+
# and CA certificate that signed the server's certificate
|
|
22
|
+
cert_file = os.environ.get("CLIENT_CERT", "/path/to/client.crt")
|
|
23
|
+
key_file = os.environ.get("CLIENT_KEY", "/path/to/client.key")
|
|
24
|
+
ca_file = os.environ.get("CA_CERT", "/path/to/ca.crt")
|
|
25
|
+
|
|
26
|
+
# Check if the certificate files exist
|
|
27
|
+
for file_path, file_name in [
|
|
28
|
+
(cert_file, "Client certificate"),
|
|
29
|
+
(key_file, "Client key"),
|
|
30
|
+
(ca_file, "CA certificate")
|
|
31
|
+
]:
|
|
32
|
+
if not os.path.exists(file_path):
|
|
33
|
+
print(f"Warning: {file_name} file not found at {file_path}")
|
|
34
|
+
print("This example requires valid TLS certificates to work.")
|
|
35
|
+
print("You can set the paths via environment variables:")
|
|
36
|
+
print(" CLIENT_CERT: Path to client certificate file")
|
|
37
|
+
print(" CLIENT_KEY: Path to client key file")
|
|
38
|
+
print(" CA_CERT: Path to CA certificate file")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
# Create the TLS configuration
|
|
42
|
+
tls_config = ClientTLSConfig(
|
|
43
|
+
cert_file=cert_file,
|
|
44
|
+
key_file=key_file,
|
|
45
|
+
ca_file=ca_file,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
print("Creating secure client with mTLS...")
|
|
50
|
+
# Create a client with mTLS configuration
|
|
51
|
+
with Client(host=host, port=port, tls_config=tls_config) as client:
|
|
52
|
+
# Connect to the server
|
|
53
|
+
print("Connecting to SMQ server securely...")
|
|
54
|
+
client.connect()
|
|
55
|
+
print("Connected securely!")
|
|
56
|
+
|
|
57
|
+
# Example: Create a topic
|
|
58
|
+
topic = "secure-example-topic"
|
|
59
|
+
try:
|
|
60
|
+
print(f"Creating topic '{topic}'...")
|
|
61
|
+
client.create_topic(topic)
|
|
62
|
+
print(f"Topic '{topic}' created successfully!")
|
|
63
|
+
except Exception as e:
|
|
64
|
+
# Topic may already exist, which is okay
|
|
65
|
+
print(f"Note: {e}")
|
|
66
|
+
|
|
67
|
+
# Example: Publish a message
|
|
68
|
+
message = {
|
|
69
|
+
"id": 1,
|
|
70
|
+
"timestamp": time.time(),
|
|
71
|
+
"content": "Secure message",
|
|
72
|
+
"secure": True,
|
|
73
|
+
}
|
|
74
|
+
message_bytes = json.dumps(message).encode('utf-8')
|
|
75
|
+
|
|
76
|
+
print("Publishing a secure message...")
|
|
77
|
+
offset = client.produce(topic, message_bytes)
|
|
78
|
+
print(f"Message published securely at offset {offset}")
|
|
79
|
+
|
|
80
|
+
# Example: Consume the message
|
|
81
|
+
print("Consuming the message...")
|
|
82
|
+
received_bytes, received_offset = client.consume(topic, offset)
|
|
83
|
+
|
|
84
|
+
# Decode and print the message
|
|
85
|
+
received_message = json.loads(received_bytes.decode('utf-8'))
|
|
86
|
+
print(f"Received secure message at offset {received_offset}:")
|
|
87
|
+
print(f" ID: {received_message.get('id')}")
|
|
88
|
+
print(f" Timestamp: {received_message.get('timestamp')}")
|
|
89
|
+
print(f" Content: {received_message.get('content')}")
|
|
90
|
+
print(f" Secure: {received_message.get('secure')}")
|
|
91
|
+
|
|
92
|
+
print("Secure connection example completed successfully!")
|
|
93
|
+
|
|
94
|
+
except SMQAuthenticationError as e:
|
|
95
|
+
print(f"TLS Authentication Error: {e}")
|
|
96
|
+
print("Make sure your certificates are correctly configured and valid.")
|
|
97
|
+
except SMQConnectionError as e:
|
|
98
|
+
print(f"Connection Error: {e}")
|
|
99
|
+
print("Make sure the server is running and configured for mTLS.")
|
|
100
|
+
except Exception as e:
|
|
101
|
+
print(f"Unexpected Error: {e}")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == "__main__":
|
|
105
|
+
main()
|