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

Error submitting metrics with async api client #951

Closed
dxmaxwell opened this issue Apr 11, 2022 · 3 comments · Fixed by #952
Closed

Error submitting metrics with async api client #951

dxmaxwell opened this issue Apr 11, 2022 · 3 comments · Fixed by #952
Labels

Comments

@dxmaxwell
Copy link

dxmaxwell commented Apr 11, 2022

Describe the bug
When using the Datadog API async client, an error occurs when submitting metrics data:

HTTP response body: Payload is not in the expected format: invalid character 's' looking for beginning of value

Exact same metrics data can be successfully submitted using the non-async client.

To Reproduce
The following code (adapted from the async example in the README) will reproduce the error:

from datadog_api_client.v1 import AsyncApiClient, Configuration
from datadog_api_client.v1.api.metrics_api import MetricsApi
from datadog_api_client.v1.model.metrics_payload import MetricsPayload
from datadog_api_client.v1.model.point import Point
from datadog_api_client.v1.model.series import Series

try:
    body = MetricsPayload(
        series=[
            Series(
                metric="system.load.1",
                type="gauge",
                points=[Point([datetime.now().timestamp(), 2.1])],
                tags=["test:ExampleSubmitmetricsreturnsPayloadacceptedresponse"],
            )
        ]
    )

    configuration = Configuration()
    async with AsyncApiClient(configuration) as api_client:
        api_instance = MetricsApi(api_client)
        response = await api_instance.submit_metrics(body=body)
        print(response)

except BaseException as ex:
    logger.exception('Error submitting metrics to datadog: {}', ex)

Error response:

datadog_api_client.v1.exceptions.ApiException: (400)
Reason: Bad
HTTP response headers: HttpHeaders({'Date': 'Fri, 08 Apr 2022 20:26:30 GMT', 'Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '91', 'Connection': 'keep-alive', 'x-content-type-options': 'nosniff', 'strict-transport-security': 'max-age=15724800;', 'content-security-policy': "frame-ancestors 'self'; report-uri https://logs.browser-intake-datadoghq.com/api/v2/logs?dd-api-key=pube4f163c23bbf91c16b8f57f56af9fc58&dd-evp-origin=content-security-policy&ddsource=csp-report&ddtags=site%3Adatadoghq.com", 'x-frame-options': 'SAMEORIGIN'})
HTTP response body: Payload is not in the expected format: invalid character 's' looking for beginning of value

Expected behavior
Request should succeed and metrics data should be available in the DataDog metrics explorer. (Like it is when making the request with the non-async client.)

Screenshots
If applicable, add screenshots to help explain your problem.

Environment and Versions (please complete the following information):
Linux with Python v3.8.10 and datadog-api-client = {extras = ["async"], version = "^1.10.0"}

Additional context
After looking at the differences between the non-async and async API clients, I noticed that it appears the async client never actually serializes the provided body data.

For reference, the non-async client does it here, but I did not see similar code for the async client.

@therve
Copy link
Contributor

therve commented Apr 11, 2022

Thanks for the report, reproduced. We're indeed missing the serialization step in the async case. I'll fix it, sorry for the troubles.

therve added a commit that referenced this issue Apr 11, 2022
@dxmaxwell
Copy link
Author

My original bug report had a small mistake, for the body I used a plan dictionary, but if I follow the examples for the non-async client I should be sending a MetricsPayload object:

    body = MetricsPayload(
        series=[
            Series(
                metric="system.load.1",
                type="gauge",
                points=[Point([datetime.now().timestamp(), 2.1])],
                tags=["test:ExampleSubmitmetricsreturnsPayloadacceptedresponse"],
            )
        ]
    )

But for some reason the MetricsPayload object is not serializable to json, but I don't understand why since I thought that's what the non-async client is actually doing?

@dxmaxwell
Copy link
Author

Ok, I found the problem looks like I needed to call body.to_dict() first before serializing to json. That must be done by one of the intermediate layers in the client.

therve added a commit that referenced this issue Apr 13, 2022
* Serialiaze body in async client

Closes #951

* Support compression as well
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants