diff --git a/polylan_submitter/submissions/services/aandt_client.py b/polylan_submitter/submissions/services/aandt_client.py deleted file mode 100644 index b1bea42..0000000 --- a/polylan_submitter/submissions/services/aandt_client.py +++ /dev/null @@ -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() diff --git a/polylan_submitter/submissions/services/aandt_client/__init__.py b/polylan_submitter/submissions/services/aandt_client/__init__.py new file mode 100644 index 0000000..42bd93d --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/__init__.py @@ -0,0 +1,8 @@ +"""A client library for accessing PolyLAN AAndT Bot API""" + +from .client import AuthenticatedClient, Client + +__all__ = ( + "AuthenticatedClient", + "Client", +) diff --git a/polylan_submitter/submissions/services/aandt_client/api/__init__.py b/polylan_submitter/submissions/services/aandt_client/api/__init__.py new file mode 100644 index 0000000..81f9fa2 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/__init__.py @@ -0,0 +1 @@ +"""Contains methods for accessing the API""" diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/__init__.py b/polylan_submitter/submissions/services/aandt_client/api/default/__init__.py new file mode 100644 index 0000000..2d7c0b2 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/__init__.py @@ -0,0 +1 @@ +"""Contains endpoint functions for accessing the API""" diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_apibot_get.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_apibot_get.py new file mode 100644 index 0000000..9804e29 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_apibot_get.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_apibot_set.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_apibot_set.py new file mode 100644 index 0000000..7d24e82 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_apibot_set.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_infos.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_infos.py new file mode 100644 index 0000000..0038017 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_infos.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_log.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_log.py new file mode 100644 index 0000000..0bca409 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_log.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_messages_get.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_messages_get.py new file mode 100644 index 0000000..7ec7e5c --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_messages_get.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_messages_set.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_messages_set.py new file mode 100644 index 0000000..ff6b8c1 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_messages_set.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_metadata_get.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_metadata_get.py new file mode 100644 index 0000000..60b06bf --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_metadata_get.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_metadata_set.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_metadata_set.py new file mode 100644 index 0000000..c0349d1 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_metadata_set.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_submit_results.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_submit_results.py new file mode 100644 index 0000000..4f73121 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_match_submit_results.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_matches.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_matches.py new file mode 100644 index 0000000..351a25d --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_matches.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_members.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_members.py new file mode 100644 index 0000000..1fe3ef6 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_members.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_message_get.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_message_get.py new file mode 100644 index 0000000..ac03cb1 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_message_get.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_message_set.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_message_set.py new file mode 100644 index 0000000..925a21b --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_message_set.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_metadata_get.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_metadata_get.py new file mode 100644 index 0000000..de59d1a --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_metadata_get.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_metadata_set.py b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_metadata_set.py new file mode 100644 index 0000000..821f33c --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/api/default/aandt_api_metadata_set.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/client.py b/polylan_submitter/submissions/services/aandt_client/client.py new file mode 100644 index 0000000..08206ec --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/client.py @@ -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) diff --git a/polylan_submitter/submissions/services/aandt_client/errors.py b/polylan_submitter/submissions/services/aandt_client/errors.py new file mode 100644 index 0000000..5f92e76 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/errors.py @@ -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"] diff --git a/polylan_submitter/submissions/services/aandt_client/models/__init__.py b/polylan_submitter/submissions/services/aandt_client/models/__init__.py new file mode 100644 index 0000000..ab39384 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/__init__.py @@ -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", +) diff --git a/polylan_submitter/submissions/services/aandt_client/models/a_and_t_infos.py b/polylan_submitter/submissions/services/aandt_client/models/a_and_t_infos.py new file mode 100644 index 0000000..c400042 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/a_and_t_infos.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/a_and_t_infos_status.py b/polylan_submitter/submissions/services/aandt_client/models/a_and_t_infos_status.py new file mode 100644 index 0000000..0ea18a6 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/a_and_t_infos_status.py @@ -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) diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_get_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_get_response_200.py new file mode 100644 index 0000000..a19acbc --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_get_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_get_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_get_response_401.py new file mode 100644 index 0000000..e4b2986 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_get_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_set_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_set_body.py new file mode 100644 index 0000000..05032b9 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_set_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_set_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_set_response_401.py new file mode 100644 index 0000000..3661f7d --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_apibot_set_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_infos_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_infos_response_200.py new file mode 100644 index 0000000..eccd249 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_infos_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_infos_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_infos_response_401.py new file mode 100644 index 0000000..d1b9dda --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_infos_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_log_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_log_body.py new file mode 100644 index 0000000..8a5a460 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_log_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_log_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_log_response_401.py new file mode 100644 index 0000000..0394b3c --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_log_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_get_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_get_response_200.py new file mode 100644 index 0000000..55bf39c --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_get_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_get_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_get_response_401.py new file mode 100644 index 0000000..c4fca53 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_get_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_set_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_set_body.py new file mode 100644 index 0000000..f5dbc7b --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_set_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_set_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_set_response_401.py new file mode 100644 index 0000000..663f892 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_messages_set_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_get_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_get_response_200.py new file mode 100644 index 0000000..c466a1d --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_get_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_get_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_get_response_401.py new file mode 100644 index 0000000..b4d3c89 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_get_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_set_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_set_body.py new file mode 100644 index 0000000..ca6fa27 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_set_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_set_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_set_response_401.py new file mode 100644 index 0000000..ee502cf --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_metadata_set_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_body.py new file mode 100644 index 0000000..e20cf86 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_body_results.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_body_results.py new file mode 100644 index 0000000..f223399 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_body_results.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_200.py new file mode 100644 index 0000000..d225051 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_200_message.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_200_message.py new file mode 100644 index 0000000..4e25e7b --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_200_message.py @@ -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) diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_401.py new file mode 100644 index 0000000..e3b6e6f --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_match_submit_results_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_matches_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_matches_response_200.py new file mode 100644 index 0000000..bb79c0a --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_matches_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_matches_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_matches_response_401.py new file mode 100644 index 0000000..e153246 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_matches_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_members_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_members_response_200.py new file mode 100644 index 0000000..f38ae0d --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_members_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_members_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_members_response_401.py new file mode 100644 index 0000000..9b8ec90 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_members_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_get_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_get_response_200.py new file mode 100644 index 0000000..5b29176 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_get_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_get_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_get_response_401.py new file mode 100644 index 0000000..0b62fd6 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_get_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_set_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_set_body.py new file mode 100644 index 0000000..cdb11b6 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_set_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_set_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_set_response_401.py new file mode 100644 index 0000000..05811b4 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_message_set_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_get_response_200.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_get_response_200.py new file mode 100644 index 0000000..e580175 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_get_response_200.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_get_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_get_response_401.py new file mode 100644 index 0000000..57361fd --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_get_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_set_body.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_set_body.py new file mode 100644 index 0000000..ed80147 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_set_body.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_set_response_401.py b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_set_response_401.py new file mode 100644 index 0000000..00c1567 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/aandt_api_metadata_set_response_401.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/match.py b/polylan_submitter/submissions/services/aandt_client/models/match.py new file mode 100644 index 0000000..953ae9c --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/match.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/match_multiround_modes.py b/polylan_submitter/submissions/services/aandt_client/models/match_multiround_modes.py new file mode 100644 index 0000000..536a802 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/match_multiround_modes.py @@ -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) diff --git a/polylan_submitter/submissions/services/aandt_client/models/match_players.py b/polylan_submitter/submissions/services/aandt_client/models/match_players.py new file mode 100644 index 0000000..7adb95c --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/match_players.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/match_round.py b/polylan_submitter/submissions/services/aandt_client/models/match_round.py new file mode 100644 index 0000000..e699dcc --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/match_round.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/match_round_result.py b/polylan_submitter/submissions/services/aandt_client/models/match_round_result.py new file mode 100644 index 0000000..ae82eb7 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/match_round_result.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/match_status.py b/polylan_submitter/submissions/services/aandt_client/models/match_status.py new file mode 100644 index 0000000..b4e8ddc --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/match_status.py @@ -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) diff --git a/polylan_submitter/submissions/services/aandt_client/models/member.py b/polylan_submitter/submissions/services/aandt_client/models/member.py new file mode 100644 index 0000000..6f85b83 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/member.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/member_team.py b/polylan_submitter/submissions/services/aandt_client/models/member_team.py new file mode 100644 index 0000000..35007ba --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/member_team.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/member_user.py b/polylan_submitter/submissions/services/aandt_client/models/member_user.py new file mode 100644 index 0000000..000ab2e --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/member_user.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/metadata.py b/polylan_submitter/submissions/services/aandt_client/models/metadata.py new file mode 100644 index 0000000..db27ad4 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/metadata.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/models/success_response.py b/polylan_submitter/submissions/services/aandt_client/models/success_response.py new file mode 100644 index 0000000..d7b8167 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/models/success_response.py @@ -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 diff --git a/polylan_submitter/submissions/services/aandt_client/types.py b/polylan_submitter/submissions/services/aandt_client/types.py new file mode 100644 index 0000000..b64af09 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_client/types.py @@ -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"] diff --git a/polylan_submitter/submissions/services/aandt_openapi.yaml b/polylan_submitter/submissions/services/aandt_openapi.yaml new file mode 100644 index 0000000..ec5e190 --- /dev/null +++ b/polylan_submitter/submissions/services/aandt_openapi.yaml @@ -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 ` 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" diff --git a/polylan_submitter/submissions/services/aandt_sync.py b/polylan_submitter/submissions/services/aandt_sync.py index 17afc7f..f76e1cc 100644 --- a/polylan_submitter/submissions/services/aandt_sync.py +++ b/polylan_submitter/submissions/services/aandt_sync.py @@ -1,5 +1,8 @@ from dataclasses import dataclass, field +from datetime import datetime +from typing import Any, TypeVar +import httpx from django.conf import settings from django.db import transaction from django.urls import reverse @@ -9,7 +12,26 @@ from accounts.models import CustomUser from games.models import EventGame from ..models import Scope -from .aandt_client import AAndTAPIError, AAndTClient +from .aandt_client import AuthenticatedClient +from .aandt_client.api.default import ( + aandt_api_match_messages_set, + aandt_api_matches, + aandt_api_members, +) +from .aandt_client.models import ( + AandtApiMatchesResponse200, + AandtApiMatchMessagesSetBody, + AandtApiMembersResponse200, + Match, + Member, + MatchStatus, +) +from .aandt_client.types import Unset + +# Generated from ../aandt_openapi.yaml (a hand-maintained snapshot of the legacy +# PolyLAN site's AAndT bot API). Regenerate after the spec changes with: +# uvx openapi-python-client generate --path aandt_openapi.yaml --meta none \ +# --output-path aandt_client --overwrite class ScopeSyncError(Exception): @@ -23,6 +45,21 @@ class ScopeSyncResult: warnings: list[str] = field(default_factory=list) +_T = TypeVar("_T") + + +def _unwrap(value: "_T | Unset", default: Any = None) -> "_T | Any": + return default if isinstance(value, Unset) else value + + +def _client(event_game: EventGame, /) -> AuthenticatedClient: + base_url = settings.AANDT_API_BASE_URL.rstrip("/") + return AuthenticatedClient( + base_url=f"{base_url}/Plamingo/aandt/api/aandt", + token=event_game.apibot_token, + ) + + def _submission_url(scope: Scope, /) -> str: path = reverse( "submissions.view", @@ -35,17 +72,31 @@ def _submission_url(scope: Scope, /) -> str: return f"{settings.SUBMITTER_BASE_URL.rstrip('/')}{path}" -def _userid_by_members(members: list[dict]) -> dict[int, set[int]]: - userids_by_members: dict[int, set[int]] = {} +def _userids_by_member_id(members: list[Member]) -> dict[int, set[int]]: + userids_by_member_id: dict[int, set[int]] = {} for member in members: - if "team" in member: - userids = {u["id"] for u in member["team"]["members"]} - else: - userids = {member["user"]["id"]} - userids_by_members[member["id"]] = userids + member_id = _unwrap(member.id) + if member_id is None: + continue - return userids_by_members + userids_by_member_id[int(member_id)] = _userids_for_member(member) + + return userids_by_member_id + + +def _userids_for_member(member: Member) -> set[int]: + team = _unwrap(member.team) + if team is not None: + return { + int(u.id) for u in _unwrap(team.members, []) if not isinstance(u.id, Unset) + } + + user = _unwrap(member.user) + if user is not None and not isinstance(user.id, Unset): + return {int(user.id)} + + return set() @transaction.atomic @@ -54,9 +105,9 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult: Each remote match becomes one Scope (matched on `external_id`), with `assigned_users` set to every local account tied to either side of the - match, resolved by username. Active scopes get their submission page's - URL pushed back as the match's player-facing message, so participants - browsing the legacy site get a direct link here. + match, resolved by legacy user id (`cas_user_id`). Active scopes get their + submission page's URL pushed back as the match's player-facing message, so + participants browsing the legacy site get a direct link here. Args: event_game: The EventGame to sync; must have `apibot_token` set. @@ -70,62 +121,115 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult: if not event_game.apibot_token: raise ScopeSyncError(f"{event_game} has no AAndT token configured") - client = AAndTClient(settings.AANDT_API_BASE_URL, event_game.apibot_token) + client = _client(event_game) try: - userids_by_members = _userid_by_members(client.get_members()) - matches = client.get_matches() - except AAndTAPIError as exc: - raise ScopeSyncError(str(exc)) from exc + members_response = aandt_api_members.sync_detailed(client=client) + matches_response = aandt_api_matches.sync_detailed(client=client) + except (httpx.HTTPError, ValueError) as exc: + # ValueError: the spec's 401 response is mistakenly typed `text/json` with an + # object schema, so the generated client tries `dict(response.text)` on an + # actual 401 and blows up instead of returning a parsed error. Fix upstream in + # aandt_openapi.yaml (Unauthorized response) -> `application/json`, then + # resync this copy and regenerate. + raise ScopeSyncError(f"Failed to reach AAndT API: {exc}") from exc + members_parsed = members_response.parsed + matches_parsed = matches_response.parsed + + if not isinstance(members_parsed, AandtApiMembersResponse200) or not isinstance( + matches_parsed, AandtApiMatchesResponse200 + ): + raise ScopeSyncError( + "AAndT API returned " + f"{members_response.status_code.value}/{matches_response.status_code.value}" + ) + + members = _unwrap(members_parsed.members, []) + matches = _unwrap(matches_parsed.matches, []) + + userids_by_member_id = _userids_by_member_id(members) result = ScopeSyncResult() now = timezone.now() for match in matches: - userids: set[int] = set() - for member_id in match.get("players", {}): - userids.update(userids_by_members.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": match.get("title") or f"Match {match['id']}", - "is_active": match.get("status") == "playing", - "synced_at": now, - }, - ) - scope.assigned_users.set(users) - + created, warnings = _sync_match(event_game, client, match, userids_by_member_id, now) + if created is None: + continue result.created += created result.updated += not created - - 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=( - "

