Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions mpt_api_client/mpt_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
AsyncCatalog,
AsyncCommerce,
AsyncExchange,
AsyncExtensibility,
AsyncHelpdesk,
AsyncNotifications,
Audit,
Billing,
Catalog,
Commerce,
Exchange,
Extensibility,
Helpdesk,
Notifications,
)
Expand Down Expand Up @@ -90,6 +92,11 @@ def exchange(self) -> AsyncExchange:
"""Exchange MPT API Client."""
return AsyncExchange(http_client=self.http_client)

@property
def extensibility(self) -> AsyncExtensibility:
"""Extensibility MPT API Client."""
return AsyncExtensibility(http_client=self.http_client)


class MPTClient:
"""MPT API Client."""
Expand Down Expand Up @@ -164,3 +171,8 @@ def helpdesk(self) -> Helpdesk:
def exchange(self) -> Exchange:
"""Exchange MPT API Client."""
return Exchange(http_client=self.http_client)

@property
def extensibility(self) -> Extensibility:
"""Extensibility MPT API Client."""
return Extensibility(http_client=self.http_client)
3 changes: 3 additions & 0 deletions mpt_api_client/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from mpt_api_client.resources.catalog import AsyncCatalog, Catalog
from mpt_api_client.resources.commerce import AsyncCommerce, Commerce
from mpt_api_client.resources.exchange import AsyncExchange, Exchange
from mpt_api_client.resources.extensibility import AsyncExtensibility, Extensibility
from mpt_api_client.resources.helpdesk import AsyncHelpdesk, Helpdesk
from mpt_api_client.resources.notifications import AsyncNotifications, Notifications

Expand All @@ -15,13 +16,15 @@
"AsyncCatalog",
"AsyncCommerce",
"AsyncExchange",
"AsyncExtensibility",
"AsyncHelpdesk",
"AsyncNotifications",
"Audit",
"Billing",
"Catalog",
"Commerce",
"Exchange",
"Extensibility",
"Helpdesk",
"Notifications",
]
9 changes: 9 additions & 0 deletions mpt_api_client/resources/extensibility/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from mpt_api_client.resources.extensibility.extensibility import (
AsyncExtensibility,
Extensibility,
)

__all__ = [ # noqa: WPS410
"AsyncExtensibility",
"Extensibility",
]
29 changes: 29 additions & 0 deletions mpt_api_client/resources/extensibility/extensibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
from mpt_api_client.resources.extensibility.extensions import (
AsyncExtensionsService,
ExtensionsService,
)


class Extensibility:
"""Extensibility MPT API Module."""

def __init__(self, *, http_client: HTTPClient):
self.http_client = http_client

@property
def extensions(self) -> ExtensionsService:
"""Extensions service."""
return ExtensionsService(http_client=self.http_client)


class AsyncExtensibility:
"""Async Extensibility MPT API Module."""

def __init__(self, *, http_client: AsyncHTTPClient):
self.http_client = http_client

@property
def extensions(self) -> AsyncExtensionsService:
"""Extensions service."""
return AsyncExtensionsService(http_client=self.http_client)
93 changes: 93 additions & 0 deletions mpt_api_client/resources/extensibility/extensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from mpt_api_client.http import AsyncService, Service
from mpt_api_client.http.mixins import (
AsyncCollectionMixin,
AsyncCreateFileMixin,
AsyncDeleteMixin,
AsyncGetMixin,
AsyncUpdateFileMixin,
CollectionMixin,
CreateFileMixin,
DeleteMixin,
GetMixin,
UpdateFileMixin,
)
from mpt_api_client.models import Model
from mpt_api_client.models.model import BaseModel
from mpt_api_client.resources.extensibility.mixins import (
AsyncExtensionMixin,
ExtensionMixin,
)


class Extension(Model):
"""Extension resource.

Attributes:
name: Display name of the extension.
icon: URL or identifier for the extension icon.
revision: Revision number.
status: Extension status (Draft, Private, Public, Deleted).
website: Extension website URL.
short_description: Short description of the extension.
long_description: Long description of the extension.
vendor: Reference to the vendor account.
categories: Categories assigned to the extension.
modules: Modules referenced by the extension.
statistics: Extension usage statistics.
configuration: Extension configuration data.
meta: Metadata reference.
service: Service details.
audit: Audit information (created, updated events).
"""

name: str | None
icon: str | None
revision: int | None
status: str | None
website: str | None
short_description: str | None
long_description: str | None
vendor: BaseModel | None
categories: list[BaseModel] | None
modules: list[BaseModel] | None
statistics: BaseModel | None
configuration: BaseModel | None
meta: BaseModel | None
service: BaseModel | None
audit: BaseModel | None


class ExtensionsServiceConfig:
"""Extensions service configuration."""

_endpoint = "/public/v1/extensibility/extensions"
_model_class = Extension
_collection_key = "data"
_upload_file_key = "icon"
_upload_data_key = "extension"


class ExtensionsService(
ExtensionMixin[Extension],
CreateFileMixin[Extension],
UpdateFileMixin[Extension],
GetMixin[Extension],
DeleteMixin,
CollectionMixin[Extension],
Service[Extension],
ExtensionsServiceConfig,
):
"""Sync service for the /public/v1/extensibility/extensions endpoint."""


