diff --git a/API.md b/API.md index d7ab460..a01061d 100644 --- a/API.md +++ b/API.md @@ -4,11 +4,12 @@ Внутри объекта ведётся учёт скорости отправки запросов к серверу, поэтому важно, чтобы все запросы приложения в отношении одного аккаунта с одного IP-адреса отправлялись из одного экземпляра `Bitrix`. -### Метод ` __init__(self, webhook: str, verbose: bool = True, respect_velocity_policy: bool = True, request_pool_size: int = 50, requests_per_second: float = 2.0, client: aiohttp.ClientSession = None):` +### Метод ` __init__(self, webhook: str, token_func: Awaitable = None, verbose: bool = True, respect_velocity_policy: bool = True, request_pool_size: int = 50, requests_per_second: float = 2.0, ssl: bool = True, client: aiohttp.ClientSession = None):` Создаёт клиента для доступа к Битрикс24. #### Параметры - `webhook: str` - URL вебхука, полученного от сервера Битрикс. +- `token_func: Awaitable = None` - ссылка на асинхронную функцию, возвращающаю OAuth-токен для запросов к серверу. Если не указана, то OAuth-авторизация не используется. - `verbose: bool = True` - показывать прогрессбар при выполнении запроса. - `respect_velocity_policy: bool = True` - соблюдать политику Битрикса о скорости запросов. - `request_pool_size: int = 50` - размер пула запросов, который diff --git a/README.md b/README.md index 8c53d93..a5465ec 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ API wrapper для Питона для быстрого получения да - Высокоуровневые списочные методы для сокращения количества необходимого кода. Большинство операций занимают только одну строку кода. Обработка параллельных запросов, упаковка запросов в батчи и многое другое убрано "под капот". - Позволяет задавать параметры запроса именно в таком виде, как они приведены в [документации к Bitrix24 REST API](https://dev.1c-bitrix.ru/rest_help/index.php). Параметры проверяются на корректность для облегчения отладки. - Выполнение запросов автоматически сопровождается прогресс-баром из пакета `tqdm`, иллюстрирующим не только количество обработанных элементов, но и прошедшее и оставшееся время выполнения запроса. +- При работе с приложениями отслеживает устаревание токена авторизации и автоматически обновляет его через вызов функции, передаваемой пользователем. ### Синхронный и асинхронный клиенты - Наличие асинхронного клиента позволяет использовать библиотеку для написания веб-приложений (например, телеграм-ботов). @@ -160,7 +161,7 @@ results = bx.call_batch ({ ``` ### Асинхронные вызовы -Если требуется использование бибилиотеки в асинхронном коде, то вместо клиента `Bitrix()` создавайте клиент класса `BitrixAsync()`: +Если требуется использование бибилиотеки в асинхронном коде (или в ноутбуках), то вместо клиента `Bitrix()` создавайте клиент класса `BitrixAsync()`: ```python from fast_bitrix24 import BitrixAsync bx = BitrixAsync(webhook) @@ -169,7 +170,30 @@ bx = BitrixAsync(webhook) ```python leads = await bx.get_all('crm.lead.list') ``` -## Как это работает + +### Авторизация через OAuth +Если требуется авторизация через OAuth, то при инициализации клиента `Bitrix()` необходимо передать в параметре `token_func` ссылку на асинхронную функцию, которая будет возвращать токен авторизации: +```python +from fast_bitrix24 import Bitrix +import requests + +async def get_new_token() -> str: + oauth_url = 'https://oauth.bitrix.info/oauth/token/' + params={ + 'grant_type': 'refresh_token', + 'client_id': ..., + 'client_secret': ..., + 'refresh_token': ... + } + result = requests.get(oauth_url, timeout=10, params=params) + return result.json()["access_token"] + +bx = Bitrix(webhook, token_func=get_new_token) +... +``` +`token_func` будет вызываться каждый раз, когда необходимо получить впервые или обновить токен авторизации. + +## Как работает библиотека 1. Перед обращением к серверу во всех методах класса `Bitrix` происходит проверка корректности самых популярных параметров, передаваемых к серверу, и поднимаются исключения `TypeError` и `ValueError` при наличии ошибок. 2. Cоздаются запросы на получение всех элементов из запрошенного списка. 3. Созданные запросы упаковываются в батчи по 50 запросов в каждом. diff --git a/fast_bitrix24/bitrix.py b/fast_bitrix24/bitrix.py index ee7ba46..21d489f 100644 --- a/fast_bitrix24/bitrix.py +++ b/fast_bitrix24/bitrix.py @@ -3,7 +3,7 @@ import asyncio import functools as ft from contextlib import contextmanager -from typing import Iterable, Union, Awaitable +from typing import Awaitable, Iterable, Union import aiohttp import icontract @@ -42,6 +42,8 @@ def __init__( Параметры: - `webhook: str` - URL вебхука, полученного от сервера Битрикс + - `token_func: Awaitable = None` - асинхронная функция для получения + и обновления токена в случае работы с приложениями и OAuth-авторизацией - `verbose: bool = True` - показывать ли прогрессбар при выполнении запроса - `respect_velocity_policy: bool = True` - соблюдать ли политику diff --git a/fast_bitrix24/srh.py b/fast_bitrix24/srh.py index 9fe1a16..3d9be64 100644 --- a/fast_bitrix24/srh.py +++ b/fast_bitrix24/srh.py @@ -178,13 +178,13 @@ async def request_attempt(self, method, params=None) -> dict: params_with_auth = params.copy() if params else {} - if self.token_func: # если требуется авторизация + if self.token_func: # если требуется авторизация # если вдруг процесс получения токена уже запущен, # то подождать его окончания await self.token_request_in_progress.wait() - if not self.token: # начальное получение токена + if not self.token: # начальное получение токена await self.update_token() params_with_auth["auth"] = self.token @@ -317,6 +317,8 @@ async def limit_concurrent_requests(self): async def update_token(self): """Запросить новый токен авторизации.""" + logger.debug("Requesting new token") + self.token_request_in_progress.clear() self.token = await self.token_func() self.token_request_in_progress.set()