markethub-ddn 1.0.0__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.
@@ -0,0 +1,94 @@
1
+ .idea
2
+ .ruff_cache
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ .Python
14
+ env/
15
+ build/
16
+ develop-eggs/
17
+ dist/
18
+ downloads/
19
+ eggs/
20
+ .eggs/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *,cover
50
+ .hypothesis/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+
60
+ # Flask stuff:
61
+ instance/
62
+ .webassets-cache
63
+
64
+ # Scrapy stuff:
65
+ .scrapy
66
+
67
+ # Sphinx documentation
68
+ docs/_build/
69
+
70
+ # PyBuilder
71
+ target/
72
+
73
+ # Jupyter Notebook
74
+ .ipynb_checkpoints
75
+
76
+ # pyenv
77
+ .python-version
78
+
79
+ # celery beat schedule file
80
+ celerybeat-schedule
81
+
82
+ # dotenv
83
+ .env
84
+
85
+ # virtualenv
86
+ .venv/
87
+ venv/
88
+ ENV/
89
+
90
+ # Spyder project settings
91
+ .spyderproject
92
+
93
+ # Rope project settings
94
+ .ropeproject
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Centrifugal Labs LTD
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.4
2
+ Name: markethub-ddn
3
+ Version: 1.0.0
4
+ Summary: MarketHub DDN - WebSocket SDK for Centrifugo with built-in offset persistence and automatic recovery
5
+ Author: MarketHub
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: Centrifugo,DDN,MarketHub,Offset Persistence,Pub/Sub,Realtime,Streaming,WebSocket
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Framework :: AsyncIO
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Internet
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Classifier: Topic :: System :: Networking
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.9
28
+ Requires-Dist: protobuf<7.0.0,>=4.23.4
29
+ Requires-Dist: websockets<16.0.0,>=14.0.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pre-commit~=3.5.0; extra == 'dev'
32
+ Requires-Dist: ruff~=0.1.4; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # centrifuge-python
36
+
37
+ [![CI](https://github.com/centrifugal/centrifuge-python/actions/workflows/test.yml/badge.svg)](https://github.com/centrifugal/centrifuge-python/actions/workflows/test.yml?query=event%3Apush+branch%3Amaster+workflow%3ATest)
38
+ [![pypi](https://img.shields.io/pypi/v/centrifuge-python.svg)](https://pypi.python.org/pypi/centrifuge-python)
39
+ [![versions](https://img.shields.io/pypi/pyversions/centrifuge-python.svg)](https://github.com/centrifugal/centrifuge-python)
40
+ [![license](https://img.shields.io/github/license/centrifugal/centrifuge-python.svg)](https://github.com/centrifugal/centrifuge-python/blob/master/LICENSE)
41
+
42
+ This is a WebSocket real-time SDK for [Centrifugo](https://github.com/centrifugal/centrifugo) server (and any [Centrifuge-based](https://github.com/centrifugal/centrifuge) server) on top of Python asyncio library.
43
+
44
+ > [!TIP]
45
+ > If you are looking for Centrifugo [server API](https://centrifugal.dev/docs/server/server_api) client – check out [pycent](https://github.com/centrifugal/pycent) instead.
46
+
47
+ Before starting to work with this library check out Centrifugo [client SDK API specification](https://centrifugal.dev/docs/transports/client_api) as it contains common information about Centrifugal real-time SDK behavior. This SDK supports all major features of Centrifugo client protocol - see [SDK feature matrix](https://centrifugal.dev/docs/transports/client_sdk#sdk-feature-matrix).
48
+
49
+ ## Install
50
+
51
+ ```
52
+ pip install centrifuge-python
53
+ ```
54
+
55
+ Then in your code:
56
+
57
+ ```
58
+ from centrifuge import Client
59
+ ```
60
+
61
+ See [example code](https://github.com/centrifugal/centrifuge-python/blob/master/example.py) and [how to run it](#run-example) locally.
62
+
63
+ ## JSON vs Protobuf protocols
64
+
65
+ By default, SDK uses JSON protocol. If you want to use Protobuf protocol instead then pass `use_protobuf=True` option to `Client` constructor.
66
+
67
+ When using JSON protocol:
68
+
69
+ * all payloads (data to publish, connect/subscribe data) you pass to the library are encoded to JSON internally using `json.dumps` before sending to server. So make sure you pass only JSON-serializable data to the library.
70
+ * all payloads received from server are decoded to Python objects using `json.loads` internally before passing to your code.
71
+
72
+ When using Protobuf protocol:
73
+
74
+ * all payloads you pass to the library must be `bytes` or `None` if optional. If you pass non-`bytes` data – exception will be raised.
75
+ * all payloads received from the library will be `bytes` or `None` if not present.
76
+ * don't forget that when using Protobuf protocol you can still have JSON payloads - just encode them to `bytes` before passing to the library.
77
+
78
+ ## Callbacks should not block
79
+
80
+ Event callbacks are called by SDK using `await` internally, the websocket connection read loop is blocked for the time SDK waits for the callback to be executed. This means that if you need to perform long operations in callbacks consider moving the work to a separate coroutine/task to return fast and continue reading data from the websocket.
81
+
82
+ The fact WebSocket read is blocked for the time we execute callbacks means that you can not call awaitable SDK APIs from callback – because SDK does not have a chance to read the reply. You will get `OperationTimeoutError` exception. The rule is the same - do the work asynchronously, for example use `asyncio.ensure_future`.
83
+
84
+ ## Run example
85
+
86
+ To run [example](https://github.com/centrifugal/centrifuge-python/blob/master/example.py), first start Centrifugo with config like this:
87
+
88
+ ```json
89
+ {
90
+ "client": {
91
+ "token": {
92
+ "hmac_secret_key": "secret"
93
+ }
94
+ },
95
+ "channel": {
96
+ "namespaces": [
97
+ {
98
+ "name": "example",
99
+ "presence": true,
100
+ "history_size": 300,
101
+ "history_ttl": "300s",
102
+ "join_leave": true,
103
+ "force_push_join_leave": true,
104
+ "allow_publish_for_subscriber": true,
105
+ "allow_presence_for_subscriber": true,
106
+ "allow_history_for_subscriber": true
107
+ }
108
+ ]
109
+ }
110
+ }
111
+ ```
112
+
113
+ And then:
114
+
115
+ ```bash
116
+ python -m venv env
117
+ . env/bin/activate
118
+ make dev
119
+ python example.py
120
+ ```
121
+
122
+ ## Run tests
123
+
124
+ To run tests, first start Centrifugo server:
125
+
126
+ ```bash
127
+ docker pull centrifugo/centrifugo:v6
128
+ docker run -d -p 8000:8000 \
129
+ -e CENTRIFUGO_CLIENT_TOKEN_HMAC_SECRET_KEY="secret" \
130
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOWED_DELTA_TYPES="fossil" \
131
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_DELTA_PUBLISH="true" \
132
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_PRESENCE="true" \
133
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_JOIN_LEAVE="true" \
134
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_FORCE_PUSH_JOIN_LEAVE="true" \
135
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_HISTORY_SIZE="100" \
136
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_HISTORY_TTL="300s" \
137
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_FORCE_RECOVERY="true" \
138
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOW_PUBLISH_FOR_SUBSCRIBER="true" \
139
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOW_PRESENCE_FOR_SUBSCRIBER="true" \
140
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOW_HISTORY_FOR_SUBSCRIBER="true" \
141
+ -e CENTRIFUGO_CLIENT_SUBSCRIBE_TO_USER_PERSONAL_CHANNEL_ENABLED="true" \
142
+ -e CENTRIFUGO_LOG_LEVEL="trace" \
143
+ centrifugo/centrifugo:v6 centrifugo
144
+ ```
145
+
146
+ And then (from cloned repo root):
147
+
148
+ ```bash
149
+ python -m venv env
150
+ . env/bin/activate
151
+ make dev
152
+ make test
153
+ ```
@@ -0,0 +1,119 @@
1
+ # centrifuge-python
2
+
3
+ [![CI](https://github.com/centrifugal/centrifuge-python/actions/workflows/test.yml/badge.svg)](https://github.com/centrifugal/centrifuge-python/actions/workflows/test.yml?query=event%3Apush+branch%3Amaster+workflow%3ATest)
4
+ [![pypi](https://img.shields.io/pypi/v/centrifuge-python.svg)](https://pypi.python.org/pypi/centrifuge-python)
5
+ [![versions](https://img.shields.io/pypi/pyversions/centrifuge-python.svg)](https://github.com/centrifugal/centrifuge-python)
6
+ [![license](https://img.shields.io/github/license/centrifugal/centrifuge-python.svg)](https://github.com/centrifugal/centrifuge-python/blob/master/LICENSE)
7
+
8
+ This is a WebSocket real-time SDK for [Centrifugo](https://github.com/centrifugal/centrifugo) server (and any [Centrifuge-based](https://github.com/centrifugal/centrifuge) server) on top of Python asyncio library.
9
+
10
+ > [!TIP]
11
+ > If you are looking for Centrifugo [server API](https://centrifugal.dev/docs/server/server_api) client – check out [pycent](https://github.com/centrifugal/pycent) instead.
12
+
13
+ Before starting to work with this library check out Centrifugo [client SDK API specification](https://centrifugal.dev/docs/transports/client_api) as it contains common information about Centrifugal real-time SDK behavior. This SDK supports all major features of Centrifugo client protocol - see [SDK feature matrix](https://centrifugal.dev/docs/transports/client_sdk#sdk-feature-matrix).
14
+
15
+ ## Install
16
+
17
+ ```
18
+ pip install centrifuge-python
19
+ ```
20
+
21
+ Then in your code:
22
+
23
+ ```
24
+ from centrifuge import Client
25
+ ```
26
+
27
+ See [example code](https://github.com/centrifugal/centrifuge-python/blob/master/example.py) and [how to run it](#run-example) locally.
28
+
29
+ ## JSON vs Protobuf protocols
30
+
31
+ By default, SDK uses JSON protocol. If you want to use Protobuf protocol instead then pass `use_protobuf=True` option to `Client` constructor.
32
+
33
+ When using JSON protocol:
34
+
35
+ * all payloads (data to publish, connect/subscribe data) you pass to the library are encoded to JSON internally using `json.dumps` before sending to server. So make sure you pass only JSON-serializable data to the library.
36
+ * all payloads received from server are decoded to Python objects using `json.loads` internally before passing to your code.
37
+
38
+ When using Protobuf protocol:
39
+
40
+ * all payloads you pass to the library must be `bytes` or `None` if optional. If you pass non-`bytes` data – exception will be raised.
41
+ * all payloads received from the library will be `bytes` or `None` if not present.
42
+ * don't forget that when using Protobuf protocol you can still have JSON payloads - just encode them to `bytes` before passing to the library.
43
+
44
+ ## Callbacks should not block
45
+
46
+ Event callbacks are called by SDK using `await` internally, the websocket connection read loop is blocked for the time SDK waits for the callback to be executed. This means that if you need to perform long operations in callbacks consider moving the work to a separate coroutine/task to return fast and continue reading data from the websocket.
47
+
48
+ The fact WebSocket read is blocked for the time we execute callbacks means that you can not call awaitable SDK APIs from callback – because SDK does not have a chance to read the reply. You will get `OperationTimeoutError` exception. The rule is the same - do the work asynchronously, for example use `asyncio.ensure_future`.
49
+
50
+ ## Run example
51
+
52
+ To run [example](https://github.com/centrifugal/centrifuge-python/blob/master/example.py), first start Centrifugo with config like this:
53
+
54
+ ```json
55
+ {
56
+ "client": {
57
+ "token": {
58
+ "hmac_secret_key": "secret"
59
+ }
60
+ },
61
+ "channel": {
62
+ "namespaces": [
63
+ {
64
+ "name": "example",
65
+ "presence": true,
66
+ "history_size": 300,
67
+ "history_ttl": "300s",
68
+ "join_leave": true,
69
+ "force_push_join_leave": true,
70
+ "allow_publish_for_subscriber": true,
71
+ "allow_presence_for_subscriber": true,
72
+ "allow_history_for_subscriber": true
73
+ }
74
+ ]
75
+ }
76
+ }
77
+ ```
78
+
79
+ And then:
80
+
81
+ ```bash
82
+ python -m venv env
83
+ . env/bin/activate
84
+ make dev
85
+ python example.py
86
+ ```
87
+
88
+ ## Run tests
89
+
90
+ To run tests, first start Centrifugo server:
91
+
92
+ ```bash
93
+ docker pull centrifugo/centrifugo:v6
94
+ docker run -d -p 8000:8000 \
95
+ -e CENTRIFUGO_CLIENT_TOKEN_HMAC_SECRET_KEY="secret" \
96
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOWED_DELTA_TYPES="fossil" \
97
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_DELTA_PUBLISH="true" \
98
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_PRESENCE="true" \
99
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_JOIN_LEAVE="true" \
100
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_FORCE_PUSH_JOIN_LEAVE="true" \
101
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_HISTORY_SIZE="100" \
102
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_HISTORY_TTL="300s" \
103
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_FORCE_RECOVERY="true" \
104
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOW_PUBLISH_FOR_SUBSCRIBER="true" \
105
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOW_PRESENCE_FOR_SUBSCRIBER="true" \
106
+ -e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOW_HISTORY_FOR_SUBSCRIBER="true" \
107
+ -e CENTRIFUGO_CLIENT_SUBSCRIBE_TO_USER_PERSONAL_CHANNEL_ENABLED="true" \
108
+ -e CENTRIFUGO_LOG_LEVEL="trace" \
109
+ centrifugo/centrifugo:v6 centrifugo
110
+ ```
111
+
112
+ And then (from cloned repo root):
113
+
114
+ ```bash
115
+ python -m venv env
116
+ . env/bin/activate
117
+ make dev
118
+ make test
119
+ ```
@@ -0,0 +1,84 @@
1
+ """Main module of a Centrifuge Python client library."""
2
+
3
+ from .client import Client, ClientState, Subscription, SubscriptionState, DeltaType
4
+ from .contexts import (
5
+ ConnectedContext,
6
+ ConnectingContext,
7
+ DisconnectedContext,
8
+ ErrorContext,
9
+ JoinContext,
10
+ LeaveContext,
11
+ PublicationContext,
12
+ ServerJoinContext,
13
+ ServerLeaveContext,
14
+ ServerPublicationContext,
15
+ ServerSubscribedContext,
16
+ ServerSubscribingContext,
17
+ ServerUnsubscribedContext,
18
+ SubscribedContext,
19
+ SubscribingContext,
20
+ SubscriptionErrorContext,
21
+ UnsubscribedContext,
22
+ )
23
+ from .exceptions import (
24
+ CentrifugeError,
25
+ ClientDisconnectedError,
26
+ OperationTimeoutError,
27
+ DuplicateSubscriptionError,
28
+ ReplyError,
29
+ SubscriptionUnsubscribedError,
30
+ UnauthorizedError,
31
+ )
32
+ from .handlers import ClientEventHandler, SubscriptionEventHandler
33
+ from .types import (
34
+ ClientInfo,
35
+ HistoryResult,
36
+ PresenceResult,
37
+ PresenceStatsResult,
38
+ Publication,
39
+ PublishResult,
40
+ RpcResult,
41
+ StreamPosition,
42
+ )
43
+
44
+ __all__ = [
45
+ "CentrifugeError",
46
+ "Client",
47
+ "ClientDisconnectedError",
48
+ "ClientEventHandler",
49
+ "ClientInfo",
50
+ "ClientState",
51
+ "ConnectedContext",
52
+ "ConnectingContext",
53
+ "DeltaType",
54
+ "DisconnectedContext",
55
+ "DuplicateSubscriptionError",
56
+ "ErrorContext",
57
+ "HistoryResult",
58
+ "JoinContext",
59
+ "LeaveContext",
60
+ "OperationTimeoutError",
61
+ "PresenceResult",
62
+ "PresenceStatsResult",
63
+ "Publication",
64
+ "PublicationContext",
65
+ "PublishResult",
66
+ "ReplyError",
67
+ "RpcResult",
68
+ "ServerJoinContext",
69
+ "ServerLeaveContext",
70
+ "ServerPublicationContext",
71
+ "ServerSubscribedContext",
72
+ "ServerSubscribingContext",
73
+ "ServerUnsubscribedContext",
74
+ "StreamPosition",
75
+ "SubscribedContext",
76
+ "SubscribingContext",
77
+ "Subscription",
78
+ "SubscriptionErrorContext",
79
+ "SubscriptionEventHandler",
80
+ "SubscriptionState",
81
+ "SubscriptionUnsubscribedError",
82
+ "UnauthorizedError",
83
+ "UnsubscribedContext",
84
+ ]
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0"