zeed 1.2.2__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.
zeed-1.2.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 <Maxim Zhovner>
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.
zeed-1.2.2/PKG-INFO ADDED
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: zeed
3
+ Version: 1.2.2
4
+ Summary: Fast, dependency-light Telegram Bot API framework built on urllib3
5
+ Author-email: Maxim Zhovner <zovnercukmaksim197@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/fakeskyline/zeed
8
+ Project-URL: Source, https://github.com/fakeskyline/zeed
9
+ Project-URL: Issues, https://github.com/fakeskyline/zeed/issues
10
+ Project-URL: Changelog, https://github.com/fakeskyline/zeed/blob/main/CHANGELOG.md
11
+ Keywords: telegram,bot,api,urllib3,framework,async-free
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Communications :: Chat
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: urllib3>=2.0
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest>=7; extra == "test"
28
+ Dynamic: license-file
29
+
30
+ # zeed
31
+
32
+ **Fast, dependency-light Telegram Bot API framework built on urllib3.**
33
+ No aiohttp. No requests. No httpx.
34
+
35
+ [![PyPI](https://img.shields.io/pypi/v/zeed.svg)](https://pypi.org/project/zeed/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/zeed.svg)](https://pypi.org/project/zeed/)
37
+ [![License](https://img.shields.io/pypi/l/zeed.svg)](https://github.com/fakeskyline/zeed/blob/main/LICENSE)
38
+
39
+ ## Why zeed?
40
+
41
+ Most Telegram Python libraries pull in `aiohttp` or `requests`. zeed
42
+ talks directly to the Telegram Bot API through `urllib3` with a keep-alive
43
+ connection pool. That means:
44
+
45
+ - **Small** — no heavy dependencies, just `urllib3`
46
+ - **Fast** — direct JSON requests, no middleware layers
47
+ - **Sync** — simple, predictable, easy to debug
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ pip install zeed
53
+ ```
54
+
55
+ Requires Python 3.9+.
56
+
57
+ ## Quick start
58
+
59
+ ```python
60
+ from zeed import Bot
61
+
62
+ bot = Bot("YOUR_TOKEN", parse_mode="HTML")
63
+
64
+ @bot.message_handler(commands=["start"])
65
+ def start(msg):
66
+ bot.send_message(msg.chat.id, f"Hi, <b>{msg.from_user.first_name}</b>!")
67
+
68
+ @bot.message_handler(content_types=["text"])
69
+ def echo(msg):
70
+ bot.send_message(msg.chat.id, f"You said: <b>{msg.text}</b>")
71
+
72
+ if __name__ == "__main__":
73
+ bot.run_polling()
74
+ ```
75
+
76
+ ## FSM example
77
+
78
+ ```python
79
+ from zeed import Bot, RemoveKeyboard, State, StatesGroup
80
+
81
+ bot = Bot("YOUR_TOKEN", parse_mode="HTML")
82
+
83
+ class Form(StatesGroup):
84
+ name = State()
85
+ age = State()
86
+
87
+ @bot.message_handler(commands=["start"])
88
+ def start(msg, data):
89
+ data["state"].set_state(Form.name)
90
+ bot.send_message(msg.chat.id, "What's your name?")
91
+
92
+ @bot.message_handler(state=Form.name)
93
+ def on_name(msg, data):
94
+ data["state"].update_data(name=msg.text)
95
+ data["state"].set_state(Form.age)
96
+ bot.send_message(msg.chat.id, f"Nice to meet you, {msg.text}. How old are you?")
97
+
98
+ @bot.message_handler(state=Form.age)
99
+ def on_age(msg, data):
100
+ ctx = data["state"]
101
+ if not msg.text.isdigit():
102
+ bot.send_message(msg.chat.id, "Please enter a number.")
103
+ return
104
+ ctx.update_data(age=int(msg.text))
105
+ info = ctx.get_data()
106
+ ctx.clear()
107
+ bot.send_message(
108
+ msg.chat.id,
109
+ f"Done!\nName: {info['name']}\nAge: {info['age']}",
110
+ reply_markup=RemoveKeyboard(),
111
+ )
112
+
113
+ bot.run_polling()
114
+ ```
115
+
116
+ ## Inline mode
117
+
118
+ ```python
119
+ from zeed import Bot, InlineQueryResultArticle
120
+
121
+ bot = Bot("YOUR_TOKEN")
122
+
123
+ @bot.inline_query_handler()
124
+ def on_inline(q):
125
+ results = [
126
+ InlineQueryResultArticle(
127
+ id="hello",
128
+ title="Send hello",
129
+ input_message_content={"message_text": "Hello!"},
130
+ ),
131
+ ]
132
+ bot.answer_inline_query(q.id, results)
133
+
134
+ bot.run_polling()
135
+ ```
136
+
137
+ ## Middleware
138
+
139
+ ```python
140
+ from zeed import Bot, LoggingMiddleware, ThrottlingMiddleware
141
+
142
+ bot = Bot("YOUR_TOKEN")
143
+ bot.middleware(LoggingMiddleware())
144
+ bot.middleware(ThrottlingMiddleware(rate=0.5))
145
+
146
+ @bot.message_handler(content_types=["text"])
147
+ def echo(msg):
148
+ bot.send_message(msg.chat.id, msg.text)
149
+
150
+ bot.run_polling(workers=4)
151
+ ```
152
+
153
+ ## Webhook
154
+
155
+ ```python
156
+ from zeed import Bot, WebhookServer
157
+
158
+ bot = Bot("YOUR_TOKEN")
159
+
160
+ @bot.message_handler(commands=["start"])
161
+ def start(msg):
162
+ bot.send_message(msg.chat.id, "Hello via webhook!")
163
+
164
+ if __name__ == "__main__":
165
+ server = WebhookServer(
166
+ bot,
167
+ host="0.0.0.0",
168
+ port=8080,
169
+ path="/webhook",
170
+ secret_token="change-me-to-random-32-chars",
171
+ )
172
+ server.install("https://your-domain.com/webhook")
173
+ server.start(blocking=True)
174
+ ```
175
+
176
+ ## Features
177
+
178
+ - Long-polling and webhook (pure stdlib `http.server`)
179
+ - Inline mode: `@yourbot query` with results
180
+ - FSM: `State`, `StatesGroup`, `MemoryStorage`, `FileStorage`, `SQLiteStorage`
181
+ - Middleware: logging, throttling, timing
182
+ - Filters: `Command`, `Text`, `Regexp`, `ContentTypes`, `ChatType`, `ChatId`, `UserId`, `CallbackData`, `CallbackDataPrefix`, `Func`
183
+ - Filter operators: `&` (and), `|` (or), `~` (not)
184
+ - File sending: photo, document, video, audio, voice, sticker
185
+ - Extras: poll, location, contact, dice
186
+ - Auto-split for long messages: `send_long_message`
187
+ - Security: path traversal guard, size limits, ReDoS protection, token redaction, dedup, safe SQLite
188
+ - Zero dependencies except `urllib3`
189
+
190
+ ## Performance
191
+
192
+ Benchmarked on Termux (Android, same Wi-Fi, ~30 ms to Telegram, median of 3 trials):
193
+
194
+ | Workload | zeed | pyTelegramBotAPI |
195
+ |---|---|---|
196
+ | 5 × sendMessage | 85 ms/msg | 89 ms/msg |
197
+ | 3 × sendPhoto | 99 ms/msg | 116 ms/msg |
198
+
199
+ Your results will vary with network latency.
200
+
201
+ ## Security
202
+
203
+ - **Path traversal** — `safe_path()` rejects `/etc`, `/proc`, `/sys`, `/root`, `/dev`
204
+ - **Upload size** — 50 MB limit enforced
205
+ - **Callback data** — validated to ≤64 UTF-8 bytes
206
+ - **ReDoS** — `compile_safe_regex()` rejects nested quantifiers
207
+ - **Webhook forgery** — `hmac.compare_digest` on secret token
208
+ - **Token leakage** — bot tokens redacted from logs
209
+ - **Idempotency** — duplicate `update_id` dropped via LRU
210
+ - **SQL injection** — parameterized queries only
211
+
212
+ ## Documentation
213
+
214
+ Full beginner's guide: [ABOUT.md](https://github.com/fakeskyline/zeed/blob/main/ABOUT.md).
215
+
216
+ Changelog: [CHANGELOG.md](https://github.com/fakeskyline/zeed/blob/main/CHANGELOG.md).
217
+
218
+ ## License
219
+
220
+ MIT — see [LICENSE](https://github.com/fakeskyline/zeed/blob/main/LICENSE).
zeed-1.2.2/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # zeed
2
+
3
+ **Fast, dependency-light Telegram Bot API framework built on urllib3.**
4
+ No aiohttp. No requests. No httpx.
5
+
6
+ [![PyPI](https://img.shields.io/pypi/v/zeed.svg)](https://pypi.org/project/zeed/)
7
+ [![Python](https://img.shields.io/pypi/pyversions/zeed.svg)](https://pypi.org/project/zeed/)
8
+ [![License](https://img.shields.io/pypi/l/zeed.svg)](https://github.com/fakeskyline/zeed/blob/main/LICENSE)
9
+
10
+ ## Why zeed?
11
+
12
+ Most Telegram Python libraries pull in `aiohttp` or `requests`. zeed
13
+ talks directly to the Telegram Bot API through `urllib3` with a keep-alive
14
+ connection pool. That means:
15
+
16
+ - **Small** — no heavy dependencies, just `urllib3`
17
+ - **Fast** — direct JSON requests, no middleware layers
18
+ - **Sync** — simple, predictable, easy to debug
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install zeed
24
+ ```
25
+
26
+ Requires Python 3.9+.
27
+
28
+ ## Quick start
29
+
30
+ ```python
31
+ from zeed import Bot
32
+
33
+ bot = Bot("YOUR_TOKEN", parse_mode="HTML")
34
+
35
+ @bot.message_handler(commands=["start"])
36
+ def start(msg):
37
+ bot.send_message(msg.chat.id, f"Hi, <b>{msg.from_user.first_name}</b>!")
38
+
39
+ @bot.message_handler(content_types=["text"])
40
+ def echo(msg):
41
+ bot.send_message(msg.chat.id, f"You said: <b>{msg.text}</b>")
42
+
43
+ if __name__ == "__main__":
44
+ bot.run_polling()
45
+ ```
46
+
47
+ ## FSM example
48
+
49
+ ```python
50
+ from zeed import Bot, RemoveKeyboard, State, StatesGroup
51
+
52
+ bot = Bot("YOUR_TOKEN", parse_mode="HTML")
53
+
54
+ class Form(StatesGroup):
55
+ name = State()
56
+ age = State()
57
+
58
+ @bot.message_handler(commands=["start"])
59
+ def start(msg, data):
60
+ data["state"].set_state(Form.name)
61
+ bot.send_message(msg.chat.id, "What's your name?")
62
+
63
+ @bot.message_handler(state=Form.name)
64
+ def on_name(msg, data):
65
+ data["state"].update_data(name=msg.text)
66
+ data["state"].set_state(Form.age)
67
+ bot.send_message(msg.chat.id, f"Nice to meet you, {msg.text}. How old are you?")
68
+
69
+ @bot.message_handler(state=Form.age)
70
+ def on_age(msg, data):
71
+ ctx = data["state"]
72
+ if not msg.text.isdigit():
73
+ bot.send_message(msg.chat.id, "Please enter a number.")
74
+ return
75
+ ctx.update_data(age=int(msg.text))
76
+ info = ctx.get_data()
77
+ ctx.clear()
78
+ bot.send_message(
79
+ msg.chat.id,
80
+ f"Done!\nName: {info['name']}\nAge: {info['age']}",
81
+ reply_markup=RemoveKeyboard(),
82
+ )
83
+
84
+ bot.run_polling()
85
+ ```
86
+
87
+ ## Inline mode
88
+
89
+ ```python
90
+ from zeed import Bot, InlineQueryResultArticle
91
+
92
+ bot = Bot("YOUR_TOKEN")
93
+
94
+ @bot.inline_query_handler()
95
+ def on_inline(q):
96
+ results = [
97
+ InlineQueryResultArticle(
98
+ id="hello",
99
+ title="Send hello",
100
+ input_message_content={"message_text": "Hello!"},
101
+ ),
102
+ ]
103
+ bot.answer_inline_query(q.id, results)
104
+
105
+ bot.run_polling()
106
+ ```
107
+
108
+ ## Middleware
109
+
110
+ ```python
111
+ from zeed import Bot, LoggingMiddleware, ThrottlingMiddleware
112
+
113
+ bot = Bot("YOUR_TOKEN")
114
+ bot.middleware(LoggingMiddleware())
115
+ bot.middleware(ThrottlingMiddleware(rate=0.5))
116
+
117
+ @bot.message_handler(content_types=["text"])
118
+ def echo(msg):
119
+ bot.send_message(msg.chat.id, msg.text)
120
+
121
+ bot.run_polling(workers=4)
122
+ ```
123
+
124
+ ## Webhook
125
+
126
+ ```python
127
+ from zeed import Bot, WebhookServer
128
+
129
+ bot = Bot("YOUR_TOKEN")
130
+
131
+ @bot.message_handler(commands=["start"])
132
+ def start(msg):
133
+ bot.send_message(msg.chat.id, "Hello via webhook!")
134
+
135
+ if __name__ == "__main__":
136
+ server = WebhookServer(
137
+ bot,
138
+ host="0.0.0.0",
139
+ port=8080,
140
+ path="/webhook",
141
+ secret_token="change-me-to-random-32-chars",
142
+ )
143
+ server.install("https://your-domain.com/webhook")
144
+ server.start(blocking=True)
145
+ ```
146
+
147
+ ## Features
148
+
149
+ - Long-polling and webhook (pure stdlib `http.server`)
150
+ - Inline mode: `@yourbot query` with results
151
+ - FSM: `State`, `StatesGroup`, `MemoryStorage`, `FileStorage`, `SQLiteStorage`
152
+ - Middleware: logging, throttling, timing
153
+ - Filters: `Command`, `Text`, `Regexp`, `ContentTypes`, `ChatType`, `ChatId`, `UserId`, `CallbackData`, `CallbackDataPrefix`, `Func`
154
+ - Filter operators: `&` (and), `|` (or), `~` (not)
155
+ - File sending: photo, document, video, audio, voice, sticker
156
+ - Extras: poll, location, contact, dice
157
+ - Auto-split for long messages: `send_long_message`
158
+ - Security: path traversal guard, size limits, ReDoS protection, token redaction, dedup, safe SQLite
159
+ - Zero dependencies except `urllib3`
160
+
161
+ ## Performance
162
+
163
+ Benchmarked on Termux (Android, same Wi-Fi, ~30 ms to Telegram, median of 3 trials):
164
+
165
+ | Workload | zeed | pyTelegramBotAPI |
166
+ |---|---|---|
167
+ | 5 × sendMessage | 85 ms/msg | 89 ms/msg |
168
+ | 3 × sendPhoto | 99 ms/msg | 116 ms/msg |
169
+
170
+ Your results will vary with network latency.
171
+
172
+ ## Security
173
+
174
+ - **Path traversal** — `safe_path()` rejects `/etc`, `/proc`, `/sys`, `/root`, `/dev`
175
+ - **Upload size** — 50 MB limit enforced
176
+ - **Callback data** — validated to ≤64 UTF-8 bytes
177
+ - **ReDoS** — `compile_safe_regex()` rejects nested quantifiers
178
+ - **Webhook forgery** — `hmac.compare_digest` on secret token
179
+ - **Token leakage** — bot tokens redacted from logs
180
+ - **Idempotency** — duplicate `update_id` dropped via LRU
181
+ - **SQL injection** — parameterized queries only
182
+
183
+ ## Documentation
184
+
185
+ Full beginner's guide: [ABOUT.md](https://github.com/fakeskyline/zeed/blob/main/ABOUT.md).
186
+
187
+ Changelog: [CHANGELOG.md](https://github.com/fakeskyline/zeed/blob/main/CHANGELOG.md).
188
+
189
+ ## License
190
+
191
+ MIT — see [LICENSE](https://github.com/fakeskyline/zeed/blob/main/LICENSE).
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "zeed"
7
+ version = "1.2.2"
8
+ description = "Fast, dependency-light Telegram Bot API framework built on urllib3"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ authors = [
12
+ { name = "Maxim Zhovner", email = "zovnercukmaksim197@gmail.com" }
13
+ ]
14
+ license = "MIT"
15
+ license-files = ["LICENSE"]
16
+ keywords = ["telegram", "bot", "api", "urllib3", "framework", "async-free"]
17
+ dependencies = ["urllib3>=2.0"]
18
+ classifiers = [
19
+ "Development Status :: 4 - Beta",
20
+ "Intended Audience :: Developers",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.9",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Topic :: Communications :: Chat",
28
+ "Topic :: Software Development :: Libraries :: Python Modules",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/fakeskyline/zeed"
33
+ Source = "https://github.com/fakeskyline/zeed"
34
+ Issues = "https://github.com/fakeskyline/zeed/issues"
35
+ Changelog = "https://github.com/fakeskyline/zeed/blob/main/CHANGELOG.md"
36
+
37
+ [project.optional-dependencies]
38
+ test = ["pytest>=7"]
39
+
40
+ [tool.setuptools.packages.find]
41
+ where = ["."]
42
+ include = ["zeed*"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
zeed-1.2.2/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+