refactor: add polylan-aandt generated client

This commit is contained in:
2026-09-16 15:36:51 +02:00
parent fabf06e6d4
commit 9ec9a54649
73 changed files with 7000 additions and 125 deletions
@@ -1,65 +0,0 @@
import requests
class AAndTAPIError(Exception):
"""Raised when the legacy PolyLAN AAndT API is unreachable or errors out."""
class AAndTClient:
"""Thin wrapper around the legacy PolyLAN site's per-AAndT JWT-bearer API."""
def __init__(self, base_url: str, token: str, /, *, timeout: int = 15) -> None:
self.timeout = timeout
self.base_url = base_url.rstrip("/")
self.session = requests.Session()
self.session.headers["Authorization"] = f"Bearer {token}"
def get_members(self) -> list[dict]:
return self._get("members")["members"]
def get_matches(self) -> list[dict]:
return self._get("matches")["matches"]
def set_match_message(
self,
match_id: int,
/,
*,
players: str | None = None,
admin: str | None = None,
msg_all: str | None = None,
) -> None:
body = {
key: value
for key, value in {
"players": players,
"admin": admin,
"all": msg_all,
}.items()
if value is not None
}
self._post(f"match/{match_id}/messages", body)
def _get(self, path: str) -> dict:
try:
response = self.session.get(
f"{self.base_url}/Plamingo/aandt/api/aandt/{path}", timeout=self.timeout
)
response.raise_for_status()
except requests.RequestException as exc:
raise AAndTAPIError(f"Failed to reach AAndT API ({path}): {exc}") from exc
return response.json()
def _post(self, path: str, data: dict) -> dict:
try:
response = self.session.post(
f"{self.base_url}/Plamingo/aandt/api/aandt/{path}",
json=data,
timeout=self.timeout,
)
response.raise_for_status()
except requests.RequestException as exc:
raise AAndTAPIError(f"Failed to reach AAndT API ({path}): {exc}") from exc
return response.json()
@@ -0,0 +1,8 @@
"""A client library for accessing PolyLAN AAndT Bot API"""
from .client import AuthenticatedClient, Client
__all__ = (
"AuthenticatedClient",
"Client",
)
@@ -0,0 +1 @@
"""Contains methods for accessing the API"""
@@ -0,0 +1 @@
"""Contains endpoint functions for accessing the API"""
@@ -0,0 +1,134 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_apibot_get_response_200 import AandtApiApibotGetResponse200
from ...models.aandt_api_apibot_get_response_401 import AandtApiApibotGetResponse401
from ...types import Response
def _get_kwargs() -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/apibot",
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401 | None:
if response.status_code == 200:
response_200 = AandtApiApibotGetResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiApibotGetResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401]:
"""Get the AAndT's apibot activation state and display name
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401]
"""
kwargs = _get_kwargs()
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
) -> AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401 | None:
"""Get the AAndT's apibot activation state and display name
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401
"""
return sync_detailed(
client=client,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401]:
"""Get the AAndT's apibot activation state and display name
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401]
"""
kwargs = _get_kwargs()
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
) -> AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401 | None:
"""Get the AAndT's apibot activation state and display name
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiApibotGetResponse200 | AandtApiApibotGetResponse401
"""
return (
await asyncio_detailed(
client=client,
)
).parsed
@@ -0,0 +1,174 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_apibot_set_body import AandtApiApibotSetBody
from ...models.aandt_api_apibot_set_response_401 import AandtApiApibotSetResponse401
from ...models.success_response import SuccessResponse
from ...types import Response
def _get_kwargs(
*,
body: AandtApiApibotSetBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/apibot",
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiApibotSetResponse401 | SuccessResponse | None:
if response.status_code == 200:
response_200 = SuccessResponse.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiApibotSetResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiApibotSetResponse401 | SuccessResponse]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiApibotSetBody,
) -> Response[AandtApiApibotSetResponse401 | SuccessResponse]:
"""Set the AAndT's apibot activation state and/or display name
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiApibotSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiApibotSetResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
body: AandtApiApibotSetBody,
) -> AandtApiApibotSetResponse401 | SuccessResponse | None:
"""Set the AAndT's apibot activation state and/or display name
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiApibotSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiApibotSetResponse401 | SuccessResponse
"""
return sync_detailed(
client=client,
body=body,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiApibotSetBody,
) -> Response[AandtApiApibotSetResponse401 | SuccessResponse]:
"""Set the AAndT's apibot activation state and/or display name
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiApibotSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiApibotSetResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
body: AandtApiApibotSetBody,
) -> AandtApiApibotSetResponse401 | SuccessResponse | None:
"""Set the AAndT's apibot activation state and/or display name
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiApibotSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiApibotSetResponse401 | SuccessResponse
"""
return (
await asyncio_detailed(
client=client,
body=body,
)
).parsed
@@ -0,0 +1,142 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_infos_response_200 import AandtApiInfosResponse200
from ...models.aandt_api_infos_response_401 import AandtApiInfosResponse401
from ...types import Response
def _get_kwargs() -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/",
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiInfosResponse200 | AandtApiInfosResponse401 | None:
if response.status_code == 200:
response_200 = AandtApiInfosResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiInfosResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiInfosResponse200 | AandtApiInfosResponse401]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiInfosResponse200 | AandtApiInfosResponse401]:
"""Get general information about the AAndT
Read-only. AAndT is resolved from the bearer token.
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiInfosResponse200 | AandtApiInfosResponse401]
"""
kwargs = _get_kwargs()
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
) -> AandtApiInfosResponse200 | AandtApiInfosResponse401 | None:
"""Get general information about the AAndT
Read-only. AAndT is resolved from the bearer token.
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiInfosResponse200 | AandtApiInfosResponse401
"""
return sync_detailed(
client=client,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiInfosResponse200 | AandtApiInfosResponse401]:
"""Get general information about the AAndT
Read-only. AAndT is resolved from the bearer token.
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiInfosResponse200 | AandtApiInfosResponse401]
"""
kwargs = _get_kwargs()
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
) -> AandtApiInfosResponse200 | AandtApiInfosResponse401 | None:
"""Get general information about the AAndT
Read-only. AAndT is resolved from the bearer token.
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiInfosResponse200 | AandtApiInfosResponse401
"""
return (
await asyncio_detailed(
client=client,
)
).parsed
@@ -0,0 +1,166 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_log_body import AandtApiLogBody
from ...models.aandt_api_log_response_401 import AandtApiLogResponse401
from ...models.success_response import SuccessResponse
from ...types import Response
def _get_kwargs(
*,
body: AandtApiLogBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/log",
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiLogResponse401 | SuccessResponse | None:
if response.status_code == 200:
response_200 = SuccessResponse.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiLogResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiLogResponse401 | SuccessResponse]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiLogBody,
) -> Response[AandtApiLogResponse401 | SuccessResponse]:
"""Add a log entry to the AAndT's log (prefixed with "API:")
Args:
body (AandtApiLogBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiLogResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
body: AandtApiLogBody,
) -> AandtApiLogResponse401 | SuccessResponse | None:
"""Add a log entry to the AAndT's log (prefixed with "API:")
Args:
body (AandtApiLogBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiLogResponse401 | SuccessResponse
"""
return sync_detailed(
client=client,
body=body,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiLogBody,
) -> Response[AandtApiLogResponse401 | SuccessResponse]:
"""Add a log entry to the AAndT's log (prefixed with "API:")
Args:
body (AandtApiLogBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiLogResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
body: AandtApiLogBody,
) -> AandtApiLogResponse401 | SuccessResponse | None:
"""Add a log entry to the AAndT's log (prefixed with "API:")
Args:
body (AandtApiLogBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiLogResponse401 | SuccessResponse
"""
return (
await asyncio_detailed(
client=client,
body=body,
)
).parsed
@@ -0,0 +1,190 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_match_messages_get_response_200 import (
AandtApiMatchMessagesGetResponse200,
)
from ...models.aandt_api_match_messages_get_response_401 import (
AandtApiMatchMessagesGetResponse401,
)
from ...types import Response
def _get_kwargs(
pk: int,
) -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/match/{pk}/messages".format(
pk=quote(str(pk), safe=""),
),
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> (
AandtApiMatchMessagesGetResponse200
| AandtApiMatchMessagesGetResponse401
| str
| None
):
if response.status_code == 200:
response_200 = AandtApiMatchMessagesGetResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMatchMessagesGetResponse401.from_dict(response.text)
return response_401
if response.status_code == 404:
response_404 = response.text
return response_404
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[
AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str
]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> Response[
AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str
]:
"""Get a match's bot messages (all/players/admin)
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str]
"""
kwargs = _get_kwargs(
pk=pk,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> (
AandtApiMatchMessagesGetResponse200
| AandtApiMatchMessagesGetResponse401
| str
| None
):
"""Get a match's bot messages (all/players/admin)
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str
"""
return sync_detailed(
pk=pk,
client=client,
).parsed
async def asyncio_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> Response[
AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str
]:
"""Get a match's bot messages (all/players/admin)
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str]
"""
kwargs = _get_kwargs(
pk=pk,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> (
AandtApiMatchMessagesGetResponse200
| AandtApiMatchMessagesGetResponse401
| str
| None
):
"""Get a match's bot messages (all/players/admin)
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMessagesGetResponse200 | AandtApiMatchMessagesGetResponse401 | str
"""
return (
await asyncio_detailed(
pk=pk,
client=client,
)
).parsed
@@ -0,0 +1,200 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_match_messages_set_body import AandtApiMatchMessagesSetBody
from ...models.aandt_api_match_messages_set_response_401 import (
AandtApiMatchMessagesSetResponse401,
)
from ...models.success_response import SuccessResponse
from ...types import Response
def _get_kwargs(
pk: int,
*,
body: AandtApiMatchMessagesSetBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/match/{pk}/messages".format(
pk=quote(str(pk), safe=""),
),
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMatchMessagesSetResponse401 | SuccessResponse | str | None:
if response.status_code == 200:
response_200 = SuccessResponse.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMatchMessagesSetResponse401.from_dict(response.text)
return response_401
if response.status_code == 404:
response_404 = response.text
return response_404
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMatchMessagesSetResponse401 | SuccessResponse | str]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMessagesSetBody,
) -> Response[AandtApiMatchMessagesSetResponse401 | SuccessResponse | str]:
"""Set one or more of a match's bot messages
Any of `all`, `players`, `admin` may be omitted; only the keys present in the body are updated.
Triggers a Zuperpush update.
Args:
pk (int):
body (AandtApiMatchMessagesSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMessagesSetResponse401 | SuccessResponse | str]
"""
kwargs = _get_kwargs(
pk=pk,
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMessagesSetBody,
) -> AandtApiMatchMessagesSetResponse401 | SuccessResponse | str | None:
"""Set one or more of a match's bot messages
Any of `all`, `players`, `admin` may be omitted; only the keys present in the body are updated.
Triggers a Zuperpush update.
Args:
pk (int):
body (AandtApiMatchMessagesSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMessagesSetResponse401 | SuccessResponse | str
"""
return sync_detailed(
pk=pk,
client=client,
body=body,
).parsed
async def asyncio_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMessagesSetBody,
) -> Response[AandtApiMatchMessagesSetResponse401 | SuccessResponse | str]:
"""Set one or more of a match's bot messages
Any of `all`, `players`, `admin` may be omitted; only the keys present in the body are updated.
Triggers a Zuperpush update.
Args:
pk (int):
body (AandtApiMatchMessagesSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMessagesSetResponse401 | SuccessResponse | str]
"""
kwargs = _get_kwargs(
pk=pk,
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMessagesSetBody,
) -> AandtApiMatchMessagesSetResponse401 | SuccessResponse | str | None:
"""Set one or more of a match's bot messages
Any of `all`, `players`, `admin` may be omitted; only the keys present in the body are updated.
Triggers a Zuperpush update.
Args:
pk (int):
body (AandtApiMatchMessagesSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMessagesSetResponse401 | SuccessResponse | str
"""
return (
await asyncio_detailed(
pk=pk,
client=client,
body=body,
)
).parsed
@@ -0,0 +1,190 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_match_metadata_get_response_200 import (
AandtApiMatchMetadataGetResponse200,
)
from ...models.aandt_api_match_metadata_get_response_401 import (
AandtApiMatchMetadataGetResponse401,
)
from ...types import Response
def _get_kwargs(
pk: int,
) -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/match/{pk}/metadata".format(
pk=quote(str(pk), safe=""),
),
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> (
AandtApiMatchMetadataGetResponse200
| AandtApiMatchMetadataGetResponse401
| str
| None
):
if response.status_code == 200:
response_200 = AandtApiMatchMetadataGetResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMatchMetadataGetResponse401.from_dict(response.text)
return response_401
if response.status_code == 404:
response_404 = response.text
return response_404
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[
AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str
]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> Response[
AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str
]:
"""Get a match's bot metadata
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str]
"""
kwargs = _get_kwargs(
pk=pk,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> (
AandtApiMatchMetadataGetResponse200
| AandtApiMatchMetadataGetResponse401
| str
| None
):
"""Get a match's bot metadata
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str
"""
return sync_detailed(
pk=pk,
client=client,
).parsed
async def asyncio_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> Response[
AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str
]:
"""Get a match's bot metadata
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str]
"""
kwargs = _get_kwargs(
pk=pk,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
pk: int,
*,
client: AuthenticatedClient | Client,
) -> (
AandtApiMatchMetadataGetResponse200
| AandtApiMatchMetadataGetResponse401
| str
| None
):
"""Get a match's bot metadata
Args:
pk (int):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMetadataGetResponse200 | AandtApiMatchMetadataGetResponse401 | str
"""
return (
await asyncio_detailed(
pk=pk,
client=client,
)
).parsed
@@ -0,0 +1,188 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_match_metadata_set_body import AandtApiMatchMetadataSetBody
from ...models.aandt_api_match_metadata_set_response_401 import (
AandtApiMatchMetadataSetResponse401,
)
from ...models.success_response import SuccessResponse
from ...types import Response
def _get_kwargs(
pk: int,
*,
body: AandtApiMatchMetadataSetBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/match/{pk}/metadata".format(
pk=quote(str(pk), safe=""),
),
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMatchMetadataSetResponse401 | SuccessResponse | str | None:
if response.status_code == 200:
response_200 = SuccessResponse.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMatchMetadataSetResponse401.from_dict(response.text)
return response_401
if response.status_code == 404:
response_404 = response.text
return response_404
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMatchMetadataSetResponse401 | SuccessResponse | str]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMetadataSetBody,
) -> Response[AandtApiMatchMetadataSetResponse401 | SuccessResponse | str]:
"""Set a match's bot metadata
Args:
pk (int):
body (AandtApiMatchMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMetadataSetResponse401 | SuccessResponse | str]
"""
kwargs = _get_kwargs(
pk=pk,
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMetadataSetBody,
) -> AandtApiMatchMetadataSetResponse401 | SuccessResponse | str | None:
"""Set a match's bot metadata
Args:
pk (int):
body (AandtApiMatchMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMetadataSetResponse401 | SuccessResponse | str
"""
return sync_detailed(
pk=pk,
client=client,
body=body,
).parsed
async def asyncio_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMetadataSetBody,
) -> Response[AandtApiMatchMetadataSetResponse401 | SuccessResponse | str]:
"""Set a match's bot metadata
Args:
pk (int):
body (AandtApiMatchMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchMetadataSetResponse401 | SuccessResponse | str]
"""
kwargs = _get_kwargs(
pk=pk,
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchMetadataSetBody,
) -> AandtApiMatchMetadataSetResponse401 | SuccessResponse | str | None:
"""Set a match's bot metadata
Args:
pk (int):
body (AandtApiMatchMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchMetadataSetResponse401 | SuccessResponse | str
"""
return (
await asyncio_detailed(
pk=pk,
client=client,
body=body,
)
).parsed
@@ -0,0 +1,231 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_match_submit_results_body import AandtApiMatchSubmitResultsBody
from ...models.aandt_api_match_submit_results_response_200 import (
AandtApiMatchSubmitResultsResponse200,
)
from ...models.aandt_api_match_submit_results_response_401 import (
AandtApiMatchSubmitResultsResponse401,
)
from ...types import Response
def _get_kwargs(
pk: int,
*,
body: AandtApiMatchSubmitResultsBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/match/{pk}/sumbit_results".format(
pk=quote(str(pk), safe=""),
),
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> (
AandtApiMatchSubmitResultsResponse200
| AandtApiMatchSubmitResultsResponse401
| str
| None
):
if response.status_code == 200:
response_200 = AandtApiMatchSubmitResultsResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMatchSubmitResultsResponse401.from_dict(response.text)
return response_401
if response.status_code == 404:
response_404 = response.text
return response_404
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[
AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str
]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchSubmitResultsBody,
) -> Response[
AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str
]:
"""Submit results for the match's current round
`round` must equal the match's current round (`Matsch.cRound()`), otherwise the request is rejected.
`results` maps a MatschHasPlayerOrTeam pk (string key) to that participant's score for the round
(omitted participants default to 0 if `usePoints`, else 1). Advances/finishes the match and pushes
live updates.
Args:
pk (int):
body (AandtApiMatchSubmitResultsBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str]
"""
kwargs = _get_kwargs(
pk=pk,
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchSubmitResultsBody,
) -> (
AandtApiMatchSubmitResultsResponse200
| AandtApiMatchSubmitResultsResponse401
| str
| None
):
"""Submit results for the match's current round
`round` must equal the match's current round (`Matsch.cRound()`), otherwise the request is rejected.
`results` maps a MatschHasPlayerOrTeam pk (string key) to that participant's score for the round
(omitted participants default to 0 if `usePoints`, else 1). Advances/finishes the match and pushes
live updates.
Args:
pk (int):
body (AandtApiMatchSubmitResultsBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str
"""
return sync_detailed(
pk=pk,
client=client,
body=body,
).parsed
async def asyncio_detailed(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchSubmitResultsBody,
) -> Response[
AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str
]:
"""Submit results for the match's current round
`round` must equal the match's current round (`Matsch.cRound()`), otherwise the request is rejected.
`results` maps a MatschHasPlayerOrTeam pk (string key) to that participant's score for the round
(omitted participants default to 0 if `usePoints`, else 1). Advances/finishes the match and pushes
live updates.
Args:
pk (int):
body (AandtApiMatchSubmitResultsBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str]
"""
kwargs = _get_kwargs(
pk=pk,
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
pk: int,
*,
client: AuthenticatedClient | Client,
body: AandtApiMatchSubmitResultsBody,
) -> (
AandtApiMatchSubmitResultsResponse200
| AandtApiMatchSubmitResultsResponse401
| str
| None
):
"""Submit results for the match's current round
`round` must equal the match's current round (`Matsch.cRound()`), otherwise the request is rejected.
`results` maps a MatschHasPlayerOrTeam pk (string key) to that participant's score for the round
(omitted participants default to 0 if `usePoints`, else 1). Advances/finishes the match and pushes
live updates.
Args:
pk (int):
body (AandtApiMatchSubmitResultsBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchSubmitResultsResponse200 | AandtApiMatchSubmitResultsResponse401 | str
"""
return (
await asyncio_detailed(
pk=pk,
client=client,
body=body,
)
).parsed
@@ -0,0 +1,134 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_matches_response_200 import AandtApiMatchesResponse200
from ...models.aandt_api_matches_response_401 import AandtApiMatchesResponse401
from ...types import Response
def _get_kwargs() -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/matches",
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMatchesResponse200 | AandtApiMatchesResponse401 | None:
if response.status_code == 200:
response_200 = AandtApiMatchesResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMatchesResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMatchesResponse200 | AandtApiMatchesResponse401]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMatchesResponse200 | AandtApiMatchesResponse401]:
"""List all matches of the AAndT with their rounds/results
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchesResponse200 | AandtApiMatchesResponse401]
"""
kwargs = _get_kwargs()
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMatchesResponse200 | AandtApiMatchesResponse401 | None:
"""List all matches of the AAndT with their rounds/results
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchesResponse200 | AandtApiMatchesResponse401
"""
return sync_detailed(
client=client,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMatchesResponse200 | AandtApiMatchesResponse401]:
"""List all matches of the AAndT with their rounds/results
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMatchesResponse200 | AandtApiMatchesResponse401]
"""
kwargs = _get_kwargs()
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMatchesResponse200 | AandtApiMatchesResponse401 | None:
"""List all matches of the AAndT with their rounds/results
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMatchesResponse200 | AandtApiMatchesResponse401
"""
return (
await asyncio_detailed(
client=client,
)
).parsed
@@ -0,0 +1,134 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_members_response_200 import AandtApiMembersResponse200
from ...models.aandt_api_members_response_401 import AandtApiMembersResponse401
from ...types import Response
def _get_kwargs() -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/members",
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMembersResponse200 | AandtApiMembersResponse401 | None:
if response.status_code == 200:
response_200 = AandtApiMembersResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMembersResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMembersResponse200 | AandtApiMembersResponse401]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMembersResponse200 | AandtApiMembersResponse401]:
"""List the AAndT's registered members (users or teams)
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMembersResponse200 | AandtApiMembersResponse401]
"""
kwargs = _get_kwargs()
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMembersResponse200 | AandtApiMembersResponse401 | None:
"""List the AAndT's registered members (users or teams)
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMembersResponse200 | AandtApiMembersResponse401
"""
return sync_detailed(
client=client,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMembersResponse200 | AandtApiMembersResponse401]:
"""List the AAndT's registered members (users or teams)
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMembersResponse200 | AandtApiMembersResponse401]
"""
kwargs = _get_kwargs()
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMembersResponse200 | AandtApiMembersResponse401 | None:
"""List the AAndT's registered members (users or teams)
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMembersResponse200 | AandtApiMembersResponse401
"""
return (
await asyncio_detailed(
client=client,
)
).parsed
@@ -0,0 +1,134 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_message_get_response_200 import AandtApiMessageGetResponse200
from ...models.aandt_api_message_get_response_401 import AandtApiMessageGetResponse401
from ...types import Response
def _get_kwargs() -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/message",
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401 | None:
if response.status_code == 200:
response_200 = AandtApiMessageGetResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMessageGetResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401]:
"""Get the AAndT's apibot page message
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401]
"""
kwargs = _get_kwargs()
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401 | None:
"""Get the AAndT's apibot page message
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401
"""
return sync_detailed(
client=client,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401]:
"""Get the AAndT's apibot page message
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401]
"""
kwargs = _get_kwargs()
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401 | None:
"""Get the AAndT's apibot page message
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMessageGetResponse200 | AandtApiMessageGetResponse401
"""
return (
await asyncio_detailed(
client=client,
)
).parsed
@@ -0,0 +1,174 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_message_set_body import AandtApiMessageSetBody
from ...models.aandt_api_message_set_response_401 import AandtApiMessageSetResponse401
from ...models.success_response import SuccessResponse
from ...types import Response
def _get_kwargs(
*,
body: AandtApiMessageSetBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/message",
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMessageSetResponse401 | SuccessResponse | None:
if response.status_code == 200:
response_200 = SuccessResponse.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMessageSetResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMessageSetResponse401 | SuccessResponse]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiMessageSetBody,
) -> Response[AandtApiMessageSetResponse401 | SuccessResponse]:
"""Set the AAndT's apibot page message
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiMessageSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMessageSetResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
body: AandtApiMessageSetBody,
) -> AandtApiMessageSetResponse401 | SuccessResponse | None:
"""Set the AAndT's apibot page message
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiMessageSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMessageSetResponse401 | SuccessResponse
"""
return sync_detailed(
client=client,
body=body,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiMessageSetBody,
) -> Response[AandtApiMessageSetResponse401 | SuccessResponse]:
"""Set the AAndT's apibot page message
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiMessageSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMessageSetResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
body: AandtApiMessageSetBody,
) -> AandtApiMessageSetResponse401 | SuccessResponse | None:
"""Set the AAndT's apibot page message
Broadcasts the update over Zuperpush after saving.
Args:
body (AandtApiMessageSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMessageSetResponse401 | SuccessResponse
"""
return (
await asyncio_detailed(
client=client,
body=body,
)
).parsed
@@ -0,0 +1,134 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_metadata_get_response_200 import AandtApiMetadataGetResponse200
from ...models.aandt_api_metadata_get_response_401 import AandtApiMetadataGetResponse401
from ...types import Response
def _get_kwargs() -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/metadata",
}
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401 | None:
if response.status_code == 200:
response_200 = AandtApiMetadataGetResponse200.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMetadataGetResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401]:
"""Get the AAndT's bot metadata
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401]
"""
kwargs = _get_kwargs()
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401 | None:
"""Get the AAndT's bot metadata
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401
"""
return sync_detailed(
client=client,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
) -> Response[AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401]:
"""Get the AAndT's bot metadata
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401]
"""
kwargs = _get_kwargs()
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
) -> AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401 | None:
"""Get the AAndT's bot metadata
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMetadataGetResponse200 | AandtApiMetadataGetResponse401
"""
return (
await asyncio_detailed(
client=client,
)
).parsed
@@ -0,0 +1,166 @@
from http import HTTPStatus
from typing import Any
import httpx
from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.aandt_api_metadata_set_body import AandtApiMetadataSetBody
from ...models.aandt_api_metadata_set_response_401 import AandtApiMetadataSetResponse401
from ...models.success_response import SuccessResponse
from ...types import Response
def _get_kwargs(
*,
body: AandtApiMetadataSetBody,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/metadata",
}
_kwargs["json"] = body.to_dict()
headers["Content-Type"] = "application/json"
_kwargs["headers"] = headers
return _kwargs
def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> AandtApiMetadataSetResponse401 | SuccessResponse | None:
if response.status_code == 200:
response_200 = SuccessResponse.from_dict(response.json())
return response_200
if response.status_code == 401:
response_401 = AandtApiMetadataSetResponse401.from_dict(response.text)
return response_401
if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None
def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[AandtApiMetadataSetResponse401 | SuccessResponse]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)
def sync_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiMetadataSetBody,
) -> Response[AandtApiMetadataSetResponse401 | SuccessResponse]:
"""Set the AAndT's bot metadata
Args:
body (AandtApiMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMetadataSetResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = client.get_httpx_client().request(
**kwargs,
)
return _build_response(client=client, response=response)
def sync(
*,
client: AuthenticatedClient | Client,
body: AandtApiMetadataSetBody,
) -> AandtApiMetadataSetResponse401 | SuccessResponse | None:
"""Set the AAndT's bot metadata
Args:
body (AandtApiMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMetadataSetResponse401 | SuccessResponse
"""
return sync_detailed(
client=client,
body=body,
).parsed
async def asyncio_detailed(
*,
client: AuthenticatedClient | Client,
body: AandtApiMetadataSetBody,
) -> Response[AandtApiMetadataSetResponse401 | SuccessResponse]:
"""Set the AAndT's bot metadata
Args:
body (AandtApiMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
Response[AandtApiMetadataSetResponse401 | SuccessResponse]
"""
kwargs = _get_kwargs(
body=body,
)
response = await client.get_async_httpx_client().request(**kwargs)
return _build_response(client=client, response=response)
async def asyncio(
*,
client: AuthenticatedClient | Client,
body: AandtApiMetadataSetBody,
) -> AandtApiMetadataSetResponse401 | SuccessResponse | None:
"""Set the AAndT's bot metadata
Args:
body (AandtApiMetadataSetBody):
Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.
Returns:
AandtApiMetadataSetResponse401 | SuccessResponse
"""
return (
await asyncio_detailed(
client=client,
body=body,
)
).parsed
@@ -0,0 +1,280 @@
import ssl
from typing import Any, Self
import httpx
from attrs import define, evolve, field
@define
class Client:
"""A class for keeping track of data related to the API
The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
``base_url``: The base URL for the API, all requests are made to a relative path to this URL
``cookies``: A dictionary of cookies to be sent with every request
``headers``: A dictionary of headers to be sent with every request
``timeout``: The maximum amount of a time a request can take. API functions will raise
httpx.TimeoutException if this is exceeded.
``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
but can be set to False for testing purposes.
``follow_redirects``: Whether or not to follow redirects. Default value is False.
``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
Attributes:
raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
argument to the constructor.
"""
raise_on_unexpected_status: bool = field(default=False, kw_only=True)
_base_url: str = field(alias="base_url")
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
_timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
_verify_ssl: str | bool | ssl.SSLContext = field(
default=True, kw_only=True, alias="verify_ssl"
)
_follow_redirects: bool = field(
default=False, kw_only=True, alias="follow_redirects"
)
_httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
_client: httpx.Client | None = field(default=None, init=False)
_async_client: httpx.AsyncClient | None = field(default=None, init=False)
def with_headers(self, headers: dict[str, str]) -> "Client":
"""Get a new client matching this one with additional headers"""
if self._client is not None:
self._client.headers.update(headers)
if self._async_client is not None:
self._async_client.headers.update(headers)
return evolve(self, headers={**self._headers, **headers})
def with_cookies(self, cookies: dict[str, str]) -> "Client":
"""Get a new client matching this one with additional cookies"""
if self._client is not None:
self._client.cookies.update(cookies)
if self._async_client is not None:
self._async_client.cookies.update(cookies)
return evolve(self, cookies={**self._cookies, **cookies})
def with_timeout(self, timeout: httpx.Timeout) -> "Client":
"""Get a new client matching this one with a new timeout configuration"""
if self._client is not None:
self._client.timeout = timeout
if self._async_client is not None:
self._async_client.timeout = timeout
return evolve(self, timeout=timeout)
def set_httpx_client(self, client: httpx.Client) -> Self:
"""Manually set the underlying httpx.Client
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
"""
self._client = client
return self
def get_httpx_client(self) -> httpx.Client:
"""Get the underlying httpx.Client, constructing a new one if not previously set"""
if self._client is None:
self._client = httpx.Client(
base_url=self._base_url,
cookies=self._cookies,
headers=self._headers,
timeout=self._timeout,
verify=self._verify_ssl,
follow_redirects=self._follow_redirects,
**self._httpx_args,
)
return self._client
def __enter__(self) -> Self:
"""Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
self.get_httpx_client().__enter__()
return self
def __exit__(self, *args: object, **kwargs: Any) -> None:
"""Exit a context manager for internal httpx.Client (see httpx docs)"""
self.get_httpx_client().__exit__(*args, **kwargs)
def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> Self:
"""Manually set the underlying httpx.AsyncClient
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
"""
self._async_client = async_client
return self
def get_async_httpx_client(self) -> httpx.AsyncClient:
"""Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
if self._async_client is None:
self._async_client = httpx.AsyncClient(
base_url=self._base_url,
cookies=self._cookies,
headers=self._headers,
timeout=self._timeout,
verify=self._verify_ssl,
follow_redirects=self._follow_redirects,
**self._httpx_args,
)
return self._async_client
async def __aenter__(self) -> Self:
"""Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
await self.get_async_httpx_client().__aenter__()
return self
async def __aexit__(self, *args: object, **kwargs: Any) -> None:
"""Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
await self.get_async_httpx_client().__aexit__(*args, **kwargs)
@define
class AuthenticatedClient:
"""A Client which has been authenticated for use on secured endpoints
The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
``base_url``: The base URL for the API, all requests are made to a relative path to this URL
``cookies``: A dictionary of cookies to be sent with every request
``headers``: A dictionary of headers to be sent with every request
``timeout``: The maximum amount of a time a request can take. API functions will raise
httpx.TimeoutException if this is exceeded.
``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
but can be set to False for testing purposes.
``follow_redirects``: Whether or not to follow redirects. Default value is False.
``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
Attributes:
raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
argument to the constructor.
token: The token to use for authentication
prefix: The prefix to use for the Authorization header
auth_header_name: The name of the Authorization header
"""
raise_on_unexpected_status: bool = field(default=False, kw_only=True)
_base_url: str = field(alias="base_url")
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
_timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
_verify_ssl: str | bool | ssl.SSLContext = field(
default=True, kw_only=True, alias="verify_ssl"
)
_follow_redirects: bool = field(
default=False, kw_only=True, alias="follow_redirects"
)
_httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
_client: httpx.Client | None = field(default=None, init=False)
_async_client: httpx.AsyncClient | None = field(default=None, init=False)
token: str
prefix: str = "Bearer"
auth_header_name: str = "Authorization"
def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient":
"""Get a new client matching this one with additional headers"""
if self._client is not None:
self._client.headers.update(headers)
if self._async_client is not None:
self._async_client.headers.update(headers)
return evolve(self, headers={**self._headers, **headers})
def with_cookies(self, cookies: dict[str, str]) -> "AuthenticatedClient":
"""Get a new client matching this one with additional cookies"""
if self._client is not None:
self._client.cookies.update(cookies)
if self._async_client is not None:
self._async_client.cookies.update(cookies)
return evolve(self, cookies={**self._cookies, **cookies})
def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient":
"""Get a new client matching this one with a new timeout configuration"""
if self._client is not None:
self._client.timeout = timeout
if self._async_client is not None:
self._async_client.timeout = timeout
return evolve(self, timeout=timeout)
def set_httpx_client(self, client: httpx.Client) -> Self:
"""Manually set the underlying httpx.Client
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
"""
self._client = client
return self
def get_httpx_client(self) -> httpx.Client:
"""Get the underlying httpx.Client, constructing a new one if not previously set"""
if self._client is None:
self._headers[self.auth_header_name] = (
f"{self.prefix} {self.token}" if self.prefix else self.token
)
self._client = httpx.Client(
base_url=self._base_url,
cookies=self._cookies,
headers=self._headers,
timeout=self._timeout,
verify=self._verify_ssl,
follow_redirects=self._follow_redirects,
**self._httpx_args,
)
return self._client
def __enter__(self) -> Self:
"""Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
self.get_httpx_client().__enter__()
return self
def __exit__(self, *args: object, **kwargs: Any) -> None:
"""Exit a context manager for internal httpx.Client (see httpx docs)"""
self.get_httpx_client().__exit__(*args, **kwargs)
def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> Self:
"""Manually set the underlying httpx.AsyncClient
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
"""
self._async_client = async_client
return self
def get_async_httpx_client(self) -> httpx.AsyncClient:
"""Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
if self._async_client is None:
self._headers[self.auth_header_name] = (
f"{self.prefix} {self.token}" if self.prefix else self.token
)
self._async_client = httpx.AsyncClient(
base_url=self._base_url,
cookies=self._cookies,
headers=self._headers,
timeout=self._timeout,
verify=self._verify_ssl,
follow_redirects=self._follow_redirects,
**self._httpx_args,
)
return self._async_client
async def __aenter__(self) -> Self:
"""Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
await self.get_async_httpx_client().__aenter__()
return self
async def __aexit__(self, *args: object, **kwargs: Any) -> None:
"""Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
await self.get_async_httpx_client().__aexit__(*args, **kwargs)
@@ -0,0 +1,16 @@
"""Contains shared errors types that can be raised from API functions"""
class UnexpectedStatus(Exception):
"""Raised by api functions when the response status an undocumented status and Client.raise_on_unexpected_status is True"""
def __init__(self, status_code: int, content: bytes):
self.status_code = status_code
self.content = content
super().__init__(
f"Unexpected status code: {status_code}\n\nResponse content:\n{content.decode(errors='ignore')}"
)
__all__ = ["UnexpectedStatus"]
@@ -0,0 +1,117 @@
"""Contains all the data models used in inputs/outputs"""
from .a_and_t_infos import AAndTInfos
from .a_and_t_infos_status import AAndTInfosStatus
from .aandt_api_apibot_get_response_200 import AandtApiApibotGetResponse200
from .aandt_api_apibot_get_response_401 import AandtApiApibotGetResponse401
from .aandt_api_apibot_set_body import AandtApiApibotSetBody
from .aandt_api_apibot_set_response_401 import AandtApiApibotSetResponse401
from .aandt_api_infos_response_200 import AandtApiInfosResponse200
from .aandt_api_infos_response_401 import AandtApiInfosResponse401
from .aandt_api_log_body import AandtApiLogBody
from .aandt_api_log_response_401 import AandtApiLogResponse401
from .aandt_api_match_messages_get_response_200 import (
AandtApiMatchMessagesGetResponse200,
)
from .aandt_api_match_messages_get_response_401 import (
AandtApiMatchMessagesGetResponse401,
)
from .aandt_api_match_messages_set_body import AandtApiMatchMessagesSetBody
from .aandt_api_match_messages_set_response_401 import (
AandtApiMatchMessagesSetResponse401,
)
from .aandt_api_match_metadata_get_response_200 import (
AandtApiMatchMetadataGetResponse200,
)
from .aandt_api_match_metadata_get_response_401 import (
AandtApiMatchMetadataGetResponse401,
)
from .aandt_api_match_metadata_set_body import AandtApiMatchMetadataSetBody
from .aandt_api_match_metadata_set_response_401 import (
AandtApiMatchMetadataSetResponse401,
)
from .aandt_api_match_submit_results_body import AandtApiMatchSubmitResultsBody
from .aandt_api_match_submit_results_body_results import (
AandtApiMatchSubmitResultsBodyResults,
)
from .aandt_api_match_submit_results_response_200 import (
AandtApiMatchSubmitResultsResponse200,
)
from .aandt_api_match_submit_results_response_200_message import (
AandtApiMatchSubmitResultsResponse200Message,
)
from .aandt_api_match_submit_results_response_401 import (
AandtApiMatchSubmitResultsResponse401,
)
from .aandt_api_matches_response_200 import AandtApiMatchesResponse200
from .aandt_api_matches_response_401 import AandtApiMatchesResponse401
from .aandt_api_members_response_200 import AandtApiMembersResponse200
from .aandt_api_members_response_401 import AandtApiMembersResponse401
from .aandt_api_message_get_response_200 import AandtApiMessageGetResponse200
from .aandt_api_message_get_response_401 import AandtApiMessageGetResponse401
from .aandt_api_message_set_body import AandtApiMessageSetBody
from .aandt_api_message_set_response_401 import AandtApiMessageSetResponse401
from .aandt_api_metadata_get_response_200 import AandtApiMetadataGetResponse200
from .aandt_api_metadata_get_response_401 import AandtApiMetadataGetResponse401
from .aandt_api_metadata_set_body import AandtApiMetadataSetBody
from .aandt_api_metadata_set_response_401 import AandtApiMetadataSetResponse401
from .match import Match
from .match_multiround_modes import MatchMultiroundModes
from .match_players import MatchPlayers
from .match_round import MatchRound
from .match_round_result import MatchRoundResult
from .match_status import MatchStatus
from .member import Member
from .member_team import MemberTeam
from .member_user import MemberUser
from .metadata import Metadata
from .success_response import SuccessResponse
__all__ = (
"AAndTInfos",
"AAndTInfosStatus",
"AandtApiApibotGetResponse200",
"AandtApiApibotGetResponse401",
"AandtApiApibotSetBody",
"AandtApiApibotSetResponse401",
"AandtApiInfosResponse200",
"AandtApiInfosResponse401",
"AandtApiLogBody",
"AandtApiLogResponse401",
"AandtApiMatchMessagesGetResponse200",
"AandtApiMatchMessagesGetResponse401",
"AandtApiMatchMessagesSetBody",
"AandtApiMatchMessagesSetResponse401",
"AandtApiMatchMetadataGetResponse200",
"AandtApiMatchMetadataGetResponse401",
"AandtApiMatchMetadataSetBody",
"AandtApiMatchMetadataSetResponse401",
"AandtApiMatchSubmitResultsBody",
"AandtApiMatchSubmitResultsBodyResults",
"AandtApiMatchSubmitResultsResponse200",
"AandtApiMatchSubmitResultsResponse200Message",
"AandtApiMatchSubmitResultsResponse401",
"AandtApiMatchesResponse200",
"AandtApiMatchesResponse401",
"AandtApiMembersResponse200",
"AandtApiMembersResponse401",
"AandtApiMessageGetResponse200",
"AandtApiMessageGetResponse401",
"AandtApiMessageSetBody",
"AandtApiMessageSetResponse401",
"AandtApiMetadataGetResponse200",
"AandtApiMetadataGetResponse401",
"AandtApiMetadataSetBody",
"AandtApiMetadataSetResponse401",
"Match",
"MatchMultiroundModes",
"MatchPlayers",
"MatchRound",
"MatchRoundResult",
"MatchStatus",
"Member",
"MemberTeam",
"MemberUser",
"Metadata",
"SuccessResponse",
)
@@ -0,0 +1,106 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..models.a_and_t_infos_status import AAndTInfosStatus
from ..types import UNSET, Unset
T = TypeVar("T", bound="AAndTInfos")
@_attrs_define
class AAndTInfos:
"""
Attributes:
name (str | Unset):
status (AAndTInfosStatus | Unset):
status_display (str | Unset): Example: Matchs en cours.
use_teams (bool | Unset):
max_entities (int | Unset):
"""
name: str | Unset = UNSET
status: AAndTInfosStatus | Unset = UNSET
status_display: str | Unset = UNSET
use_teams: bool | Unset = UNSET
max_entities: int | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
name = self.name
status: str | Unset = UNSET
if not isinstance(self.status, Unset):
status = self.status.value
status_display = self.status_display
use_teams = self.use_teams
max_entities = self.max_entities
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if name is not UNSET:
field_dict["name"] = name
if status is not UNSET:
field_dict["status"] = status
if status_display is not UNSET:
field_dict["status_display"] = status_display
if use_teams is not UNSET:
field_dict["use_teams"] = use_teams
if max_entities is not UNSET:
field_dict["max_entities"] = max_entities
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
name = d.pop("name", UNSET)
_status = d.pop("status", UNSET)
status: AAndTInfosStatus | Unset
if isinstance(_status, Unset):
status = UNSET
else:
status = AAndTInfosStatus(_status)
status_display = d.pop("status_display", UNSET)
use_teams = d.pop("use_teams", UNSET)
max_entities = d.pop("max_entities", UNSET)
a_and_t_infos = cls(
name=name,
status=status,
status_display=status_display,
use_teams=use_teams,
max_entities=max_entities,
)
a_and_t_infos.additional_properties = d
return a_and_t_infos
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,14 @@
from enum import StrEnum
class AAndTInfosStatus(StrEnum):
VALUE_0 = "0prep"
VALUE_1 = "1publ"
VALUE_2 = "3insc"
VALUE_3 = "5inscdone"
VALUE_4 = "7inprog"
VALUE_5 = "9done"
VALUE_6 = "11reviewed"
def __str__(self) -> str:
return str(self.value)
@@ -0,0 +1,71 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiApibotGetResponse200")
@_attrs_define
class AandtApiApibotGetResponse200:
"""
Attributes:
activated (bool | Unset):
name (str | Unset):
"""
activated: bool | Unset = UNSET
name: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
activated = self.activated
name = self.name
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if activated is not UNSET:
field_dict["activated"] = activated
if name is not UNSET:
field_dict["name"] = name
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
activated = d.pop("activated", UNSET)
name = d.pop("name", UNSET)
aandt_api_apibot_get_response_200 = cls(
activated=activated,
name=name,
)
aandt_api_apibot_get_response_200.additional_properties = d
return aandt_api_apibot_get_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiApibotGetResponse401")
@_attrs_define
class AandtApiApibotGetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_apibot_get_response_401 = cls(
message=message,
)
aandt_api_apibot_get_response_401.additional_properties = d
return aandt_api_apibot_get_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,71 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiApibotSetBody")
@_attrs_define
class AandtApiApibotSetBody:
"""
Attributes:
activated (bool | Unset):
name (str | Unset):
"""
activated: bool | Unset = UNSET
name: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
activated = self.activated
name = self.name
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if activated is not UNSET:
field_dict["activated"] = activated
if name is not UNSET:
field_dict["name"] = name
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
activated = d.pop("activated", UNSET)
name = d.pop("name", UNSET)
aandt_api_apibot_set_body = cls(
activated=activated,
name=name,
)
aandt_api_apibot_set_body.additional_properties = d
return aandt_api_apibot_set_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiApibotSetResponse401")
@_attrs_define
class AandtApiApibotSetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_apibot_set_response_401 = cls(
message=message,
)
aandt_api_apibot_set_response_401.additional_properties = d
return aandt_api_apibot_set_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,75 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.a_and_t_infos import AAndTInfos
T = TypeVar("T", bound="AandtApiInfosResponse200")
@_attrs_define
class AandtApiInfosResponse200:
"""
Attributes:
aandt (AAndTInfos | Unset):
"""
aandt: AAndTInfos | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
aandt: dict[str, Any] | Unset = UNSET
if not isinstance(self.aandt, Unset):
aandt = self.aandt.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if aandt is not UNSET:
field_dict["aandt"] = aandt
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.a_and_t_infos import AAndTInfos
d = dict(src_dict)
_aandt = d.pop("aandt", UNSET)
aandt: AAndTInfos | Unset
if isinstance(_aandt, Unset):
aandt = UNSET
else:
aandt = AAndTInfos.from_dict(_aandt)
aandt_api_infos_response_200 = cls(
aandt=aandt,
)
aandt_api_infos_response_200.additional_properties = d
return aandt_api_infos_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiInfosResponse401")
@_attrs_define
class AandtApiInfosResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_infos_response_401 = cls(
message=message,
)
aandt_api_infos_response_401.additional_properties = d
return aandt_api_infos_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,70 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
T = TypeVar("T", bound="AandtApiLogBody")
@_attrs_define
class AandtApiLogBody:
"""
Attributes:
type_ (str): AAndTLog type, e.g. "info", "error"
message (str):
"""
type_: str
message: str
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
type_ = self.type_
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update(
{
"type": type_,
"message": message,
}
)
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
type_ = d.pop("type")
message = d.pop("message")
aandt_api_log_body = cls(
type_=type_,
message=message,
)
aandt_api_log_body.additional_properties = d
return aandt_api_log_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiLogResponse401")
@_attrs_define
class AandtApiLogResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_log_response_401 = cls(
message=message,
)
aandt_api_log_response_401.additional_properties = d
return aandt_api_log_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,114 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar, cast
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchMessagesGetResponse200")
@_attrs_define
class AandtApiMatchMessagesGetResponse200:
"""
Attributes:
all_ (None | str | Unset):
players (None | str | Unset):
admin (None | str | Unset):
"""
all_: None | str | Unset = UNSET
players: None | str | Unset = UNSET
admin: None | str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
all_: None | str | Unset
if isinstance(self.all_, Unset):
all_ = UNSET
else:
all_ = self.all_
players: None | str | Unset
if isinstance(self.players, Unset):
players = UNSET
else:
players = self.players
admin: None | str | Unset
if isinstance(self.admin, Unset):
admin = UNSET
else:
admin = self.admin
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if all_ is not UNSET:
field_dict["all"] = all_
if players is not UNSET:
field_dict["players"] = players
if admin is not UNSET:
field_dict["admin"] = admin
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
def _parse_all_(data: object) -> None | str | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(None | str | Unset, data)
all_ = _parse_all_(d.pop("all", UNSET))
def _parse_players(data: object) -> None | str | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(None | str | Unset, data)
players = _parse_players(d.pop("players", UNSET))
def _parse_admin(data: object) -> None | str | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(None | str | Unset, data)
admin = _parse_admin(d.pop("admin", UNSET))
aandt_api_match_messages_get_response_200 = cls(
all_=all_,
players=players,
admin=admin,
)
aandt_api_match_messages_get_response_200.additional_properties = d
return aandt_api_match_messages_get_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchMessagesGetResponse401")
@_attrs_define
class AandtApiMatchMessagesGetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_match_messages_get_response_401 = cls(
message=message,
)
aandt_api_match_messages_get_response_401.additional_properties = d
return aandt_api_match_messages_get_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,80 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchMessagesSetBody")
@_attrs_define
class AandtApiMatchMessagesSetBody:
"""
Attributes:
all_ (str | Unset):
players (str | Unset):
admin (str | Unset):
"""
all_: str | Unset = UNSET
players: str | Unset = UNSET
admin: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
all_ = self.all_
players = self.players
admin = self.admin
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if all_ is not UNSET:
field_dict["all"] = all_
if players is not UNSET:
field_dict["players"] = players
if admin is not UNSET:
field_dict["admin"] = admin
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
all_ = d.pop("all", UNSET)
players = d.pop("players", UNSET)
admin = d.pop("admin", UNSET)
aandt_api_match_messages_set_body = cls(
all_=all_,
players=players,
admin=admin,
)
aandt_api_match_messages_set_body.additional_properties = d
return aandt_api_match_messages_set_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchMessagesSetResponse401")
@_attrs_define
class AandtApiMatchMessagesSetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_match_messages_set_response_401 = cls(
message=message,
)
aandt_api_match_messages_set_response_401.additional_properties = d
return aandt_api_match_messages_set_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,75 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.metadata import Metadata
T = TypeVar("T", bound="AandtApiMatchMetadataGetResponse200")
@_attrs_define
class AandtApiMatchMetadataGetResponse200:
"""
Attributes:
metadata (Metadata | Unset): Arbitrary JSON metadata stored by the bot
"""
metadata: Metadata | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
metadata: dict[str, Any] | Unset = UNSET
if not isinstance(self.metadata, Unset):
metadata = self.metadata.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if metadata is not UNSET:
field_dict["metadata"] = metadata
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.metadata import Metadata
d = dict(src_dict)
_metadata = d.pop("metadata", UNSET)
metadata: Metadata | Unset
if isinstance(_metadata, Unset):
metadata = UNSET
else:
metadata = Metadata.from_dict(_metadata)
aandt_api_match_metadata_get_response_200 = cls(
metadata=metadata,
)
aandt_api_match_metadata_get_response_200.additional_properties = d
return aandt_api_match_metadata_get_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchMetadataGetResponse401")
@_attrs_define
class AandtApiMatchMetadataGetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_match_metadata_get_response_401 = cls(
message=message,
)
aandt_api_match_metadata_get_response_401.additional_properties = d
return aandt_api_match_metadata_get_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,75 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.metadata import Metadata
T = TypeVar("T", bound="AandtApiMatchMetadataSetBody")
@_attrs_define
class AandtApiMatchMetadataSetBody:
"""
Attributes:
metadata (Metadata | Unset): Arbitrary JSON metadata stored by the bot
"""
metadata: Metadata | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
metadata: dict[str, Any] | Unset = UNSET
if not isinstance(self.metadata, Unset):
metadata = self.metadata.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if metadata is not UNSET:
field_dict["metadata"] = metadata
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.metadata import Metadata
d = dict(src_dict)
_metadata = d.pop("metadata", UNSET)
metadata: Metadata | Unset
if isinstance(_metadata, Unset):
metadata = UNSET
else:
metadata = Metadata.from_dict(_metadata)
aandt_api_match_metadata_set_body = cls(
metadata=metadata,
)
aandt_api_match_metadata_set_body.additional_properties = d
return aandt_api_match_metadata_set_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchMetadataSetResponse401")
@_attrs_define
class AandtApiMatchMetadataSetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_match_metadata_set_response_401 = cls(
message=message,
)
aandt_api_match_metadata_set_response_401.additional_properties = d
return aandt_api_match_metadata_set_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,80 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
if TYPE_CHECKING:
from ..models.aandt_api_match_submit_results_body_results import (
AandtApiMatchSubmitResultsBodyResults,
)
T = TypeVar("T", bound="AandtApiMatchSubmitResultsBody")
@_attrs_define
class AandtApiMatchSubmitResultsBody:
"""
Attributes:
round_ (int):
results (AandtApiMatchSubmitResultsBodyResults): map of MatschHasPlayerOrTeam pk (string) -> score (int)
"""
round_: int
results: AandtApiMatchSubmitResultsBodyResults
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
round_ = self.round_
results = self.results.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update(
{
"round": round_,
"results": results,
}
)
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.aandt_api_match_submit_results_body_results import (
AandtApiMatchSubmitResultsBodyResults,
)
d = dict(src_dict)
round_ = d.pop("round")
results = AandtApiMatchSubmitResultsBodyResults.from_dict(d.pop("results"))
aandt_api_match_submit_results_body = cls(
round_=round_,
results=results,
)
aandt_api_match_submit_results_body.additional_properties = d
return aandt_api_match_submit_results_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,48 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
T = TypeVar("T", bound="AandtApiMatchSubmitResultsBodyResults")
@_attrs_define
class AandtApiMatchSubmitResultsBodyResults:
"""map of MatschHasPlayerOrTeam pk (string) -> score (int)"""
additional_properties: dict[str, int] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
aandt_api_match_submit_results_body_results = cls()
aandt_api_match_submit_results_body_results.additional_properties = d
return aandt_api_match_submit_results_body_results
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> int:
return self.additional_properties[key]
def __setitem__(self, key: str, value: int) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,81 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..models.aandt_api_match_submit_results_response_200_message import (
AandtApiMatchSubmitResultsResponse200Message,
)
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchSubmitResultsResponse200")
@_attrs_define
class AandtApiMatchSubmitResultsResponse200:
"""
Attributes:
success (bool | Unset):
message (AandtApiMatchSubmitResultsResponse200Message | Unset):
"""
success: bool | Unset = UNSET
message: AandtApiMatchSubmitResultsResponse200Message | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
success = self.success
message: str | Unset = UNSET
if not isinstance(self.message, Unset):
message = self.message.value
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if success is not UNSET:
field_dict["success"] = success
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
success = d.pop("success", UNSET)
_message = d.pop("message", UNSET)
message: AandtApiMatchSubmitResultsResponse200Message | Unset
if isinstance(_message, Unset):
message = UNSET
else:
message = AandtApiMatchSubmitResultsResponse200Message(_message)
aandt_api_match_submit_results_response_200 = cls(
success=success,
message=message,
)
aandt_api_match_submit_results_response_200.additional_properties = d
return aandt_api_match_submit_results_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,9 @@
from enum import StrEnum
class AandtApiMatchSubmitResultsResponse200Message(StrEnum):
MISSING_PARAMETERS = "Missing parameters"
WRONG_ROUND = "Wrong round"
def __str__(self) -> str:
return str(self.value)
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchSubmitResultsResponse401")
@_attrs_define
class AandtApiMatchSubmitResultsResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_match_submit_results_response_401 = cls(
message=message,
)
aandt_api_match_submit_results_response_401.additional_properties = d
return aandt_api_match_submit_results_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,80 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.match import Match
T = TypeVar("T", bound="AandtApiMatchesResponse200")
@_attrs_define
class AandtApiMatchesResponse200:
"""
Attributes:
matches (list[Match] | Unset):
"""
matches: list[Match] | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
matches: list[dict[str, Any]] | Unset = UNSET
if not isinstance(self.matches, Unset):
matches = []
for matches_item_data in self.matches:
matches_item = matches_item_data.to_dict()
matches.append(matches_item)
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if matches is not UNSET:
field_dict["matches"] = matches
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.match import Match
d = dict(src_dict)
_matches = d.pop("matches", UNSET)
matches: list[Match] | Unset = UNSET
if _matches is not UNSET:
matches = []
for matches_item_data in _matches:
matches_item = Match.from_dict(matches_item_data)
matches.append(matches_item)
aandt_api_matches_response_200 = cls(
matches=matches,
)
aandt_api_matches_response_200.additional_properties = d
return aandt_api_matches_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMatchesResponse401")
@_attrs_define
class AandtApiMatchesResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_matches_response_401 = cls(
message=message,
)
aandt_api_matches_response_401.additional_properties = d
return aandt_api_matches_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,80 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.member import Member
T = TypeVar("T", bound="AandtApiMembersResponse200")
@_attrs_define
class AandtApiMembersResponse200:
"""
Attributes:
members (list[Member] | Unset):
"""
members: list[Member] | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
members: list[dict[str, Any]] | Unset = UNSET
if not isinstance(self.members, Unset):
members = []
for members_item_data in self.members:
members_item = members_item_data.to_dict()
members.append(members_item)
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if members is not UNSET:
field_dict["members"] = members
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.member import Member
d = dict(src_dict)
_members = d.pop("members", UNSET)
members: list[Member] | Unset = UNSET
if _members is not UNSET:
members = []
for members_item_data in _members:
members_item = Member.from_dict(members_item_data)
members.append(members_item)
aandt_api_members_response_200 = cls(
members=members,
)
aandt_api_members_response_200.additional_properties = d
return aandt_api_members_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMembersResponse401")
@_attrs_define
class AandtApiMembersResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_members_response_401 = cls(
message=message,
)
aandt_api_members_response_401.additional_properties = d
return aandt_api_members_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,74 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar, cast
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMessageGetResponse200")
@_attrs_define
class AandtApiMessageGetResponse200:
"""
Attributes:
message (None | str | Unset):
"""
message: None | str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message: None | str | Unset
if isinstance(self.message, Unset):
message = UNSET
else:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
def _parse_message(data: object) -> None | str | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(None | str | Unset, data)
message = _parse_message(d.pop("message", UNSET))
aandt_api_message_get_response_200 = cls(
message=message,
)
aandt_api_message_get_response_200.additional_properties = d
return aandt_api_message_get_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMessageGetResponse401")
@_attrs_define
class AandtApiMessageGetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_message_get_response_401 = cls(
message=message,
)
aandt_api_message_get_response_401.additional_properties = d
return aandt_api_message_get_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMessageSetBody")
@_attrs_define
class AandtApiMessageSetBody:
"""
Attributes:
message (str | Unset):
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_message_set_body = cls(
message=message,
)
aandt_api_message_set_body.additional_properties = d
return aandt_api_message_set_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMessageSetResponse401")
@_attrs_define
class AandtApiMessageSetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_message_set_response_401 = cls(
message=message,
)
aandt_api_message_set_response_401.additional_properties = d
return aandt_api_message_set_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,75 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.metadata import Metadata
T = TypeVar("T", bound="AandtApiMetadataGetResponse200")
@_attrs_define
class AandtApiMetadataGetResponse200:
"""
Attributes:
metadata (Metadata | Unset): Arbitrary JSON metadata stored by the bot
"""
metadata: Metadata | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
metadata: dict[str, Any] | Unset = UNSET
if not isinstance(self.metadata, Unset):
metadata = self.metadata.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if metadata is not UNSET:
field_dict["metadata"] = metadata
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.metadata import Metadata
d = dict(src_dict)
_metadata = d.pop("metadata", UNSET)
metadata: Metadata | Unset
if isinstance(_metadata, Unset):
metadata = UNSET
else:
metadata = Metadata.from_dict(_metadata)
aandt_api_metadata_get_response_200 = cls(
metadata=metadata,
)
aandt_api_metadata_get_response_200.additional_properties = d
return aandt_api_metadata_get_response_200
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMetadataGetResponse401")
@_attrs_define
class AandtApiMetadataGetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_metadata_get_response_401 = cls(
message=message,
)
aandt_api_metadata_get_response_401.additional_properties = d
return aandt_api_metadata_get_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,75 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.metadata import Metadata
T = TypeVar("T", bound="AandtApiMetadataSetBody")
@_attrs_define
class AandtApiMetadataSetBody:
"""
Attributes:
metadata (Metadata | Unset): Arbitrary JSON metadata stored by the bot
"""
metadata: Metadata | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
metadata: dict[str, Any] | Unset = UNSET
if not isinstance(self.metadata, Unset):
metadata = self.metadata.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if metadata is not UNSET:
field_dict["metadata"] = metadata
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.metadata import Metadata
d = dict(src_dict)
_metadata = d.pop("metadata", UNSET)
metadata: Metadata | Unset
if isinstance(_metadata, Unset):
metadata = UNSET
else:
metadata = Metadata.from_dict(_metadata)
aandt_api_metadata_set_body = cls(
metadata=metadata,
)
aandt_api_metadata_set_body.additional_properties = d
return aandt_api_metadata_set_body
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="AandtApiMetadataSetResponse401")
@_attrs_define
class AandtApiMetadataSetResponse401:
"""
Attributes:
message (str | Unset): Example: No Authorization header.
"""
message: str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
message = self.message
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if message is not UNSET:
field_dict["message"] = message
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
message = d.pop("message", UNSET)
aandt_api_metadata_set_response_401 = cls(
message=message,
)
aandt_api_metadata_set_response_401.additional_properties = d
return aandt_api_metadata_set_response_401
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,253 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar, cast
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..models.match_multiround_modes import MatchMultiroundModes
from ..models.match_status import MatchStatus
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.match_players import MatchPlayers
from ..models.match_round import MatchRound
T = TypeVar("T", bound="Match")
@_attrs_define
class Match:
"""
Attributes:
id (int | Unset):
title (str | Unset):
internal_id (str | Unset):
status (MatchStatus | Unset):
status_display (str | Unset):
rounds_count (int | Unset):
use_points (bool | Unset):
points_are_positions (bool | Unset):
multiround_modes (MatchMultiroundModes | Unset):
multiround_modes_display (None | str | Unset):
creation_date (str | Unset): Example: 2026-08-01 10:00:00+00:00.
playing_date (str | Unset):
done_date (str | Unset):
current_round (int | Unset):
players (MatchPlayers | Unset): map of AAndTHasUserOrTeam pk (string key) -> MatschHasPlayerOrTeam pk
rounds (list[MatchRound] | Unset):
"""
id: int | Unset = UNSET
title: str | Unset = UNSET
internal_id: str | Unset = UNSET
status: MatchStatus | Unset = UNSET
status_display: str | Unset = UNSET
rounds_count: int | Unset = UNSET
use_points: bool | Unset = UNSET
points_are_positions: bool | Unset = UNSET
multiround_modes: MatchMultiroundModes | Unset = UNSET
multiround_modes_display: None | str | Unset = UNSET
creation_date: str | Unset = UNSET
playing_date: str | Unset = UNSET
done_date: str | Unset = UNSET
current_round: int | Unset = UNSET
players: MatchPlayers | Unset = UNSET
rounds: list[MatchRound] | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
id = self.id
title = self.title
internal_id = self.internal_id
status: str | Unset = UNSET
if not isinstance(self.status, Unset):
status = self.status.value
status_display = self.status_display
rounds_count = self.rounds_count
use_points = self.use_points
points_are_positions = self.points_are_positions
multiround_modes: str | Unset = UNSET
if not isinstance(self.multiround_modes, Unset):
multiround_modes = self.multiround_modes.value
multiround_modes_display: None | str | Unset
if isinstance(self.multiround_modes_display, Unset):
multiround_modes_display = UNSET
else:
multiround_modes_display = self.multiround_modes_display
creation_date = self.creation_date
playing_date = self.playing_date
done_date = self.done_date
current_round = self.current_round
players: dict[str, Any] | Unset = UNSET
if not isinstance(self.players, Unset):
players = self.players.to_dict()
rounds: list[dict[str, Any]] | Unset = UNSET
if not isinstance(self.rounds, Unset):
rounds = []
for rounds_item_data in self.rounds:
rounds_item = rounds_item_data.to_dict()
rounds.append(rounds_item)
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if id is not UNSET:
field_dict["id"] = id
if title is not UNSET:
field_dict["title"] = title
if internal_id is not UNSET:
field_dict["internal_id"] = internal_id
if status is not UNSET:
field_dict["status"] = status
if status_display is not UNSET:
field_dict["status_display"] = status_display
if rounds_count is not UNSET:
field_dict["rounds_count"] = rounds_count
if use_points is not UNSET:
field_dict["use_points"] = use_points
if points_are_positions is not UNSET:
field_dict["points_are_positions"] = points_are_positions
if multiround_modes is not UNSET:
field_dict["multiround_modes"] = multiround_modes
if multiround_modes_display is not UNSET:
field_dict["multiround_modes_display"] = multiround_modes_display
if creation_date is not UNSET:
field_dict["creation_date"] = creation_date
if playing_date is not UNSET:
field_dict["playing_date"] = playing_date
if done_date is not UNSET:
field_dict["done_date"] = done_date
if current_round is not UNSET:
field_dict["current_round"] = current_round
if players is not UNSET:
field_dict["players"] = players
if rounds is not UNSET:
field_dict["rounds"] = rounds
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.match_players import MatchPlayers
from ..models.match_round import MatchRound
d = dict(src_dict)
id = d.pop("id", UNSET)
title = d.pop("title", UNSET)
internal_id = d.pop("internal_id", UNSET)
_status = d.pop("status", UNSET)
status: MatchStatus | Unset
if isinstance(_status, Unset):
status = UNSET
else:
status = MatchStatus(_status)
status_display = d.pop("status_display", UNSET)
rounds_count = d.pop("rounds_count", UNSET)
use_points = d.pop("use_points", UNSET)
points_are_positions = d.pop("points_are_positions", UNSET)
_multiround_modes = d.pop("multiround_modes", UNSET)
multiround_modes: MatchMultiroundModes | Unset
if isinstance(_multiround_modes, Unset):
multiround_modes = UNSET
else:
multiround_modes = MatchMultiroundModes(_multiround_modes)
def _parse_multiround_modes_display(data: object) -> None | str | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(None | str | Unset, data)
multiround_modes_display = _parse_multiround_modes_display(
d.pop("multiround_modes_display", UNSET)
)
creation_date = d.pop("creation_date", UNSET)
playing_date = d.pop("playing_date", UNSET)
done_date = d.pop("done_date", UNSET)
current_round = d.pop("current_round", UNSET)
_players = d.pop("players", UNSET)
players: MatchPlayers | Unset
if isinstance(_players, Unset):
players = UNSET
else:
players = MatchPlayers.from_dict(_players)
_rounds = d.pop("rounds", UNSET)
rounds: list[MatchRound] | Unset = UNSET
if _rounds is not UNSET:
rounds = []
for rounds_item_data in _rounds:
rounds_item = MatchRound.from_dict(rounds_item_data)
rounds.append(rounds_item)
match = cls(
id=id,
title=title,
internal_id=internal_id,
status=status,
status_display=status_display,
rounds_count=rounds_count,
use_points=use_points,
points_are_positions=points_are_positions,
multiround_modes=multiround_modes,
multiround_modes_display=multiround_modes_display,
creation_date=creation_date,
playing_date=playing_date,
done_date=done_date,
current_round=current_round,
players=players,
rounds=rounds,
)
match.additional_properties = d
return match
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,10 @@
from enum import StrEnum
class MatchMultiroundModes(StrEnum):
AP = "AP"
PA = "PA"
PS = "PS"
def __str__(self) -> str:
return str(self.value)
@@ -0,0 +1,48 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
T = TypeVar("T", bound="MatchPlayers")
@_attrs_define
class MatchPlayers:
"""map of AAndTHasUserOrTeam pk (string key) -> MatschHasPlayerOrTeam pk"""
additional_properties: dict[str, int] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
match_players = cls()
match_players.additional_properties = d
return match_players
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> int:
return self.additional_properties[key]
def __setitem__(self, key: str, value: int) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,89 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.match_round_result import MatchRoundResult
T = TypeVar("T", bound="MatchRound")
@_attrs_define
class MatchRound:
"""
Attributes:
round_id (int | Unset):
results (list[MatchRoundResult] | Unset):
"""
round_id: int | Unset = UNSET
results: list[MatchRoundResult] | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
round_id = self.round_id
results: list[dict[str, Any]] | Unset = UNSET
if not isinstance(self.results, Unset):
results = []
for results_item_data in self.results:
results_item = results_item_data.to_dict()
results.append(results_item)
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if round_id is not UNSET:
field_dict["round_id"] = round_id
if results is not UNSET:
field_dict["results"] = results
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.match_round_result import MatchRoundResult
d = dict(src_dict)
round_id = d.pop("round_id", UNSET)
_results = d.pop("results", UNSET)
results: list[MatchRoundResult] | Unset = UNSET
if _results is not UNSET:
results = []
for results_item_data in _results:
results_item = MatchRoundResult.from_dict(results_item_data)
results.append(results_item)
match_round = cls(
round_id=round_id,
results=results,
)
match_round.additional_properties = d
return match_round
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,71 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="MatchRoundResult")
@_attrs_define
class MatchRoundResult:
"""
Attributes:
score (float | Unset):
player_id (int | Unset): AAndTHasUserOrTeam pk
"""
score: float | Unset = UNSET
player_id: int | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
score = self.score
player_id = self.player_id
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if score is not UNSET:
field_dict["score"] = score
if player_id is not UNSET:
field_dict["player_id"] = player_id
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
score = d.pop("score", UNSET)
player_id = d.pop("player_id", UNSET)
match_round_result = cls(
score=score,
player_id=player_id,
)
match_round_result.additional_properties = d
return match_round_result
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,11 @@
from enum import StrEnum
class MatchStatus(StrEnum):
DONE = "done"
NEEDCONFIRM = "needConfirm"
PLAYING = "playing"
WAITPLAYER = "waitPlayer"
def __str__(self) -> str:
return str(self.value)
@@ -0,0 +1,120 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.member_team import MemberTeam
from ..models.member_user import MemberUser
T = TypeVar("T", bound="Member")
@_attrs_define
class Member:
"""
Attributes:
id (int | Unset): AAndTHasUserOrTeam pk
score (float | Unset):
done_all_matches (bool | Unset):
user (MemberUser | Unset):
team (MemberTeam | Unset):
"""
id: int | Unset = UNSET
score: float | Unset = UNSET
done_all_matches: bool | Unset = UNSET
user: MemberUser | Unset = UNSET
team: MemberTeam | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
id = self.id
score = self.score
done_all_matches = self.done_all_matches
user: dict[str, Any] | Unset = UNSET
if not isinstance(self.user, Unset):
user = self.user.to_dict()
team: dict[str, Any] | Unset = UNSET
if not isinstance(self.team, Unset):
team = self.team.to_dict()
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if id is not UNSET:
field_dict["id"] = id
if score is not UNSET:
field_dict["score"] = score
if done_all_matches is not UNSET:
field_dict["done_all_matches"] = done_all_matches
if user is not UNSET:
field_dict["user"] = user
if team is not UNSET:
field_dict["team"] = team
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.member_team import MemberTeam
from ..models.member_user import MemberUser
d = dict(src_dict)
id = d.pop("id", UNSET)
score = d.pop("score", UNSET)
done_all_matches = d.pop("done_all_matches", UNSET)
_user = d.pop("user", UNSET)
user: MemberUser | Unset
if isinstance(_user, Unset):
user = UNSET
else:
user = MemberUser.from_dict(_user)
_team = d.pop("team", UNSET)
team: MemberTeam | Unset
if isinstance(_team, Unset):
team = UNSET
else:
team = MemberTeam.from_dict(_team)
member = cls(
id=id,
score=score,
done_all_matches=done_all_matches,
user=user,
team=team,
)
member.additional_properties = d
return member
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,109 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar, cast
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
if TYPE_CHECKING:
from ..models.member_user import MemberUser
T = TypeVar("T", bound="MemberTeam")
@_attrs_define
class MemberTeam:
"""
Attributes:
name (str | Unset):
leader (int | None | Unset): pk of the leader's user, null if no leader
members (list[MemberUser] | Unset):
"""
name: str | Unset = UNSET
leader: int | None | Unset = UNSET
members: list[MemberUser] | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
name = self.name
leader: int | None | Unset
if isinstance(self.leader, Unset):
leader = UNSET
else:
leader = self.leader
members: list[dict[str, Any]] | Unset = UNSET
if not isinstance(self.members, Unset):
members = []
for members_item_data in self.members:
members_item = members_item_data.to_dict()
members.append(members_item)
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if name is not UNSET:
field_dict["name"] = name
if leader is not UNSET:
field_dict["leader"] = leader
if members is not UNSET:
field_dict["members"] = members
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
from ..models.member_user import MemberUser
d = dict(src_dict)
name = d.pop("name", UNSET)
def _parse_leader(data: object) -> int | None | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(int | None | Unset, data)
leader = _parse_leader(d.pop("leader", UNSET))
_members = d.pop("members", UNSET)
members: list[MemberUser] | Unset = UNSET
if _members is not UNSET:
members = []
for members_item_data in _members:
members_item = MemberUser.from_dict(members_item_data)
members.append(members_item)
member_team = cls(
name=name,
leader=leader,
members=members,
)
member_team.additional_properties = d
return member_team
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,91 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar, cast
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="MemberUser")
@_attrs_define
class MemberUser:
"""
Attributes:
id (int | Unset):
username (str | Unset):
tournois_alias (None | str | Unset):
"""
id: int | Unset = UNSET
username: str | Unset = UNSET
tournois_alias: None | str | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
id = self.id
username = self.username
tournois_alias: None | str | Unset
if isinstance(self.tournois_alias, Unset):
tournois_alias = UNSET
else:
tournois_alias = self.tournois_alias
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if id is not UNSET:
field_dict["id"] = id
if username is not UNSET:
field_dict["username"] = username
if tournois_alias is not UNSET:
field_dict["tournois_alias"] = tournois_alias
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
id = d.pop("id", UNSET)
username = d.pop("username", UNSET)
def _parse_tournois_alias(data: object) -> None | str | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
return cast(None | str | Unset, data)
tournois_alias = _parse_tournois_alias(d.pop("tournois_alias", UNSET))
member_user = cls(
id=id,
username=username,
tournois_alias=tournois_alias,
)
member_user.additional_properties = d
return member_user
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,48 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
T = TypeVar("T", bound="Metadata")
@_attrs_define
class Metadata:
"""Arbitrary JSON metadata stored by the bot"""
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
metadata = cls()
metadata.additional_properties = d
return metadata
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,62 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, TypeVar
from attrs import define as _attrs_define
from attrs import field as _attrs_field
from typing_extensions import Self
from ..types import UNSET, Unset
T = TypeVar("T", bound="SuccessResponse")
@_attrs_define
class SuccessResponse:
"""
Attributes:
success (bool | Unset):
"""
success: bool | Unset = UNSET
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
def to_dict(self) -> dict[str, Any]:
success = self.success
field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if success is not UNSET:
field_dict["success"] = success
return field_dict
@classmethod
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
d = dict(src_dict)
success = d.pop("success", UNSET)
success_response = cls(
success=success,
)
success_response.additional_properties = d
return success_response
@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())
def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]
def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value
def __delitem__(self, key: str) -> None:
del self.additional_properties[key]
def __contains__(self, key: str) -> bool:
return key in self.additional_properties
@@ -0,0 +1,54 @@
"""Contains some shared types for properties"""
from collections.abc import Mapping, MutableMapping
from http import HTTPStatus
from typing import IO, BinaryIO, Generic, Literal, TypeVar
from attrs import define
class Unset:
def __bool__(self) -> Literal[False]:
return False
UNSET: Unset = Unset()
# The types that `httpx.Client(files=)` can accept, copied from that library.
FileContent = IO[bytes] | bytes | str
FileTypes = (
# (filename, file (or bytes), content_type)
tuple[str | None, FileContent, str | None]
# (filename, file (or bytes), content_type, headers)
| tuple[str | None, FileContent, str | None, Mapping[str, str]]
)
RequestFiles = list[tuple[str, FileTypes]]
@define
class File:
"""Contains information for file uploads"""
payload: BinaryIO
file_name: str | None = None
mime_type: str | None = None
def to_tuple(self) -> FileTypes:
"""Return a tuple representation that httpx will accept for multipart/form-data"""
return self.file_name, self.payload, self.mime_type
T = TypeVar("T")
@define
class Response(Generic[T]):
"""A response from an endpoint"""
status_code: HTTPStatus
content: bytes
headers: MutableMapping[str, str]
parsed: T | None
__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"]
@@ -0,0 +1,557 @@
openapi: 3.0.3
info:
title: PolyLAN AAndT Bot API
description: >-
Endpoints protected by the `aandt_apitoken_required` decorator
(Plamingo/pAAndT/views.py). Intended for external "apibot" integrations
that manage a single AAndT (animation/tournament) identified by the JWT
bearer token, so no per-request AAndT id is otherwise needed.
This spec was written by hand as a one-off snapshot of the current
behaviour, not generated automatically — re-check it if the views change.
version: "1.0.0"
servers:
- url: /Plamingo/aandt/api/aandt
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: >-
`Authorization: Bearer <token>` header. The token is a JWT signed
with `settings.JWT_SECRET_KEY` (HS256), issuer `PolyLAN:AAndT`, and
must carry an `aandt_pk` claim identifying the target AAndT. Obtained
via `AAndT.generate_token()` (see `aandt_apibot` admin view).
responses:
Unauthorized:
description: Missing/invalid Authorization header or token
content:
text/json:
schema:
type: object
properties:
message:
type: string
example: "No Authorization header"
NotFound:
description: The AAndT (or nested match) referenced by the token/path does not exist
content:
text/html:
schema:
type: string
schemas:
AAndTInfos:
type: object
properties:
name:
type: string
status:
type: string
enum: [0prep, 1publ, 3insc, 5inscdone, 7inprog, 9done, 11reviewed]
status_display:
type: string
example: "Matchs en cours"
use_teams:
type: boolean
max_entities:
type: integer
MemberUser:
type: object
properties:
id:
type: integer
username:
type: string
tournois_alias:
type: string
nullable: true
MemberTeam:
type: object
properties:
name:
type: string
leader:
type: integer
nullable: true
description: pk of the leader's user, null if no leader
members:
type: array
items:
$ref: "#/components/schemas/MemberUser"
Member:
type: object
properties:
id:
type: integer
description: AAndTHasUserOrTeam pk
score:
type: number
done_all_matches:
type: boolean
user:
allOf:
- $ref: "#/components/schemas/MemberUser"
description: present only when the AAndT does not use teams
team:
allOf:
- $ref: "#/components/schemas/MemberTeam"
description: present only when the AAndT uses teams
MatchRoundResult:
type: object
properties:
score:
type: number
player_id:
type: integer
description: AAndTHasUserOrTeam pk
MatchRound:
type: object
properties:
round_id:
type: integer
results:
type: array
items:
$ref: "#/components/schemas/MatchRoundResult"
Match:
type: object
properties:
id:
type: integer
title:
type: string
internal_id:
type: string
status:
type: string
enum: [waitPlayer, needConfirm, playing, done]
status_display:
type: string
rounds_count:
type: integer
use_points:
type: boolean
points_are_positions:
type: boolean
multiround_modes:
type: string
nullable: true
enum: [PA, PS, AP]
multiround_modes_display:
type: string
nullable: true
creation_date:
type: string
example: "2026-08-01 10:00:00+00:00"
playing_date:
type: string
done_date:
type: string
current_round:
type: integer
players:
type: object
description: map of AAndTHasUserOrTeam pk (string key) -> MatschHasPlayerOrTeam pk
additionalProperties:
type: integer
rounds:
type: array
items:
$ref: "#/components/schemas/MatchRound"
Metadata:
type: object
description: Arbitrary JSON metadata stored by the bot
additionalProperties: true
SuccessResponse:
type: object
properties:
success:
type: boolean
paths:
/:
get:
operationId: aandt_api_infos
summary: Get general information about the AAndT
description: Read-only. AAndT is resolved from the bearer token.
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
aandt:
$ref: "#/components/schemas/AAndTInfos"
"401":
$ref: "#/components/responses/Unauthorized"
/members:
get:
operationId: aandt_api_members
summary: List the AAndT's registered members (users or teams)
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
members:
type: array
items:
$ref: "#/components/schemas/Member"
"401":
$ref: "#/components/responses/Unauthorized"
/matches:
get:
operationId: aandt_api_matches
summary: List all matches of the AAndT with their rounds/results
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
matches:
type: array
items:
$ref: "#/components/schemas/Match"
"401":
$ref: "#/components/responses/Unauthorized"
/metadata:
get:
operationId: aandt_api_metadata_get
summary: Get the AAndT's bot metadata
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
metadata:
$ref: "#/components/schemas/Metadata"
"401":
$ref: "#/components/responses/Unauthorized"
post:
operationId: aandt_api_metadata_set
summary: Set the AAndT's bot metadata
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
metadata:
$ref: "#/components/schemas/Metadata"
responses:
"200":
description: Saved
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
"401":
$ref: "#/components/responses/Unauthorized"
/apibot:
get:
operationId: aandt_api_apibot_get
summary: Get the AAndT's apibot activation state and display name
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
activated:
type: boolean
name:
type: string
"401":
$ref: "#/components/responses/Unauthorized"
post:
operationId: aandt_api_apibot_set
summary: Set the AAndT's apibot activation state and/or display name
description: Broadcasts the update over Zuperpush after saving.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
activated:
type: boolean
name:
type: string
responses:
"200":
description: Saved
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
"401":
$ref: "#/components/responses/Unauthorized"
/message:
get:
operationId: aandt_api_message_get
summary: Get the AAndT's apibot page message
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
message:
type: string
nullable: true
"401":
$ref: "#/components/responses/Unauthorized"
post:
operationId: aandt_api_message_set
summary: Set the AAndT's apibot page message
description: Broadcasts the update over Zuperpush after saving.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
message:
type: string
responses:
"200":
description: Saved
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
"401":
$ref: "#/components/responses/Unauthorized"
/log:
post:
operationId: aandt_api_log
summary: Add a log entry to the AAndT's log (prefixed with "API:")
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [type, message]
properties:
type:
type: string
description: AAndTLog type, e.g. "info", "error"
message:
type: string
responses:
"200":
description: >-
Always HTTP 200. `success` is false when the request is not a
POST, or when `type`/`message` are missing from the body.
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
"401":
$ref: "#/components/responses/Unauthorized"
/match/{pk}/metadata:
parameters:
- name: pk
in: path
required: true
schema:
type: integer
description: Matsch pk (must belong to the token's AAndT)
get:
operationId: aandt_api_match_metadata_get
summary: Get a match's bot metadata
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
metadata:
$ref: "#/components/schemas/Metadata"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
post:
operationId: aandt_api_match_metadata_set
summary: Set a match's bot metadata
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
metadata:
$ref: "#/components/schemas/Metadata"
responses:
"200":
description: Saved
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
/match/{pk}/messages:
parameters:
- name: pk
in: path
required: true
schema:
type: integer
description: Matsch pk (must belong to the token's AAndT)
get:
operationId: aandt_api_match_messages_get
summary: Get a match's bot messages (all/players/admin)
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
all:
type: string
nullable: true
players:
type: string
nullable: true
admin:
type: string
nullable: true
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
post:
operationId: aandt_api_match_messages_set
summary: Set one or more of a match's bot messages
description: >-
Any of `all`, `players`, `admin` may be omitted; only the keys
present in the body are updated. Triggers a Zuperpush update.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
all:
type: string
players:
type: string
admin:
type: string
responses:
"200":
description: Saved
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
/match/{pk}/sumbit_results:
parameters:
- name: pk
in: path
required: true
schema:
type: integer
description: >-
Matsch pk. Must belong to the token's AAndT and currently have
status "playing", otherwise the request 404s.
post:
operationId: aandt_api_match_submit_results
summary: Submit results for the match's current round
description: >-
`round` must equal the match's current round (`Matsch.cRound()`),
otherwise the request is rejected. `results` maps a
MatschHasPlayerOrTeam pk (string key) to that participant's score
for the round (omitted participants default to 0 if `usePoints`,
else 1). Advances/finishes the match and pushes live updates.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [round, results]
properties:
round:
type: integer
results:
type: object
description: map of MatschHasPlayerOrTeam pk (string) -> score (int)
additionalProperties:
type: integer
responses:
"200":
description: >-
Always HTTP 200. `success` is false with a `message` when the
request is not a POST, is missing `round`/`results`, or `round`
does not match the match's current round.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
enum: ["Missing parameters", "Wrong round"]
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
@@ -1,5 +1,8 @@
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, TypeVar
import httpx
from django.conf import settings
from django.db import transaction
from django.urls import reverse
@@ -9,7 +12,26 @@ from accounts.models import CustomUser
from games.models import EventGame
from ..models import Scope
from .aandt_client import AAndTAPIError, AAndTClient
from .aandt_client import AuthenticatedClient
from .aandt_client.api.default import (
aandt_api_match_messages_set,
aandt_api_matches,
aandt_api_members,
)
from .aandt_client.models import (
AandtApiMatchesResponse200,
AandtApiMatchMessagesSetBody,
AandtApiMembersResponse200,
Match,
Member,
MatchStatus,
)
from .aandt_client.types import Unset
# Generated from ../aandt_openapi.yaml (a hand-maintained snapshot of the legacy
# PolyLAN site's AAndT bot API). Regenerate after the spec changes with:
# uvx openapi-python-client generate --path aandt_openapi.yaml --meta none \
# --output-path aandt_client --overwrite
class ScopeSyncError(Exception):
@@ -23,6 +45,21 @@ class ScopeSyncResult:
warnings: list[str] = field(default_factory=list)
_T = TypeVar("_T")
def _unwrap(value: "_T | Unset", default: Any = None) -> "_T | Any":
return default if isinstance(value, Unset) else value
def _client(event_game: EventGame, /) -> AuthenticatedClient:
base_url = settings.AANDT_API_BASE_URL.rstrip("/")
return AuthenticatedClient(
base_url=f"{base_url}/Plamingo/aandt/api/aandt",
token=event_game.apibot_token,
)
def _submission_url(scope: Scope, /) -> str:
path = reverse(
"submissions.view",
@@ -35,17 +72,31 @@ def _submission_url(scope: Scope, /) -> str:
return f"{settings.SUBMITTER_BASE_URL.rstrip('/')}{path}"
def _userid_by_members(members: list[dict]) -> dict[int, set[int]]:
userids_by_members: dict[int, set[int]] = {}
def _userids_by_member_id(members: list[Member]) -> dict[int, set[int]]:
userids_by_member_id: dict[int, set[int]] = {}
for member in members:
if "team" in member:
userids = {u["id"] for u in member["team"]["members"]}
else:
userids = {member["user"]["id"]}
userids_by_members[member["id"]] = userids
member_id = _unwrap(member.id)
if member_id is None:
continue
return userids_by_members
userids_by_member_id[int(member_id)] = _userids_for_member(member)
return userids_by_member_id
def _userids_for_member(member: Member) -> set[int]:
team = _unwrap(member.team)
if team is not None:
return {
int(u.id) for u in _unwrap(team.members, []) if not isinstance(u.id, Unset)
}
user = _unwrap(member.user)
if user is not None and not isinstance(user.id, Unset):
return {int(user.id)}
return set()
@transaction.atomic
@@ -54,9 +105,9 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult:
Each remote match becomes one Scope (matched on `external_id`), with
`assigned_users` set to every local account tied to either side of the
match, resolved by username. Active scopes get their submission page's
URL pushed back as the match's player-facing message, so participants
browsing the legacy site get a direct link here.
match, resolved by legacy user id (`cas_user_id`). Active scopes get their
submission page's URL pushed back as the match's player-facing message, so
participants browsing the legacy site get a direct link here.
Args:
event_game: The EventGame to sync; must have `apibot_token` set.
@@ -70,62 +121,115 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult:
if not event_game.apibot_token:
raise ScopeSyncError(f"{event_game} has no AAndT token configured")
client = AAndTClient(settings.AANDT_API_BASE_URL, event_game.apibot_token)
client = _client(event_game)
try:
userids_by_members = _userid_by_members(client.get_members())
matches = client.get_matches()
except AAndTAPIError as exc:
raise ScopeSyncError(str(exc)) from exc
members_response = aandt_api_members.sync_detailed(client=client)
matches_response = aandt_api_matches.sync_detailed(client=client)
except (httpx.HTTPError, ValueError) as exc:
# ValueError: the spec's 401 response is mistakenly typed `text/json` with an
# object schema, so the generated client tries `dict(response.text)` on an
# actual 401 and blows up instead of returning a parsed error. Fix upstream in
# aandt_openapi.yaml (Unauthorized response) -> `application/json`, then
# resync this copy and regenerate.
raise ScopeSyncError(f"Failed to reach AAndT API: {exc}") from exc
members_parsed = members_response.parsed
matches_parsed = matches_response.parsed
if not isinstance(members_parsed, AandtApiMembersResponse200) or not isinstance(
matches_parsed, AandtApiMatchesResponse200
):
raise ScopeSyncError(
"AAndT API returned "
f"{members_response.status_code.value}/{matches_response.status_code.value}"
)
members = _unwrap(members_parsed.members, [])
matches = _unwrap(matches_parsed.matches, [])
userids_by_member_id = _userids_by_member_id(members)
result = ScopeSyncResult()
now = timezone.now()
for match in matches:
created, warnings = _sync_match(event_game, client, match, userids_by_member_id, now)
if created is None:
continue
result.created += created
result.updated += not created
result.warnings.extend(warnings)
return result
def _sync_match(
event_game: EventGame,
client: AuthenticatedClient,
match: Match,
userids_by_member_id: dict[int, set[int]],
now: datetime,
) -> tuple[bool | None, list[str]]:
match_id = _unwrap(match.id)
if match_id is None:
return None, []
warnings: list[str] = []
userids: set[int] = set()
for member_id in match.get("players", {}):
userids.update(userids_by_members.get(int(member_id), set()))
players = _unwrap(match.players)
if players is not None:
for member_id in players.additional_properties:
userids.update(userids_by_member_id.get(int(member_id), set()))
users = list(CustomUser.objects.filter(cas_user_id__in=userids))
scope, created = Scope.objects.update_or_create(
event_game=event_game,
external_id=match["id"],
external_id=match_id,
defaults={
"name": match.get("title") or f"Match {match['id']}",
"is_active": match.get("status") == "playing",
"name": _unwrap(match.title) or f"Match {match_id}",
"is_active": _unwrap(match.status) == MatchStatus.PLAYING,
"synced_at": now,
},
)
scope.assigned_users.set(users)
result.created += created
result.updated += not created
matched_ids = {
int(u.cas_user_id)
for u in users
if u.cas_user_id and u.cas_user_id.isdigit()
int(u.cas_user_id) for u in users if u.cas_user_id and u.cas_user_id.isdigit()
}
missing = userids - matched_ids
if missing:
result.warnings.append(
f"Match {match['id']}: no local account for {', '.join(sorted(map(str, missing)))}"
warnings.append(
f"Match {match_id}: no local account for {', '.join(sorted(map(str, missing)))}"
)
if scope.is_active:
try:
client.set_match_message(
match["id"],
warnings.extend(_push_submission_link(client, match_id, scope))
return created, warnings
def _push_submission_link(client: AuthenticatedClient, match_id: int, scope: Scope) -> list[str]:
body = AandtApiMatchMessagesSetBody(
players=(
"<h3>Submit your result</h3>"
f'<a href="{_submission_url(scope)}" target="_blank" rel="noopener">'
"Submit your proof here</a>"
),
)
except AAndTAPIError as exc:
result.warnings.append(
f"Match {match['id']}: failed to push submission link ({exc})"
)
return result
try:
response = aandt_api_match_messages_set.sync_detailed(
pk=match_id, client=client, body=body
)
except (httpx.HTTPError, ValueError) as exc:
return [f"Match {match_id}: failed to push submission link ({exc})"]
if response.status_code != 200:
return [
f"Match {match_id}: failed to push submission link "
f"(HTTP {response.status_code.value})"
]
return []
+1
View File
@@ -24,6 +24,7 @@ dependencies = [
"channels-redis",
"django-rq",
"django-tasks-rq",
"httpx>=0.28.1",
]
[dependency-groups]
Generated
+53
View File
@@ -23,6 +23,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
]
[[package]]
name = "anyio"
version = "4.14.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
{ name = "idna" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", size = 260176, upload-time = "2026-07-12T20:29:07.082Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" },
]
[[package]]
name = "asgiref"
version = "3.11.1"
@@ -881,6 +895,43 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl", hash = "sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc", size = 212009, upload-time = "2026-05-05T06:38:23.007Z" },
]
[[package]]
name = "h11"
version = "0.16.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
]
[[package]]
name = "httpcore"
version = "1.0.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
]
[[package]]
name = "httpx"
version = "0.28.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
]
[[package]]
name = "hyperlink"
version = "21.0.0"
@@ -1583,6 +1634,7 @@ dependencies = [
{ name = "django-vite" },
{ name = "furl" },
{ name = "gunicorn" },
{ name = "httpx" },
{ name = "opencv-python" },
{ name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
{ name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
@@ -1622,6 +1674,7 @@ requires-dist = [
{ name = "django-vite" },
{ name = "furl" },
{ name = "gunicorn" },
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "opencv-python" },
{ name = "pandas" },
{ name = "pillow" },