class AsyncExtensionsService(
AsyncExtensionMixin[Extension],
AsyncCreateFileMixin[Extension],
AsyncUpdateFileMixin[Extension],
AsyncGetMixin[Extension],
AsyncDeleteMixin,
AsyncCollectionMixin[Extension],
AsyncService[Extension],
ExtensionsServiceConfig,
):
"""Async service for the /public/v1/extensibility/extensions endpoint."""
9 changes: 9 additions & 0 deletions mpt_api_client/resources/extensibility/mixins/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from mpt_api_client.resources.extensibility.mixins.extension_mixin import (
AsyncExtensionMixin,
ExtensionMixin,
)

__all__ = [ # noqa: WPS410
"AsyncExtensionMixin",
"ExtensionMixin",
]
121 changes: 121 additions & 0 deletions mpt_api_client/resources/extensibility/mixins/extension_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
from mpt_api_client.models import FileModel


class ExtensionMixin[Model]:
"""Mixin that adds extension-specific actions: publish, unpublish, regenerate, token, icon."""

def publish(self, resource_id: str) -> Model:
"""Publish the extension, moving it to Public status.

Args:
resource_id: Extension ID.

Returns:
Updated extension.
"""
return self._resource(resource_id).post("publish") # type: ignore[attr-defined, no-any-return]

def unpublish(self, resource_id: str) -> Model:
"""Unpublish the extension, moving it to Private status.

Args:
resource_id: Extension ID.

Returns:
Updated extension.
"""
return self._resource(resource_id).post("unpublish") # type: ignore[attr-defined, no-any-return]

def regenerate(self, resource_id: str) -> Model:
"""Regenerate the extension credentials.

Args:
resource_id: Extension ID.

Returns:
Updated extension.
"""
return self._resource(resource_id).post("regenerate") # type: ignore[attr-defined, no-any-return]

def token(self, resource_id: str) -> Model:
"""Retrieve an access token for the extension.

Args:
resource_id: Extension ID.

Returns:
Token response.
"""
return self._resource(resource_id).post("token") # type: ignore[attr-defined, no-any-return]

def download_icon(self, resource_id: str) -> FileModel:
"""Download the icon for the given extension.

Args:
resource_id: Extension ID.

Returns:
File model containing the downloaded icon.
"""
response = self._resource(resource_id).do_request("GET", "icon") # type: ignore[attr-defined]
return FileModel(response)


class AsyncExtensionMixin[Model]:
"""Async mixin for extension-specific actions: publish, unpublish, regenerate, token, icon."""

async def publish(self, resource_id: str) -> Model:
"""Publish the extension, moving it to Public status.

Args:
resource_id: Extension ID.

Returns:
Updated extension.
"""
return await self._resource(resource_id).post("publish") # type: ignore[attr-defined, no-any-return]

async def unpublish(self, resource_id: str) -> Model:
"""Unpublish the extension, moving it to Private status.

Args:
resource_id: Extension ID.

Returns:
Updated extension.
"""
return await self._resource(resource_id).post("unpublish") # type: ignore[attr-defined, no-any-return]

async def regenerate(self, resource_id: str) -> Model:
"""Regenerate the extension credentials.

Args:
resource_id: Extension ID.

Returns:
Updated extension.
"""
return await self._resource(resource_id).post("regenerate") # type: ignore[attr-defined, no-any-return]

async def token(self, resource_id: str) -> Model:
"""Retrieve an access token for the extension.

Args:
resource_id: Extension ID.

Returns:
Token response.
"""
return await self._resource(resource_id).post("token") # type: ignore[attr-defined, no-any-return]

async def download_icon(self, resource_id: str) -> FileModel:
"""Download the icon for the given extension.

Args:
resource_id: Extension ID.

Returns:
File model containing the downloaded icon.
"""
response = await self._resource(resource_id).do_request("GET", "icon") # type: ignore[attr-defined]
return FileModel(response)
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ per-file-ignores = [
"mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215 WPS235",
"mpt_api_client/resources/commerce/*.py: WPS235 WPS215",
"mpt_api_client/resources/exchange/*.py: WPS235 WPS215",
"mpt_api_client/resources/extensibility/*.py: WPS214 WPS215 WPS235",
"mpt_api_client/resources/helpdesk/*.py: WPS204 WPS215 WPS214",
"mpt_api_client/rql/query_builder.py: WPS110 WPS115 WPS210 WPS214",
"tests/e2e/accounts/*.py: WPS430 WPS202",
Expand All @@ -142,6 +143,7 @@ per-file-ignores = [
"tests/unit/http/mixins/*: WPS204 WPS202 WPS210",
"tests/unit/resources/accounts/*.py: WPS204 WPS202 WPS210",
"tests/unit/resources/catalog/test_products.py: WPS202 WPS210",
"tests/unit/resources/extensibility/*.py: WPS202 WPS210 WPS218",
"tests/unit/resources/commerce/*.py: WPS202 WPS204",
"tests/unit/test_mpt_client.py: WPS235",
"tests/*: WPS432 WPS202",
Expand Down
Empty file.
Empty file.
Loading