Skip to content

feat: upstream pagination, iterators, embeds, and new API methods#12

Open
vidiecan wants to merge 1 commit intofix/upstream-bugfixes-and-proxy-supportfrom
feature/upstream-pagination-and-new-features
Open

feat: upstream pagination, iterators, embeds, and new API methods#12
vidiecan wants to merge 1 commit intofix/upstream-bugfixes-and-proxy-supportfrom
feature/upstream-pagination-and-new-features

Conversation

@vidiecan
Copy link

Summary

Backport of major features from upstream the-library-code/dspace-rest-python v0.1.16 into our fork. This PR builds on top of #11 (bugfixes and proxy support) and adds all significant new features.

Target branch: fix/upstream-bugfixes-and-proxy-support (PR #11) merge #11 first, then this PR into dtq.


Changes

Pagination & Iterators

  • paginated() decorator generic decorator that wraps any endpoint to automatically handle DSpace REST API pagination, yielding results one at a time without loading everything into memory.
  • New *_iter methods that use the decorator:
    • get_bundles_iter(parent, ...)
    • get_bitstreams_iter(bundle, ...)
    • get_communities_iter(...)
    • get_collections_iter(...)
    • get_users_iter(...)
    • search_groups_by_metadata_iter(query, ...)
    • get_resource_policies_iter(parent, ...)

Embeds Support

  • parse_params() helper function builds query parameter dicts with proper embed entries for HAL+JSON responses.
  • Added embeds parameter to all major retrieval/mutation methods: get_dso, create_dso, update_dso, get_bundles, get_bitstreams, get_communities, get_collections, get_items, get_users, search_objects.

Search Enhancements

  • search_objects now accepts a configuration parameter (e.g. 'administrativeView').
  • Search results are returned as SimpleDSpaceObject instead of full DSpaceObject (matches upstream behavior).
  • Added search_objects_iter for paginated discovery search iteration.

New API Methods

Method Description
create_item_version(item_uuid, summary) Create a new version of an existing item
resolve_identifier_to_dso(identifier) Resolve handle/DOI/UUID to a DSpaceObject
create_resource_policy(resource_policy, parent, eperson, group) Create authorization policies on DSpace objects

New Model Classes (models.py)

Class Parent Description
BitstreamFormat AddressableHALResource Bitstream format metadata (mimetype, extensions, support level)
SearchResult HALResource Discovery search result container (query, scope, filters)

Infrastructure

  • __version__ exposed via importlib.metadata (falls back to 'unknown').
  • Optional smart_open integration if installed, create_bitstream can read from remote URIs (S3, HTTP, etc.) in addition to local files.
  • functools import for decorator support.

Preserved Custom Code

All dataquest-dev custom features are untouched:

  • verify_response / last_err / _last_err error tracking
  • get_resourcepolicy / get_owningCollection / remove_metadata
  • ResourcePolicy with groupName / groupUUID
  • 401 retry logic in api_post
  • details parameter in search_objects
  • Named _logger throughout

Testing

  • Both client.py and models.py compile cleanly (py_compile).
  • No lint errors.

Backport major features from upstream the-library-code/dspace-rest-python v0.1.16:

Pagination & iterators:
- Add paginated() decorator for automatic pagination handling
- Add *_iter methods: get_bundles_iter, get_bitstreams_iter,
  get_communities_iter, get_collections_iter, get_users_iter,
  search_groups_by_metadata_iter, get_resource_policies_iter

Embeds support:
- Add parse_params() helper for building query params with embeds
- Add embeds parameter to: get_dso, create_dso, update_dso,
  get_bundles, get_bitstreams, get_communities, get_collections,
  get_items, get_users, search_objects

Search enhancements:
- Add configuration parameter to search_objects
- Return SimpleDSpaceObject for search results instead of full DSpaceObject
- Add search_objects_iter with paginated iteration

New API methods:
- create_item_version: Create versioned copies of items
- resolve_identifier_to_dso: Resolve handles/DOIs/UUIDs to DSOs
- create_resource_policy: Create authorization policies on objects

New model classes:
- BitstreamFormat: Model for bitstream format metadata
- SearchResult: Model for discovery search results

Infrastructure:
- Add __version__ via importlib.metadata
- Add smart_open support (optional) for remote bitstream paths
- Add functools import for decorator support
Copilot AI review requested due to automatic review settings February 13, 2026 22:45
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR backports major features from upstream dspace-rest-python v0.1.16, adding pagination support, HAL+JSON embeds, and new API methods while preserving all dataquest-dev customizations.

Changes:

  • Added pagination decorator and iterator methods for resource retrieval (bundles, bitstreams, communities, collections, users, groups, search results)
  • Implemented embeds support across all major retrieval/mutation methods using new parse_params() helper
  • Added new API methods: create_item_version, resolve_identifier_to_dso, create_resource_policy
  • Introduced BitstreamFormat and SearchResult model classes
  • Integrated optional smart_open support for remote file URIs in bitstream creation

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
dspace_rest_client/models.py Added BitstreamFormat and SearchResult model classes to support new API features
dspace_rest_client/client.py Added pagination decorator, iterator methods, embeds support, version management, identifier resolution, and resource policy creation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +897 to +900
if smart_open is not None:
file = (name, smart_open.open(path, 'rb'), mime)
else:
file = (name, open(path, 'rb'), mime)
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file handle opened with either smart_open.open() or open() is never explicitly closed. This could lead to resource leaks. Consider using a context manager (with statement) to ensure the file is properly closed after use.

Copilot uses AI. Check for mistakes.
mimetype = None
supportLevel = None
internal = False
extensions = []
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a mutable default value (empty list) as a class attribute can cause unintended sharing of state between instances. If one instance modifies this list, all instances will see the change. Initialize extensions to None and set it to an empty list in __init__, or use extensions = None as the default.

Copilot uses AI. Check for mistakes.
Comment on lines +565 to +569
appliedFilters = []
type = None

def __init__(self, api_resource):
super(SearchResult, self).__init__(api_resource)
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a mutable default value (empty list) as a class attribute can cause unintended sharing of state between instances. Initialize appliedFilters to None and set it to an empty list in __init__, or use appliedFilters = None as the default.

Suggested change
appliedFilters = []
type = None
def __init__(self, api_resource):
super(SearchResult, self).__init__(api_resource)
appliedFilters = None
type = None
def __init__(self, api_resource):
super(SearchResult, self).__init__(api_resource)
# Ensure each instance has its own list of applied filters
self.appliedFilters = []

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant