yashserver 0.1.0__py3-none-any.whl
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.
- yashserver/__init__.py +4 -0
- yashserver-0.1.0.dist-info/METADATA +227 -0
- yashserver-0.1.0.dist-info/RECORD +13 -0
- yashserver-0.1.0.dist-info/WHEEL +5 -0
- yashserver-0.1.0.dist-info/licenses/LICENSE.md +21 -0
- yashserver-0.1.0.dist-info/top_level.txt +2 -0
- yserver/__init__.py +45 -0
- yserver/database.py +870 -0
- yserver/plugin.py +117 -0
- yserver/plugins.py +45 -0
- yserver/server.py +1220 -0
- yserver/sync.py +259 -0
- yserver/tools.py +122 -0
yashserver/__init__.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yashserver
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async-first server toolkit with plugins, native WebSocket support, auth/rate limiting, and TLS.
|
|
5
|
+
Author: yashserver contributors
|
|
6
|
+
Keywords: asyncio,server,plugin,websocket,tls,auth,rate-limit,database
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE.md
|
|
15
|
+
Provides-Extra: db
|
|
16
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "db"
|
|
17
|
+
Requires-Dist: pymongo>=4.0; extra == "db"
|
|
18
|
+
Requires-Dist: redis>=5.0; extra == "db"
|
|
19
|
+
Requires-Dist: cassandra-driver>=3.29; extra == "db"
|
|
20
|
+
Requires-Dist: boto3>=1.34; extra == "db"
|
|
21
|
+
Requires-Dist: firebase-admin>=6.0; extra == "db"
|
|
22
|
+
Requires-Dist: couchbase>=4.2; extra == "db"
|
|
23
|
+
Requires-Dist: elasticsearch>=8.0; extra == "db"
|
|
24
|
+
Requires-Dist: neo4j>=5.0; extra == "db"
|
|
25
|
+
Requires-Dist: influxdb-client>=1.40; extra == "db"
|
|
26
|
+
Requires-Dist: duckdb>=1.0; extra == "db"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# yashserver
|
|
30
|
+
|
|
31
|
+
`yashserver` is an independent Python server library focused on simple APIs:
|
|
32
|
+
- `YServer` for line-based TCP command servers
|
|
33
|
+
- `YWebSocketServer` for WebSocket routes
|
|
34
|
+
- `YHttpServer` for lightweight HTML/API serving
|
|
35
|
+
- `YSyncServer`, `YSyncWebSocketServer`, `YSyncHttpServer` for non-async usage
|
|
36
|
+
- Built-in TLS (`ssl_context`) support
|
|
37
|
+
- Optional token auth and sliding-window rate limiting
|
|
38
|
+
- Plugin hooks for lifecycle, traffic, and error handling
|
|
39
|
+
|
|
40
|
+
Core networking is standard library based. Database connectors are optional and loaded only when used.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install -e .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
From PyPI:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install yashserver
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For database drivers (optional):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install -e ".[db]"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Task 1 Demo (Browser + HTML)
|
|
61
|
+
|
|
62
|
+
Run:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python examples/task1_browser_server.py
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Then open:
|
|
69
|
+
|
|
70
|
+
`http://127.0.0.1:8080`
|
|
71
|
+
|
|
72
|
+
You will see a small HTML page served by `YHttpServer`.
|
|
73
|
+
Live chat is enabled by `YWebSocketServer` with no external dependencies.
|
|
74
|
+
The page code is in `test.html`, served on `/` and `/test.html`.
|
|
75
|
+
|
|
76
|
+
Demo highlights:
|
|
77
|
+
- Chunked **binary** file upload (no base64 transfer path), including videos
|
|
78
|
+
- ACK/retry chunk handling in the browser client
|
|
79
|
+
- Server-side file storage + `/download/<id>` links
|
|
80
|
+
- Optional auth token via env var `YSERVER_TOKEN`
|
|
81
|
+
- Optional MongoDB text-message persistence
|
|
82
|
+
|
|
83
|
+
Mongo text persistence env vars for `examples/task1_browser_server.py`:
|
|
84
|
+
- `YSERVER_MONGO_TEXT_ENABLED` (`1` or `0`)
|
|
85
|
+
- `YSERVER_MONGO_URI` (example: `mongodb://localhost:27018`)
|
|
86
|
+
- `YSERVER_MONGO_DB` (default: `yserver_chat`)
|
|
87
|
+
- `YSERVER_MONGO_COLLECTION` (default: `messages`)
|
|
88
|
+
- `YSERVER_MONGO_GRIDFS_BUCKET` (default: `fs`, creates `<bucket>.files` + `<bucket>.chunks`)
|
|
89
|
+
- `YSERVER_MONGO_GRIDFS_CHUNK_SIZE` (default: `524288` bytes)
|
|
90
|
+
- `YSERVER_MONGO_WRITE_CONCERN` (default: `1` for fast local visibility in Compass)
|
|
91
|
+
- `YSERVER_MONGO_JOURNAL` (`1` or `0`, default: `0`)
|
|
92
|
+
- or set `YSERVER_MONGO_HOST` + `YSERVER_MONGO_PORT` instead of a full URI
|
|
93
|
+
|
|
94
|
+
## Minimal Sync Example
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import yserver
|
|
98
|
+
|
|
99
|
+
app = yserver.YSyncServer(port=9000)
|
|
100
|
+
|
|
101
|
+
@app.route("ping")
|
|
102
|
+
def ping(client, payload, server):
|
|
103
|
+
return {"reply": "pong"}
|
|
104
|
+
|
|
105
|
+
app.run()
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
You can use a single import and access all public helpers from `yserver.*`, for example:
|
|
109
|
+
`yserver.ConnectionStatsPlugin`, `yserver.LoggingPlugin`, `yserver.ServerTools`,
|
|
110
|
+
`yserver.YSyncHttpServer`, `yserver.YSyncWebSocketServer`, and `yserver.run_many`.
|
|
111
|
+
|
|
112
|
+
## Database Support
|
|
113
|
+
|
|
114
|
+
Single import API:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import yserver
|
|
118
|
+
|
|
119
|
+
db = yserver.connect_database("sqlite", database=":memory:")
|
|
120
|
+
db.execute("CREATE TABLE users (id INTEGER, name TEXT)")
|
|
121
|
+
db.execute("INSERT INTO users (id, name) VALUES (?, ?)", (1, "Ada"))
|
|
122
|
+
print(db.fetch_all("SELECT * FROM users"))
|
|
123
|
+
db.close()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Also available through tools:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
db = yserver.ServerTools.connect_database("sqlite", database="app.db")
|
|
130
|
+
print(yserver.ServerTools.supported_databases())
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Supported backends:
|
|
134
|
+
- MySQL
|
|
135
|
+
- PostgreSQL
|
|
136
|
+
- Microsoft SQL Server
|
|
137
|
+
- Oracle Database
|
|
138
|
+
- SQLite
|
|
139
|
+
- MariaDB
|
|
140
|
+
- MongoDB
|
|
141
|
+
- Redis
|
|
142
|
+
- Cassandra
|
|
143
|
+
- DynamoDB
|
|
144
|
+
- Firebase Realtime Database
|
|
145
|
+
- Couchbase
|
|
146
|
+
- Snowflake
|
|
147
|
+
- Google BigQuery
|
|
148
|
+
- Amazon Redshift
|
|
149
|
+
- ClickHouse
|
|
150
|
+
- Elasticsearch
|
|
151
|
+
- Neo4j
|
|
152
|
+
- InfluxDB
|
|
153
|
+
- DuckDB
|
|
154
|
+
|
|
155
|
+
Quick DB demo script:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
python examples/task2_database_support.py
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
MongoDB Compass quick test (default local port `27018`):
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
python examples/task3_mongodb_compass_test.py
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Compass connection string:
|
|
168
|
+
|
|
169
|
+
`mongodb://localhost:27018`
|
|
170
|
+
|
|
171
|
+
Notes:
|
|
172
|
+
- SQL backends use SQLAlchemy (`url=` or DSN-style config).
|
|
173
|
+
- SQLite is supported via stdlib `sqlite3`.
|
|
174
|
+
- Non-SQL backends use their ecosystem drivers (optional install).
|
|
175
|
+
|
|
176
|
+
## TLS / HTTPS
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
import yserver
|
|
180
|
+
|
|
181
|
+
ssl_ctx = yserver.ServerTools.create_server_ssl_context(
|
|
182
|
+
certfile="cert.pem",
|
|
183
|
+
keyfile="key.pem",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
http = yserver.YSyncHttpServer(port=8443, ssl_context=ssl_ctx)
|
|
187
|
+
ws = yserver.YSyncWebSocketServer(port=9443, ssl_context=ssl_ctx)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
For the demo script (`examples/task1_browser_server.py`), you can enable TLS by env vars:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
set YSERVER_TLS_CERT=cert.pem
|
|
194
|
+
set YSERVER_TLS_KEY=key.pem
|
|
195
|
+
python examples/task1_browser_server.py
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
If `tls/cert.pem` and `tls/key.pem` exist in the project root, the demo auto-enables HTTPS/WSS.
|
|
199
|
+
|
|
200
|
+
## Auth + Rate Limit
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
import yserver
|
|
204
|
+
|
|
205
|
+
ws = yserver.YSyncWebSocketServer(
|
|
206
|
+
auth_token="my-secret-token",
|
|
207
|
+
rate_limit_per_window=300,
|
|
208
|
+
rate_limit_window_seconds=60.0,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
http = yserver.YSyncHttpServer(
|
|
212
|
+
auth_token="my-secret-token",
|
|
213
|
+
rate_limit_per_window=800,
|
|
214
|
+
rate_limit_window_seconds=60.0,
|
|
215
|
+
)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Token can be provided as:
|
|
219
|
+
- Query param: `?token=...`
|
|
220
|
+
- Header: `x-yserver-token: ...`
|
|
221
|
+
- Header: `Authorization: Bearer ...`
|
|
222
|
+
|
|
223
|
+
## Test Suite
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
python -m unittest discover -s tests -p "test_*.py" -v
|
|
227
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
yashserver/__init__.py,sha256=1Bj8cgmTAubrUFS-NGNSKnULgr7ngJmkff7hrS8qcyg,108
|
|
2
|
+
yashserver-0.1.0.dist-info/licenses/LICENSE.md,sha256=fKra_bdTQIr0joKOW0g4MTdCuItypRKOQZEFO0KB-rs,1080
|
|
3
|
+
yserver/__init__.py,sha256=s8gOQrJRiUeou0MxhFG1VHv9Pf7ISG2BU3lkUNVbVbw,1194
|
|
4
|
+
yserver/database.py,sha256=nyMQUjtFYyBrx2TJczSNMes-NercnRVgCU6E_BbIf6o,32194
|
|
5
|
+
yserver/plugin.py,sha256=v-Zv5xpuXw7z-BhhRgOrsLhUhCpDeRvPmTNhAJoomgA,4517
|
|
6
|
+
yserver/plugins.py,sha256=I8GbFo4R3HFCirqK308w0MVGCwf1aFYcWMOMYZWW-UU,1449
|
|
7
|
+
yserver/server.py,sha256=pY_aMn1uC4Ncc15DrLvqWCmnJsBfZRcBVre3kxF9H4E,45403
|
|
8
|
+
yserver/sync.py,sha256=YJaJofieWqGh4Kx5jLk2tWBkqEc9bTlBw4gZkRrumjQ,9511
|
|
9
|
+
yserver/tools.py,sha256=1G9vS-A0diAupj0uWXaiOoYZDcK2tz5y3hR4enKrYtc,3911
|
|
10
|
+
yashserver-0.1.0.dist-info/METADATA,sha256=Iq0Q1BtyPgYyVMa1DeY9bvkjFQfdot-eAP15Bdvh-MU,6102
|
|
11
|
+
yashserver-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
12
|
+
yashserver-0.1.0.dist-info/top_level.txt,sha256=SRM7mlm-usE-5y9jW_TZfwSyuW8u8hIWWR-IfDYCkPM,19
|
|
13
|
+
yashserver-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 yashserver contributors
|
|
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.
|
yserver/__init__.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""yserver: make asyncio server development simple."""
|
|
2
|
+
|
|
3
|
+
from .database import (
|
|
4
|
+
DatabaseClient,
|
|
5
|
+
DatabaseConfigError,
|
|
6
|
+
DatabaseError,
|
|
7
|
+
MissingDependencyError,
|
|
8
|
+
UnsupportedDatabaseError,
|
|
9
|
+
build_sqlalchemy_url,
|
|
10
|
+
connect_database,
|
|
11
|
+
database_support_matrix,
|
|
12
|
+
list_supported_databases,
|
|
13
|
+
)
|
|
14
|
+
from .plugin import LoggingPlugin, ServerPlugin
|
|
15
|
+
from .plugins import ConnectionStatsPlugin
|
|
16
|
+
from .server import HttpRequest, TcpClient, WebSocketClient, WsMessage, YHttpServer, YServer, YWebSocketServer
|
|
17
|
+
from .sync import YSyncHttpServer, YSyncServer, YSyncWebSocketServer, run_many
|
|
18
|
+
from .tools import ServerTools
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"build_sqlalchemy_url",
|
|
22
|
+
"connect_database",
|
|
23
|
+
"database_support_matrix",
|
|
24
|
+
"list_supported_databases",
|
|
25
|
+
"ConnectionStatsPlugin",
|
|
26
|
+
"DatabaseClient",
|
|
27
|
+
"DatabaseConfigError",
|
|
28
|
+
"DatabaseError",
|
|
29
|
+
"LoggingPlugin",
|
|
30
|
+
"MissingDependencyError",
|
|
31
|
+
"ServerPlugin",
|
|
32
|
+
"ServerTools",
|
|
33
|
+
"HttpRequest",
|
|
34
|
+
"UnsupportedDatabaseError",
|
|
35
|
+
"WsMessage",
|
|
36
|
+
"TcpClient",
|
|
37
|
+
"WebSocketClient",
|
|
38
|
+
"YHttpServer",
|
|
39
|
+
"YServer",
|
|
40
|
+
"YSyncHttpServer",
|
|
41
|
+
"YSyncServer",
|
|
42
|
+
"YSyncWebSocketServer",
|
|
43
|
+
"YWebSocketServer",
|
|
44
|
+
"run_many",
|
|
45
|
+
]
|