Metadata-Version: 2.4
Name: moysklad-api-client
Version: 0.1.1
Summary: Lightweight MoySklad API client built on httpx with retries
License: Apache-2.0
License-File: LICENSE
Keywords: moysklad
Requires-Python: >=3.9,<4.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Dist: httpx (>=0.28.1,<0.29.0)
Description-Content-Type: text/markdown

# moysklad-api-client

Лёгкий **асинхронный Python-клиент** для работы с [MoySklad API](https://dev.moysklad.ru/doc/api/remap/1.2/), основанный на [`httpx`](https://www.python-httpx.org/).

Поддерживает:
- Автоматический **ретрай** при ответах `429` и `503` с **экспоненциальной паузой (exponential backoff)**;  
- **DSL** для сборки URL-запросов;
- Парсер ответов API с безопасным доступом к данным.

---

##  Установка

**pip**
```bash
pip install moysklad-api-client
```

**poetry**
```bash
poetry add moysklad-api-client
```

---

## ⚙️ Использование

### Работа через контекстный менеджер
```python
import asyncio
from moysklad_api_client import APIClient

async def main():
    async with APIClient() as client:
        response = await client.get('api_key', 'url', {'limit': 10})
        print(response.status_code, response.json())

asyncio.run(main())
```

### Работа напрямую через экземпляр класса
```python
import asyncio
from moysklad_api_client import APIClient

async def main():
    client = APIClient()
    response = await client.get(
        api_key='api_key',
        url='url',
        params={'limit': 1, 'offset': 100}
    )
    print(response.json())

asyncio.run(main())
```

---

##  URLbuilder — генерация URL и параметров запроса

Простой DSL для построения цепочки фильтров, параметров и ссылок на сущности.

```python
from moysklad_api_client.msurlbuilder import URLbuilder, MSObject

builder = (
    URLbuilder(ms_object_type=MSObject.customerorder)
    .expand('demands.salesChannel', 'invoicesOut')
    .limit(100)
    .filter('agent').eq('agent_id')
    .filter('moment').gt('2025-09-11').filter('moment').lt('2025-10-12')
    .offset(10)
)

print(builder.url)
print(builder.encode_url(include_params=True))
print(builder.params)

# Пример построения ссылки на конкретный документ
url = URLbuilder().document(MSObject.product).document_id('id').url
```

---

##  MSObject — перечисление сущностей API

Класс `MSObject` содержит `Enum` всех доступных сущностей API.

```python
from moysklad_api_client.msurlbuilder import URLbuilder, MSObject

print(MSObject.available_list())   # Все доступные типы сущностей

builder = URLbuilder()
print(builder.available_documents) # Документы, доступные через builder
```

---

##  BaseEntityParser — удобный парсер ответов API

```python
import asyncio
from moysklad_api_client import APIClient
from moysklad_api_client.msurlbuilder import URLbuilder, MSObject
from moysklad_api_client.msparser import BaseEntityParser

async def main():
    async with APIClient() as client:
        url = URLbuilder(MSObject.demand).document_id('demand_id').url
        response = await client.get(api_key='api_key', url=url)

        data = BaseEntityParser(response)
        print(data.meta)
        print(data.type)
        print(data.external_code)

        # Безопасный доступ к вложенным данным
        print(data.get_value('rate', 'currency', 'meta'))

asyncio.run(main())
```

---

## Примечания
- Все запросы выполняются асинхронно, синхронного клиента нет.
- При ответах `429` и `503` выполняются повторные попытки с увеличивающимся интервалом ожидания.
- Совместим с Python `3.9+`.

---

https://github.com/redschuhart/MoySklad-API-client

