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
18 changes: 18 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 2025-05-30 "Metadata Enhancements & SDK Improvements" - version 1.13.0

### Added
- Implemented `get_field(field_name: str)` method in `pythonik.specs.metadata.MetadataSpec` to retrieve a specific metadata field by its name.
- Added corresponding unit tests for `get_field` covering success (200), not found (404), and unauthorized (401) scenarios.
- Implemented `list_fields` method in `pythonik.specs.metadata.MetadataSpec` to retrieve a list of all metadata fields.
- Added corresponding unit tests for `list_fields`
- Implemented methods for retrieving metadata for specific object types (e.g., assets, collections, segments) and generic object metadata retrieval in `MetadataSpec` (PR #78).

### Changed
- Updated `.gitignore` to include macOS-specific patterns (e.g., `.DS_Store`) for improved repository hygiene (PR #82).

### Fixed
- N/A

### Technical Details
This release introduces the ability to fetch individual metadata fields by name, adds comprehensive integration testing capabilities for metadata fields, and enhances object metadata retrieval. It also includes improvements to the development environment with an updated .gitignore.

## 2025-05-09 "IconikFieldType Update" - version 1.12.2

### Fixed
Expand Down
19 changes: 19 additions & 0 deletions pythonik/models/metadata/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,22 @@ class FieldResponse(BaseModel):

class Config:
use_enum_values = True


class FieldListResponse(BaseModel):
"""Response model for a paginated list of metadata fields.

This follows the standard pagination format used by the Iconik API.
"""
first_url: Optional[str] = None
last_url: Optional[str] = None
next_url: Optional[str] = None
objects: List[FieldResponse] = []
page: Optional[int] = None
pages: Optional[int] = None
per_page: Optional[int] = None
prev_url: Optional[str] = None
total: Optional[int] = None

class Config:
use_enum_values = True
70 changes: 66 additions & 4 deletions pythonik/specs/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@
UpdateMetadata,
UpdateMetadataResponse,
)
from pythonik.models.metadata.fields import FieldCreate, FieldUpdate, FieldResponse
from pythonik.models.metadata.fields import (
FieldCreate,
FieldUpdate,
FieldResponse,
FieldListResponse,
)
from pythonik.specs.base import Spec
from typing import Literal, Union, Dict, Any, List
from typing import Literal, Union, Dict, Any, List, Optional


# Asset metadata paths
Expand Down Expand Up @@ -634,6 +639,33 @@ def create_field(
resp = self._post(FIELDS_BASE_PATH, json=json_data, **kwargs)
return self.parse_response(resp, FieldResponse)

def get_field(
self,
field_name: str,
**kwargs,
) -> Response:
"""Retrieve a specific metadata field by its name.

Args:
field_name: The name of the field to retrieve.
**kwargs: Additional kwargs to pass to the request.

Required roles:
- can_read_metadata_fields

Returns:
Response: An object containing the HTTP response and a `data` attribute
with a `FieldResponse` model instance on success, or `None` on error.

Raises:
- 400 Bad request
- 401 Token is invalid
- 404 Metadata field doesn't exist
"""
endpoint = FIELD_BY_NAME_PATH.format(field_name=field_name)
resp = self._get(endpoint, **kwargs)
return self.parse_response(resp, FieldResponse)

def update_field(
self,
field_name: str,
Expand Down Expand Up @@ -678,8 +710,38 @@ def delete_field(
resp = self._delete(endpoint, **kwargs)
return self.parse_response(resp)

# Backward compatibility aliases
# ------------------------------
def list_fields(
self,
per_page: Optional[int] = None,
last_field_name: Optional[str] = None,
filter: Optional[str] = None,
**kwargs,
) -> Response:
"""List all metadata fields.

Args:
per_page: Optional The number of items for each page (Default 500).
last_field_name: Optional If your request returns per_page entries,
send the last value of "name" to fetch next page.
filter: Optional A comma separated list of fieldnames to filter by.
**kwargs: Additional query parameters to pass to the request.

Returns:
Response: A paginated response containing a list of FieldResponse objects.
"""
params = {}
if per_page is not None:
params["per_page"] = per_page
if last_field_name:
params["last_field_name"] = last_field_name
if filter:
params["filter"] = filter

# Add any additional params from kwargs
params.update(kwargs)

resp = self._get(FIELDS_BASE_PATH, params=params)
return self.parse_response(resp, FieldListResponse)

def create_metadata_field(
self,
Expand Down
Loading
Loading