Skip to content

Commit 7b07dcd

Browse files
authored
MPT-20684 introduce shared base models for file-like resources (#325)
🤖 AI-generated PR — Please review carefully. ## Summary Reduces duplicated field declarations across the model layer by extracting a shared `FileResourceModel` base for attachments, documents, media, and term variants, plus four specialized subclasses (`AttachmentModel`, `DocumentModel`, `MediaModel`, `TermVariantModel`). Resource classes across billing, catalog, commerce, helpdesk, integration, and program domains now inherit from the new base models instead of redeclaring the same fields locally. ## What changed ### New base models (`mpt_api_client/models/`) - `file_resource_model.py` — shared fields: `name`, `type`, `size`, `description`, `content_type` - `attachment_model.py` — attachment-specific fields on top of the base - `document_model.py` — document-specific fields - `media_model.py` — media-specific fields - `term_variant_model.py` — term-variant-specific fields - `__init__.py` re-exports the new classes ### Migrated resource classes - `billing/`: credit_memo_attachments, custom_ledger_attachments, invoice_attachments, journal_attachments, ledger_attachments, statement_attachments - `catalog/`: pricing_policy_attachments, product_term_variants, products_documents, products_media - `helpdesk/`: chat_attachments - `integration/`: extension_documents, extension_media, extension_term_variants - `program/`: enrollments_attachments, programs_documents, programs_media, programs_terms_variant Resource-specific fields (parent references, audit, language, revision, etc.) remain on the subclasses. ### Tests - New `tests/unit/conftest.py` fixtures for inherited-field coverage - New unit test files for each base model under `tests/unit/models/` - Updated existing unit tests to reflect the new convention where missing optional fields default to `None` instead of raising `AttributeError` ## Testing - [ ] `make check` (lint + types) - [ ] `make test` (unit suite) - [ ] Smoke-run a few e2e tests touching the migrated resources to confirm response parsing still works against the live API ## Jira MPT-20684 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> Closes [MPT-20684](https://softwareone.atlassian.net/browse/MPT-20684) ## Release Notes - **Introduced shared base models** to reduce code duplication for file-like resources: - `FileResourceModel`: Base class with common fields (`name`, `type`, `size`, `description`, `content_type`) - `AttachmentModel`: Specialization of `FileResourceModel` for attachment resources - `DocumentModel`: Extends `FileResourceModel` with document-specific fields (`status`, `filename`, `url`) - `MediaModel`: Extends `FileResourceModel` with media-specific fields (`status`, `filename`, `display_order`, `url`) - `TermVariantModel`: Extends `FileResourceModel` with term variant fields (`asset_url`, `language_code`, `status`, `filename`, `file_id`) - **Updated resource classes** across multiple modules to inherit from appropriate base models instead of directly from `Model`: - Billing: `CreditMemoAttachment`, `CustomLedgerAttachment`, `InvoiceAttachment`, `JournalAttachment`, `LedgerAttachment`, `StatementAttachment` - Catalog: `PricingPolicyAttachment`, `TermVariant`, `Document`, `Media` - Helpdesk: Removed `ChatAttachment` and updated service to use `AttachmentModel` directly - Integration: `ExtensionDocument`, `ExtensionMedia`, `ExtensionTermVariant` - Program: `Document`, `Media`, `TermVariant`, `EnrollmentAttachment` - **Eliminated duplicate field declarations** by migrating resource classes to inherit shared fields from their respective base models - **Added comprehensive unit test coverage** for new base models including field initialization, camelCase-to-snake_case mapping, serialization round-trips, and `repr()` formatting - **Updated existing resource tests** to validate inherited field behavior with optional fields defaulting to `None` instead of being absent - **Updated E2E tests** for chat attachments to validate against `AttachmentModel` instead of the removed `ChatAttachment` class - **Expanded module exports** in `mpt_api_client/models/__init__.py` to include new model classes for public API access <!-- end of auto-generated comment: release notes by coderabbit.ai --> [MPT-20684]: https://softwareone.atlassian.net/browse/MPT-20684?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2 parents 8389441 + 6ed09ac commit 7b07dcd

48 files changed

Lines changed: 729 additions & 319 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

mpt_api_client/models/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
1+
from mpt_api_client.models.attachment_model import AttachmentModel
2+
from mpt_api_client.models.document_model import DocumentModel
13
from mpt_api_client.models.file_model import FileModel
4+
from mpt_api_client.models.file_resource_model import FileResourceModel
5+
from mpt_api_client.models.media_model import MediaModel
26
from mpt_api_client.models.meta import Meta, Pagination
37
from mpt_api_client.models.model import Model, ResourceData
48
from mpt_api_client.models.model_collection import ModelCollection
9+
from mpt_api_client.models.term_variant_model import TermVariantModel
510

6-
__all__ = ["FileModel", "Meta", "Model", "ModelCollection", "Pagination", "ResourceData"] # noqa: WPS410
11+
__all__ = [ # noqa: WPS410
12+
"AttachmentModel",
13+
"DocumentModel",
14+
"FileModel",
15+
"FileResourceModel",
16+
"MediaModel",
17+
"Meta",
18+
"Model",
19+
"ModelCollection",
20+
"Pagination",
21+
"ResourceData",
22+
"TermVariantModel",
23+
]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from mpt_api_client.models.file_resource_model import FileResourceModel
2+
3+
4+
class AttachmentModel(FileResourceModel):
5+
"""Base model for attachment resources. Inherits fields from FileResourceModel."""
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from mpt_api_client.models.file_resource_model import FileResourceModel
2+
3+
4+
class DocumentModel(FileResourceModel):
5+
"""Base model for document resources.
6+
7+
Attributes:
8+
status: Document status.
9+
filename: Original file name.
10+
url: URL to access the document.
11+
"""
12+
13+
status: str | None = None
14+
filename: str | None = None
15+
url: str | None = None
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from mpt_api_client.models.model import Model
2+
3+
4+
class FileResourceModel(Model):
5+
"""Base model for file-like resources (attachments, documents, media, term variants).
6+
7+
Attributes:
8+
name: Resource name.
9+
type: Resource type.
10+
size: File size in bytes.
11+
description: Resource description.
12+
content_type: MIME content type.
13+
"""
14+
15+
name: str | None = None
16+
type: str | None = None
17+
size: int | None = None
18+
description: str | None = None
19+
content_type: str | None = None
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from mpt_api_client.models.file_resource_model import FileResourceModel
2+
3+
4+
class MediaModel(FileResourceModel):
5+
"""Base model for media resources.
6+
7+
Attributes:
8+
status: Media status.
9+
filename: Original file name.
10+
display_order: Display order of the media item.
11+
url: URL to access the media file.
12+
"""
13+
14+
status: str | None = None
15+
filename: str | None = None
16+
display_order: int | None = None
17+
url: str | None = None
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from mpt_api_client.models.file_resource_model import FileResourceModel
2+
3+
4+
class TermVariantModel(FileResourceModel):
5+
"""Base model for term variant resources.
6+
7+
Attributes:
8+
asset_url: URL to the variant asset.
9+
language_code: Language code for this variant.
10+
status: Variant status.
11+
filename: Original file name.
12+
file_id: Identifier of the uploaded file.
13+
"""
14+
15+
asset_url: str | None = None
16+
language_code: str | None = None
17+
status: str | None = None
18+
filename: str | None = None
19+
file_id: str | None = None

mpt_api_client/resources/billing/credit_memo_attachments.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
AsyncCollectionMixin,
44
CollectionMixin,
55
)
6-
from mpt_api_client.models import Model
6+
from mpt_api_client.models import AttachmentModel
77
from mpt_api_client.resources.billing.mixins import AsyncAttachmentMixin, AttachmentMixin
88

