diff --git a/changes/240.canada.feature b/changes/240.canada.feature new file mode 100644 index 00000000000..4ad513b1c49 --- /dev/null +++ b/changes/240.canada.feature @@ -0,0 +1 @@ +Added `TypedDict` sub-classes for `package_show`, `resource_show`, and `organization_show` to help improve code type checking. diff --git a/ckan/types/__init__.py b/ckan/types/__init__.py index 779acf85b13..70066e68848 100644 --- a/ckan/types/__init__.py +++ b/ckan/types/__init__.py @@ -26,6 +26,12 @@ if TYPE_CHECKING: from ckanext.activity.model import Activity +# (canada fork only): TypedDict sub-classes for action results +# TODO: upstream contrib!!! +from sqlalchemy.types import DateTime +from typing_extensions import Required +from typing import Dict, List + __all__ = [ "Response", "Request", @@ -41,6 +47,11 @@ "AuthResult", "Action", "ChainedAction", "AuthFunction", "ChainedAuthFunction", "PFeed", "PFeedFactory", "PResourceUploader", "PUploader", + # (canada fork only): TypedDict sub-classes for action results + # TODO: upstream contrib!!! + 'ExtrasDict', 'TagDict', 'TrackingSummaryDict', + 'ResourceShowDict', 'PackageShowDict', 'GroupPackageDict', + 'GroupMemberDict', 'OrganizationShowDict' ] Config: TypeAlias = Dict[str, Union[str, Mapping[str, str]]] CKANApp = Any @@ -242,3 +253,155 @@ def get_path(self, id: str) -> str: def upload(self, id: str, max_size: int = ...) -> None: ... + + +# (canada fork only): TypedDict sub-classes for action results +# TODO: upstream contrib!!! +class ExtrasDict(TypedDict, total=False): + ''' + Dictionary for object extras. + + see: ckan.logic.schema.default_tags_schema + ''' + id: str + key: Required[str] + value: Required[Any] + state: str + deleted: bool + revision_timestamp: DateTime + + +class TagDict(TypedDict, total=False): + ''' + Dictionary for tags. + + see: ckan.logic.schema.default_tags_schema + ''' + name: Required[str] + vocabulary_id: str + revision_timestamp: DateTime + state: str + display_name: str + + +class TrackingSummaryDict(TypedDict): + ''' + Dictionary for tracking summaries. + + see: ckan.model.tracking:TrackingSummary + ''' + total: int + recent: int + + +class ResourceShowDict(TypedDict, total=False): + ''' + Dictionary returned from the resource_show action. + + see: ckan.logic.schema.default_show_package_schema + ''' + id: Required[str] + package_id: Required[str] + url: str + description: str + format: str + hash: str + state: str + position: int + name: str + resource_type: str + url_type: str + mimetype: str + mimetype_inner: str + cache_url: str + size: int + created: Required[DateTime] + last_modified: DateTime + metadata_modified: DateTime + cache_last_updated: DateTime + datastore_active: bool + tracking_summary: TrackingSummaryDict + + +class PackageShowDict(TypedDict, total=False): + ''' + Dictionary returned from the package_show action. + + see: ckan.logic.schema.default_show_package_schema + ''' + id: Required[str] + name: Optional[str] + title: str + notes: str + type: str + url: str + version: str + metadata_created: Required[DateTime] + metadata_modified: DateTime + plugin_data: Dict[str, Any] + private: bool + state: str + isopen: bool + license_url: str + creator_user_id: str + author: str + author_email: str + maintainer: str + maintainer_email: str + license_id: str + license_title: str + tracking_summary: TrackingSummaryDict + owner_org: str + organization: OrganizationShowDict + resources: List[ResourceShowDict] + num_resources: int + tags: List[TagDict] + tag_string: str + num_tags: int + + +class GroupPackageDict(TypedDict, total=False): + ''' + Dictionary part of a group's packages. + + see: ckan.logic.schema.default_group_schema + ''' + id: Required[str] + title: str + name: str + + +class GroupMemberDict(TypedDict, total=False): + ''' + Dictionary part of a group's users and groups. + + see: ckan.logic.schema.default_group_schema + ''' + name: Required[str] + capacity: str + + +class OrganizationShowDict(TypedDict, total=False): + ''' + Dictionary returned from the organization_show action. + + see: ckan.logic.schema.default_show_group_schema + ''' + id: Required[str] + name: Required[str] + title: str + description: str + image_url: str + image_display_url: str + type: str + state: str + created: DateTime + is_organization: bool + approval_status: str + extras: List[ExtrasDict] + packages: List[GroupPackageDict] + users: List[GroupMemberDict] + groups: List[GroupMemberDict] + num_followers: int + display_name: str + package_count: int