assistagro-client 0.3.1__tar.gz
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.
- assistagro_client-0.3.1/PKG-INFO +171 -0
- assistagro_client-0.3.1/README.md +155 -0
- assistagro_client-0.3.1/pyproject.toml +39 -0
- assistagro_client-0.3.1/setup.cfg +4 -0
- assistagro_client-0.3.1/src/assistagro_client/__init__.py +20 -0
- assistagro_client-0.3.1/src/assistagro_client/api/__init__.py +1 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/__init__.py +1 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/accounts.py +42 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/companies.py +108 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/dictionaries.py +691 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/fields.py +147 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/meteostations.py +152 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/reports.py +157 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/seasons.py +99 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/structures.py +53 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/tasks.py +135 -0
- assistagro_client-0.3.1/src/assistagro_client/api/v1/techmaps.py +71 -0
- assistagro_client-0.3.1/src/assistagro_client/auth.py +114 -0
- assistagro_client-0.3.1/src/assistagro_client/client.py +500 -0
- assistagro_client-0.3.1/src/assistagro_client/config.py +15 -0
- assistagro_client-0.3.1/src/assistagro_client/exceptions.py +27 -0
- assistagro_client-0.3.1/src/assistagro_client/models/__init__.py +56 -0
- assistagro_client-0.3.1/src/assistagro_client/models/accounts.py +21 -0
- assistagro_client-0.3.1/src/assistagro_client/models/companies.py +45 -0
- assistagro_client-0.3.1/src/assistagro_client/models/dictionaries.py +38 -0
- assistagro_client-0.3.1/src/assistagro_client/models/fields.py +33 -0
- assistagro_client-0.3.1/src/assistagro_client/models/meteostations.py +77 -0
- assistagro_client-0.3.1/src/assistagro_client/models/reports.py +29 -0
- assistagro_client-0.3.1/src/assistagro_client/models/seasons.py +33 -0
- assistagro_client-0.3.1/src/assistagro_client/models/structures.py +21 -0
- assistagro_client-0.3.1/src/assistagro_client/models/tasks.py +30 -0
- assistagro_client-0.3.1/src/assistagro_client/models/techmaps.py +38 -0
- assistagro_client-0.3.1/src/assistagro_client/py.typed +0 -0
- assistagro_client-0.3.1/src/assistagro_client.egg-info/PKG-INFO +171 -0
- assistagro_client-0.3.1/src/assistagro_client.egg-info/SOURCES.txt +38 -0
- assistagro_client-0.3.1/src/assistagro_client.egg-info/dependency_links.txt +1 -0
- assistagro_client-0.3.1/src/assistagro_client.egg-info/requires.txt +5 -0
- assistagro_client-0.3.1/src/assistagro_client.egg-info/top_level.txt +1 -0
- assistagro_client-0.3.1/tests/test_auth.py +154 -0
- assistagro_client-0.3.1/tests/test_client.py +229 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: assistagro-client
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: HTTP client for AssistAgro API
|
|
5
|
+
Author-email: Dmitriy Kazakov <dmitriyfile@yandex.ru>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: httpx>=0.28.1
|
|
12
|
+
Requires-Dist: pydantic>=2.12.5
|
|
13
|
+
Requires-Dist: pydantic-settings>=2.13.1
|
|
14
|
+
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
15
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
16
|
+
|
|
17
|
+
# AssistAgro API Client
|
|
18
|
+
|
|
19
|
+
Синхронный и асинхронный HTTP-клиент для AssistAgro API.
|
|
20
|
+
|
|
21
|
+
## Установка
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install assistagro-client
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Асинхронное использование
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import asyncio
|
|
31
|
+
from assistagro_client import AssistAgroClient
|
|
32
|
+
|
|
33
|
+
async def main():
|
|
34
|
+
async with AssistAgroClient(base_url="https://gateway-frontend.agroassist.ru") as client:
|
|
35
|
+
tokens = await client.auth.sign_in(
|
|
36
|
+
email="user@example.com",
|
|
37
|
+
password="password123"
|
|
38
|
+
)
|
|
39
|
+
print(f"Access token: {tokens.access_token[:20]}...")
|
|
40
|
+
|
|
41
|
+
structures = await client.structures.list_()
|
|
42
|
+
structure_guid = structures[0].structure_guid
|
|
43
|
+
|
|
44
|
+
season = await client.seasons.get_current()
|
|
45
|
+
|
|
46
|
+
fields = await client.fields.list_(
|
|
47
|
+
structure_guids=[structure_guid],
|
|
48
|
+
season_id=season.season_id,
|
|
49
|
+
)
|
|
50
|
+
print(f"Найдено полей: {len(fields)}")
|
|
51
|
+
|
|
52
|
+
crops_response = await client.dictionaries.get_crops()
|
|
53
|
+
print(f"Культур: {len(crops_response.crops)}")
|
|
54
|
+
|
|
55
|
+
tasks = await client.tasks.list_(structure_guid=structure_guid)
|
|
56
|
+
print(f"Найдено задач: {len(tasks)}")
|
|
57
|
+
|
|
58
|
+
if __name__ == "__main__":
|
|
59
|
+
asyncio.run(main())
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Синхронное использование
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from assistagro_client import AssistAgroSyncClient
|
|
66
|
+
|
|
67
|
+
with AssistAgroSyncClient(base_url="https://gateway-frontend.agroassist.ru") as client:
|
|
68
|
+
tokens = client.auth.sign_in(
|
|
69
|
+
email="user@example.com",
|
|
70
|
+
password="password123",
|
|
71
|
+
)
|
|
72
|
+
print(f"Access token: {tokens.access_token[:20]}...")
|
|
73
|
+
|
|
74
|
+
structures = client.structures.list_()
|
|
75
|
+
print(f"Найдено структур: {len(structures)}")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`AssistAgroClient` остается асинхронным клиентом для обратной совместимости.
|
|
79
|
+
`AssistAgroSyncClient` предоставляет тот же набор API-разделов для обычного синхронного кода.
|
|
80
|
+
Если нужно передать контекст пользователя в `x-user-data`, используйте `set_user_data(...)`;
|
|
81
|
+
заголовок сериализуется как компактный JSON, например
|
|
82
|
+
`{"company_guid":"...","user_guid":"..."}`.
|
|
83
|
+
|
|
84
|
+
## TLS/SSL сертификаты
|
|
85
|
+
|
|
86
|
+
По умолчанию клиент проверяет TLS-сертификат сервера. Если окружение использует свой
|
|
87
|
+
CA-bundle, передайте путь к нему:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
client = AssistAgroClient(verify="/path/to/ca-bundle.pem")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Если сервер временно отдает некорректную цепочку сертификатов, проверку можно отключить
|
|
94
|
+
явно:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
client = AssistAgroClient(verify=False)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
То же доступно для `AssistAgroSyncClient` и через переменную окружения
|
|
101
|
+
`ASSISTAGRO_VERIFY_SSL=false`.
|
|
102
|
+
|
|
103
|
+
## API эндпоинты
|
|
104
|
+
|
|
105
|
+
| Модуль | Описание | Основные методы |
|
|
106
|
+
|--------|----------|-----------------|
|
|
107
|
+
| **auth** | Аутентификация | `sign_in`, `refresh_tokens`, `logout` |
|
|
108
|
+
| **accounts** | Пользователи | `get_current_user`, `get_users` |
|
|
109
|
+
| **companies** | Компании | `list_()`, `list_all`, `get`, `get_license`, `get_license_metadata`, `get_activities`, `get_dashboards` |
|
|
110
|
+
| **structures** | Структуры | `list_()`, `list_plain` |
|
|
111
|
+
| **seasons** | Сезоны | `list`, `get_current`, `get_by_name`, `get_season_id_by_name` |
|
|
112
|
+
| **fields** | Поля | `list_()`, `get_contours`, `get_phenophases`, `get_monitoring`, `list_meta` |
|
|
113
|
+
| **tasks** | Задачи | `list_()`, `create`, `get_list_meta` |
|
|
114
|
+
| **reports** | Отчёты | `list_()`, `create`, `get_metadata`, `get_problems`, `get_list_meta` |
|
|
115
|
+
| **techmaps** | Технологические карты | `list_()`, `create` |
|
|
116
|
+
| **meteostations** | Метеостанции | `list_()`, `get`, `get_by_field`, `get_manufacturers`, `get_providers`, `get_sensors`, `get_coordinates_history`, `get_history` |
|
|
117
|
+
| **dictionaries** | Справочники | `get_crops`, `get_crop_products`, `get_techoperations`, `get_pesticides`, `get_fertilizers`, `get_machines`, `get_tools`, `get_units`, `get_regions`, `get_countries`, и др. |
|
|
118
|
+
|
|
119
|
+
## Примеры
|
|
120
|
+
|
|
121
|
+
Скопируйте `.env.example` в `.env` и заполните переменные:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
cp .env.example .env
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```env
|
|
128
|
+
ASSISTAGRO_EMAIL=user@example.com
|
|
129
|
+
ASSISTAGRO_PASSWORD=your-password
|
|
130
|
+
ASSISTAGRO_BASE_URL=https://gateway-frontend.agroassist.ru
|
|
131
|
+
ASSISTAGRO_DEBUG=false
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Запуск примеров:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Запустить все модули
|
|
138
|
+
uv run python examples/run_tests.py
|
|
139
|
+
|
|
140
|
+
# Запустить конкретный модуль
|
|
141
|
+
uv run python examples/run_tests.py --module structures
|
|
142
|
+
uv run python examples/run_tests.py -m auth
|
|
143
|
+
|
|
144
|
+
# Доступные модули:
|
|
145
|
+
# auth, structures, companies, current_user, users,
|
|
146
|
+
# dictionaries, meteostations, tasks, fields, reports, techmaps, seasons
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Разработка
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Установить зависимости
|
|
153
|
+
uv sync
|
|
154
|
+
|
|
155
|
+
# Запустить тесты
|
|
156
|
+
uv run pytest
|
|
157
|
+
|
|
158
|
+
# Запустить линтер
|
|
159
|
+
uv run ruff check .
|
|
160
|
+
uv run ruff check --fix .
|
|
161
|
+
|
|
162
|
+
# Проверка типов
|
|
163
|
+
uv run mypy src/
|
|
164
|
+
|
|
165
|
+
# Форматирование
|
|
166
|
+
uv run black .
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Лицензия
|
|
170
|
+
|
|
171
|
+
MIT
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# AssistAgro API Client
|
|
2
|
+
|
|
3
|
+
Синхронный и асинхронный HTTP-клиент для AssistAgro API.
|
|
4
|
+
|
|
5
|
+
## Установка
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install assistagro-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Асинхронное использование
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import asyncio
|
|
15
|
+
from assistagro_client import AssistAgroClient
|
|
16
|
+
|
|
17
|
+
async def main():
|
|
18
|
+
async with AssistAgroClient(base_url="https://gateway-frontend.agroassist.ru") as client:
|
|
19
|
+
tokens = await client.auth.sign_in(
|
|
20
|
+
email="user@example.com",
|
|
21
|
+
password="password123"
|
|
22
|
+
)
|
|
23
|
+
print(f"Access token: {tokens.access_token[:20]}...")
|
|
24
|
+
|
|
25
|
+
structures = await client.structures.list_()
|
|
26
|
+
structure_guid = structures[0].structure_guid
|
|
27
|
+
|
|
28
|
+
season = await client.seasons.get_current()
|
|
29
|
+
|
|
30
|
+
fields = await client.fields.list_(
|
|
31
|
+
structure_guids=[structure_guid],
|
|
32
|
+
season_id=season.season_id,
|
|
33
|
+
)
|
|
34
|
+
print(f"Найдено полей: {len(fields)}")
|
|
35
|
+
|
|
36
|
+
crops_response = await client.dictionaries.get_crops()
|
|
37
|
+
print(f"Культур: {len(crops_response.crops)}")
|
|
38
|
+
|
|
39
|
+
tasks = await client.tasks.list_(structure_guid=structure_guid)
|
|
40
|
+
print(f"Найдено задач: {len(tasks)}")
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
asyncio.run(main())
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Синхронное использование
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from assistagro_client import AssistAgroSyncClient
|
|
50
|
+
|
|
51
|
+
with AssistAgroSyncClient(base_url="https://gateway-frontend.agroassist.ru") as client:
|
|
52
|
+
tokens = client.auth.sign_in(
|
|
53
|
+
email="user@example.com",
|
|
54
|
+
password="password123",
|
|
55
|
+
)
|
|
56
|
+
print(f"Access token: {tokens.access_token[:20]}...")
|
|
57
|
+
|
|
58
|
+
structures = client.structures.list_()
|
|
59
|
+
print(f"Найдено структур: {len(structures)}")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`AssistAgroClient` остается асинхронным клиентом для обратной совместимости.
|
|
63
|
+
`AssistAgroSyncClient` предоставляет тот же набор API-разделов для обычного синхронного кода.
|
|
64
|
+
Если нужно передать контекст пользователя в `x-user-data`, используйте `set_user_data(...)`;
|
|
65
|
+
заголовок сериализуется как компактный JSON, например
|
|
66
|
+
`{"company_guid":"...","user_guid":"..."}`.
|
|
67
|
+
|
|
68
|
+
## TLS/SSL сертификаты
|
|
69
|
+
|
|
70
|
+
По умолчанию клиент проверяет TLS-сертификат сервера. Если окружение использует свой
|
|
71
|
+
CA-bundle, передайте путь к нему:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
client = AssistAgroClient(verify="/path/to/ca-bundle.pem")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Если сервер временно отдает некорректную цепочку сертификатов, проверку можно отключить
|
|
78
|
+
явно:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
client = AssistAgroClient(verify=False)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
То же доступно для `AssistAgroSyncClient` и через переменную окружения
|
|
85
|
+
`ASSISTAGRO_VERIFY_SSL=false`.
|
|
86
|
+
|
|
87
|
+
## API эндпоинты
|
|
88
|
+
|
|
89
|
+
| Модуль | Описание | Основные методы |
|
|
90
|
+
|--------|----------|-----------------|
|
|
91
|
+
| **auth** | Аутентификация | `sign_in`, `refresh_tokens`, `logout` |
|
|
92
|
+
| **accounts** | Пользователи | `get_current_user`, `get_users` |
|
|
93
|
+
| **companies** | Компании | `list_()`, `list_all`, `get`, `get_license`, `get_license_metadata`, `get_activities`, `get_dashboards` |
|
|
94
|
+
| **structures** | Структуры | `list_()`, `list_plain` |
|
|
95
|
+
| **seasons** | Сезоны | `list`, `get_current`, `get_by_name`, `get_season_id_by_name` |
|
|
96
|
+
| **fields** | Поля | `list_()`, `get_contours`, `get_phenophases`, `get_monitoring`, `list_meta` |
|
|
97
|
+
| **tasks** | Задачи | `list_()`, `create`, `get_list_meta` |
|
|
98
|
+
| **reports** | Отчёты | `list_()`, `create`, `get_metadata`, `get_problems`, `get_list_meta` |
|
|
99
|
+
| **techmaps** | Технологические карты | `list_()`, `create` |
|
|
100
|
+
| **meteostations** | Метеостанции | `list_()`, `get`, `get_by_field`, `get_manufacturers`, `get_providers`, `get_sensors`, `get_coordinates_history`, `get_history` |
|
|
101
|
+
| **dictionaries** | Справочники | `get_crops`, `get_crop_products`, `get_techoperations`, `get_pesticides`, `get_fertilizers`, `get_machines`, `get_tools`, `get_units`, `get_regions`, `get_countries`, и др. |
|
|
102
|
+
|
|
103
|
+
## Примеры
|
|
104
|
+
|
|
105
|
+
Скопируйте `.env.example` в `.env` и заполните переменные:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
cp .env.example .env
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```env
|
|
112
|
+
ASSISTAGRO_EMAIL=user@example.com
|
|
113
|
+
ASSISTAGRO_PASSWORD=your-password
|
|
114
|
+
ASSISTAGRO_BASE_URL=https://gateway-frontend.agroassist.ru
|
|
115
|
+
ASSISTAGRO_DEBUG=false
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Запуск примеров:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Запустить все модули
|
|
122
|
+
uv run python examples/run_tests.py
|
|
123
|
+
|
|
124
|
+
# Запустить конкретный модуль
|
|
125
|
+
uv run python examples/run_tests.py --module structures
|
|
126
|
+
uv run python examples/run_tests.py -m auth
|
|
127
|
+
|
|
128
|
+
# Доступные модули:
|
|
129
|
+
# auth, structures, companies, current_user, users,
|
|
130
|
+
# dictionaries, meteostations, tasks, fields, reports, techmaps, seasons
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Разработка
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Установить зависимости
|
|
137
|
+
uv sync
|
|
138
|
+
|
|
139
|
+
# Запустить тесты
|
|
140
|
+
uv run pytest
|
|
141
|
+
|
|
142
|
+
# Запустить линтер
|
|
143
|
+
uv run ruff check .
|
|
144
|
+
uv run ruff check --fix .
|
|
145
|
+
|
|
146
|
+
# Проверка типов
|
|
147
|
+
uv run mypy src/
|
|
148
|
+
|
|
149
|
+
# Форматирование
|
|
150
|
+
uv run black .
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Лицензия
|
|
154
|
+
|
|
155
|
+
MIT
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "assistagro-client"
|
|
3
|
+
version = "0.3.1"
|
|
4
|
+
description = "HTTP client for AssistAgro API"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Dmitriy Kazakov", email = "dmitriyfile@yandex.ru"},
|
|
10
|
+
]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Programming Language :: Python :: 3.13",
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"httpx>=0.28.1",
|
|
17
|
+
"pydantic>=2.12.5",
|
|
18
|
+
"pydantic-settings>=2.13.1",
|
|
19
|
+
"python-dateutil>=2.9.0.post0",
|
|
20
|
+
"python-dotenv>=1.0.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[dependency-groups]
|
|
24
|
+
dev = [
|
|
25
|
+
"pytest>=9.0.2",
|
|
26
|
+
"pytest-asyncio>=1.3.0",
|
|
27
|
+
"ruff>=0.9.0",
|
|
28
|
+
"mypy>=1.15.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["setuptools>=68"]
|
|
33
|
+
build-backend = "setuptools.build_meta"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
where = ["src"]
|
|
37
|
+
|
|
38
|
+
[tool.pytest.ini_options]
|
|
39
|
+
pythonpath = ["src"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""AssistAgro API Client."""
|
|
2
|
+
|
|
3
|
+
from .client import AssistAgroClient, AssistAgroSyncClient
|
|
4
|
+
from .auth import Auth, AuthTokens, SignInRequest, OTPResponse
|
|
5
|
+
from .exceptions import AssistAgroError, AuthenticationError, APIError, TimeoutError
|
|
6
|
+
from .api.v1.seasons import Season
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"AssistAgroClient",
|
|
10
|
+
"AssistAgroSyncClient",
|
|
11
|
+
"Auth",
|
|
12
|
+
"AuthTokens",
|
|
13
|
+
"SignInRequest",
|
|
14
|
+
"OTPResponse",
|
|
15
|
+
"AssistAgroError",
|
|
16
|
+
"AuthenticationError",
|
|
17
|
+
"APIError",
|
|
18
|
+
"TimeoutError",
|
|
19
|
+
"Season",
|
|
20
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""API v1 endpoints."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""API v1 endpoints."""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Accounts API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
|
|
8
|
+
from assistagro_client.models.accounts import UserProfile
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from assistagro_client.client import AssistAgroClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AccountsAPI:
|
|
15
|
+
"""Accounts API endpoints."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, client: AssistAgroClient):
|
|
18
|
+
self._client = client
|
|
19
|
+
|
|
20
|
+
async def get_users(self, account_guid: UUID | None = None) -> list[UserProfile]:
|
|
21
|
+
"""Get user profiles."""
|
|
22
|
+
params = {}
|
|
23
|
+
if account_guid:
|
|
24
|
+
params["account_guid"] = str(account_guid)
|
|
25
|
+
response = await self._client.get("/account/users", params=params)
|
|
26
|
+
response.raise_for_status()
|
|
27
|
+
data = self._client._parse_json_response(response)
|
|
28
|
+
return [UserProfile(**item) for item in data] if data else []
|
|
29
|
+
|
|
30
|
+
async def get_current_user(self) -> dict:
|
|
31
|
+
"""Get current user info."""
|
|
32
|
+
response = await self._client.get("/account/users/current")
|
|
33
|
+
response.raise_for_status()
|
|
34
|
+
data = self._client._parse_json_response(response)
|
|
35
|
+
return data if data else {}
|
|
36
|
+
|
|
37
|
+
async def get_user(self, user_guid: UUID) -> dict:
|
|
38
|
+
"""Get user by GUID."""
|
|
39
|
+
response = await self._client.get(f"/account/users/{user_guid}")
|
|
40
|
+
response.raise_for_status()
|
|
41
|
+
data = self._client._parse_json_response(response)
|
|
42
|
+
return data if data else {}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Companies API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
|
|
8
|
+
from assistagro_client.models.companies import Company, CompanyLicense
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from assistagro_client.client import AssistAgroClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CompaniesAPI:
|
|
15
|
+
"""Companies API endpoints."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, client: AssistAgroClient):
|
|
18
|
+
self._client = client
|
|
19
|
+
|
|
20
|
+
async def list_(self) -> list[Company]:
|
|
21
|
+
"""Get current user's company.
|
|
22
|
+
|
|
23
|
+
Returns the company associated with the authenticated user.
|
|
24
|
+
"""
|
|
25
|
+
response = await self._client.get("/account/users/current")
|
|
26
|
+
response.raise_for_status()
|
|
27
|
+
data = self._client._parse_json_response(response)
|
|
28
|
+
if isinstance(data, dict) and "company" in data:
|
|
29
|
+
company_data = data["company"]
|
|
30
|
+
return [Company(**company_data)] if company_data else []
|
|
31
|
+
return []
|
|
32
|
+
|
|
33
|
+
async def list_all(self) -> list[dict[str, Any]]:
|
|
34
|
+
"""Get all companies (requires superadmin permission 1).
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
List of company objects with guid, name, user_count, active_flag, license.
|
|
38
|
+
"""
|
|
39
|
+
response = await self._client.get("/companies")
|
|
40
|
+
response.raise_for_status()
|
|
41
|
+
data = self._client._parse_json_response(response)
|
|
42
|
+
return data if isinstance(data, list) else []
|
|
43
|
+
|
|
44
|
+
async def get(self, company_guid: UUID) -> dict[str, Any]:
|
|
45
|
+
"""Get company by GUID.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
company_guid: Company GUID.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Company data with guid, name, user_count, active_flag.
|
|
52
|
+
"""
|
|
53
|
+
response = await self._client.get(f"/companies/{company_guid}")
|
|
54
|
+
response.raise_for_status()
|
|
55
|
+
return self._client._parse_json_response(response)
|
|
56
|
+
|
|
57
|
+
async def get_license(
|
|
58
|
+
self, company_guid: Optional[UUID] = None
|
|
59
|
+
) -> CompanyLicense:
|
|
60
|
+
"""Get company license info.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
company_guid: Optional company GUID. If not provided, uses token's company.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Company license information.
|
|
67
|
+
"""
|
|
68
|
+
params: dict[str, Any] = {}
|
|
69
|
+
if company_guid:
|
|
70
|
+
params["company_guid"] = str(company_guid)
|
|
71
|
+
response = await self._client.get("/companies/license", params=params)
|
|
72
|
+
response.raise_for_status()
|
|
73
|
+
data = self._client._parse_json_response(response)
|
|
74
|
+
return CompanyLicense(**data)
|
|
75
|
+
|
|
76
|
+
async def get_license_metadata(self) -> dict[str, Any]:
|
|
77
|
+
"""Get license metadata (modules, permissions, license types, limits).
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Dict with modules, permissions, permission_groups, license_types, license_limits.
|
|
81
|
+
"""
|
|
82
|
+
response = await self._client.get("/companies/license/metadata")
|
|
83
|
+
response.raise_for_status()
|
|
84
|
+
return self._client._parse_json_response(response)
|
|
85
|
+
|
|
86
|
+
async def get_activities(self) -> list[dict[str, Any]]:
|
|
87
|
+
"""Get company activity types.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
List of company activities with id and description.
|
|
91
|
+
"""
|
|
92
|
+
response = await self._client.get("/companies/activities")
|
|
93
|
+
response.raise_for_status()
|
|
94
|
+
data = self._client._parse_json_response(response)
|
|
95
|
+
if isinstance(data, dict) and "company_activities" in data:
|
|
96
|
+
return data["company_activities"]
|
|
97
|
+
return []
|
|
98
|
+
|
|
99
|
+
async def get_dashboards(self) -> list[dict[str, Any]]:
|
|
100
|
+
"""Get company dashboards (requires permission 55).
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
List of dashboard objects with id and name.
|
|
104
|
+
"""
|
|
105
|
+
response = await self._client.get("/companies/dashboards")
|
|
106
|
+
response.raise_for_status()
|
|
107
|
+
data = self._client._parse_json_response(response)
|
|
108
|
+
return data if isinstance(data, list) else []
|