99

10-
class CreditMemoAttachment(Model):
11-
"""Credit Memo Attachment resource."""
10+
class CreditMemoAttachment(AttachmentModel):
11+
"""Credit Memo Attachment resource. Inherits fields from AttachmentModel."""
1212

1313

1414
class CreditMemoAttachmentsServiceConfig:

mpt_api_client/resources/billing/custom_ledger_attachments.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
AsyncCollectionMixin,
44
CollectionMixin,
55
)
6-
from mpt_api_client.models import Model
6+
from mpt_api_client.models import AttachmentModel
77
from mpt_api_client.resources.billing.mixins import AsyncAttachmentMixin, AttachmentMixin
88

99

10-
class CustomLedgerAttachment(Model):
11-
"""Custom Ledger Attachment resource."""
10+
class CustomLedgerAttachment(AttachmentModel):
11+
"""Custom Ledger Attachment resource. Inherits fields from AttachmentModel."""
1212

1313

1414
class CustomLedgerAttachmentsServiceConfig:

mpt_api_client/resources/billing/invoice_attachments.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
AsyncCollectionMixin,
44
CollectionMixin,
55
)
6-
from mpt_api_client.models import Model
6+
from mpt_api_client.models import AttachmentModel
77
from mpt_api_client.resources.billing.mixins import AsyncAttachmentMixin, AttachmentMixin
88

99

10-
class InvoiceAttachment(Model):
11-
"""Invoice Attachment resource."""
10+
class InvoiceAttachment(AttachmentModel):
11+
"""Invoice Attachment resource. Inherits fields from AttachmentModel."""
1212

1313

1414
class InvoiceAttachmentsServiceConfig:

mpt_api_client/resources/billing/journal_attachments.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
AsyncCollectionMixin,
44
CollectionMixin,
55
)
6-
from mpt_api_client.models import Model
6+
from mpt_api_client.models import AttachmentModel
77
from mpt_api_client.resources.billing.mixins import AsyncAttachmentMixin, AttachmentMixin
88

99

10-
class JournalAttachment(Model):
11-
"""Journal Attachment resource."""
10+
class JournalAttachment(AttachmentModel):
11+
"""Journal Attachment resource. Inherits fields from AttachmentModel."""
1212

1313

1414
class JournalAttachmentsServiceConfig:

0 commit comments

Comments
 (0)