Skip to content
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

400 Client Error: Bad request #37

Open
lukeallister opened this issue Jan 25, 2023 · 8 comments
Open

400 Client Error: Bad request #37

lukeallister opened this issue Jan 25, 2023 · 8 comments

Comments

@lukeallister
Copy link

lukeallister commented Jan 25, 2023

I suspect that this is related to #33 but I wanted to ask.

I am extending the AssetBankClient to create metaproperty option (as mentioned in #30):

    def create_metaproperty_option(self, property_id, query: dict = None):
        """ Creates a new meta property option. """    
        return self.session.post(f'/v4/metaproperties/{property_id}/options', data=query or {})

Using OAuth2 permanent access token, I'm getting an error triggered from the util.py post function,

raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://<myclienturl>.bynder.com/api/v4/metaproperties/3508BEA1-6255-4225-82D14EBC652BE240/options

Is this the same issue, or different?

[edit: I'm actually using a permanent token with full read/write permissions for Assets, Collections, Metaproperties, and Analytics]

@Arpit-Sharma-USC
Copy link
Contributor

Hi @lukeallister it might be related to it. However, we made a release-fix for that issue for oauth2 here
Please give that a try and let us know if you continue to face any issue(s).

@lukeallister
Copy link
Author

Hi @Arpit-Sharma-USC

I updated to release 1.1.5 but unfortunately still get the 'Bad request' error.

@Arpit-Sharma-USC
Copy link
Contributor

Hi @lukeallister thanks for your reply. It seems like this isn't related to the fix the other issue then. We'll create a ticket and look into it.

@lukeallister
Copy link
Author

Thanks! Do you need anything more from me for testing?

Do we know if this is a python-sdk issue or an API issue? (Do you know if other clients handle this correctly?)

@ahongbynder
Copy link
Contributor

Hi @lukeallister I was able to reproduce the issue and it seems to be related how the form data is encoded from the SDK. Behind the scenes the Bynder Public API call is made to /api/v4/metaproperties/id/options/ with a data payload in the body of the request https://bynder.docs.apiary.io/#reference/metaproperties/metaproperty-option-operations/create-metaproperty-option.
Screen Shot 2023-02-14 at 2 08 49 PM

Here is an example of making a request directly to the endpoint with Postman and with x-www-form-urlencoded:
Screen Shot 2023-02-14 at 2 05 21 PM

The payload of the Python example is in the form of payload = 'data=%7B%22name%22%3A%20%22Test%22%7D' where the contents are URL encoded.

Adding a snippet of code I tested with with your addition of create_metaproperty_option added to AssetBankClient to get the method to work:

    import json
    import urllib.parse

    from bynder_sdk import BynderClient
    
    domain_name = "your-domain.bynder.com"
    perm_token = "******"
    bynder_client = BynderClient(
        domain=domain_name,
        permanent_token=perm_token
    )

    asset_bank_client = bynder_client.asset_bank_client

    # set metaproperty id
    metaproperty_id = "0D563E99-218C-4613-86232D416EB7EA8A"

    new_metaproperty_option = {"name": "Test_Option"}

    # convert Python dictionary to JSON string
    new_metaproperty_option = json.dumps(new_metaproperty_option)

    # URL encode values for Content Type application/x-www-form-urlencoded
    new_metaproperty_option = urllib.parse.quote(new_metaproperty_option)
    
    # Add leading data=
    new_metaproperty_option = "data=" + new_metaproperty_option

    # send request to add metaproperty option to metaproperty id
    asset_bank_client.create_metaproperty_option(metaproperty_id, new_metaproperty_option)

The main points from this example is to convert the dictionary to a JSON string and then URL encode the string correctly to ensure it matches the payload structure of {data: {name: ...} etc.

@lukeallister
Copy link
Author

lukeallister commented Feb 16, 2023

That works; thanks!

I didn't expect the urlencoded content type mixed in with json (like set_media_poperties). I guess maybe the SDK could standardize this as a function that could be added to the create_metaproperty_option and the like? Something like

    def format_urlencoded(self, data):
        """ Converts a dictionary to bynder urlencoded """

        # convert Python dictionary to JSON string
        data = json.dumps(data)

        # URL encode values for Content Type application/x-www-form-urlencoded
        data = urllib.parse.quote(data)
        
        # Add leading data=
        data = "data=" + data

        return data

    def create_metaproperty_option(self, property_id, query: dict = None):
        """ Creates a new metaproperty option. """    
        # if query is dict format_urlencoded
        if isinstance(query, dict):
            query = self.format_urlencoded(query)
        return self.session.post(f'/v4/metaproperties/{property_id}/options', data=query or {})

That would let us could interact with this in the same way as the set_media_poperties and others

Does that make sense?

@ahongbynder
Copy link
Contributor

@lukeallister
I believe right now the SDK offers the following POST methods, one for set_media_properties and create_usage.

set_media_properties calls https://bynder.docs.apiary.io/#reference/assets/specific-asset-operations/modify-asset in which the body parameters are not nested JSON values.

create_usage calls https://bynder.docs.apiary.io/#reference/asset-usage/asset-usage-operations/create-asset-usage in which the body parameters are not nested JSON values.

Since create_metaproperty_option currently is not a method in the SDK, would need to check with @TimBloembergen whether we should add this in addition to the helper method you provided.

When available @TimBloembergen could clarify on it.

@TimBloembergen
Copy link

Hi @lukeallister ,

If you would like to have these new methods available in the SDK, I would like to request that you would create a PR with the changes. Our team currently does not have the bandwidth to work on this ourselves. For the SDKs we' like to rely on our community to collaborate on these projects.

If you would be up in collobating, a PR would need to meet the folllowing:

  • add new methods
  • add proper unit tests for new methods, make sure all unit tests still work
  • update README with new method

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

4 participants