from __future__ import annotations
import requests
from .auth import OAuthConfig
from .client import AmoCRM
from .exceptions import AmoCRMTokenRefreshError
_client: AmoCRM | None = None
[документация]
def exchange_code(subdomain: str, code: str, oauth: OAuthConfig) -> None:
"""Обменять код авторизации на токены и инициализировать глобальный клиент.
После успешного обмена глобальный клиент готов к работе;
повторный вызов :func:`get_client` вернёт уже созданный экземпляр.
Args:
subdomain: Поддомен аккаунта AmoCRM (например, ``"mycompany"``).
code: Одноразовый код авторизации из callback-запроса OAuth 2.0.
oauth: Конфигурация OAuth с реквизитами интеграции и хранилищем токенов.
Raises:
AmoCRMTokenRefreshError: Если обмен кода на токены завершился ошибкой.
"""
global _client
resp = requests.post(
f"https://{subdomain}.amocrm.ru/oauth2/access_token",
json={
"client_id": oauth.client_id,
"client_secret": oauth.client_secret,
"grant_type": "authorization_code",
"code": code,
"redirect_uri": oauth.redirect_uri,
},
)
if not resp.ok:
raise AmoCRMTokenRefreshError(
f"Authorization code exchange failed {resp.status_code}: {resp.text}"
)
data = resp.json()
oauth.storage.save(data["access_token"], data["refresh_token"])
_client = AmoCRM(subdomain=subdomain, oauth=oauth)
[документация]
def get_client(subdomain: str, oauth: OAuthConfig) -> AmoCRM:
"""Вернуть глобальный клиент, создав его из хранилища при первом вызове.
При первом вызове создаёт :class:`~amocrm.client.AmoCRM`, загружая
токены из ``oauth.storage``. Последующие вызовы возвращают тот же экземпляр.
Args:
subdomain: Поддомен аккаунта AmoCRM.
oauth: Конфигурация OAuth с реквизитами интеграции и хранилищем токенов.
Returns:
Инициализированный экземпляр :class:`~amocrm.client.AmoCRM`.
"""
global _client
if _client is None:
_client = AmoCRM(subdomain=subdomain, oauth=oauth)
return _client
[документация]
def reset() -> None:
"""Сбросить глобальный клиент (полезно в тестах)."""
global _client
_client = None