Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JohnVillalovos opened this issue Dec 7, 2021 · 6 comments
Open

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

JohnVillalovos opened this issue Dec 7, 2021 · 6 comments

Comments

@JohnVillalovos
Copy link
Member

JohnVillalovos commented Dec 7, 2021

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

@JohnVillalovos
Copy link
Member Author

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

@fletchowns
Copy link

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!

@JohnVillalovos
Copy link
Member Author

JohnVillalovos commented Aug 24, 2024

@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 ☹️

@fletchowns
Copy link

fletchowns commented Aug 24, 2024

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

@fletchowns
Copy link

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')

@JohnVillalovos
Copy link
Member Author

@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.

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

No branches or pull requests

2 participants