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 dataclasses import dataclass, field
from datetime import datetime
from typing import Any, TypeVar
import httpx
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.urls import reverse from django.urls import reverse
@@ -9,7 +12,26 @@ from accounts.models import CustomUser
from games.models import EventGame from games.models import EventGame
from ..models import Scope 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): class ScopeSyncError(Exception):
@@ -23,6 +45,21 @@ class ScopeSyncResult:
warnings: list[str] = field(default_factory=list) 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: def _submission_url(scope: Scope, /) -> str:
path = reverse( path = reverse(
"submissions.view", "submissions.view",
@@ -35,17 +72,31 @@ def _submission_url(scope: Scope, /) -> str:
return f"{settings.SUBMITTER_BASE_URL.rstrip('/')}{path}" return f"{settings.SUBMITTER_BASE_URL.rstrip('/')}{path}"
def _userid_by_members(members: list[dict]) -> dict[int, set[int]]: def _userids_by_member_id(members: list[Member]) -> dict[int, set[int]]:
userids_by_members: dict[int, set[int]] = {} userids_by_member_id: dict[int, set[int]] = {}
for member in members: for member in members:
if "team" in member: member_id = _unwrap(member.id)
userids = {u["id"] for u in member["team"]["members"]} if member_id is None:
else: continue
userids = {member["user"]["id"]}
userids_by_members[member["id"]] = userids
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 @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 Each remote match becomes one Scope (matched on `external_id`), with
`assigned_users` set to every local account tied to either side of the `assigned_users` set to every local account tied to either side of the
match, resolved by username. Active scopes get their submission page's match, resolved by legacy user id (`cas_user_id`). Active scopes get their
URL pushed back as the match's player-facing message, so participants submission page's URL pushed back as the match's player-facing message, so
browsing the legacy site get a direct link here. participants browsing the legacy site get a direct link here.
Args: Args:
event_game: The EventGame to sync; must have `apibot_token` set. 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: if not event_game.apibot_token:
raise ScopeSyncError(f"{event_game} has no AAndT token configured") 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: try:
userids_by_members = _userid_by_members(client.get_members()) members_response = aandt_api_members.sync_detailed(client=client)
matches = client.get_matches() matches_response = aandt_api_matches.sync_detailed(client=client)
except AAndTAPIError as exc: except (httpx.HTTPError, ValueError) as exc:
raise ScopeSyncError(str(exc)) from 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() result = ScopeSyncResult()
now = timezone.now() now = timezone.now()
for match in matches: for match in matches:
userids: set[int] = set() created, warnings = _sync_match(event_game, client, match, userids_by_member_id, now)
for member_id in match.get("players", {}): if created is None:
userids.update(userids_by_members.get(int(member_id), set())) continue
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"],
defaults={
"name": match.get("title") or f"Match {match['id']}",
"is_active": match.get("status") == "playing",
"synced_at": now,
},
)
scope.assigned_users.set(users)
result.created += created result.created += created
result.updated += not created result.updated += not created
result.warnings.extend(warnings)
matched_ids = {
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)))}"
)
if scope.is_active:
try:
client.set_match_message(
match["id"],
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 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()
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,
defaults={
"name": _unwrap(match.title) or f"Match {match_id}",
"is_active": _unwrap(match.status) == MatchStatus.PLAYING,
"synced_at": now,
},
)
scope.assigned_users.set(users)
matched_ids = {
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:
warnings.append(
f"Match {match_id}: no local account for {', '.join(sorted(map(str, missing)))}"
)
if scope.is_active:
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>"
),
)
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", "channels-redis",
"django-rq", "django-rq",
"django-tasks-rq", "django-tasks-rq",
"httpx>=0.28.1",
] ]
[dependency-groups] [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" }, { 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]] [[package]]
name = "asgiref" name = "asgiref"
version = "3.11.1" 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" }, { 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]] [[package]]
name = "hyperlink" name = "hyperlink"
version = "21.0.0" version = "21.0.0"
@@ -1583,6 +1634,7 @@ dependencies = [
{ name = "django-vite" }, { name = "django-vite" },
{ name = "furl" }, { name = "furl" },
{ name = "gunicorn" }, { name = "gunicorn" },
{ name = "httpx" },
{ name = "opencv-python" }, { name = "opencv-python" },
{ name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { 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'" }, { 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 = "django-vite" },
{ name = "furl" }, { name = "furl" },
{ name = "gunicorn" }, { name = "gunicorn" },
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "opencv-python" }, { name = "opencv-python" },
{ name = "pandas" }, { name = "pandas" },
{ name = "pillow" }, { name = "pillow" },