AssistagroAPI 0.1.0__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.
- assistagroapi-0.1.0/PKG-INFO +79 -0
- assistagroapi-0.1.0/README.md +63 -0
- assistagroapi-0.1.0/pyproject.toml +32 -0
- assistagroapi-0.1.0/setup.cfg +4 -0
- assistagroapi-0.1.0/src/AssistagroAPI.egg-info/PKG-INFO +79 -0
- assistagroapi-0.1.0/src/AssistagroAPI.egg-info/SOURCES.txt +26 -0
- assistagroapi-0.1.0/src/AssistagroAPI.egg-info/dependency_links.txt +1 -0
- assistagroapi-0.1.0/src/AssistagroAPI.egg-info/requires.txt +4 -0
- assistagroapi-0.1.0/src/AssistagroAPI.egg-info/top_level.txt +1 -0
- assistagroapi-0.1.0/src/assistagro_client/__init__.py +17 -0
- assistagroapi-0.1.0/src/assistagro_client/api/__init__.py +1 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/__init__.py +1 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/accounts.py +53 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/companies.py +39 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/dictionaries.py +69 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/fields.py +62 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/meteostations.py +31 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/reports.py +67 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/structures.py +30 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/tasks.py +93 -0
- assistagroapi-0.1.0/src/assistagro_client/api/v1/techmaps.py +83 -0
- assistagroapi-0.1.0/src/assistagro_client/auth.py +100 -0
- assistagroapi-0.1.0/src/assistagro_client/client.py +218 -0
- assistagroapi-0.1.0/src/assistagro_client/config.py +14 -0
- assistagroapi-0.1.0/src/assistagro_client/exceptions.py +27 -0
- assistagroapi-0.1.0/src/assistagro_client/models/__init__.py +1 -0
- assistagroapi-0.1.0/tests/test_auth.py +112 -0
- assistagroapi-0.1.0/tests/test_client.py +80 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: AssistagroAPI
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async HTTP client for AssistAgro API
|
|
5
|
+
Author-email: Dmitriy Kazakov <dmitriyfile@yandex.ru>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Requires-Python: >=3.13
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: httpx>=0.28.1
|
|
13
|
+
Requires-Dist: pydantic>=2.12.5
|
|
14
|
+
Requires-Dist: pydantic-settings>=2.13.1
|
|
15
|
+
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
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://dev-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
|
+
fields = await client.fields.list_()
|
|
42
|
+
print(f"Найдено полей: {len(fields)}")
|
|
43
|
+
|
|
44
|
+
tasks = await client.tasks.list_(limit=10)
|
|
45
|
+
print(f"Найдено задач: {len(tasks)}")
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
asyncio.run(main())
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API эндпоинты
|
|
52
|
+
|
|
53
|
+
- **auth** - Аутентификация (sign_in, refresh_tokens, logout)
|
|
54
|
+
- **accounts** - Профили пользователей и аккаунты
|
|
55
|
+
- **companies** - Управление компаниями
|
|
56
|
+
- **fields** - Поля и контуры
|
|
57
|
+
- **tasks** - Управление задачами
|
|
58
|
+
- **techmaps** - Технологические карты
|
|
59
|
+
- **reports** - Отчёты
|
|
60
|
+
- **dictionaries** - Справочники (культуры, пестициды и т.д.)
|
|
61
|
+
- **meteostations** - Метеостанции
|
|
62
|
+
- **structures** - Структуры
|
|
63
|
+
|
|
64
|
+
## Разработка
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Установить зависимости
|
|
68
|
+
uv sync
|
|
69
|
+
|
|
70
|
+
# Запустить тесты
|
|
71
|
+
uv run pytest
|
|
72
|
+
|
|
73
|
+
# Запустить линтер
|
|
74
|
+
uv run ruff check .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Лицензия
|
|
78
|
+
|
|
79
|
+
MIT
|
|
@@ -0,0 +1,63 @@
|
|
|
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://dev-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
|
+
fields = await client.fields.list_()
|
|
26
|
+
print(f"Найдено полей: {len(fields)}")
|
|
27
|
+
|
|
28
|
+
tasks = await client.tasks.list_(limit=10)
|
|
29
|
+
print(f"Найдено задач: {len(tasks)}")
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
asyncio.run(main())
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API эндпоинты
|
|
36
|
+
|
|
37
|
+
- **auth** - Аутентификация (sign_in, refresh_tokens, logout)
|
|
38
|
+
- **accounts** - Профили пользователей и аккаунты
|
|
39
|
+
- **companies** - Управление компаниями
|
|
40
|
+
- **fields** - Поля и контуры
|
|
41
|
+
- **tasks** - Управление задачами
|
|
42
|
+
- **techmaps** - Технологические карты
|
|
43
|
+
- **reports** - Отчёты
|
|
44
|
+
- **dictionaries** - Справочники (культуры, пестициды и т.д.)
|
|
45
|
+
- **meteostations** - Метеостанции
|
|
46
|
+
- **structures** - Структуры
|
|
47
|
+
|
|
48
|
+
## Разработка
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Установить зависимости
|
|
52
|
+
uv sync
|
|
53
|
+
|
|
54
|
+
# Запустить тесты
|
|
55
|
+
uv run pytest
|
|
56
|
+
|
|
57
|
+
# Запустить линтер
|
|
58
|
+
uv run ruff check .
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Лицензия
|
|
62
|
+
|
|
63
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "AssistagroAPI"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Async HTTP client for AssistAgro API"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
license = {text = "MIT"}
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Dmitriy Kazakov", email = "dmitriyfile@yandex.ru"},
|
|
10
|
+
]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"Programming Language :: Python :: 3.13",
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"httpx>=0.28.1",
|
|
18
|
+
"pydantic>=2.12.5",
|
|
19
|
+
"pydantic-settings>=2.13.1",
|
|
20
|
+
"python-dateutil>=2.9.0.post0",
|
|
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
|
+
[tool.setuptools.packages.find]
|
|
32
|
+
where = ["src"]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: AssistagroAPI
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async HTTP client for AssistAgro API
|
|
5
|
+
Author-email: Dmitriy Kazakov <dmitriyfile@yandex.ru>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Requires-Python: >=3.13
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: httpx>=0.28.1
|
|
13
|
+
Requires-Dist: pydantic>=2.12.5
|
|
14
|
+
Requires-Dist: pydantic-settings>=2.13.1
|
|
15
|
+
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
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://dev-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
|
+
fields = await client.fields.list_()
|
|
42
|
+
print(f"Найдено полей: {len(fields)}")
|
|
43
|
+
|
|
44
|
+
tasks = await client.tasks.list_(limit=10)
|
|
45
|
+
print(f"Найдено задач: {len(tasks)}")
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
asyncio.run(main())
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API эндпоинты
|
|
52
|
+
|
|
53
|
+
- **auth** - Аутентификация (sign_in, refresh_tokens, logout)
|
|
54
|
+
- **accounts** - Профили пользователей и аккаунты
|
|
55
|
+
- **companies** - Управление компаниями
|
|
56
|
+
- **fields** - Поля и контуры
|
|
57
|
+
- **tasks** - Управление задачами
|
|
58
|
+
- **techmaps** - Технологические карты
|
|
59
|
+
- **reports** - Отчёты
|
|
60
|
+
- **dictionaries** - Справочники (культуры, пестициды и т.д.)
|
|
61
|
+
- **meteostations** - Метеостанции
|
|
62
|
+
- **structures** - Структуры
|
|
63
|
+
|
|
64
|
+
## Разработка
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Установить зависимости
|
|
68
|
+
uv sync
|
|
69
|
+
|
|
70
|
+
# Запустить тесты
|
|
71
|
+
uv run pytest
|
|
72
|
+
|
|
73
|
+
# Запустить линтер
|
|
74
|
+
uv run ruff check .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Лицензия
|
|
78
|
+
|
|
79
|
+
MIT
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/AssistagroAPI.egg-info/PKG-INFO
|
|
4
|
+
src/AssistagroAPI.egg-info/SOURCES.txt
|
|
5
|
+
src/AssistagroAPI.egg-info/dependency_links.txt
|
|
6
|
+
src/AssistagroAPI.egg-info/requires.txt
|
|
7
|
+
src/AssistagroAPI.egg-info/top_level.txt
|
|
8
|
+
src/assistagro_client/__init__.py
|
|
9
|
+
src/assistagro_client/auth.py
|
|
10
|
+
src/assistagro_client/client.py
|
|
11
|
+
src/assistagro_client/config.py
|
|
12
|
+
src/assistagro_client/exceptions.py
|
|
13
|
+
src/assistagro_client/api/__init__.py
|
|
14
|
+
src/assistagro_client/api/v1/__init__.py
|
|
15
|
+
src/assistagro_client/api/v1/accounts.py
|
|
16
|
+
src/assistagro_client/api/v1/companies.py
|
|
17
|
+
src/assistagro_client/api/v1/dictionaries.py
|
|
18
|
+
src/assistagro_client/api/v1/fields.py
|
|
19
|
+
src/assistagro_client/api/v1/meteostations.py
|
|
20
|
+
src/assistagro_client/api/v1/reports.py
|
|
21
|
+
src/assistagro_client/api/v1/structures.py
|
|
22
|
+
src/assistagro_client/api/v1/tasks.py
|
|
23
|
+
src/assistagro_client/api/v1/techmaps.py
|
|
24
|
+
src/assistagro_client/models/__init__.py
|
|
25
|
+
tests/test_auth.py
|
|
26
|
+
tests/test_client.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
assistagro_client
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""AssistAgro API Client."""
|
|
2
|
+
|
|
3
|
+
from .client import AssistAgroClient
|
|
4
|
+
from .auth import Auth, AuthTokens, SignInRequest, OTPResponse
|
|
5
|
+
from .exceptions import AssistAgroError, AuthenticationError, APIError, TimeoutError
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"AssistAgroClient",
|
|
9
|
+
"Auth",
|
|
10
|
+
"AuthTokens",
|
|
11
|
+
"SignInRequest",
|
|
12
|
+
"OTPResponse",
|
|
13
|
+
"AssistAgroError",
|
|
14
|
+
"AuthenticationError",
|
|
15
|
+
"APIError",
|
|
16
|
+
"TimeoutError",
|
|
17
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""API v1 endpoints."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""API v1 endpoints."""
|
|
@@ -0,0 +1,53 @@
|
|
|
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 pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .client import AssistAgroClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Company(BaseModel):
|
|
15
|
+
guid: UUID
|
|
16
|
+
name: str
|
|
17
|
+
parent_guid: UUID | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class UserProfile(BaseModel):
|
|
21
|
+
company: Company
|
|
22
|
+
user_guid: UUID
|
|
23
|
+
permissions: list[str]
|
|
24
|
+
is_current: bool
|
|
25
|
+
is_confirmed: bool
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AccountsAPI:
|
|
29
|
+
"""Accounts API endpoints."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, client: AssistAgroClient):
|
|
32
|
+
self._client = client
|
|
33
|
+
|
|
34
|
+
async def get_users(self, account_guid: UUID | None = None) -> list[UserProfile]:
|
|
35
|
+
"""Get user profiles."""
|
|
36
|
+
params = {}
|
|
37
|
+
if account_guid:
|
|
38
|
+
params["account_guid"] = str(account_guid)
|
|
39
|
+
response = await self._client.get("/account/users", params=params)
|
|
40
|
+
response.raise_for_status()
|
|
41
|
+
return [UserProfile(**item) for item in response.json()]
|
|
42
|
+
|
|
43
|
+
async def get_current_user(self) -> dict:
|
|
44
|
+
"""Get current user info."""
|
|
45
|
+
response = await self._client.get("/account/users/current")
|
|
46
|
+
response.raise_for_status()
|
|
47
|
+
return response.json()
|
|
48
|
+
|
|
49
|
+
async def get_user(self, user_guid: UUID) -> dict:
|
|
50
|
+
"""Get user by GUID."""
|
|
51
|
+
response = await self._client.get(f"/account/users/{user_guid}")
|
|
52
|
+
response.raise_for_status()
|
|
53
|
+
return response.json()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Companies API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import date
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
from uuid import UUID
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .client import AssistAgroClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class License(BaseModel):
|
|
16
|
+
begin_date: date
|
|
17
|
+
end_date: date
|
|
18
|
+
modules: list[int]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Company(BaseModel):
|
|
22
|
+
guid: UUID
|
|
23
|
+
name: str
|
|
24
|
+
user_count: int
|
|
25
|
+
active_flag: bool
|
|
26
|
+
license: License
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class CompaniesAPI:
|
|
30
|
+
"""Companies API endpoints."""
|
|
31
|
+
|
|
32
|
+
def __init__(self, client: AssistAgroClient):
|
|
33
|
+
self._client = client
|
|
34
|
+
|
|
35
|
+
async def list_(self) -> list[Company]:
|
|
36
|
+
"""Get all companies."""
|
|
37
|
+
response = await self._client.get("/companies")
|
|
38
|
+
response.raise_for_status()
|
|
39
|
+
return [Company(**item) for item in response.json()]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Dictionaries API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .client import AssistAgroClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DictionariesAPI:
|
|
12
|
+
"""Dictionaries API endpoints."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, client: AssistAgroClient):
|
|
15
|
+
self._client = client
|
|
16
|
+
|
|
17
|
+
async def get_crops(self) -> list[dict[str, Any]]:
|
|
18
|
+
"""Get crops dictionary."""
|
|
19
|
+
response = await self._client.get("/dictionaries/crops")
|
|
20
|
+
response.raise_for_status()
|
|
21
|
+
return response.json()
|
|
22
|
+
|
|
23
|
+
async def get_crop_products(self) -> list[dict[str, Any]]:
|
|
24
|
+
"""Get crop products dictionary."""
|
|
25
|
+
response = await self._client.get("/dictionaries/crop_products")
|
|
26
|
+
response.raise_for_status()
|
|
27
|
+
return response.json()
|
|
28
|
+
|
|
29
|
+
async def get_techoperations(self) -> list[dict[str, Any]]:
|
|
30
|
+
"""Get techoperations dictionary."""
|
|
31
|
+
response = await self._client.get("/dictionaries/techoperations")
|
|
32
|
+
response.raise_for_status()
|
|
33
|
+
return response.json()
|
|
34
|
+
|
|
35
|
+
async def get_machine_models(self) -> list[dict[str, Any]]:
|
|
36
|
+
"""Get machine models dictionary."""
|
|
37
|
+
response = await self._client.get("/dictionaries/machine_models")
|
|
38
|
+
response.raise_for_status()
|
|
39
|
+
return response.json()
|
|
40
|
+
|
|
41
|
+
async def get_pesticides(self) -> list[dict[str, Any]]:
|
|
42
|
+
"""Get pesticides dictionary."""
|
|
43
|
+
response = await self._client.get("/dictionaries/pesticides")
|
|
44
|
+
response.raise_for_status()
|
|
45
|
+
return response.json()
|
|
46
|
+
|
|
47
|
+
async def get_fertilizers(self) -> list[dict[str, Any]]:
|
|
48
|
+
"""Get fertilizers dictionary."""
|
|
49
|
+
response = await self._client.get("/dictionaries/fertilizers")
|
|
50
|
+
response.raise_for_status()
|
|
51
|
+
return response.json()
|
|
52
|
+
|
|
53
|
+
async def get_varieties(self) -> list[dict[str, Any]]:
|
|
54
|
+
"""Get varieties dictionary."""
|
|
55
|
+
response = await self._client.get("/dictionaries/varieties")
|
|
56
|
+
response.raise_for_status()
|
|
57
|
+
return response.json()
|
|
58
|
+
|
|
59
|
+
async def get_meteostations(self) -> list[dict[str, Any]]:
|
|
60
|
+
"""Get meteostations."""
|
|
61
|
+
response = await self._client.get("/meteostations")
|
|
62
|
+
response.raise_for_status()
|
|
63
|
+
return response.json()
|
|
64
|
+
|
|
65
|
+
async def get_notifications_channels(self) -> list[dict[str, Any]]:
|
|
66
|
+
"""Get notification channels."""
|
|
67
|
+
response = await self._client.get("/notifications/channels")
|
|
68
|
+
response.raise_for_status()
|
|
69
|
+
return response.json()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Fields API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
from uuid import UUID
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .client import AssistAgroClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FieldContour(BaseModel):
|
|
16
|
+
contour_guid: UUID
|
|
17
|
+
field_guid: UUID
|
|
18
|
+
superfield_guid: UUID
|
|
19
|
+
contour: str
|
|
20
|
+
area_fact_hectare: float
|
|
21
|
+
area_etalon_hectare: float
|
|
22
|
+
start_datetime: datetime
|
|
23
|
+
author_guid: UUID
|
|
24
|
+
editor_guid: UUID
|
|
25
|
+
created_at: datetime
|
|
26
|
+
updated_at: datetime
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class FieldListItem(BaseModel):
|
|
30
|
+
guid: UUID
|
|
31
|
+
name: str
|
|
32
|
+
company_guid: UUID
|
|
33
|
+
area_fact_hectare: float
|
|
34
|
+
area_etalon_hectare: float
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class FieldsAPI:
|
|
38
|
+
"""Fields API endpoints."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, client: AssistAgroClient):
|
|
41
|
+
self._client = client
|
|
42
|
+
|
|
43
|
+
async def get_contours(self, field_guid: UUID) -> list[FieldContour]:
|
|
44
|
+
"""Get field contours."""
|
|
45
|
+
response = await self._client.get(
|
|
46
|
+
"/fields/contours",
|
|
47
|
+
params={"field_guid": str(field_guid)},
|
|
48
|
+
)
|
|
49
|
+
response.raise_for_status()
|
|
50
|
+
return [FieldContour(**item) for item in response.json()]
|
|
51
|
+
|
|
52
|
+
async def list_(self) -> list[FieldListItem]:
|
|
53
|
+
"""List all fields."""
|
|
54
|
+
response = await self._client.get("/fields/list")
|
|
55
|
+
response.raise_for_status()
|
|
56
|
+
return [FieldListItem(**item) for item in response.json()]
|
|
57
|
+
|
|
58
|
+
async def list_meta(self) -> dict:
|
|
59
|
+
"""List fields with metadata."""
|
|
60
|
+
response = await self._client.get("/fields/list_meta")
|
|
61
|
+
response.raise_for_status()
|
|
62
|
+
return response.json()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Meteostations API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .client import AssistAgroClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Meteostation(BaseModel):
|
|
15
|
+
guid: UUID
|
|
16
|
+
name: str
|
|
17
|
+
latitude: float
|
|
18
|
+
longitude: float
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MeteostationsAPI:
|
|
22
|
+
"""Meteostations API endpoints."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, client: AssistAgroClient):
|
|
25
|
+
self._client = client
|
|
26
|
+
|
|
27
|
+
async def list_(self) -> list[Meteostation]:
|
|
28
|
+
"""List all meteostations."""
|
|
29
|
+
response = await self._client.get("/meteostations")
|
|
30
|
+
response.raise_for_status()
|
|
31
|
+
return [Meteostation(**item) for item in response.json()]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Reports API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from uuid import UUID
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .client import AssistAgroClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Report(BaseModel):
|
|
16
|
+
guid: UUID
|
|
17
|
+
task_guid: UUID | None = None
|
|
18
|
+
season_id: int
|
|
19
|
+
entity_guid: UUID | None = None
|
|
20
|
+
entity_type: str | None = None
|
|
21
|
+
status_id: int
|
|
22
|
+
name: str
|
|
23
|
+
created_at: datetime
|
|
24
|
+
updated_at: datetime
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ReportCreateRequest(BaseModel):
|
|
28
|
+
task_guid: UUID | None = None
|
|
29
|
+
season_id: int
|
|
30
|
+
entity_guid: UUID | None = None
|
|
31
|
+
entity_type: str | None = None
|
|
32
|
+
entity_data: dict[str, Any]
|
|
33
|
+
datetimes: dict
|
|
34
|
+
history: list[dict]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ReportsAPI:
|
|
38
|
+
"""Reports API endpoints."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, client: AssistAgroClient):
|
|
41
|
+
self._client = client
|
|
42
|
+
|
|
43
|
+
async def create(
|
|
44
|
+
self,
|
|
45
|
+
season_id: int,
|
|
46
|
+
entity_data: dict[str, Any],
|
|
47
|
+
datetimes: dict,
|
|
48
|
+
history: list[dict],
|
|
49
|
+
task_guid: UUID | None = None,
|
|
50
|
+
entity_guid: UUID | None = None,
|
|
51
|
+
entity_type: str | None = None,
|
|
52
|
+
) -> Report:
|
|
53
|
+
"""Create a report."""
|
|
54
|
+
response = await self._client.post(
|
|
55
|
+
"/reports",
|
|
56
|
+
json={
|
|
57
|
+
"task_guid": str(task_guid) if task_guid else None,
|
|
58
|
+
"season_id": season_id,
|
|
59
|
+
"entity_guid": str(entity_guid) if entity_guid else None,
|
|
60
|
+
"entity_type": entity_type,
|
|
61
|
+
"entity_data": entity_data,
|
|
62
|
+
"datetimes": datetimes,
|
|
63
|
+
"history": history,
|
|
64
|
+
},
|
|
65
|
+
)
|
|
66
|
+
response.raise_for_status()
|
|
67
|
+
return Report(**response.json())
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Structures API endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .client import AssistAgroClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Structure(BaseModel):
|
|
15
|
+
guid: UUID
|
|
16
|
+
name: str
|
|
17
|
+
company_guid: UUID
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StructuresAPI:
|
|
21
|
+
"""Structures API endpoints."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, client: AssistAgroClient):
|
|
24
|
+
self._client = client
|
|
25
|
+
|
|
26
|
+
async def list_(self) -> list[Structure]:
|
|
27
|
+
"""List structures."""
|
|
28
|
+
response = await self._client.get("/structures")
|
|
29
|
+
response.raise_for_status()
|
|
30
|
+
return [Structure(**item) for item in response.json()]
|