Skip to content

Add support for hash and Array of hashes data types #1735

Open

Description

@JohnVillalovos

We need to add support for hash and Array of hashes types.

https://docs.gitlab.com/ee/api/#encoding-api-parameters-of-array-and-hash-types

Currently we don't support either of these. Also at this moment there is a PR #1699 open to better support handling array types.

A related issue is #1732

Activity

  1. JohnVillalovos commented on Jan 6, 2022

    @JohnVillalovos
    MemberAuthor

    So there seems to be some sort of support for hash here:

    def copy_dict(dest: Dict[str, Any], src: Dict[str, Any]) -> None:
    for k, v in src.items():
    if isinstance(v, dict):
    # Transform dict values to new attributes. For example:
    # custom_attributes: {'foo', 'bar'} =>
    # "custom_attributes['foo']": "bar"
    for dict_k, dict_v in v.items():
    dest[f"{k}[{dict_k}]"] = dict_v
    else:
    dest[k] = v

  2. fletchowns commented on Aug 24, 2024

    @fletchowns

    Does this issue prevent the ability of using not condition in query_parameters? I came across an example that made it seem like it would be supported.

    For example, when retrieving merge requests that a reviewer has not yet approved, I was thinking it would be something like:

    gl.mergerequests.list(query_parameters={
        "scope": "all",
        "state": "open",
        "reviewer_username": "some.user",
        "not[approved_by_username][]": "some-user",
    }, iterator=True)

    Here's the logs of what is generated by the above attempt:

    DEBUG:http.client:send: b'GET /api/v4/merge_requests?scope=all&state=opened&reviewer_username=some.user&not%5Bapproved_by_usernames%5D%5B%5D=some.user&per_page=100 ...'
    

    That does not seem to work though, perhaps due to the encoding of the square brackets? I also tried:

    gl.mergerequests.list(query_parameters={
        'scope': 'all',
        'state': 'opened',
        'reviewer_username': 'some.user',
        'not': {
            'approved_by_usernames': ['some.user']
        }
    }, iterator=True)

    That didn't seem to work either. Is this not currently possible?

    The Gitlab UI itself generates query parameters such as the following for it:

    scope=all&state=opened&reviewer_username=some.user&not[approved_by_usernames][]=some.user
    

    I also came across https://gitlab.com/gitlab-org/gitlab/-/issues/358418 which talks about potentially changing the Gitlab API to respect RFC 6570 encoding of parameters like this that was a bit related to this topic.

    Thanks for the great library!

  3. JohnVillalovos commented on Aug 24, 2024

    @JohnVillalovos
    MemberAuthor

    @fletchowns I don't think that will work. Now you might try doing: {'not[approved_byusernames]': ['some.user']}

    Maybe that would work but I don't know.

    EDIT: Oh I see you attempted that already. So never mind ☹️

  4. fletchowns commented on Aug 24, 2024

    @fletchowns

    Thank you for the suggestion @JohnVillalovos . I had not tried exactly that, but I just tried that as well and it does not seem to work:

    gl.mergerequests.list(query_parameters={
        'scope': 'all',
        'state': 'opened',
        'reviewer_username': 'some.user',
        'not[approved_by_usernames]': ['some.user']
    }, iterator=True)
    

    Resulting URL from debug logs:

    &not%5Bapproved_by_usernames%5D=some.user
    
  5. fletchowns commented on Aug 25, 2024

    @fletchowns

    I tried using http_get as a workaround, but that seemed to have the encoding issue as well:

    self.gl.http_get(/merge_requests?scope=all&state=opened&reviewer_username=some.user&not[approved_by_usernames][]=some.user')
    

    It really doesn't like those square brackets! It seems like encoding them should be the correct behavior though. Is it the gitlab API that is not following URL encoding standards here?

    To run a similar request via cURL, I have to use --globoff in order for it to work:

    curl 'https://.../api/v4/merge_requests?scope=all&state=opened&reviewer_username=some.user&not[approved_by_usernames][]=some.user'  --globoff
    

    As a workaround for my particular use case, I am doing the filtering myself by sifting through the approvals response (this API doesn't seem to be supported yet by the library, so using low level method here):

    self.gl.http_get(f'/projects/{project_id}/merge_requests/{merge_request_id}/approvals')
    
  6. JohnVillalovos commented on Aug 27, 2024

    @JohnVillalovos
    MemberAuthor

    @fletchowns So it seems like requests will always escape the [] characters. While --globoff in curl does not escape those characters. If GitLab requires unescaped characters then it might be very difficult to do this.

  7. github-actions commented on Jul 9, 2025

    @github-actions

    This issue was marked stale because it has been open 60 days with
    no activity. Please remove the stale label or comment on this
    issue. Otherwise, it will be closed in 15 days.

    As an open-source project, we rely on community contributions to
    address many of the reported issues. Without a proposed fix or
    active work towards a solution it is our policy to close inactive
    issues. This is documented in CONTRIBUTING.rst

    How to keep this issue open:

    • If you are still experiencing this issue and are willing to
      investigate a fix, please comment and let us know.
    • If you (or someone else) can propose a pull request with a
      solution, that would be fantastic.
    • Any significant update or active discussion indicating progress
      will also prevent closure.

    We value your input. If you can help provide a fix, we'd be happy
    to keep this issue open and support your efforts.

    This is documented in CONTRIBUTING.rst
    https://github.com/python-gitlab/python-gitlab/blob/main/CONTRIBUTING.rst

  8. AdrianDC commented on Sep 6, 2025

    @AdrianDC
    Contributor

    The missing support also prevents from adding the not[type]=value Python and CLI implementation for Issues list API :

    Python workarounds are suggested here, but CLI can't be done for now :

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions