nicebot 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.
nicebot/__about__.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
nicebot/__init__.py ADDED
@@ -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
+ ]
nicebot/_base.py ADDED
@@ -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})"