diff --git a/scaleway-async/scaleway_async/mailbox/v1alpha1/__init__.py b/scaleway-async/scaleway_async/mailbox/v1alpha1/__init__.py index b1035b544..730ab8101 100644 --- a/scaleway-async/scaleway_async/mailbox/v1alpha1/__init__.py +++ b/scaleway-async/scaleway_async/mailbox/v1alpha1/__init__.py @@ -8,6 +8,7 @@ from .content import DOMAIN_RECORD_TRANSIENT_STATUSES from .types import DomainStatus from .content import DOMAIN_TRANSIENT_STATUSES +from .types import ListAliasesRequestOrderBy from .types import ListDomainsRequestOrderBy from .types import ListMailboxesRequestOrderBy from .types import MailboxStatus @@ -16,18 +17,22 @@ from .types import BatchCreateMailboxesRequestMailboxParameters from .types import Mailbox from .types import DomainRecord -from .types import Domain from .types import Alias +from .types import Domain from .types import BatchCreateMailboxesRequest from .types import BatchCreateMailboxesResponse from .types import CreateAliasRequest from .types import CreateDomainRequest +from .types import DeleteAliasRequest from .types import DeleteDomainRequest from .types import DeleteMailboxRequest +from .types import GetAliasRequest from .types import GetDomainRecordsRequest from .types import GetDomainRecordsResponse from .types import GetDomainRequest from .types import GetMailboxRequest +from .types import ListAliasesRequest +from .types import ListAliasesResponse from .types import ListDomainsRequest from .types import ListDomainsResponse from .types import ListMailboxesRequest @@ -46,6 +51,7 @@ "DOMAIN_RECORD_TRANSIENT_STATUSES", "DomainStatus", "DOMAIN_TRANSIENT_STATUSES", + "ListAliasesRequestOrderBy", "ListDomainsRequestOrderBy", "ListMailboxesRequestOrderBy", "MailboxStatus", @@ -54,18 +60,22 @@ "BatchCreateMailboxesRequestMailboxParameters", "Mailbox", "DomainRecord", - "Domain", "Alias", + "Domain", "BatchCreateMailboxesRequest", "BatchCreateMailboxesResponse", "CreateAliasRequest", "CreateDomainRequest", + "DeleteAliasRequest", "DeleteDomainRequest", "DeleteMailboxRequest", + "GetAliasRequest", "GetDomainRecordsRequest", "GetDomainRecordsResponse", "GetDomainRequest", "GetMailboxRequest", + "ListAliasesRequest", + "ListAliasesResponse", "ListDomainsRequest", "ListDomainsResponse", "ListMailboxesRequest", diff --git a/scaleway-async/scaleway_async/mailbox/v1alpha1/api.py b/scaleway-async/scaleway_async/mailbox/v1alpha1/api.py index 148331c45..ae6914806 100644 --- a/scaleway-async/scaleway_async/mailbox/v1alpha1/api.py +++ b/scaleway-async/scaleway_async/mailbox/v1alpha1/api.py @@ -11,7 +11,9 @@ wait_for_resource_async, ) from .types import ( + AliasStatus, DomainStatus, + ListAliasesRequestOrderBy, ListDomainsRequestOrderBy, ListMailboxesRequestOrderBy, MailboxStatus, @@ -24,21 +26,24 @@ CreateDomainRequest, Domain, GetDomainRecordsResponse, + ListAliasesResponse, ListDomainsResponse, ListMailboxesResponse, Mailbox, UpdateMailboxRequest, ) from .content import ( + ALIAS_TRANSIENT_STATUSES, DOMAIN_TRANSIENT_STATUSES, MAILBOX_TRANSIENT_STATUSES, ) from .marshalling import ( unmarshal_Mailbox, - unmarshal_Domain, unmarshal_Alias, + unmarshal_Domain, unmarshal_BatchCreateMailboxesResponse, unmarshal_GetDomainRecordsResponse, + unmarshal_ListAliasesResponse, unmarshal_ListDomainsResponse, unmarshal_ListMailboxesResponse, marshal_BatchCreateMailboxesRequest, @@ -364,6 +369,7 @@ async def list_mailboxes( domain_id: Optional[str] = None, statuses: Optional[list[MailboxStatus]] = None, search: Optional[str] = None, + project_id: Optional[str] = None, ) -> ListMailboxesResponse: """ List mailboxes in an organization. @@ -374,6 +380,7 @@ async def list_mailboxes( :param domain_id: (Optional) ID of the domain in which to list the mailboxes. :param statuses: (Optional) Filter mailboxes by their statuses. :param search: (Optional) Search term to filter mailboxes on name and local_part. + :param project_id: (Optional) Project ID to filter mailboxes on. :return: :class:`ListMailboxesResponse ` Usage: @@ -390,6 +397,7 @@ async def list_mailboxes( "order_by": order_by, "page": page, "page_size": page_size or self.client.default_page_size, + "project_id": project_id or self.client.default_project_id, "search": search, "statuses": statuses, }, @@ -407,6 +415,7 @@ async def list_mailboxes_all( domain_id: Optional[str] = None, statuses: Optional[list[MailboxStatus]] = None, search: Optional[str] = None, + project_id: Optional[str] = None, ) -> list[Mailbox]: """ List mailboxes in an organization. @@ -417,6 +426,7 @@ async def list_mailboxes_all( :param domain_id: (Optional) ID of the domain in which to list the mailboxes. :param statuses: (Optional) Filter mailboxes by their statuses. :param search: (Optional) Search term to filter mailboxes on name and local_part. + :param project_id: (Optional) Project ID to filter mailboxes on. :return: :class:`list[Mailbox] ` Usage: @@ -436,6 +446,7 @@ async def list_mailboxes_all( "domain_id": domain_id, "statuses": statuses, "search": search, + "project_id": project_id, }, ) @@ -620,11 +631,9 @@ async def create_alias( ) """ - param_mailbox_id = validate_path_param("mailbox_id", mailbox_id) - res = self._request( "POST", - f"/mailbox/v1alpha1/mailboxes/{param_mailbox_id}/aliases", + "/mailbox/v1alpha1/aliases", body=marshal_CreateAliasRequest( CreateAliasRequest( local_part=local_part, @@ -637,3 +646,174 @@ async def create_alias( self._throw_on_error(res) return unmarshal_Alias(res.json()) + + async def list_aliases( + self, + *, + order_by: Optional[ListAliasesRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + mailbox_id: Optional[str] = None, + status: Optional[AliasStatus] = None, + project_id: Optional[str] = None, + ) -> ListAliasesResponse: + """ + List aliases for a mailbox. + :param order_by: Order aliases by specific criteria. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Requested page size. Value must be between 1 and 100. + :param mailbox_id: ID of the mailbox for which to list aliases. + :param status: (Optional) Filter aliases by their status. + :param project_id: Project ID to filter on. + :return: :class:`ListAliasesResponse ` + + Usage: + :: + + result = await api.list_aliases() + """ + + res = self._request( + "GET", + "/mailbox/v1alpha1/aliases", + params={ + "mailbox_id": mailbox_id, + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + "project_id": project_id or self.client.default_project_id, + "status": status, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListAliasesResponse(res.json()) + + async def list_aliases_all( + self, + *, + order_by: Optional[ListAliasesRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + mailbox_id: Optional[str] = None, + status: Optional[AliasStatus] = None, + project_id: Optional[str] = None, + ) -> list[Alias]: + """ + List aliases for a mailbox. + :param order_by: Order aliases by specific criteria. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Requested page size. Value must be between 1 and 100. + :param mailbox_id: ID of the mailbox for which to list aliases. + :param status: (Optional) Filter aliases by their status. + :param project_id: Project ID to filter on. + :return: :class:`list[Alias] ` + + Usage: + :: + + result = await api.list_aliases_all() + """ + + return await fetch_all_pages_async( + type=ListAliasesResponse, + key="aliases", + fetcher=self.list_aliases, + args={ + "order_by": order_by, + "page": page, + "page_size": page_size, + "mailbox_id": mailbox_id, + "status": status, + "project_id": project_id, + }, + ) + + async def get_alias( + self, + *, + alias_id: str, + ) -> Alias: + """ + Get an alias by its ID. + :param alias_id: ID of the alias to get. + :return: :class:`Alias ` + + Usage: + :: + + result = await api.get_alias( + alias_id="example", + ) + """ + + param_alias_id = validate_path_param("alias_id", alias_id) + + res = self._request( + "GET", + f"/mailbox/v1alpha1/aliases/{param_alias_id}", + ) + + self._throw_on_error(res) + return unmarshal_Alias(res.json()) + + async def wait_for_alias( + self, + *, + alias_id: str, + options: Optional[WaitForOptions[Alias, Union[bool, Awaitable[bool]]]] = None, + ) -> Alias: + """ + Get an alias by its ID. + :param alias_id: ID of the alias to get. + :return: :class:`Alias ` + + Usage: + :: + + result = await api.get_alias( + alias_id="example", + ) + """ + + if not options: + options = WaitForOptions() + + if not options.stop: + options.stop = lambda res: res.status not in ALIAS_TRANSIENT_STATUSES + + return await wait_for_resource_async( + fetcher=self.get_alias, + options=options, + args={ + "alias_id": alias_id, + }, + ) + + async def delete_alias( + self, + *, + alias_id: str, + ) -> Alias: + """ + Delete an alias by its ID. + :param alias_id: ID of the alias to delete. + :return: :class:`Alias ` + + Usage: + :: + + result = await api.delete_alias( + alias_id="example", + ) + """ + + param_alias_id = validate_path_param("alias_id", alias_id) + + res = self._request( + "DELETE", + f"/mailbox/v1alpha1/aliases/{param_alias_id}", + ) + + self._throw_on_error(res) + return unmarshal_Alias(res.json()) diff --git a/scaleway-async/scaleway_async/mailbox/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/mailbox/v1alpha1/marshalling.py index 5c1a0a325..fae8fd1af 100644 --- a/scaleway-async/scaleway_async/mailbox/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/mailbox/v1alpha1/marshalling.py @@ -14,11 +14,12 @@ MailboxStatus, MailboxSubscriptionPeriod, Mailbox, - Domain, Alias, + Domain, BatchCreateMailboxesResponse, DomainRecord, GetDomainRecordsResponse, + ListAliasesResponse, ListDomainsResponse, ListMailboxesResponse, BatchCreateMailboxesRequestMailboxParameters, @@ -116,6 +117,59 @@ def unmarshal_Mailbox(data: Any) -> Mailbox: return Mailbox(**args) +def unmarshal_Alias(data: Any) -> Alias: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Alias' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("email", None) + if field is not None: + args["email"] = field + else: + args["email"] = None + + field = data.get("mailbox_id", None) + if field is not None: + args["mailbox_id"] = field + else: + args["mailbox_id"] = None + + field = data.get("description", None) + if field is not None: + args["description"] = field + else: + args["description"] = None + + field = data.get("status", None) + if field is not None: + args["status"] = field + else: + args["status"] = AliasStatus.UNKNOWN_STATUS + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("updated_at", None) + if field is not None: + args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["updated_at"] = None + + return Alias(**args) + + def unmarshal_Domain(data: Any) -> Domain: if not isinstance(data, dict): raise TypeError( @@ -193,59 +247,6 @@ def unmarshal_Domain(data: Any) -> Domain: return Domain(**args) -def unmarshal_Alias(data: Any) -> Alias: - if not isinstance(data, dict): - raise TypeError( - "Unmarshalling the type 'Alias' failed as data isn't a dictionary." - ) - - args: dict[str, Any] = {} - - field = data.get("id", None) - if field is not None: - args["id"] = field - else: - args["id"] = None - - field = data.get("email", None) - if field is not None: - args["email"] = field - else: - args["email"] = None - - field = data.get("mailbox_id", None) - if field is not None: - args["mailbox_id"] = field - else: - args["mailbox_id"] = None - - field = data.get("description", None) - if field is not None: - args["description"] = field - else: - args["description"] = None - - field = data.get("status", None) - if field is not None: - args["status"] = field - else: - args["status"] = AliasStatus.UNKNOWN_STATUS - - field = data.get("created_at", None) - if field is not None: - args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field - else: - args["created_at"] = None - - field = data.get("updated_at", None) - if field is not None: - args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field - else: - args["updated_at"] = None - - return Alias(**args) - - def unmarshal_BatchCreateMailboxesResponse(data: Any) -> BatchCreateMailboxesResponse: if not isinstance(data, dict): raise TypeError( @@ -419,6 +420,31 @@ def unmarshal_GetDomainRecordsResponse(data: Any) -> GetDomainRecordsResponse: return GetDomainRecordsResponse(**args) +def unmarshal_ListAliasesResponse(data: Any) -> ListAliasesResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListAliasesResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + field = data.get("aliases", None) + if field is not None: + args["aliases"] = ( + [unmarshal_Alias(v) for v in field] if field is not None else None + ) + else: + args["aliases"] = [] + + return ListAliasesResponse(**args) + + def unmarshal_ListDomainsResponse(data: Any) -> ListDomainsResponse: if not isinstance(data, dict): raise TypeError( @@ -514,6 +540,9 @@ def marshal_CreateAliasRequest( if request.local_part is not None: output["local_part"] = request.local_part + if request.mailbox_id is not None: + output["mailbox_id"] = request.mailbox_id + if request.description is not None: output["description"] = request.description diff --git a/scaleway-async/scaleway_async/mailbox/v1alpha1/types.py b/scaleway-async/scaleway_async/mailbox/v1alpha1/types.py index 69d944ae4..84b8b34bc 100644 --- a/scaleway-async/scaleway_async/mailbox/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/mailbox/v1alpha1/types.py @@ -68,6 +68,18 @@ def __str__(self) -> str: return str(self.value) +class ListAliasesRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_DESC = "created_at_desc" + CREATED_AT_ASC = "created_at_asc" + UPDATED_AT_DESC = "updated_at_desc" + UPDATED_AT_ASC = "updated_at_asc" + NAME_DESC = "name_desc" + NAME_ASC = "name_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListDomainsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): CREATED_AT_DESC = "created_at_desc" CREATED_AT_ASC = "created_at_asc" @@ -239,98 +251,98 @@ class DomainRecord: @dataclass -class Domain: +class Alias: id: str """ - Unique identifier of the domain. + Unique identifier of the alias. """ - project_id: str + email: str """ - ID of the Project to which the domain belongs. + Email address of the alias as local_part@domain. """ - name: str + mailbox_id: str """ - Fully qualified domain name. + ID of the mailbox to which the alias belongs. """ - status: DomainStatus + description: str """ - Status of the domain. + Description of the alias. """ - mailbox_total_count: int + status: AliasStatus """ - Number of mailboxes of the domain. + Current status of the alias. """ - webmail_url: str + created_at: Optional[datetime] = None """ - URL of the domain's webmail. + Date and time of alias creation. """ - imap_url: str + updated_at: Optional[datetime] = None """ - URL of the domain's IMAP service. + Date and time when the alias was last updated. """ - pop3_url: str + +@dataclass +class Domain: + id: str """ - URL of the domain's POP3 service. + Unique identifier of the domain. """ - smtp_url: str + project_id: str """ - URL of the domain's SMTP service. + ID of the Project to which the domain belongs. """ - created_at: Optional[datetime] = None + name: str """ - Date and time of domain creation. + Fully qualified domain name. """ - updated_at: Optional[datetime] = None + status: DomainStatus """ - Date and time of the domain's last update. + Status of the domain. """ - -@dataclass -class Alias: - id: str + mailbox_total_count: int """ - Unique identifier of the alias. + Number of mailboxes of the domain. """ - email: str + webmail_url: str """ - Email address of the alias as local_part@domain. + URL of the domain's webmail. """ - mailbox_id: str + imap_url: str """ - ID of the mailbox to which the alias belongs. + URL of the domain's IMAP service. """ - description: str + pop3_url: str """ - Description of the alias. + URL of the domain's POP3 service. """ - status: AliasStatus + smtp_url: str """ - Current status of the alias. + URL of the domain's SMTP service. """ created_at: Optional[datetime] = None """ - Date and time of alias creation. + Date and time of domain creation. """ updated_at: Optional[datetime] = None """ - Date and time when the alias was last updated. + Date and time of the domain's last update. """ @@ -395,6 +407,14 @@ class CreateDomainRequest: """ +@dataclass +class DeleteAliasRequest: + alias_id: str + """ + ID of the alias to delete. + """ + + @dataclass class DeleteDomainRequest: domain_id: str @@ -411,6 +431,14 @@ class DeleteMailboxRequest: """ +@dataclass +class GetAliasRequest: + alias_id: str + """ + ID of the alias to get. + """ + + @dataclass class GetDomainRecordsRequest: domain_id: str @@ -498,6 +526,54 @@ class GetMailboxRequest: """ +@dataclass +class ListAliasesRequest: + order_by: Optional[ListAliasesRequestOrderBy] = ( + ListAliasesRequestOrderBy.CREATED_AT_DESC + ) + """ + Order aliases by specific criteria. + """ + + page: Optional[int] = 0 + """ + Requested page number. Value must be greater or equal to 1. + """ + + page_size: Optional[int] = 0 + """ + Requested page size. Value must be between 1 and 100. + """ + + mailbox_id: Optional[str] = None + """ + ID of the mailbox for which to list aliases. + """ + + status: Optional[AliasStatus] = AliasStatus.UNKNOWN_STATUS + """ + (Optional) Filter aliases by their status. + """ + + project_id: Optional[str] = None + """ + Project ID to filter on. + """ + + +@dataclass +class ListAliasesResponse: + total_count: int + """ + Number of aliases that match the request (without pagination). + """ + + aliases: list[Alias] + """ + Single page of aliases matching the requested criteria. + """ + + @dataclass class ListDomainsRequest: order_by: Optional[ListDomainsRequestOrderBy] = None @@ -555,6 +631,11 @@ class ListMailboxesRequest: (Optional) Search term to filter mailboxes on name and local_part. """ + project_id: Optional[str] = None + """ + (Optional) Project ID to filter mailboxes on. + """ + @dataclass class ListMailboxesResponse: diff --git a/scaleway/scaleway/mailbox/v1alpha1/__init__.py b/scaleway/scaleway/mailbox/v1alpha1/__init__.py index b1035b544..730ab8101 100644 --- a/scaleway/scaleway/mailbox/v1alpha1/__init__.py +++ b/scaleway/scaleway/mailbox/v1alpha1/__init__.py @@ -8,6 +8,7 @@ from .content import DOMAIN_RECORD_TRANSIENT_STATUSES from .types import DomainStatus from .content import DOMAIN_TRANSIENT_STATUSES +from .types import ListAliasesRequestOrderBy from .types import ListDomainsRequestOrderBy from .types import ListMailboxesRequestOrderBy from .types import MailboxStatus @@ -16,18 +17,22 @@ from .types import BatchCreateMailboxesRequestMailboxParameters from .types import Mailbox from .types import DomainRecord -from .types import Domain from .types import Alias +from .types import Domain from .types import BatchCreateMailboxesRequest from .types import BatchCreateMailboxesResponse from .types import CreateAliasRequest from .types import CreateDomainRequest +from .types import DeleteAliasRequest from .types import DeleteDomainRequest from .types import DeleteMailboxRequest +from .types import GetAliasRequest from .types import GetDomainRecordsRequest from .types import GetDomainRecordsResponse from .types import GetDomainRequest from .types import GetMailboxRequest +from .types import ListAliasesRequest +from .types import ListAliasesResponse from .types import ListDomainsRequest from .types import ListDomainsResponse from .types import ListMailboxesRequest @@ -46,6 +51,7 @@ "DOMAIN_RECORD_TRANSIENT_STATUSES", "DomainStatus", "DOMAIN_TRANSIENT_STATUSES", + "ListAliasesRequestOrderBy", "ListDomainsRequestOrderBy", "ListMailboxesRequestOrderBy", "MailboxStatus", @@ -54,18 +60,22 @@ "BatchCreateMailboxesRequestMailboxParameters", "Mailbox", "DomainRecord", - "Domain", "Alias", + "Domain", "BatchCreateMailboxesRequest", "BatchCreateMailboxesResponse", "CreateAliasRequest", "CreateDomainRequest", + "DeleteAliasRequest", "DeleteDomainRequest", "DeleteMailboxRequest", + "GetAliasRequest", "GetDomainRecordsRequest", "GetDomainRecordsResponse", "GetDomainRequest", "GetMailboxRequest", + "ListAliasesRequest", + "ListAliasesResponse", "ListDomainsRequest", "ListDomainsResponse", "ListMailboxesRequest", diff --git a/scaleway/scaleway/mailbox/v1alpha1/api.py b/scaleway/scaleway/mailbox/v1alpha1/api.py index c0ddd00a4..6d2c4b48a 100644 --- a/scaleway/scaleway/mailbox/v1alpha1/api.py +++ b/scaleway/scaleway/mailbox/v1alpha1/api.py @@ -11,7 +11,9 @@ wait_for_resource, ) from .types import ( + AliasStatus, DomainStatus, + ListAliasesRequestOrderBy, ListDomainsRequestOrderBy, ListMailboxesRequestOrderBy, MailboxStatus, @@ -24,21 +26,24 @@ CreateDomainRequest, Domain, GetDomainRecordsResponse, + ListAliasesResponse, ListDomainsResponse, ListMailboxesResponse, Mailbox, UpdateMailboxRequest, ) from .content import ( + ALIAS_TRANSIENT_STATUSES, DOMAIN_TRANSIENT_STATUSES, MAILBOX_TRANSIENT_STATUSES, ) from .marshalling import ( unmarshal_Mailbox, - unmarshal_Domain, unmarshal_Alias, + unmarshal_Domain, unmarshal_BatchCreateMailboxesResponse, unmarshal_GetDomainRecordsResponse, + unmarshal_ListAliasesResponse, unmarshal_ListDomainsResponse, unmarshal_ListMailboxesResponse, marshal_BatchCreateMailboxesRequest, @@ -364,6 +369,7 @@ def list_mailboxes( domain_id: Optional[str] = None, statuses: Optional[list[MailboxStatus]] = None, search: Optional[str] = None, + project_id: Optional[str] = None, ) -> ListMailboxesResponse: """ List mailboxes in an organization. @@ -374,6 +380,7 @@ def list_mailboxes( :param domain_id: (Optional) ID of the domain in which to list the mailboxes. :param statuses: (Optional) Filter mailboxes by their statuses. :param search: (Optional) Search term to filter mailboxes on name and local_part. + :param project_id: (Optional) Project ID to filter mailboxes on. :return: :class:`ListMailboxesResponse ` Usage: @@ -390,6 +397,7 @@ def list_mailboxes( "order_by": order_by, "page": page, "page_size": page_size or self.client.default_page_size, + "project_id": project_id or self.client.default_project_id, "search": search, "statuses": statuses, }, @@ -407,6 +415,7 @@ def list_mailboxes_all( domain_id: Optional[str] = None, statuses: Optional[list[MailboxStatus]] = None, search: Optional[str] = None, + project_id: Optional[str] = None, ) -> list[Mailbox]: """ List mailboxes in an organization. @@ -417,6 +426,7 @@ def list_mailboxes_all( :param domain_id: (Optional) ID of the domain in which to list the mailboxes. :param statuses: (Optional) Filter mailboxes by their statuses. :param search: (Optional) Search term to filter mailboxes on name and local_part. + :param project_id: (Optional) Project ID to filter mailboxes on. :return: :class:`list[Mailbox] ` Usage: @@ -436,6 +446,7 @@ def list_mailboxes_all( "domain_id": domain_id, "statuses": statuses, "search": search, + "project_id": project_id, }, ) @@ -620,11 +631,9 @@ def create_alias( ) """ - param_mailbox_id = validate_path_param("mailbox_id", mailbox_id) - res = self._request( "POST", - f"/mailbox/v1alpha1/mailboxes/{param_mailbox_id}/aliases", + "/mailbox/v1alpha1/aliases", body=marshal_CreateAliasRequest( CreateAliasRequest( local_part=local_part, @@ -637,3 +646,174 @@ def create_alias( self._throw_on_error(res) return unmarshal_Alias(res.json()) + + def list_aliases( + self, + *, + order_by: Optional[ListAliasesRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + mailbox_id: Optional[str] = None, + status: Optional[AliasStatus] = None, + project_id: Optional[str] = None, + ) -> ListAliasesResponse: + """ + List aliases for a mailbox. + :param order_by: Order aliases by specific criteria. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Requested page size. Value must be between 1 and 100. + :param mailbox_id: ID of the mailbox for which to list aliases. + :param status: (Optional) Filter aliases by their status. + :param project_id: Project ID to filter on. + :return: :class:`ListAliasesResponse ` + + Usage: + :: + + result = api.list_aliases() + """ + + res = self._request( + "GET", + "/mailbox/v1alpha1/aliases", + params={ + "mailbox_id": mailbox_id, + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + "project_id": project_id or self.client.default_project_id, + "status": status, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListAliasesResponse(res.json()) + + def list_aliases_all( + self, + *, + order_by: Optional[ListAliasesRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + mailbox_id: Optional[str] = None, + status: Optional[AliasStatus] = None, + project_id: Optional[str] = None, + ) -> list[Alias]: + """ + List aliases for a mailbox. + :param order_by: Order aliases by specific criteria. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Requested page size. Value must be between 1 and 100. + :param mailbox_id: ID of the mailbox for which to list aliases. + :param status: (Optional) Filter aliases by their status. + :param project_id: Project ID to filter on. + :return: :class:`list[Alias] ` + + Usage: + :: + + result = api.list_aliases_all() + """ + + return fetch_all_pages( + type=ListAliasesResponse, + key="aliases", + fetcher=self.list_aliases, + args={ + "order_by": order_by, + "page": page, + "page_size": page_size, + "mailbox_id": mailbox_id, + "status": status, + "project_id": project_id, + }, + ) + + def get_alias( + self, + *, + alias_id: str, + ) -> Alias: + """ + Get an alias by its ID. + :param alias_id: ID of the alias to get. + :return: :class:`Alias ` + + Usage: + :: + + result = api.get_alias( + alias_id="example", + ) + """ + + param_alias_id = validate_path_param("alias_id", alias_id) + + res = self._request( + "GET", + f"/mailbox/v1alpha1/aliases/{param_alias_id}", + ) + + self._throw_on_error(res) + return unmarshal_Alias(res.json()) + + def wait_for_alias( + self, + *, + alias_id: str, + options: Optional[WaitForOptions[Alias, bool]] = None, + ) -> Alias: + """ + Get an alias by its ID. + :param alias_id: ID of the alias to get. + :return: :class:`Alias ` + + Usage: + :: + + result = api.get_alias( + alias_id="example", + ) + """ + + if not options: + options = WaitForOptions() + + if not options.stop: + options.stop = lambda res: res.status not in ALIAS_TRANSIENT_STATUSES + + return wait_for_resource( + fetcher=self.get_alias, + options=options, + args={ + "alias_id": alias_id, + }, + ) + + def delete_alias( + self, + *, + alias_id: str, + ) -> Alias: + """ + Delete an alias by its ID. + :param alias_id: ID of the alias to delete. + :return: :class:`Alias ` + + Usage: + :: + + result = api.delete_alias( + alias_id="example", + ) + """ + + param_alias_id = validate_path_param("alias_id", alias_id) + + res = self._request( + "DELETE", + f"/mailbox/v1alpha1/aliases/{param_alias_id}", + ) + + self._throw_on_error(res) + return unmarshal_Alias(res.json()) diff --git a/scaleway/scaleway/mailbox/v1alpha1/marshalling.py b/scaleway/scaleway/mailbox/v1alpha1/marshalling.py index 5c1a0a325..fae8fd1af 100644 --- a/scaleway/scaleway/mailbox/v1alpha1/marshalling.py +++ b/scaleway/scaleway/mailbox/v1alpha1/marshalling.py @@ -14,11 +14,12 @@ MailboxStatus, MailboxSubscriptionPeriod, Mailbox, - Domain, Alias, + Domain, BatchCreateMailboxesResponse, DomainRecord, GetDomainRecordsResponse, + ListAliasesResponse, ListDomainsResponse, ListMailboxesResponse, BatchCreateMailboxesRequestMailboxParameters, @@ -116,6 +117,59 @@ def unmarshal_Mailbox(data: Any) -> Mailbox: return Mailbox(**args) +def unmarshal_Alias(data: Any) -> Alias: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Alias' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("email", None) + if field is not None: + args["email"] = field + else: + args["email"] = None + + field = data.get("mailbox_id", None) + if field is not None: + args["mailbox_id"] = field + else: + args["mailbox_id"] = None + + field = data.get("description", None) + if field is not None: + args["description"] = field + else: + args["description"] = None + + field = data.get("status", None) + if field is not None: + args["status"] = field + else: + args["status"] = AliasStatus.UNKNOWN_STATUS + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("updated_at", None) + if field is not None: + args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["updated_at"] = None + + return Alias(**args) + + def unmarshal_Domain(data: Any) -> Domain: if not isinstance(data, dict): raise TypeError( @@ -193,59 +247,6 @@ def unmarshal_Domain(data: Any) -> Domain: return Domain(**args) -def unmarshal_Alias(data: Any) -> Alias: - if not isinstance(data, dict): - raise TypeError( - "Unmarshalling the type 'Alias' failed as data isn't a dictionary." - ) - - args: dict[str, Any] = {} - - field = data.get("id", None) - if field is not None: - args["id"] = field - else: - args["id"] = None - - field = data.get("email", None) - if field is not None: - args["email"] = field - else: - args["email"] = None - - field = data.get("mailbox_id", None) - if field is not None: - args["mailbox_id"] = field - else: - args["mailbox_id"] = None - - field = data.get("description", None) - if field is not None: - args["description"] = field - else: - args["description"] = None - - field = data.get("status", None) - if field is not None: - args["status"] = field - else: - args["status"] = AliasStatus.UNKNOWN_STATUS - - field = data.get("created_at", None) - if field is not None: - args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field - else: - args["created_at"] = None - - field = data.get("updated_at", None) - if field is not None: - args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field - else: - args["updated_at"] = None - - return Alias(**args) - - def unmarshal_BatchCreateMailboxesResponse(data: Any) -> BatchCreateMailboxesResponse: if not isinstance(data, dict): raise TypeError( @@ -419,6 +420,31 @@ def unmarshal_GetDomainRecordsResponse(data: Any) -> GetDomainRecordsResponse: return GetDomainRecordsResponse(**args) +def unmarshal_ListAliasesResponse(data: Any) -> ListAliasesResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListAliasesResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + field = data.get("aliases", None) + if field is not None: + args["aliases"] = ( + [unmarshal_Alias(v) for v in field] if field is not None else None + ) + else: + args["aliases"] = [] + + return ListAliasesResponse(**args) + + def unmarshal_ListDomainsResponse(data: Any) -> ListDomainsResponse: if not isinstance(data, dict): raise TypeError( @@ -514,6 +540,9 @@ def marshal_CreateAliasRequest( if request.local_part is not None: output["local_part"] = request.local_part + if request.mailbox_id is not None: + output["mailbox_id"] = request.mailbox_id + if request.description is not None: output["description"] = request.description diff --git a/scaleway/scaleway/mailbox/v1alpha1/types.py b/scaleway/scaleway/mailbox/v1alpha1/types.py index 69d944ae4..84b8b34bc 100644 --- a/scaleway/scaleway/mailbox/v1alpha1/types.py +++ b/scaleway/scaleway/mailbox/v1alpha1/types.py @@ -68,6 +68,18 @@ def __str__(self) -> str: return str(self.value) +class ListAliasesRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_DESC = "created_at_desc" + CREATED_AT_ASC = "created_at_asc" + UPDATED_AT_DESC = "updated_at_desc" + UPDATED_AT_ASC = "updated_at_asc" + NAME_DESC = "name_desc" + NAME_ASC = "name_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListDomainsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): CREATED_AT_DESC = "created_at_desc" CREATED_AT_ASC = "created_at_asc" @@ -239,98 +251,98 @@ class DomainRecord: @dataclass -class Domain: +class Alias: id: str """ - Unique identifier of the domain. + Unique identifier of the alias. """ - project_id: str + email: str """ - ID of the Project to which the domain belongs. + Email address of the alias as local_part@domain. """ - name: str + mailbox_id: str """ - Fully qualified domain name. + ID of the mailbox to which the alias belongs. """ - status: DomainStatus + description: str """ - Status of the domain. + Description of the alias. """ - mailbox_total_count: int + status: AliasStatus """ - Number of mailboxes of the domain. + Current status of the alias. """ - webmail_url: str + created_at: Optional[datetime] = None """ - URL of the domain's webmail. + Date and time of alias creation. """ - imap_url: str + updated_at: Optional[datetime] = None """ - URL of the domain's IMAP service. + Date and time when the alias was last updated. """ - pop3_url: str + +@dataclass +class Domain: + id: str """ - URL of the domain's POP3 service. + Unique identifier of the domain. """ - smtp_url: str + project_id: str """ - URL of the domain's SMTP service. + ID of the Project to which the domain belongs. """ - created_at: Optional[datetime] = None + name: str """ - Date and time of domain creation. + Fully qualified domain name. """ - updated_at: Optional[datetime] = None + status: DomainStatus """ - Date and time of the domain's last update. + Status of the domain. """ - -@dataclass -class Alias: - id: str + mailbox_total_count: int """ - Unique identifier of the alias. + Number of mailboxes of the domain. """ - email: str + webmail_url: str """ - Email address of the alias as local_part@domain. + URL of the domain's webmail. """ - mailbox_id: str + imap_url: str """ - ID of the mailbox to which the alias belongs. + URL of the domain's IMAP service. """ - description: str + pop3_url: str """ - Description of the alias. + URL of the domain's POP3 service. """ - status: AliasStatus + smtp_url: str """ - Current status of the alias. + URL of the domain's SMTP service. """ created_at: Optional[datetime] = None """ - Date and time of alias creation. + Date and time of domain creation. """ updated_at: Optional[datetime] = None """ - Date and time when the alias was last updated. + Date and time of the domain's last update. """ @@ -395,6 +407,14 @@ class CreateDomainRequest: """ +@dataclass +class DeleteAliasRequest: + alias_id: str + """ + ID of the alias to delete. + """ + + @dataclass class DeleteDomainRequest: domain_id: str @@ -411,6 +431,14 @@ class DeleteMailboxRequest: """ +@dataclass +class GetAliasRequest: + alias_id: str + """ + ID of the alias to get. + """ + + @dataclass class GetDomainRecordsRequest: domain_id: str @@ -498,6 +526,54 @@ class GetMailboxRequest: """ +@dataclass +class ListAliasesRequest: + order_by: Optional[ListAliasesRequestOrderBy] = ( + ListAliasesRequestOrderBy.CREATED_AT_DESC + ) + """ + Order aliases by specific criteria. + """ + + page: Optional[int] = 0 + """ + Requested page number. Value must be greater or equal to 1. + """ + + page_size: Optional[int] = 0 + """ + Requested page size. Value must be between 1 and 100. + """ + + mailbox_id: Optional[str] = None + """ + ID of the mailbox for which to list aliases. + """ + + status: Optional[AliasStatus] = AliasStatus.UNKNOWN_STATUS + """ + (Optional) Filter aliases by their status. + """ + + project_id: Optional[str] = None + """ + Project ID to filter on. + """ + + +@dataclass +class ListAliasesResponse: + total_count: int + """ + Number of aliases that match the request (without pagination). + """ + + aliases: list[Alias] + """ + Single page of aliases matching the requested criteria. + """ + + @dataclass class ListDomainsRequest: order_by: Optional[ListDomainsRequestOrderBy] = None @@ -555,6 +631,11 @@ class ListMailboxesRequest: (Optional) Search term to filter mailboxes on name and local_part. """ + project_id: Optional[str] = None + """ + (Optional) Project ID to filter mailboxes on. + """ + @dataclass class ListMailboxesResponse: