nicebot 0.1.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.
Files changed (49) hide show
  1. nicebot-0.1.0/.gitignore +13 -0
  2. nicebot-0.1.0/CHANGELOG.md +15 -0
  3. nicebot-0.1.0/LICENSE +21 -0
  4. nicebot-0.1.0/PKG-INFO +160 -0
  5. nicebot-0.1.0/README.md +108 -0
  6. nicebot-0.1.0/pyproject.toml +69 -0
  7. nicebot-0.1.0/src/nicebot/__about__.py +1 -0
  8. nicebot-0.1.0/src/nicebot/__init__.py +60 -0
  9. nicebot-0.1.0/src/nicebot/_base.py +75 -0
  10. nicebot-0.1.0/src/nicebot/api.py +1317 -0
  11. nicebot-0.1.0/src/nicebot/bot.py +773 -0
  12. nicebot-0.1.0/src/nicebot/broadcast.py +76 -0
  13. nicebot-0.1.0/src/nicebot/cli.py +131 -0
  14. nicebot-0.1.0/src/nicebot/client.py +223 -0
  15. nicebot-0.1.0/src/nicebot/config.py +67 -0
  16. nicebot-0.1.0/src/nicebot/context.py +820 -0
  17. nicebot-0.1.0/src/nicebot/di.py +138 -0
  18. nicebot-0.1.0/src/nicebot/errors.py +101 -0
  19. nicebot-0.1.0/src/nicebot/features.py +509 -0
  20. nicebot-0.1.0/src/nicebot/filters.py +140 -0
  21. nicebot-0.1.0/src/nicebot/i18n.py +217 -0
  22. nicebot-0.1.0/src/nicebot/keyboards.py +376 -0
  23. nicebot-0.1.0/src/nicebot/logs.py +33 -0
  24. nicebot-0.1.0/src/nicebot/menu.py +116 -0
  25. nicebot-0.1.0/src/nicebot/orm/__init__.py +7 -0
  26. nicebot-0.1.0/src/nicebot/orm/builtin.py +66 -0
  27. nicebot-0.1.0/src/nicebot/orm/db.py +128 -0
  28. nicebot-0.1.0/src/nicebot/orm/fields.py +274 -0
  29. nicebot-0.1.0/src/nicebot/orm/model.py +414 -0
  30. nicebot-0.1.0/src/nicebot/orm/mongo.py +228 -0
  31. nicebot-0.1.0/src/nicebot/orm/query.py +232 -0
  32. nicebot-0.1.0/src/nicebot/orm/sql.py +648 -0
  33. nicebot-0.1.0/src/nicebot/pagination.py +98 -0
  34. nicebot-0.1.0/src/nicebot/py.typed +0 -0
  35. nicebot-0.1.0/src/nicebot/reload.py +66 -0
  36. nicebot-0.1.0/src/nicebot/router.py +373 -0
  37. nicebot-0.1.0/src/nicebot/scheduler.py +92 -0
  38. nicebot-0.1.0/src/nicebot/server.py +224 -0
  39. nicebot-0.1.0/src/nicebot/storage.py +173 -0
  40. nicebot-0.1.0/src/nicebot/testing.py +422 -0
  41. nicebot-0.1.0/src/nicebot/types.py +5327 -0
  42. nicebot-0.1.0/src/nicebot/utils.py +231 -0
  43. nicebot-0.1.0/src/nicebot/validators.py +315 -0
  44. nicebot-0.1.0/tests/conftest.py +51 -0
  45. nicebot-0.1.0/tests/test_bot.py +399 -0
  46. nicebot-0.1.0/tests/test_extra.py +130 -0
  47. nicebot-0.1.0/tests/test_features.py +408 -0
  48. nicebot-0.1.0/tests/test_orm.py +154 -0
  49. nicebot-0.1.0/tests/test_readme.py +37 -0
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ venv/
8
+ .env
9
+ *.db
10
+ *.db-*
11
+ .pytest_cache/
12
+ .mypy_cache/
13
+ .coverage
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-11-03
4
+
5
+ Birinchi chiqarilish.
6
+
7
+ - Telegram Bot API 10.3: 403 ta tur va 185 ta metod (msgspec)
8
+ - Ichki ORM: SQLite, PostgreSQL, MySQL/MariaDB, MongoDB va avto-migratsiya
9
+ - `ctx.ask`, `confirm`, `choose`, `form` va validatorlar
10
+ - `Button(on_click=)`, callback shablonlari, Toggle, `ttl`/`once`/`only`, Menu, paginate
11
+ - Referal, broadcast, statistika, admin panel, majburiy obuna, support, Telegram Stars
12
+ - Guruh moderatsiyasi va captcha
13
+ - Mini App server: `@bot.api`, initData tekshiruvi, `nicebot.js`
14
+ - Scheduler, fon vazifalari, kesh, i18n (uz/ru/en), DI, middleware
15
+ - Hot reload, `bot.test()`, `nicebot` CLI
nicebot-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ozodbek Sobirjonovich
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.
nicebot-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.5
2
+ Name: nicebot
3
+ Version: 0.1.0
4
+ Summary: Telegram botlar uchun eng qulay Python kutubxonasi: kam kod, ichki ORM, tugmalar, suhbatlar, Mini App — hammasi bitta importda.
5
+ Project-URL: Homepage, https://ozodmeofficial.github.io/nicebot/
6
+ Project-URL: Documentation, https://ozodmeofficial.github.io/nicebot/
7
+ Project-URL: Repository, https://github.com/ozodmeofficial/nicebot
8
+ Project-URL: Issues, https://github.com/ozodmeofficial/nicebot/issues
9
+ Project-URL: Changelog, https://github.com/ozodmeofficial/nicebot/blob/main/CHANGELOG.md
10
+ Author: Ozodbek Sobirjonovich
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: aiogram-alternative,async,bot,bot-api,mini-app,orm,telegram,telegram-bot,uzbek
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Framework :: AsyncIO
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Natural Language :: English
18
+ Classifier: Natural Language :: Russian
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Communications :: Chat
27
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Requires-Dist: aiohttp>=3.9
31
+ Requires-Dist: aiosqlite>=0.19
32
+ Requires-Dist: msgspec>=0.18
33
+ Provides-Extra: all
34
+ Requires-Dist: aiomysql>=0.2; extra == 'all'
35
+ Requires-Dist: asyncpg>=0.29; extra == 'all'
36
+ Requires-Dist: motor>=3.3; extra == 'all'
37
+ Requires-Dist: redis>=5.0; extra == 'all'
38
+ Provides-Extra: dev
39
+ Requires-Dist: mongomock-motor>=0.0.29; extra == 'dev'
40
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
41
+ Requires-Dist: pytest>=8; extra == 'dev'
42
+ Requires-Dist: typing-extensions>=4; extra == 'dev'
43
+ Provides-Extra: mongo
44
+ Requires-Dist: motor>=3.3; extra == 'mongo'
45
+ Provides-Extra: mysql
46
+ Requires-Dist: aiomysql>=0.2; extra == 'mysql'
47
+ Provides-Extra: postgres
48
+ Requires-Dist: asyncpg>=0.29; extra == 'postgres'
49
+ Provides-Extra: redis
50
+ Requires-Dist: redis>=5.0; extra == 'redis'
51
+ Description-Content-Type: text/markdown
52
+
53
+ # nicebot
54
+
55
+ **Telegram botlar uchun Python kutubxonasi: kam kod, hamma narsa ichida.**
56
+
57
+ [![PyPI](https://img.shields.io/pypi/v/nicebot.svg)](https://pypi.org/project/nicebot/)
58
+ [![Python](https://img.shields.io/pypi/pyversions/nicebot.svg)](https://pypi.org/project/nicebot/)
59
+ [![Bot API](https://img.shields.io/badge/Bot%20API-10.3-c4613c.svg)](https://core.telegram.org/bots/api)
60
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
61
+
62
+ 🇺🇿 O'zbekcha · 🇷🇺 [Документация на русском](https://ozodmeofficial.github.io/nicebot/) · 🇬🇧 [English docs](https://ozodmeofficial.github.io/nicebot/)
63
+
64
+ ```python
65
+ from nicebot import Nicebot
66
+
67
+ bot = Nicebot(token="123456:ABC...")
68
+
69
+ @bot.command("start")
70
+ async def start(ctx):
71
+ name = await ctx.ask("Ismingiz?")
72
+ age = await ctx.ask("Yoshingiz?", int)
73
+ await ctx.reply(f"Salom, {name}! Siz {age} yoshdasiz.")
74
+
75
+ bot.start()
76
+ ```
77
+
78
+ Bu kodda `Dispatcher`, `StatesGroup` va FSM yo'q. `ctx.ask()` savol berib, javobni o'sha joyda kutadi. Son kiritilmasa, o'zi qayta so'raydi. Foydalanuvchi esa bazaga avtomatik saqlanadi.
79
+
80
+ ## O'rnatish
81
+
82
+ ```bash
83
+ pip install nicebot # SQLite bilan
84
+ pip install "nicebot[postgres]" # + PostgreSQL
85
+ pip install "nicebot[mysql]" # + MySQL / MariaDB
86
+ pip install "nicebot[mongo]" # + MongoDB
87
+ pip install "nicebot[all]" # hammasi + Redis
88
+ ```
89
+
90
+ Tayyor loyiha yaratish:
91
+
92
+ ```bash
93
+ nicebot new mybot && cd mybot && python bot.py
94
+ ```
95
+
96
+ ## Ichida nimalar bor
97
+
98
+ | | |
99
+ |---|---|
100
+ | **Bot API 10.3 to'liq** | 403 ta tur va 185 ta metod rasmiy spetsifikatsiyadan generatsiya qilingan, msgspec asosida |
101
+ | **Ichki ORM** | SQLite, PostgreSQL, MySQL va MongoDB uchun bitta API, avto-migratsiya bilan |
102
+ | **Suhbatlar** | `ask`, `confirm`, `choose(multiple=True)`, `form` va validatorlar (telefon +998, email, sana…) |
103
+ | **Tugmalar** | `Button(on_click=func)`, `"buy:{id:int}"` shablonlari, Toggle, `ttl`, `once`, `only`, avto-joylashuv |
104
+ | **UI** | Ko'p darajali `Menu`, `ctx.paginate()`, reply klaviatura qisqartmalari |
105
+ | **Biznes** | Referal, broadcast (davom ettirish bilan), statistika, admin panel, majburiy obuna, support, Telegram Stars |
106
+ | **Guruhlar** | `ban`, `mute`, `warn`, captcha |
107
+ | **Mini App** | `@bot.api` endpointlari, initData HMAC tekshiruvi, `nicebot.js` |
108
+ | **Arxitektura** | DI (type hint orqali), middleware, Router, `from_env()`, scheduler, fon vazifalari, kesh |
109
+ | **Ishonchlilik** | Flood-wait, retry, file_id keshi, to'g'ri to'xtash, xatolar haqida adminlarga hisobot |
110
+ | **Ishlab chiqish** | `reload=True`, `bot.test()` (Telegram'siz testlar), CLI |
111
+
112
+ To'liq ro'yxat va qo'llanma: **[hujjatlar sayti](https://ozodmeofficial.github.io/nicebot/)** (uz / ru / en).
113
+
114
+ ## Yana misollar
115
+
116
+ ```python
117
+ from nicebot import Nicebot, Button, Model, fields, Phone
118
+
119
+ bot = Nicebot(token="...", db="sqlite:///shop.db", admins=[123456789])
120
+
121
+ class Order(Model):
122
+ user_id = fields.BigInt(index=True)
123
+ product = fields.Str(100)
124
+ phone = fields.Str(20)
125
+
126
+ async def buy(ctx, product: str):
127
+ phone = await ctx.ask("Telefon raqamingiz?", Phone)
128
+ if await ctx.confirm(f"{product} buyurtma qilinsinmi?"):
129
+ await Order.create(user_id=ctx.user_id, product=product, phone=phone)
130
+ await ctx.reply("✅ Qabul qilindi!")
131
+ await ctx.notify_admins(f"🛒 Yangi buyurtma: {product}, {phone}")
132
+
133
+ @bot.command("shop", description="Do'kon")
134
+ async def shop(ctx):
135
+ await ctx.reply("Mahsulotni tanlang:", buttons=[
136
+ Button("📚 Kitob", on_click=buy, product="Kitob"),
137
+ Button("🎧 Quloqchin", on_click=buy, product="Quloqchin"),
138
+ ])
139
+
140
+ bot.start(reload=True)
141
+ ```
142
+
143
+ Adminlar uchun `/stats`, `/broadcast`, `/maintenance` va `/backup` buyruqlari avtomatik ishlaydi.
144
+
145
+ ## Testlash
146
+
147
+ ```python
148
+ async def test_shop():
149
+ async with bot.test() as t:
150
+ user = t.user(first_name="Ali")
151
+ await user.send("/shop")
152
+ await user.click("Kitob")
153
+ await user.send("90 123 45 67")
154
+ await user.click("Ha")
155
+ assert t.last_in(user.chat_id).text == "✅ Qabul qilindi!"
156
+ ```
157
+
158
+ ## Litsenziya
159
+
160
+ MIT © Ozodbek Sobirjonovich
@@ -0,0 +1,108 @@
1
+ # nicebot
2
+
3
+ **Telegram botlar uchun Python kutubxonasi: kam kod, hamma narsa ichida.**
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/nicebot.svg)](https://pypi.org/project/nicebot/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/nicebot.svg)](https://pypi.org/project/nicebot/)
7
+ [![Bot API](https://img.shields.io/badge/Bot%20API-10.3-c4613c.svg)](https://core.telegram.org/bots/api)
8
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
+
10
+ 🇺🇿 O'zbekcha · 🇷🇺 [Документация на русском](https://ozodmeofficial.github.io/nicebot/) · 🇬🇧 [English docs](https://ozodmeofficial.github.io/nicebot/)
11
+
12
+ ```python
13
+ from nicebot import Nicebot
14
+
15
+ bot = Nicebot(token="123456:ABC...")
16
+
17
+ @bot.command("start")
18
+ async def start(ctx):
19
+ name = await ctx.ask("Ismingiz?")
20
+ age = await ctx.ask("Yoshingiz?", int)
21
+ await ctx.reply(f"Salom, {name}! Siz {age} yoshdasiz.")
22
+
23
+ bot.start()
24
+ ```
25
+
26
+ Bu kodda `Dispatcher`, `StatesGroup` va FSM yo'q. `ctx.ask()` savol berib, javobni o'sha joyda kutadi. Son kiritilmasa, o'zi qayta so'raydi. Foydalanuvchi esa bazaga avtomatik saqlanadi.
27
+
28
+ ## O'rnatish
29
+
30
+ ```bash
31
+ pip install nicebot # SQLite bilan
32
+ pip install "nicebot[postgres]" # + PostgreSQL
33
+ pip install "nicebot[mysql]" # + MySQL / MariaDB
34
+ pip install "nicebot[mongo]" # + MongoDB
35
+ pip install "nicebot[all]" # hammasi + Redis
36
+ ```
37
+
38
+ Tayyor loyiha yaratish:
39
+
40
+ ```bash
41
+ nicebot new mybot && cd mybot && python bot.py
42
+ ```
43
+
44
+ ## Ichida nimalar bor
45
+
46
+ | | |
47
+ |---|---|
48
+ | **Bot API 10.3 to'liq** | 403 ta tur va 185 ta metod rasmiy spetsifikatsiyadan generatsiya qilingan, msgspec asosida |
49
+ | **Ichki ORM** | SQLite, PostgreSQL, MySQL va MongoDB uchun bitta API, avto-migratsiya bilan |
50
+ | **Suhbatlar** | `ask`, `confirm`, `choose(multiple=True)`, `form` va validatorlar (telefon +998, email, sana…) |
51
+ | **Tugmalar** | `Button(on_click=func)`, `"buy:{id:int}"` shablonlari, Toggle, `ttl`, `once`, `only`, avto-joylashuv |
52
+ | **UI** | Ko'p darajali `Menu`, `ctx.paginate()`, reply klaviatura qisqartmalari |
53
+ | **Biznes** | Referal, broadcast (davom ettirish bilan), statistika, admin panel, majburiy obuna, support, Telegram Stars |
54
+ | **Guruhlar** | `ban`, `mute`, `warn`, captcha |
55
+ | **Mini App** | `@bot.api` endpointlari, initData HMAC tekshiruvi, `nicebot.js` |
56
+ | **Arxitektura** | DI (type hint orqali), middleware, Router, `from_env()`, scheduler, fon vazifalari, kesh |
57
+ | **Ishonchlilik** | Flood-wait, retry, file_id keshi, to'g'ri to'xtash, xatolar haqida adminlarga hisobot |
58
+ | **Ishlab chiqish** | `reload=True`, `bot.test()` (Telegram'siz testlar), CLI |
59
+
60
+ To'liq ro'yxat va qo'llanma: **[hujjatlar sayti](https://ozodmeofficial.github.io/nicebot/)** (uz / ru / en).
61
+
62
+ ## Yana misollar
63
+
64
+ ```python
65
+ from nicebot import Nicebot, Button, Model, fields, Phone
66
+
67
+ bot = Nicebot(token="...", db="sqlite:///shop.db", admins=[123456789])
68
+
69
+ class Order(Model):
70
+ user_id = fields.BigInt(index=True)
71
+ product = fields.Str(100)
72
+ phone = fields.Str(20)
73
+
74
+ async def buy(ctx, product: str):
75
+ phone = await ctx.ask("Telefon raqamingiz?", Phone)
76
+ if await ctx.confirm(f"{product} buyurtma qilinsinmi?"):
77
+ await Order.create(user_id=ctx.user_id, product=product, phone=phone)
78
+ await ctx.reply("✅ Qabul qilindi!")
79
+ await ctx.notify_admins(f"🛒 Yangi buyurtma: {product}, {phone}")
80
+
81
+ @bot.command("shop", description="Do'kon")
82
+ async def shop(ctx):
83
+ await ctx.reply("Mahsulotni tanlang:", buttons=[
84
+ Button("📚 Kitob", on_click=buy, product="Kitob"),
85
+ Button("🎧 Quloqchin", on_click=buy, product="Quloqchin"),
86
+ ])
87
+
88
+ bot.start(reload=True)
89
+ ```
90
+
91
+ Adminlar uchun `/stats`, `/broadcast`, `/maintenance` va `/backup` buyruqlari avtomatik ishlaydi.
92
+
93
+ ## Testlash
94
+
95
+ ```python
96
+ async def test_shop():
97
+ async with bot.test() as t:
98
+ user = t.user(first_name="Ali")
99
+ await user.send("/shop")
100
+ await user.click("Kitob")
101
+ await user.send("90 123 45 67")
102
+ await user.click("Ha")
103
+ assert t.last_in(user.chat_id).text == "✅ Qabul qilindi!"
104
+ ```
105
+
106
+ ## Litsenziya
107
+
108
+ MIT © Ozodbek Sobirjonovich
@@ -0,0 +1,69 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.24"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "nicebot"
7
+ dynamic = ["version"]
8
+ description = "Telegram botlar uchun eng qulay Python kutubxonasi: kam kod, ichki ORM, tugmalar, suhbatlar, Mini App — hammasi bitta importda."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Ozodbek Sobirjonovich" }]
14
+ keywords = ["telegram", "bot", "telegram-bot", "bot-api", "async", "orm", "mini-app", "aiogram-alternative", "uzbek"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Framework :: AsyncIO",
18
+ "Intended Audience :: Developers",
19
+ "Natural Language :: Russian",
20
+ "Natural Language :: English",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3 :: Only",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
28
+ "Topic :: Communications :: Chat",
29
+ "Topic :: Software Development :: Libraries :: Application Frameworks",
30
+ "Typing :: Typed",
31
+ ]
32
+ dependencies = [
33
+ "aiohttp>=3.9",
34
+ "msgspec>=0.18",
35
+ "aiosqlite>=0.19",
36
+ ]
37
+
38
+ [project.optional-dependencies]
39
+ postgres = ["asyncpg>=0.29"]
40
+ mysql = ["aiomysql>=0.2"]
41
+ mongo = ["motor>=3.3"]
42
+ redis = ["redis>=5.0"]
43
+ all = ["asyncpg>=0.29", "aiomysql>=0.2", "motor>=3.3", "redis>=5.0"]
44
+ dev = ["pytest>=8", "pytest-asyncio>=0.23", "mongomock-motor>=0.0.29", "typing-extensions>=4"] # mongomock-motor imports it without declaring it (seen on 3.13)
45
+
46
+ [project.scripts]
47
+ nicebot = "nicebot.cli:main"
48
+
49
+ [project.urls]
50
+ Homepage = "https://ozodmeofficial.github.io/nicebot/"
51
+ Documentation = "https://ozodmeofficial.github.io/nicebot/"
52
+ Repository = "https://github.com/ozodmeofficial/nicebot"
53
+ Issues = "https://github.com/ozodmeofficial/nicebot/issues"
54
+ Changelog = "https://github.com/ozodmeofficial/nicebot/blob/main/CHANGELOG.md"
55
+
56
+ [tool.hatch.version]
57
+ path = "src/nicebot/__about__.py"
58
+
59
+ [tool.hatch.build.targets.wheel]
60
+ packages = ["src/nicebot"]
61
+
62
+ [tool.hatch.build.targets.sdist]
63
+ include = ["src/nicebot", "tests", "README.md", "LICENSE", "CHANGELOG.md", "pyproject.toml"]
64
+
65
+ [tool.pytest.ini_options]
66
+ asyncio_mode = "auto"
67
+ asyncio_default_fixture_loop_scope = "function"
68
+ testpaths = ["tests"]
69
+ pythonpath = ["src"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,60 @@
1
+ """nicebot — Telegram botlar uchun eng qulay Python kutubxonasi.
2
+
3
+ from nicebot import Nicebot
4
+
5
+ bot = Nicebot(token="...")
6
+
7
+ @bot.command("start")
8
+ async def start(ctx):
9
+ name = await ctx.ask("Ismingiz?")
10
+ await ctx.reply(f"Salom, {name}!")
11
+
12
+ bot.start()
13
+ """
14
+ from . import types
15
+ from .__about__ import __version__
16
+ from ._base import InputFile
17
+ from .bot import Nicebot
18
+ from .config import Config, load_env
19
+ from .context import Context, FormResult
20
+ from .errors import (
21
+ AskTimeout,
22
+ BadRequest,
23
+ Cancelled,
24
+ DoesNotExist,
25
+ Forbidden,
26
+ IntegrityError,
27
+ NicebotError,
28
+ RetryAfter,
29
+ SkipHandler,
30
+ StopHandling,
31
+ TelegramError,
32
+ ValidationError,
33
+ )
34
+ from .filters import F, Filter
35
+ from .i18n import I18n
36
+ from .keyboards import Button, ReplyButton, Toggle
37
+ from .menu import Menu
38
+ from .orm import Database, Model, Q, fields
39
+ from .orm import F as Col
40
+ from .orm.builtin import User
41
+ from .router import Router
42
+ from .server import WebAppRequest, validate_init_data
43
+ from .storage import DBStorage, MemoryStorage, RedisStorage, Storage
44
+ from .types import API_VERSION
45
+ from .utils import bold, cache, code, escape, html, italic, link, mention, parse_duration, pre, quote, spoiler, strike, underline
46
+ from .validators import Choice, Date, Email, File, Location, Phone, Photo, Regex, Text, Url
47
+ from .validators import Float as Number
48
+ from .validators import Int as Integer
49
+
50
+ __all__ = [
51
+ "Nicebot", "Router", "Context", "F", "Filter", "Button", "ReplyButton", "Toggle", "Menu",
52
+ "Model", "fields", "Database", "Q", "Col", "User",
53
+ "Phone", "Email", "Date", "Choice", "Regex", "Photo", "File", "Location", "Url", "Text", "Integer", "Number",
54
+ "html", "escape", "bold", "italic", "underline", "strike", "spoiler", "code", "pre", "link", "mention", "quote", "cache", "parse_duration",
55
+ "InputFile", "Config", "load_env", "I18n", "FormResult", "WebAppRequest", "validate_init_data",
56
+ "Storage", "MemoryStorage", "RedisStorage", "DBStorage",
57
+ "NicebotError", "TelegramError", "BadRequest", "Forbidden", "RetryAfter", "Cancelled", "AskTimeout", "ValidationError",
58
+ "SkipHandler", "StopHandling", "DoesNotExist", "IntegrityError",
59
+ "types", "API_VERSION", "__version__",
60
+ ]
@@ -0,0 +1,75 @@
1
+ """Base classes shared by generated types."""
2
+ from __future__ import annotations
3
+
4
+ import io
5
+ import mimetypes
6
+ import os
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ import msgspec
11
+
12
+
13
+ class TelegramObject(msgspec.Struct, kw_only=True, omit_defaults=True, dict=True):
14
+ """Base of every Telegram type. Fast (msgspec), typed, and convertible to dict."""
15
+
16
+ def to_dict(self) -> dict[str, Any]:
17
+ return msgspec.to_builtins(self)
18
+
19
+ def __getitem__(self, item: str) -> Any: # dict-like access for convenience
20
+ return getattr(self, item)
21
+
22
+
23
+ class InputFile:
24
+ """A file to upload: local path, bytes, file-like object or URL.
25
+
26
+ >>> InputFile("photo.jpg")
27
+ >>> InputFile(b"...", filename="report.pdf")
28
+ >>> InputFile.from_url("https://example.com/a.png") # Telegram downloads it
29
+ """
30
+
31
+ __slots__ = ("data", "filename", "url", "path")
32
+
33
+ def __init__(self, data: str | os.PathLike | bytes | io.IOBase, filename: str | None = None):
34
+ self.url: str | None = None
35
+ self.path: Path | None = None
36
+ if isinstance(data, (str, os.PathLike)):
37
+ self.path = Path(data)
38
+ self.data = None
39
+ self.filename = filename or self.path.name
40
+ elif isinstance(data, (bytes, bytearray)):
41
+ self.data = bytes(data)
42
+ self.filename = filename or "file"
43
+ else:
44
+ self.data = data.read()
45
+ self.filename = filename or Path(getattr(data, "name", "file")).name
46
+
47
+ @classmethod
48
+ def from_url(cls, url: str) -> "InputFile":
49
+ obj = cls.__new__(cls)
50
+ obj.url, obj.data, obj.path, obj.filename = url, None, None, url.rsplit("/", 1)[-1]
51
+ return obj
52
+
53
+ def read(self) -> bytes:
54
+ if self.data is not None:
55
+ return self.data
56
+ assert self.path is not None
57
+ return self.path.read_bytes()
58
+
59
+ @property
60
+ def mime(self) -> str:
61
+ return mimetypes.guess_type(self.filename)[0] or "application/octet-stream"
62
+
63
+ @property
64
+ def cache_key(self) -> str | None:
65
+ """Stable key used by the file_id cache (local paths only)."""
66
+ if self.path is None:
67
+ return None
68
+ try:
69
+ st = self.path.stat()
70
+ except OSError:
71
+ return None
72
+ return f"{self.path.resolve()}:{st.st_size}:{int(st.st_mtime)}"
73
+
74
+ def __repr__(self) -> str:
75
+ return f"InputFile({self.filename!r})"