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

415 Unsupported Media Type for projects.delete function in _operations.py #376

Open
ovidsec opened this issue Oct 29, 2024 · 0 comments
Open

Comments

@ovidsec
Copy link

ovidsec commented Oct 29, 2024

Using the example python for the Delete an Existing Project API call results in a 415 Unsupported Media Type error
(https://docs.digitalocean.com/reference/api/api-reference/#operation/projects_delete) e.g.:

resp = client.projects.delete(project_id="038ea76a-cae8-4c26-a1c6-3476e7a94ceb")

As shown in the following error output:

╰─λ python digitalOceanDroplet.py 
Request:  <HttpRequest [DELETE], url: 'https://api.digitalocean.com/v2/projects/038ea76a-cae8-4c26-a1c6-3476e7a94ceb'>
Current Headers:  {'Accept': 'application/json'}
Server Response: <HttpResponse: 415 Unsupported Media Type, Content-Type: application/json; charset=utf-8>
Traceback (most recent call last):
... ... ... ...
  File "digitalOceanDroplet.py", line 48, in deleteDOProject
    resp = client.projects.delete(project_id="038ea76a-cae8-4c26-a1c6-3476e7a94ceb")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/azure/core/tracing/decorator.py", line 94, in wrapper_use_tracer
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/pydo/operations/_operations.py", line 145454, in delete
    raise HttpResponseError(response=response)
azure.core.exceptions.HttpResponseError: Operation returned an invalid status 'Unsupported Media Type'

In file _operations.py, the project DELETE functionality is outlined, with the request sent and response handled at
(https://raw.githubusercontent.com/digitalocean/pydo/refs/heads/main/src/pydo/operations/_operations.py):

145439        _request.url = self._client.format_url(_request.url)
... ... ... 
145448        response = pipeline_response.http_response                                                                                    
145449
145450        if response.status_code not in [204, 404, 412]:
145451          if _stream:
145452              response.read()  # Load the body in memory and close the socket
145453          map_error(status_code=response.status_code, response=response, error_map=error_map)  # type: ignore
145454          raise HttpResponseError(response=response)      
... ... ... 

Temporary Workaround

As a hacky workaround, forcing the Content-Type header prior to the request within _operations.py with the following to force the Content-Type HTTP Header allows the API call to successfully process.

... ... ... 
145439         _request.url = self._client.format_url(_request.url)
                      print('Request: ', _request)                                            # <- optional print for visibility
                      print('Current Headers: ', _request.headers)                            # <- optional print for visibility
                      _request.headers['Content-Type'] = 'application/json; charset=utf-8'    # <- Update HTTP header to force Content-Type
                      print('Forced Content-Type addition headers:', _request.headers)        # <- optional print updated headers
145441         _stream = False
145442         pipeline_response: PipelineResponse = (
145443              self._client._pipeline.run(  # pylint: disable=protected-acces144581         
145444                  _request, stream=_stream, **kwargs
145445             )
145446         )
145447         
145448         response = pipeline_response.http_response
                      print('Server Response:', response)                                     # <- optional print for visibility of server response
145450         if response.status_code not in [204, 404, 412]:
145451              if _stream:
145452                 response.read()  # Load the body in memory and close the socket
145453              map_error(status_code=response.status_code, response=response, error_map=error_map)  # type: ignore
145454              raise HttpResponseError(response=response)
... ... ...

204 is returned confirming successful deletion:

[🔴] × python digitalOceanDroplet.py 
Request:  <HttpRequest [DELETE], url: 'https://api.digitalocean.com/v2/projects/038ea76a-cae8-4c26-a1c6-3476e7a94ceb'>
Current Headers:  {'Accept': 'application/json'}
Forced Content-Type addition headers: {'Accept': 'application/json', 'Content-Type': 'application/json; charset=utf-8'}
Server Response: <HttpResponse: 204 No Content, Content-Type: application/json; charset=utf-8>

Content-Type is defined in multiple places throughout the _operations.py file but not the delete projects function; it's likely better defined elsewhere.

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

1 participant