Submit your result

" - f'' - "Submit your proof here" - ), - ) - except AAndTAPIError as exc: - result.warnings.append( - f"Match {match['id']}: failed to push submission link ({exc})" - ) + result.warnings.extend(warnings) return result + + +def _sync_match( + event_game: EventGame, + client: AuthenticatedClient, + match: Match, + userids_by_member_id: dict[int, set[int]], + now: datetime, +) -> tuple[bool | None, list[str]]: + match_id = _unwrap(match.id) + if match_id is None: + return None, [] + + warnings: list[str] = [] + + userids: set[int] = set() + 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=( + "

Submit your result

" + f'' + "Submit your proof here" + ), + ) + + 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 [] diff --git a/pyproject.toml b/pyproject.toml index 7f09564..ab9d1d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "channels-redis", "django-rq", "django-tasks-rq", + "httpx>=0.28.1", ] [dependency-groups] diff --git a/uv.lock b/uv.lock index 94042a2..7ff0d35 100644 --- a/uv.lock +++ b/uv.lock @@ -23,6 +23,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] +[[package]] +name = "anyio" +version = "4.14.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", size = 260176, upload-time = "2026-07-12T20:29:07.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" }, +] + [[package]] name = "asgiref" version = "3.11.1" @@ -881,6 +895,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl", hash = "sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc", size = 212009, upload-time = "2026-05-05T06:38:23.007Z" }, ] +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + [[package]] name = "hyperlink" version = "21.0.0" @@ -1583,6 +1634,7 @@ dependencies = [ { name = "django-vite" }, { name = "furl" }, { name = "gunicorn" }, + { name = "httpx" }, { name = "opencv-python" }, { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -1622,6 +1674,7 @@ requires-dist = [ { name = "django-vite" }, { name = "furl" }, { name = "gunicorn" }, + { name = "httpx", specifier = ">=0.28.1" }, { name = "opencv-python" }, { name = "pandas" }, { name = "pillow" },