### Create AiohttpClient and call request_text Source: https://vkbottle.readthedocs.io/ru/latest/low-level/http-client Shows how to instantiate AiohttpClient and send a text request. The comment '# ...' indicates omitted setup code. The example uses the default session and calls request_text with a URL. ```python from vkbottle.http import AiohttpClient # ... http_client = AiohttpClient() await http_client.request_text("https://google.com") ``` -------------------------------- ### Import aiohttp for async HTTP requests Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Example import of the aiohttp library, necessary for making async HTTP requests. ```python import aiohttp ``` -------------------------------- ### bot.py: Run the bot Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Starts the bot's polling loop. ```python bot.run_forever() ``` -------------------------------- ### Using Formatter and Format with message.answer() Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Examples of using Formatter and Format functions with the BaseMessageMin.answer() method. ```python await message.answer(Formatter("Hello, {:bold}!").format("World")) await message.answer(underline(bold("Hello") + ", " + italic("World!"))) ``` -------------------------------- ### config.py: Initialize API, labeler, and state dispenser Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Creates the global API instance, a BotLabeler, and a BuiltinStateDispenser. The state dispenser is declared for clarity but not used in this example; import it from config.py and pass it to Bot in bot.py if needed. ```python from vkbottle import API, BuiltinStateDispenser from vkbottle.bot import BotLabeler api = API("token") labeler = BotLabeler() state_dispenser = BuiltinStateDispenser() ``` -------------------------------- ### Using formatting functions bold, italic, url Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Examples of using the formatting functions bold, italic, and url to create formatted strings. ```python bold("Hello, ") + italic("World!") # Hello, World! ('Hello, ' is bold, 'World!' is italic) "Hello, " + italic("World!") # Hello, World! ('World!' is italic) bold("Hello") + ", " + italic("World!") # Hello, World! ('Hello' is bold, 'World!' is italic) bold("vkbottle documentation:") + " " + url(italic("click me"), href="vkbottle.readthedocs.io/ru/latest") # vkbottle documentation: click me ('click me' has an url) ``` -------------------------------- ### bot.py: Imports for bot setup Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Imports Bot, the global API, state dispenser, labeler, and the chat and admin labelers. Because handlers/__init__.py exists, the labelers are already imported and no direct import from echo.py is needed. ```python from vkbottle import Bot from config import api, state_dispenser, labeler from handlers import chat_labeler, admin_labeler ``` -------------------------------- ### Async function to GET httpbin.org Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq An async function that makes a GET request to httpbin.org using aiohttp, checking the status and returning the JSON response. ```python async def send_httpbin_get() -> dict[str, Any]: async with aiohttp.ClientSession() as session: async with session.get('http://httpbin.org/get') as r: if r.status == 200: js = await r.json() return js ``` -------------------------------- ### Add a task with LoopWrapper.add_task() Source: https://vkbottle.readthedocs.io/ru/latest/tools/loop-wrapper Creates a LoopWrapper instanceainer sharing a startup task and runs the event loop. The wrapper stores the task and executes it when the loop starts via run_forever. Uses add_task() to register the coroutine. ```python from vkbottle import LoopWrapper async def my_task(): ... lw = LoopWrapper() lw.add_task(my_task()) lw.run() ``` -------------------------------- ### Accessing API via Message.ctx_api Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Shows how to access the API through a Message object using message.ctx_api. The example bot responds to the text 'админы' and retrieves admin info. ```python from vkbottle.bot import Bot, Message bot = Bot(token="token") admin_ids = [1, 100] @bot.on.message(text="админы") async def who_admins(message: Message): admins = [f"{adm.first_name} {adm.last_name}" for adm in (await message.ctx_api.users.get(admin_ids))] print((await message.ctx_api.request("users.get", {"user_ids": admin_ids}))) await message.answer(f"Администраторы этого бота: {' '.join(admins)}") bot.run_forever() ``` -------------------------------- ### Register startup and shutdown coroutines with LoopWrapper Source: https://vkbottle.readthedocs.io/ru/latest/tools/loop-wrapper Appends coroutines to LoopWrapper.on_startup and LoopWrapper.on_shutdown. on_startup coroutines run before the event loop starts; on_shutdown coroutines run when it stops. The lists accept coroutine objects directly. ```python from vkbottle import LoopWrapper async def startup_task(): print("This is startup") async def shutdown_task(): print("This is shutdown") lw = LoopWrapper() lw.on_startup.append(startup_task()) lw.on_shutdown.append(shutdown_task()) lw.run() ``` -------------------------------- ### Good: await inside async function Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Correct example: await is used inside an async function, and the program is started with asyncio.run(). ```python # good import asyncio async def foo() -> str: return "foo" async def main(): print(await foo()) asyncio.run(main()) ``` -------------------------------- ### PayloadMapRule mapping example Source: https://vkbottle.readthedocs.io/ru/latest/high-level/builtin-rules Used to create a payload map that associates expected values and types with the message payload. ```json {"name": "boba", "data": {"action": "do", "number": 12}} ``` ```python PayloadMapRule({"name": str, "data": {"action": str, "number": int}}) ``` -------------------------------- ### Bad: await at module level Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Incorrect example: calling an async function with await at module level raises SyntaxError: 'await' outside function. ```python # bad async def main(): print("main") await main() # SyntaxError: 'await' outside function ``` -------------------------------- ### Bad: await outside async function Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Incorrect example: using await outside an async function raises SyntaxError: 'await' outside async function. ```python # bad async def foo() -> str: return "foo" def main(): print(await foo()) # SyntaxError: 'await' outside async function main() ``` -------------------------------- ### Get user token with UserAuth Source: https://vkbottle.readthedocs.io/ru/latest/tools/auth Basic usage of UserAuth to obtain a user token by login and password. By default, the mobile VK application is used for login and a default set of permissions is requested. ```python from vkbottle import UserAuth login = "89012345678" password = "qwerty123" async def main(): token = await UserAuth().get_token(login, password) ``` -------------------------------- ### run_multibot function signature Source: https://vkbottle.readthedocs.io/ru/latest/high-level/bot/multibot Starts a multibot by adding run_polling tasks to the event loop. The bot parameter does not need a token for API creation; apis can be any iterable, and polling_type can be customized if you have a custom polling implementation. ```python run_multibot(bot, apis, polling_type=BotPolling) ``` -------------------------------- ### Get token with custom scope using UserPermission Source: https://vkbottle.readthedocs.io/ru/latest/tools/auth Obtain a token with a custom permission scope by passing a list of UserPermission values to the scope parameter of get_token. The default scope can be overridden this way. ```python from vkbottle import UserAuth, UserPermission login = "89012345678" password = "qwerty123" async def main(): token = await UserAuth().get_token(login, password, scope=[UserPermission.photos, UserPermission.video]) ``` -------------------------------- ### Custom Request Rescheduler Implementation Source: https://vkbottle.readthedocs.io/ru/latest/low-level/api/request-rescheduler Example of a custom rescheduler that implements the `reschedule` method. It sleeps for a configurable delay and then retries the request using `ctx_api.request`. The method signature includes `ctx_api`, `method`, `data`, and `recent_response` as required by the `ABCRequestRescheduler` interface. ```python import asyncio from typing import TYPE_CHECKING, Any, Union from vkbottle import ABCRequestRescheduler if TYPE_CHECKING: from vkbottle.api import ABCAPI, API class SomeRequestRescheduler(ABCRequestRescheduler): def __init__(self, delay: int = 1): self.delay = delay async def reschedule( self, ctx_api: "ABCAPI | API", method: str, data: dict[str, Any]: recent_response: Any, ) -> dict[str, Any]: await asyncio.sleep(self.delay) return await ctx_api.request(method, data) ``` -------------------------------- ### API Initialization and Usage Source: https://vkbottle.readthedocs.io/ru/latest/low-level/api Initializes the VKBottle API client with a token and demonstrates how to call a method, using snake_case naming. ```APIDOC ## API ### Description Create an API client instance and call VK API methods. Methods are named in snake_case, e.g., `messages.getById` becomes `api.messages.get_by_id`. ### Usage Example ```python from vkbottle import API api = API(token="token") await api.messages.send(peer_id=1, message="Привет Павел Дуров!") ``` ### Parameters - **token** - community/user token or token generator - **ignore_error** - ignore VK API errors - **http_client** - client for requests (documentation) - **request_rescheduler** - request rescheduler (documentation) ``` -------------------------------- ### bot.py: Load labelers and run bot Source: https://vkbottle.readthedocs.io/ru/latest/high-level/bot/labeler Creates a Bot instance, loads each custom labeler from the routes module, and runs the bot. Requires a valid token and the routes module with a labelers list. ```python from vkbottle import Bot from routes import labelers bot = Bot("token") for custom_labeler in labelers: bot.labeler.load(custom_labeler) bot.run_forever() ``` -------------------------------- ### bot.py: Create Bot instance Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Creates the Bot instance, passing the API, the global labeler, and the state dispenser. ```python bot = Bot( api=api, labeler=labeler, state_dispenser=state_dispenser, ) ``` -------------------------------- ### routes/__init__.py: Aggregate labelers Source: https://vkbottle.readthedocs.io/ru/latest/high-level/bot/labeler Imports labelers from greetings and goodbyes modules and exposes them as a list for the main bot to load. ```python from . import greetings, goodbyes labelers = [greetings.bl, goodbyes.bl] ``` -------------------------------- ### Formatter.format with positional and keyword arguments Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Shows how to use the format method with *args and **kwargs to replace {} placeholders. ```python Formatter("Hi, {}.").format("Alex") # Hi, Alex. Formatter("Hi, {name}.").format(name="Maria") # Hi, Maria. ``` -------------------------------- ### Good: Using AiohttpClient Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Shows the recommended approach using vkbottle's AiohttpClient for non-blocking HTTP requests. ```python # good, recommended # see https://vkbottle.rtfd.io/ru/latest/low-level/http-client/ from vkbottle.http import AiohttpClient async def send_httpbin_get() -> dict[str, Any]: http_client = AiohttpClient() return await http_client.request_json('http://httpbin.org/get') ``` -------------------------------- ### __init__.py: Import labelers and define __all__ Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Imports all labelers from the handlers package and defines __all__. The comment notes that handlers are registered in import order when using the global labeler. ```python from .chat import chat_labeler from .admin import admin_labeler from .ping import labeler # Если использовать глобальный лейблер, то все хендлеры будут зарегистрированы в том же порядке, в котором они были импортированы __all__ = ("admin_labeler", "chat_labeler", "labeler") ``` -------------------------------- ### Await an async function to get its result Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Shows that calling an async function without await returns a coroutine object, while await executes it and returns the result. Run with asyncio.run(). ```python import asyncio async def get_banana() -> str: return "banana" async def main(): print(get_banana()) # print(await get_banana()) # banana asyncio.run(main()) ``` -------------------------------- ### Initialize API and send message Source: https://vkbottle.readthedocs.io/ru/latest/low-level/api Initialize the VK API client with a token and send a message. All methods use snake_case, e.g., messages.getById becomes api.messages.get_by_id. ```python from vkbottle import API # ... api = API(token="token") await api.messages.send(peer_id=1, message="Привет Павел Дуров!") ``` -------------------------------- ### Handle captcha and 2FA errors when getting token Source: https://vkbottle.readthedocs.io/ru/latest/tools/auth Handles captcha, SMS 2FA, and 2FA app validation during token retrieval. Uses CaptchaError, APIAuthError, and AuthError exceptions, and calls validate_phone for SMS validation. ```python from __future__ import annotations import asyncio from typing import TYPE_CHECKING, cast from urllib.parse import parse_qs, urlparse from vkbottle import APIAuthError, AuthError, CaptchaError, UserAuth if TYPE_CHECKING: from typing import Optional, Union login = "89012345678" password = "qwerty123" async def main(): user_auth = UserAuth() auth_code: bool | str = True captcha_sid: str | None = None captcha_key: str | None = None while True: try: token = await user_auth.get_token( login, password, auth_code=auth_code, captcha_sid=captcha_sid, captcha_key=captcha_key ) break except CaptchaError as error: captcha_sid = error.captcha_sid captcha_key = input(f"Open url '{error.captcha_img}' in browser and enter captcha code: ") except APIAuthError as error: if error.validation_type == "2fa_sms": validation_sid = cast(str, error.validation_sid) await user_auth.validate_phone(validation_sid) auth_code = input("Enter code from SMS: ") continue if error.validation_type == "2fa_app": print(f"Enter code from 2FA app here: {error.redirect_uri}") oauth_url = input("Enter OAuth URL from VK after signin in: ") parsed_url = urlparse(url=oauth_url) token = parse_qs(parsed_url.fragment)["access_token"][0] break print(error.error_description) return except AuthError as error: print(error.error_description) return print(f"Your token: {token}") ``` -------------------------------- ### Использование шортката command для правила Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/rules Использует шорткат command в декораторе @bot.on.message. Параметры правила передаются в кортеже: команда и количество аргументов. Хендлер получает аргументы как кортеж. ```python @bot.on.message(command=("say", 1)) async def say_handler(message: Message, args: tuple[str]): await message.answer(f"<<{args[0]}>>") ``` -------------------------------- ### Define states and handle messages with StateRule Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/state-dispenser Shows how to define a state group with BaseStateGroup, set a state using bot.state_dispenser.set, and handle messages with a state rule. The handler for state SuperStates.AWKWARD_STATE responds with 'oi awkward', and the /die command sets that state and returns 'ok'. ```python from vkbottle import BaseStateGroup from vkbottle.bot import Message, Bot bot = Bot("t") class SuperStates(BaseStateGroup): AWKWARD_STATE = "awkward" CONFIDENT_STATE = "confident" TERRIFYING_STATE = "terrifying" @bot.on.message(state=SuperStates.AWKWARD_STATE) # StateRule(SuperStates.AWKWARD_STATE) async def awkward_handler(message: Message): await message.answer("oi awkward") @bot.on.message(lev="/die") async def die_handler(message: Message): await bot.state_dispenser.set(message.peer_id, SuperStates.AWKWARD_STATE) return "ok" bot.run_forever() ``` -------------------------------- ### Инициализация бота с callback Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/callback-bot Инициализация бота с токеном и callback-объектом. ```python from vkbottle import Bot bot = Bot(token=TOKEN, callback=callback) ``` -------------------------------- ### Инициализация параметров CallbackAPI Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/callback-bot Инициализация параметров для настройки CallbackAPI: токен сообщества, URL, заголовок и опциональный секретный ключ. Значения берутся из переменных окружения. ```python import os TOKEN = os.getenv("VK_TOKEN") # ключ сообщества url = os.getenv("VK_URL") # url = "http://example.com/whateveryouwnant" title = os.getenv("VK_TITLE") # title = "server" secret_key = os.getenv("VK_SECRET_KEY") # опционально ``` -------------------------------- ### Custom Response Validator with ABCResponseValidator Source: https://vkbottle.readthedocs.io/ru/latest/low-level/api/response-validator Example of creating a custom response validator that handles VK API error code 6 (too many requests) by rescheduling the request. It must be inserted after JSONResponseValidator but before VKAPIErrorResponseValidator to avoid handling the error prematurely. ```python from typing import TYPE_CHECKING, Any, NoReturn, Union from vkbottle import API, ABCResponseValidator from .request_rescheduler import SomeRequestRescheduler if TYPE_CHECKING: from vkbottle.api import ABCAPI, API class SomeResponseValidator(ABCResponseValidator): async def validate( self, method: str, data: dict[str, Any]: response: Any, ctx_api: "ABCAPI | API", ) -> Any | NoReturn: if "error" not in response: return response if ctx_api.ignore_errors: return None if response["error"]["error_code"] != 6: return response # Обрабатываем ошибку 6, которая возникает при слишком частых запросах return await SomeRequestRescheduler().reschedule( ctx_api, method, data, response ) api = API("token") # Этот валидатор должен идти после JSONResponseValidator, # но раньше VKAPIErrorResponseValidator, чтобы он не обработал эту ошибку api.response_validators.insert(1, SomeResponseValidator()) ``` -------------------------------- ### bot.py: Load labelers into global labeler Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Loads the chat and admin labelers into the global labeler so their handlers are registered. ```python labeler.load(chat_labeler) labeler.load(admin_labeler) ``` -------------------------------- ### Convert Python function to VKScript with @vkscript decorator Source: https://vkbottle.readthedocs.io/ru/latest/tools/vkscript Use the @vkscript decorator from vkbottle to wrap a function that uses the api object. The function's logic is converted to VKScript code, which can be executed via api.execute(). The example shows sending messages to multiple users and returning message IDs. ```python from vkbottle import vkscript @vkscript def my_execute(api, user_ids=()): message_ids = [] for user_id in user_ids: user = api.users.get(user_ids=user_id)[0] message_ids.append(api.messages.send(message=f"{user.first_name}, спасибо что зашел на чай", random_id=0, peer_id=user_id)) return message_ids # далее вызывая эту функцию вы можете использовать ее ответ в качестве кода для execute await api.execute(code=my_execute(user_ids=[10, 11, 12])) ``` -------------------------------- ### Запуск обернутой функции через asyncio.run Source: https://vkbottle.readthedocs.io/ru/latest/low-level/exception_handling/error-handler Запускает асинхронную функцию main с помощью asyncio.run, что приводит к обработке исключения LookupError и выводу сообщения. ```python import asyncio asyncio.run(main()) ``` -------------------------------- ### Import Formatter from vkbottle.tools.formatting Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Import statement for the Formatter class used for formatted text. ```python from vkbottle.tools.formatting import Formatter ``` -------------------------------- ### Basic bot message handler with vkbottle Bot Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/handler Creates a vkbottle bot with a token and registers a blocking handler for all messages using @bot.on.message(). The handler replies with a greeting. Run with bot.run_forever(). ```python from vkbottle.bot import Bot, Message bot = Bot("token") @bot.on.message() async def any_message(message: Message): await message.answer("Привет я бот") bot.run_forever() ``` -------------------------------- ### admin.py: Admin labeler with FromPeerRule and halt command Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Defines an admin labeler restricted to a specific user ID via FromPeerRule(1). The handler for the "halt" command exits the process. ```python from vkbottle.bot import BotLabeler, Message, rules admin_labeler = BotLabeler() admin_labeler.auto_rules = [rules.FromPeerRule(1)] # Допустим, вы являетесь Павлом Дуровым @admin_labeler.message(command="halt") async def halt(_): exit(0) ``` -------------------------------- ### Import Format from vkbottle.tools.formatting Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Import statement for the Format class used to represent formatting types. ```python from vkbottle.tools.formatting import Format ``` -------------------------------- ### Set vkbottle logging level with logging Source: https://vkbottle.readthedocs.io/ru/latest/modules Set the logging level for the 'vkbottle' logger to INFO using the standard logging library. ```python import logging logging.getLogger("vkbottle").setLevel(logging.INFO) ``` -------------------------------- ### Использование CommandRule из vkbottle.dispatch.rules.base Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/rules Импортирует CommandRule и использует его в декораторе @bot.on.message. Правило принимает команду, префиксы и количество аргументов. Хендлер получает аргументы как кортеж. ```python from vkbottle.dispatch.rules.base import CommandRule @bot.on.message(CommandRule("say", ["!", "/"], 1)) async def say_handler(message: Message, args: tuple[str]): await message.answer(f"<<{args[0]}>>") ``` -------------------------------- ### Formatter.format_map with Mapping argument Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Demonstrates the format_map method which accepts a Mapping argument. ```python Formatter("My bestie is {bestie:underline}").format_map({"bestie": "telegrinder") # My bestie is telegrinder ``` -------------------------------- ### Combine formatting types with '+' Source: https://vkbottle.readthedocs.io/ru/latest/tools/formatting Shows how to combine multiple formatting types using the '+' symbol. ```python Formatter("Very cool {:bold+italic} ^_^").format("bold-italic message") # Very cool bold-italic message ^_^ ``` -------------------------------- ### Set state with payload and access it Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/state-dispenser Shows how to pass a payload to state_dispenser.set and later access it via message.state_peer.payload. The payload key 'something' is set to 1 and then printed. ```python # ... In handler: await bot.state_dispenser.set(message.peer_id, SuperStates.TERRIFYING_STATE, something=1) # ... With state: print(message.state_peer.payload["something"]) # 1 ``` -------------------------------- ### Кастомизация MyRule через __init__ Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/rules Добавляет параметр lt (по умолчанию 100) в конструктор правила. Метод check сравнивает длину текста с self.lt. ```python # Новый вид правила class MyRule(ABCRule[Message]): def __init__(self, lt: int = 100): self.lt = lt async def check(self, event: Message) -> bool: return len(event.text) < self.lt ``` -------------------------------- ### Инициализация Bot токеном или API Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/first-bot Два способа инициализации бота: токеном (создаётся API с генератором токена) или готовым API. ```python # Инициализация токеном bot = Bot(token="token") # (или) Инициализация с апи bot = Bot(api=api) ``` -------------------------------- ### AiohttpClient Source: https://vkbottle.readthedocs.io/ru/latest/low-level/http-client The default HTTP client implementation using aiohttp. It supports methods for raw requests, text, JSON, and content. Initialization accepts optional session, json processing module, optimize flag, and session parameters. ```APIDOC ## AiohttpClient ### Description AiohttpClient is the default HTTP client in vkbottle, built on aiohttp. It always uses the same session and supports methods to perform raw requests, retrieve text, parse JSON, and fetch binary content. ### Methods #### request_raw ##### Description Performs an HTTP request and returns an `aiohttp.ClientResponse` object. ##### Parameters - `url` (str) - Required - The URL to request. - `method` (str) - Required - HTTP method (e.g., 'get'). - `data` (any, optional) - Data to send in the request. - `**kwargs` - Additional parameters passed to the request. ##### Returns - `aiohttp.ClientResponse` - The response object. #### request_text ##### Description Performs an HTTP request and returns the response text as a string. ##### Parameters Same as `request_raw`. ##### Returns - `str` - The response text. #### request_json ##### Description Performs an HTTP request and deserializes the JSON response using a chosen JSON library (json, ujson, hyperjson, or orjson). Returns a dictionary. ##### Parameters Same as `request_raw`. ##### Returns - `dict` - The deserialized JSON response. #### request_content ##### Description Performs an HTTP request and returns the raw content bytes, used for downloading media files. ##### Parameters Same as `request_raw`. ##### Returns - `bytes` - The response content. ### Initialization Parameters - `session` (aiohttp.ClientSession, optional) - Session object; if not provided, a new session is created. - `json_processing_module` (module, optional) - Module for JSON deserialization; if not provided, one of the available modules is used. - `optimize` (bool, optional) - If True, passes `raise_for_status=True` and `skip_auto_headers={"User-Agent"}` to the session constructor. - `**session_params` - Additional keyword arguments passed to the session constructor (e.g., headers, cookies). ### Example ```python from vkbottle.http import AiohttpClient # ... http_client = AiohttpClient() await http_client.request_text("https://google.com") ``` ``` -------------------------------- ### Using api.request and api.request_many for custom methods Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Demonstrates how to use API.request for a single request and API.request_many for multiple requests in one session. The response is a dictionary, not a typed object. ```python import asyncio from vkbottle.api import API api = API("token") async def main(): await api.request("users.get", {}) # Single request # Multiple request for one session async for response in api.request_many( [api.APIRequest("users.get", {}), api.APIRequest("groups.get", {})] ): print(response) asyncio.run(main()) ``` -------------------------------- ### Good: Using asyncio.sleep() Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Shows the recommended alternative using asyncio.sleep() to avoid blocking the event loop. ```python # good await asyncio.sleep(10) ``` -------------------------------- ### Регистрация мидлварей Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/middlewares-return-managers Регистрация мидлварей в MessageView через метод register_middleware, который также можно использовать как декоратор. ```python bot.labeler.message_view.register_middleware(NoBotMiddleware) bot.labeler.message_view.register_middleware(LogMiddleware) ``` -------------------------------- ### Импорт Keyboard Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/keyboards-attachments Импорт класса Keyboard из библиотеки vkbottle. ```python from vkbottle import Keyboard ``` -------------------------------- ### Using bot.api.request and bot.api.request_many Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq For bots, the API class is part of the Bot class and does not need separate initialization. Shows the same custom method usage with bot.api.request and bot.api.request_many. ```python import asyncio from vkbottle.bot import Bot bot = Bot("token") async def main(): print(await bot.api.request("users.get", {})) # Single request # Multiple request for one session async for response in bot.api.request_many( [bot.api.APIRequest("users.get", {}), bot.api.APIRequest("groups.get", {})] ): print(response) asyncio.run(main()) ``` -------------------------------- ### Обработка VKAPIError без кода Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/error-handling Обрабатывает любую ошибку API ВКонтакте с помощью общего исключения VKAPIError. При выполнении этого кода без обязательных параметров ВКонтакте вернёт ошибку, которая будет перехвачена и выведена с кодом ошибки. ```python try: await api.wall.post() except VKAPIError as e: print("Возникла ошибка", e.code) ``` -------------------------------- ### routes/greetings.py: Greeting handler Source: https://vkbottle.readthedocs.io/ru/latest/high-level/bot/labeler Defines a BotLabeler with a message handler for greeting texts. Responds with 'Привет, друг'. ```python from vkbottle.bot import BotLabeler, Message bl = BotLabeler() @bl.message(text=["привет", "хай", "здравствуй"]) async def greeting(message: Message): await message.answer("Привет, друг") ``` -------------------------------- ### Обработка VKAPIError с новым синтаксисом CodeException Source: https://vkbottle.readthedocs.io/ru/latest/whats_new/4.0 Пример обработки ошибок VKAPIError с указанием кода ошибки в квадратных скобках. Показывает перехват конкретных ошибок (5, 30) и общий обработчик. ```python async def main(): try: await api.users.get(user_ids=["123456789"]) except VKAPIError[5]: print("Ой, неверный ключ доступа.") except VKAPIError[30]: print("Ой, у пользователя закрытый профиль.") except VKAPIError as e: print(f"Произошла ошибка {e.code}.") ``` -------------------------------- ### Создание поста через API.wall.post Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/first-bot Создаёт пост на стене группы или пользователя с указанным текстом. Параметры запроса передаются как аргументы; для их получения используйте подсказки IDE. ```python api = API("token") await api.wall.post(message="#vkbottle прекрасен!") ``` -------------------------------- ### StateRule Usage Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/state-dispenser How to use StateRule to handle messages based on user state. ```APIDOC ## StateRule ### Description A rule used in handlers to filter messages based on the user's current state. ### Usage Pass the state as an argument to the handler decorator, e.g., `@bot.on.message(state=SuperStates.AWKWARD_STATE)`. ### Example ```python from vkbottle import BaseStateGroup from vkbottle.bot import Message, Bot bot = Bot("t") class SuperStates(BaseStateGroup): AWKWARD_STATE = "awkward" CONFIDENT_STATE = "confident" TERRIFYING_STATE = "terrifying" @bot.on.message(state=SuperStates.AWKWARD_STATE) # StateRule(SuperStates.AWKWARD_STATE) async def awkward_handler(message: Message): await message.answer("oi awkward") @bot.on.message(lev="/die") async def die_handler(message: Message): await bot.state_dispenser.set(message.peer_id, SuperStates.AWKWARD_STATE) return "ok" bot.run_forever() ``` ``` -------------------------------- ### Регистрация хендлеров и подключение VoteView Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/view Регистрирует хендлеры для VoteView с помощью FromFuncHandler и подключает view через кастомный BotLabeler. В методе views возвращается словарь с view, который будет обрабатываться роутером. Используется правило FuncRule для фильтрации админов. ```python from vkbottle.bot import Bot, rules, BotLabeler from vkbottle.dispatch.handlers import FromFuncHandler from vkbottle_types.events.bot_events import PollVoteNew async def vote_up(vote: PollVoteNew): print( "{} со стейтом {} голосует за {}".format( vote.object.user_id, vote.object.state_peer, vote.object.option_id ) ) async def vote_up_admin(vote: PollVoteNew): print("Админ проголосовал за {}", vote.object.option_id) my_view = VoteView() my_view.handlers = [ FromFuncHandler( vote_up_admin, rules.FuncRule(lambda v: v.object.user_id in admin_ids), ), FromFuncHandler(vote_up), ] class MyLabeler(BotLabeler): def views(self) -> dict[str, "ABCView"]: # Из views должны быть возвращены все view которые # будут позже обрабатываться роутером return {"vote_view": my_view} bot = Bot() bot.labeler = MyLabeler() admin_ids = [1] ``` -------------------------------- ### ping.py: Simple ping handler Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/code-separation Defines a simple handler that responds with "pong" when a message with text "ping" is received. Uses the global labeler imported from config.py. ```python from config import labeler @labeler.message(text="ping") async def ping_handler(message): await message.answer("pong") ``` -------------------------------- ### Отправка вложения из загрузчика Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/keyboards-attachments Пример отправки вложения, загруженного динамически с помощью загрузчика. Требуется предварительно создать загрузчик (например, AnyUploader). ```python uploader = AnyUploader(bot.api) # see uploaders types in "Uploaders documentation" above @bot.on.message() async def send_attachment(message): attachment = await uploader.upload("path/to/file") await message.answer("See that attachment!", attachment=attachment) ``` -------------------------------- ### Запуск асинхронной функции через asyncio.run Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/first-bot Базовая обёртка для запуска асинхронного кода, необходимая для выполнения запросов к API. ```python import asyncio async def main(): ... asyncio.run(main()) ``` -------------------------------- ### Первый запрос к API (итоговый код) Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/first-bot Полный пример первого запроса к API с инициализацией и запуском через asyncio.run. ```python import asyncio from vkbottle import API async def main(): api = API("token") await api.wall.post(message="#vkbottle прекрасен!") asyncio.run(main()) ``` -------------------------------- ### API methods with snake_case Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Shows the difference between official VK API methods (camelCase) and vkbottle's snake_case. The API class is initialized with a token, then methods like account.ban and account.get_banned are called asynchronously. ```python from vkbottle.api import API api = API("token") # https://api.vk.ru/method/account.ban await api.account.ban(owner_id=1) # https://api.vk.ru/method/account.getBanned await api.account.get_banned(offset=0, count=1) ``` -------------------------------- ### Создание ErrorHandler и регистрация обработчиков исключений Source: https://vkbottle.readthedocs.io/ru/latest/low-level/exception_handling/error-handler Создает экземпляр ErrorHandler с параметрами redirect_arguments=False и raise_exceptions=False. Регистрирует асинхронные обработчики для RuntimeError и LookupError через декоратор register_error_handler. ```python from vkbottle import ErrorHandler error_handler = ErrorHandler(redirect_arguments=False, raise_exceptions=False) # Если redirect_arguments = True, то все аргументы обернутой функции будут поступать и в хендлер исключения # Если raise_exceptions = True, то все необработанные исключения будут выброшены (игнорируется, если есть обработчик для ненайденных ошибок) @error_handler.register_error_handler(RuntimeError) async def exc_handler_runtime(e: RuntimeError): print("Oh no runtime error occurred:", e) @error_handler.register_error_handler(LookupError) async def exc_handler_lookup(e: LookupError): print("Oh no lookup error occurred:", e) ``` -------------------------------- ### ABCHTTPClient Source: https://vkbottle.readthedocs.io/ru/latest/low-level/http-client Abstract base class for HTTP clients. Custom clients should inherit from this class and implement the methods: request_raw, request_text, request_json, and request_content. ```APIDOC ## ABCHTTPClient ### Description Abstract base class for HTTP clients in vkbottle. Custom clients must inherit from this class and implement the abstract methods `request_raw`, `request_text`, `request_json`, and `request_content`. ### Methods to Implement - `request_raw` - Performs an HTTP request and returns the raw response. - `request_text` - Performs an HTTP request and returns the response text. - `request_json` - Performs an HTTP request and returns the deserialized JSON. - `request_content` - Performs an HTTP request and returns the response content as bytes. ``` -------------------------------- ### State and Payload Access Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/state-dispenser How to access the state and payload from event objects. ```APIDOC ## Accessing State and Payload ### Description How to retrieve the current state and payload from an event object. ### Accessing State Use `event.state_peer.state` to get the current state. ### Accessing Payload Use `message.state_peer.payload` to get the payload dictionary. ### Example ```python # ... In handler: await bot.state_dispenser.set(message.peer_id, SuperStates.TERRIFYING_STATE, something=1) # ... With state: print(message.state_peer.payload["something"]) # 1 ``` ``` -------------------------------- ### Define a middleware with BaseMiddleware[Message] Source: https://vkbottle.readthedocs.io/ru/latest/high-level/handling/middleware Defines a custom middleware class that inherits from BaseMiddleware with the Message event type specified in the generic. The constructor accepts the event, and pre/post methods can use self.stop() and self.send() to control execution. ```python from vkbottle import BaseMiddleware from vkbottle.bot import Message class MyMiddleware(BaseMiddleware[Message]): ... ``` -------------------------------- ### Использование FuncRule через шорткат func Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/rules Заменяет прямое правило MyRule на шорткат func с лямбда-функцией, проверяющей длину сообщения. ```python @bot.on.message(func=lambda message: len(message.text) < 100) ``` -------------------------------- ### VBMLRule: конструктор Source: https://vkbottle.readthedocs.io/ru/latest/high-level/builtin-rules Конструктор правила для парсинга текстов сообщений с помощью vbml-паттерна. ```python VBMLRule( pattern, patcher = None, flags = None ) ``` -------------------------------- ### Импорт API из vkbottle Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/first-bot Необходим для взаимодействия с VK API. Его удобство в vkbottle — полная типизация, доступная через vkbottle/types. ```python from vkbottle import API ``` -------------------------------- ### PhotoMessageUploader - загрузка фото в сообщение Source: https://vkbottle.readthedocs.io/ru/latest/tools/uploaders Пример использования PhotoMessageUploader для загрузки фото в сообщение. Создает бота, регистрирует обработчик сообщения, загружает файл photo.png и отправляет его как вложение. ```python from vkbottle import PhotoMessageUploader from vkbottle.bot import Bot bot = Bot("token") photo_uploader = PhotoMessageUploader(bot.api) @bot.on.message(text="photo") async def handler(message): photo = await photo_uploader.upload( file_source="photo.png", peer_id=m.peer_id, ) await message.answer(attachment=photo) bot.run_forever() ``` -------------------------------- ### Отправка клавиатуры через get_json() Source: https://vkbottle.readthedocs.io/ru/latest/tools/keyboard Отправляет сообщение с клавиатурой, используя метод get_json() для получения JSON-представления клавиатуры. ```python await message.answer(message="Смотри сколько кнопок!!", keyboard=keyboard.get_json()) ``` -------------------------------- ### Импорт Bot из vkbottle.bot Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/first-bot Импорт класса Bot для групп. Для юзербота используйте другой подход. ```python from vkbottle.bot import Bot ``` -------------------------------- ### Новый способ обработки MessageEvent через show_snackbar Source: https://vkbottle.readthedocs.io/ru/latest/tools/message-event Регистрирует обработчик на событие GroupEventType.MESSAGE_EVENT с датаклассом MessageEvent. Вместо object данные сразу находятся в event, вместе с group_id. При вызове event.show_snackbar показывается всплывающее уведомление. ```python from vkbottle import GroupEventType from vkbottle.bot import MessageEvent @bot.on.raw_event(GroupEventType.MESSAGE_EVENT, dataclass=MessageEvent) async def handle_message_event(event: MessageEvent): await event.show_snackbar("Сейчас я исчезну") ``` -------------------------------- ### Импорт BaseMiddleware и Message Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/middlewares-return-managers Импортируйте абстрактный класс BaseMiddleware и класс Message из vkbottle.bot для создания мидлвари. ```python from vkbottle import BaseMiddleware from vkbottle.bot import Message ``` -------------------------------- ### Bad: Using requests in async code Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/faq Demonstrates the incorrect use of the synchronous requests library inside an async function, which can block the bot. ```python # bad async def send_httpbin_get() -> dict[str, Any]: r = requests.get('http://httpbin.org/get') if r.status_code == 200: js = r.model_dump_json() return js ``` -------------------------------- ### Импорт компонентов для template_gen Source: https://vkbottle.readthedocs.io/ru/latest/tools/template Импортирует TemplateElement и template_gen из vkbottle для создания шаблонов. ```python from vkbottle import TemplateElement, template_gen ``` -------------------------------- ### Простейший пример с WaiterMachine Source: https://vkbottle.readthedocs.io/ru/latest/tools/waiter-machine Базовый пример использования WaiterMachine: ожидание сообщения от того же пользователя и ответ с именем. Из .wait возвращается tuple с объектом события и контекстом. ```python from vkbottle.bot import Bot, Message from vkbottle.tools import WaiterMachine bot = Bot("...") wm = WaiterMachine() @bot.on.message(text="/wm") async def greeting(message: Message): await message.answer("Как тебя зовут?") # Следующая строчка остановит выполнение хендлера, # и исполнение пойдет дальше только когда будет получено # сообщение соответствующее заданным правилам # (в данном случае просто от того же пользователя) m, _ = await wm.wait(bot.on.message_view, message) await message.answer(f"Привет, {m.text.capitalize()}! Будем знакомы.") bot.run_forever() ``` -------------------------------- ### Отправка вложения по ссылке Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/keyboards-attachments Пример отправки вложения, если у вас уже есть ссылка на него вида "type{OWNER_ID}_{ITEM_ID}". ```python attachment = ... # see example above @bot.on.message async def send_attachment(message): await message.answer("See that attachment!", attachment=attachment) ``` -------------------------------- ### Использование MyRule в декораторе Source: https://vkbottle.readthedocs.io/ru/latest/tutorial/rules Применяет правило MyRule в декораторе @bot.on.message. Правило используется без параметров. ```python @bot.on.message(MyRule()) ```