diff --git a/.apigentools-info b/.apigentools-info index a8ed35775a..ad673ee121 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.2", - "regenerated": "2022-04-25 19:54:51.323794", - "spec_repo_commit": "7f08212f" + "regenerated": "2022-05-02 14:50:02.613403", + "spec_repo_commit": "28fa4252" }, "v2": { "apigentools_version": "1.6.2", - "regenerated": "2022-04-25 19:54:51.335844", - "spec_repo_commit": "7f08212f" + "regenerated": "2022-05-02 14:50:02.625357", + "spec_repo_commit": "28fa4252" } } } \ No newline at end of file diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index 23fa75e044..d733ef7200 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -9340,8 +9340,9 @@ components: type: string type: array type: - default: gauge - description: The type of the metric either `count`, `gauge`, or `rate`. + default: '' + description: The type of the metric. Valid types are "",`count`, `gauge`, + and `rate`. example: rate type: string required: @@ -23095,7 +23096,7 @@ paths: 3.2 megabytes (3200000 bytes). Compressed payloads must have a decompressed size of less than 62 megabytes (62914560 bytes).\n\nIf you\u2019re submitting metrics directly to the Datadog API without using DogStatsD, expect:\n\n- - 64 bits for the timestamp\n- 32 bits for the value\n- 40 bytes for the metric + 64 bits for the timestamp\n- 64 bits for the value\n- 40 bytes for the metric names\n- 50 bytes for the timeseries\n- The full payload is approximately 100 bytes. However, with the DogStatsD API,\ncompression is applied, which reduces the payload size." diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 6ede603ee5..3b6a6d696d 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -2592,6 +2592,14 @@ components: required: - data type: object + IntakePayloadAccepted: + description: The payload accepted for intake. + properties: + status: + description: The status of the intake payload. + example: ok + type: string + type: object ListApplicationKeysResponse: description: Response for a list of application keys. properties: @@ -3858,6 +3866,14 @@ components: pattern: ^[A-Za-z][A-Za-z0-9\.\-\_:\/]*$ type: string type: array + MetricContentEncoding: + default: deflate + description: HTTP header used to compress the media-type. + enum: + - deflate + type: string + x-enum-varnames: + - DEFLATE MetricCustomAggregation: description: A time and space aggregation combination for use in query. example: @@ -4005,10 +4021,148 @@ components: type: string x-enum-varnames: - METRIC_VOLUMES + MetricIntakeType: + description: The type of metric. + enum: + - 0 + - 1 + - 2 + - 3 + - 15 + format: int32 + type: integer + x-enum-varnames: + - GAUGE + - COUNT + - RATE + - GAUGE_NEW + - UNSPECIFIED + MetricMetadata: + description: Metadata for the metric. + properties: + origin: + $ref: '#/components/schemas/MetricOrigin' + type: object MetricName: description: The metric name for this resource. example: test.metric.latency type: string + MetricOrigin: + description: Metric origin information. + properties: + metric_type: + default: 0 + description: The origin metric type code + format: int32 + maximum: 1000 + type: integer + product: + default: 0 + description: The origin product code + format: int32 + maximum: 1000 + type: integer + service: + default: 0 + description: The origin service code + format: int32 + maximum: 1000 + type: integer + type: object + MetricPayload: + description: The metrics' payload. + properties: + series: + description: A list of time series to submit to Datadog. + example: + - metric: system.load.1 + points: + - timestamp: 1475317847 + value: 0.7 + items: + $ref: '#/components/schemas/MetricSeries' + type: array + required: + - series + type: object + MetricPoint: + description: Array of timeseries points. + example: + timestamp: 1575317847 + value: 0.5 + properties: + timestamp: + description: The timestamp should be in seconds and current. + format: int64 + type: integer + value: + description: The numeric value format should be a 64bit float gauge-type + value. + format: double + type: number + type: object + MetricResource: + description: Metric resource. + properties: + name: + description: The name of the metric. + type: string + type: + description: The type of metric. + type: string + type: object + MetricSeries: + description: 'A metric to submit to Datadog. + + See [Datadog metrics](https://docs.datadoghq.com/developers/metrics/#custom-metrics-properties).' + properties: + interval: + description: If the type of the metric is rate or count, define the corresponding + interval. + example: 20 + format: int64 + type: integer + metadata: + $ref: '#/components/schemas/MetricMetadata' + metric: + description: The name of the timeseries. + example: system.load.1 + type: string + points: + description: Points relating to a metric. All points must be objects with + timestamp and a scalar value (cannot be a string). Timestamps should be + in POSIX time in seconds, and cannot be more than ten minutes in the future + or more than one hour in the past. + items: + $ref: '#/components/schemas/MetricPoint' + type: array + resources: + description: A list of resources to associate with this metric. + items: + $ref: '#/components/schemas/MetricResource' + type: array + source_type_name: + description: The source type name. + example: datadog + type: string + tags: + description: A list of tags associated with the metric. + example: + - environment:test + items: + description: Individual tags. + type: string + type: array + type: + $ref: '#/components/schemas/MetricIntakeType' + unit: + description: The unit of point value. + example: second + type: string + required: + - metric + - points + type: object MetricTagConfiguration: description: Object for a single metric tag configuration. example: @@ -11398,6 +11552,80 @@ paths: x-unstable: '**Note**: This endpoint is in public beta. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' + /api/v2/series: + post: + description: "The metrics end-point allows you to post time-series data that + can be graphed on Datadog\u2019s dashboards.\nThe maximum payload size is + 500 kilobytes (512000 bytes). Compressed payloads must have a decompressed + size of less than 5 megabytes (5242880 bytes).\n\nIf you\u2019re submitting + metrics directly to the Datadog API without using DogStatsD, expect:\n\n- + 64 bits for the timestamp\n- 64 bits for the value\n- 20 bytes for the metric + names\n- 50 bytes for the timeseries\n- The full payload is approximately + 100 bytes." + operationId: SubmitMetrics + parameters: + - description: HTTP header used to compress the media-type. + in: header + name: Content-Encoding + required: false + schema: + $ref: '#/components/schemas/MetricContentEncoding' + requestBody: + content: + application/json: + examples: + dynamic-points: + description: "Post time-series data that can be graphed on Datadog\u2019s + dashboards." + externalValue: examples/metrics/dynamic-points.json.sh + summary: Dynamic Points + x-variables: + NOW: $(date +%s) + schema: + $ref: '#/components/schemas/MetricPayload' + required: true + responses: + '202': + content: + application/json: + schema: + $ref: '#/components/schemas/IntakePayloadAccepted' + description: Payload accepted + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Bad Request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Authentication error + '408': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Request timeout + '413': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Payload too large + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + summary: Submit metrics + tags: + - Metrics + x-codegen-request-body-name: body + x-menu-order: 1 + x-undo: + type: safe /api/v2/service_accounts: post: description: Create a service account for your organization. diff --git a/docs/datadog_api_client.v2.model.rst b/docs/datadog_api_client.v2.model.rst index b84bb5452c..22c9815d00 100644 --- a/docs/datadog_api_client.v2.model.rst +++ b/docs/datadog_api_client.v2.model.rst @@ -1209,6 +1209,14 @@ incidents\_response :undoc-members: :show-inheritance: +intake\_payload\_accepted +------------------------- + +.. automodule:: datadog_api_client.v2.model.intake_payload_accepted + :members: + :undoc-members: + :show-inheritance: + list\_application\_keys\_response --------------------------------- @@ -1937,6 +1945,14 @@ metric\_bulk\_tag\_config\_tag\_name\_list :undoc-members: :show-inheritance: +metric\_content\_encoding +------------------------- + +.. automodule:: datadog_api_client.v2.model.metric_content_encoding + :members: + :undoc-members: + :show-inheritance: + metric\_custom\_aggregation --------------------------- @@ -2017,6 +2033,62 @@ metric\_ingested\_indexed\_volume\_type :undoc-members: :show-inheritance: +metric\_intake\_type +-------------------- + +.. automodule:: datadog_api_client.v2.model.metric_intake_type + :members: + :undoc-members: + :show-inheritance: + +metric\_metadata +---------------- + +.. automodule:: datadog_api_client.v2.model.metric_metadata + :members: + :undoc-members: + :show-inheritance: + +metric\_origin +-------------- + +.. automodule:: datadog_api_client.v2.model.metric_origin + :members: + :undoc-members: + :show-inheritance: + +metric\_payload +--------------- + +.. automodule:: datadog_api_client.v2.model.metric_payload + :members: + :undoc-members: + :show-inheritance: + +metric\_point +------------- + +.. automodule:: datadog_api_client.v2.model.metric_point + :members: + :undoc-members: + :show-inheritance: + +metric\_resource +---------------- + +.. automodule:: datadog_api_client.v2.model.metric_resource + :members: + :undoc-members: + :show-inheritance: + +metric\_series +-------------- + +.. automodule:: datadog_api_client.v2.model.metric_series + :members: + :undoc-members: + :show-inheritance: + metric\_tag\_configuration -------------------------- diff --git a/examples/v2/metrics/SubmitMetrics.py b/examples/v2/metrics/SubmitMetrics.py new file mode 100644 index 0000000000..ee92739c1a --- /dev/null +++ b/examples/v2/metrics/SubmitMetrics.py @@ -0,0 +1,33 @@ +""" +Submit metrics returns "Payload accepted" response +""" + +from datetime import datetime +from datadog_api_client.v2 import ApiClient, Configuration +from datadog_api_client.v2.api.metrics_api import MetricsApi +from datadog_api_client.v2.model.metric_intake_type import MetricIntakeType +from datadog_api_client.v2.model.metric_payload import MetricPayload +from datadog_api_client.v2.model.metric_point import MetricPoint +from datadog_api_client.v2.model.metric_series import MetricSeries + +body = MetricPayload( + series=[ + MetricSeries( + metric="system.load.1", + type=MetricIntakeType(0), + points=[ + MetricPoint( + timestamp=int(datetime.now().timestamp()), + value=0.7, + ), + ], + ), + ], +) + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = MetricsApi(api_client) + response = api_instance.submit_metrics(body=body) + + print(response) diff --git a/src/datadog_api_client/v1/api/metrics_api.py b/src/datadog_api_client/v1/api/metrics_api.py index 64c5434884..b0c09df79f 100644 --- a/src/datadog_api_client/v1/api/metrics_api.py +++ b/src/datadog_api_client/v1/api/metrics_api.py @@ -393,7 +393,7 @@ def submit_metrics(self, body, **kwargs): If you’re submitting metrics directly to the Datadog API without using DogStatsD, expect: - 64 bits for the timestamp - - 32 bits for the value + - 64 bits for the value - 40 bytes for the metric names - 50 bytes for the timeseries - The full payload is approximately 100 bytes. However, with the DogStatsD API, diff --git a/src/datadog_api_client/v1/model/series.py b/src/datadog_api_client/v1/model/series.py index 091cd8e728..945d45dfc7 100644 --- a/src/datadog_api_client/v1/model/series.py +++ b/src/datadog_api_client/v1/model/series.py @@ -58,7 +58,7 @@ def __init__(self, metric, points, *args, **kwargs): :param tags: A list of tags associated with the metric. :type tags: [str], optional - :param type: The type of the metric either `count`, `gauge`, or `rate`. + :param type: The type of the metric. Valid types are "",`count`, `gauge`, and `rate`. :type type: str, optional """ super().__init__(kwargs) diff --git a/src/datadog_api_client/v2/api/metrics_api.py b/src/datadog_api_client/v2/api/metrics_api.py index 2c88083fde..a6b2eafff8 100644 --- a/src/datadog_api_client/v2/api/metrics_api.py +++ b/src/datadog_api_client/v2/api/metrics_api.py @@ -16,6 +16,9 @@ from datadog_api_client.v2.model.metric_tag_configuration_update_request import MetricTagConfigurationUpdateRequest from datadog_api_client.v2.model.metric_tag_configuration_create_request import MetricTagConfigurationCreateRequest from datadog_api_client.v2.model.metric_volumes_response import MetricVolumesResponse +from datadog_api_client.v2.model.intake_payload_accepted import IntakePayloadAccepted +from datadog_api_client.v2.model.metric_content_encoding import MetricContentEncoding +from datadog_api_client.v2.model.metric_payload import MetricPayload class MetricsApi: @@ -242,6 +245,32 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._submit_metrics_endpoint = _Endpoint( + settings={ + "response_type": (IntakePayloadAccepted,), + "auth": ["apiKeyAuth"], + "endpoint_path": "/api/v2/series", + "operation_id": "submit_metrics", + "http_method": "POST", + "version": "v2", + "servers": None, + }, + params_map={ + "content_encoding": { + "openapi_types": (MetricContentEncoding,), + "attribute": "Content-Encoding", + "location": "header", + }, + "body": { + "required": True, + "openapi_types": (MetricPayload,), + "location": "body", + }, + }, + headers_map={"accept": ["application/json"], "content_type": ["application/json"]}, + api_client=api_client, + ) + self._update_tag_configuration_endpoint = _Endpoint( settings={ "response_type": (MetricTagConfigurationResponse,), @@ -650,6 +679,60 @@ def list_volumes_by_metric_name(self, metric_name, **kwargs): return self._list_volumes_by_metric_name_endpoint.call_with_http_info(**kwargs) + def submit_metrics(self, body, **kwargs): + """Submit metrics. + + The metrics end-point allows you to post time-series data that can be graphed on Datadog’s dashboards. + The maximum payload size is 500 kilobytes (512000 bytes). Compressed payloads must have a decompressed size of less than 5 megabytes (5242880 bytes). + + If you’re submitting metrics directly to the Datadog API without using DogStatsD, expect: + + - 64 bits for the timestamp + - 64 bits for the value + - 20 bytes for the metric names + - 50 bytes for the timeseries + - The full payload is approximately 100 bytes. + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True. + + >>> thread = api.submit_metrics(body, async_req=True) + >>> result = thread.get() + + :type body: MetricPayload + :param content_encoding: HTTP header used to compress the media-type. + :type content_encoding: MetricContentEncoding, optional + :param _return_http_data_only: Response data without head status + code and headers. Default is True. + :type _return_http_data_only: bool + :param _preload_content: If False, the urllib3.HTTPResponse object + will be returned without reading/decoding response data. + Default is True. + :type _preload_content: bool + :param _request_timeout: Timeout setting for this request. If one + number provided, it will be total request timeout. It can also be a + pair (tuple) of (connection, read) timeouts. Default is None. + :type _request_timeout: float/tuple + :param _check_input_type: Specifies if type checking should be done one + the data sent to the server. Default is True. + :type _check_input_type: bool + :param _check_return_type: Specifies if type checking should be done + one the data received from the server. Default is True. + :type _check_return_type: bool + :param _host_index: Specifies the index of the server that we want to + use. Default is read from the configuration. + :type _host_index: int/None + :param async_req: Execute request asynchronously. + :type async_req: bool + + :return: If the method is called asynchronously, returns the request thread. + :rtype: IntakePayloadAccepted + """ + kwargs = self._submit_metrics_endpoint.default_arguments(kwargs) + kwargs["body"] = body + + return self._submit_metrics_endpoint.call_with_http_info(**kwargs) + def update_tag_configuration(self, metric_name, body, **kwargs): """Update a tag configuration. diff --git a/src/datadog_api_client/v2/model/intake_payload_accepted.py b/src/datadog_api_client/v2/model/intake_payload_accepted.py new file mode 100644 index 0000000000..3d09fc3d3b --- /dev/null +++ b/src/datadog_api_client/v2/model/intake_payload_accepted.py @@ -0,0 +1,42 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +class IntakePayloadAccepted(ModelNormal): + @cached_property + def openapi_types(_): + return { + "status": (str,), + } + + attribute_map = { + "status": "status", + } + + def __init__(self, *args, **kwargs): + """ + The payload accepted for intake. + + :param status: The status of the intake payload. + :type status: str, optional + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(IntakePayloadAccepted, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + return self diff --git a/src/datadog_api_client/v2/model/metric_content_encoding.py b/src/datadog_api_client/v2/model/metric_content_encoding.py new file mode 100644 index 0000000000..3469fb08e8 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_content_encoding.py @@ -0,0 +1,54 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + + +class MetricContentEncoding(ModelSimple): + + allowed_values = { + "value": { + "DEFLATE": "deflate", + }, + } + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + def __init__(self, *args, **kwargs): + """ + HTTP header used to compress the media-type. + + Note that value can be passed either in args or in kwargs, but not in both. + + :param value: If omitted defaults to "deflate". Must be one of ["deflate"]. + :type value: str + """ + super().__init__(kwargs) + + if "value" in kwargs: + value = kwargs.pop("value") + elif args: + args = list(args) + value = args.pop(0) + else: + value = "deflate" + + self._check_pos_args(args) + + self.value = value + + self._check_kw_args(kwargs) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + return cls(*args, **kwargs) diff --git a/src/datadog_api_client/v2/model/metric_intake_type.py b/src/datadog_api_client/v2/model/metric_intake_type.py new file mode 100644 index 0000000000..142370b120 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_intake_type.py @@ -0,0 +1,63 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ApiTypeError, + ModelSimple, + cached_property, +) + + +class MetricIntakeType(ModelSimple): + + allowed_values = { + "value": { + "GAUGE": 0, + "COUNT": 1, + "RATE": 2, + "GAUGE_NEW": 3, + "UNSPECIFIED": 15, + }, + } + + @cached_property + def openapi_types(_): + return { + "value": (int,), + } + + def __init__(self, *args, **kwargs): + """ + The type of metric. + + Note that value can be passed either in args or in kwargs, but not in both. + + :param value: Must be one of [0, 1, 2, 3, 15]. + :type value: int + """ + super().__init__(kwargs) + + if "value" in kwargs: + value = kwargs.pop("value") + elif args: + args = list(args) + value = args.pop(0) + else: + raise ApiTypeError( + "value is required, but not passed in args or kwargs and doesn't have default", + path_to_item=self._path_to_item, + valid_classes=(self.__class__,), + ) + + self._check_pos_args(args) + + self.value = value + + self._check_kw_args(kwargs) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + return cls(*args, **kwargs) diff --git a/src/datadog_api_client/v2/model/metric_metadata.py b/src/datadog_api_client/v2/model/metric_metadata.py new file mode 100644 index 0000000000..f2d0495a06 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_metadata.py @@ -0,0 +1,49 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +def lazy_import(): + from datadog_api_client.v2.model.metric_origin import MetricOrigin + + globals()["MetricOrigin"] = MetricOrigin + + +class MetricMetadata(ModelNormal): + @cached_property + def openapi_types(_): + lazy_import() + return { + "origin": (MetricOrigin,), + } + + attribute_map = { + "origin": "origin", + } + + def __init__(self, *args, **kwargs): + """ + Metadata for the metric. + + :param origin: Metric origin information. + :type origin: MetricOrigin, optional + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(MetricMetadata, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + return self diff --git a/src/datadog_api_client/v2/model/metric_origin.py b/src/datadog_api_client/v2/model/metric_origin.py new file mode 100644 index 0000000000..2666f1ebe4 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_origin.py @@ -0,0 +1,64 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +class MetricOrigin(ModelNormal): + validations = { + "metric_type": { + "inclusive_maximum": 1000, + }, + "product": { + "inclusive_maximum": 1000, + }, + "service": { + "inclusive_maximum": 1000, + }, + } + + @cached_property + def openapi_types(_): + return { + "metric_type": (int,), + "product": (int,), + "service": (int,), + } + + attribute_map = { + "metric_type": "metric_type", + "product": "product", + "service": "service", + } + + def __init__(self, *args, **kwargs): + """ + Metric origin information. + + :param metric_type: The origin metric type code + :type metric_type: int, optional + + :param product: The origin product code + :type product: int, optional + + :param service: The origin service code + :type service: int, optional + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(MetricOrigin, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + return self diff --git a/src/datadog_api_client/v2/model/metric_payload.py b/src/datadog_api_client/v2/model/metric_payload.py new file mode 100644 index 0000000000..f03821bf19 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_payload.py @@ -0,0 +1,52 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +def lazy_import(): + from datadog_api_client.v2.model.metric_series import MetricSeries + + globals()["MetricSeries"] = MetricSeries + + +class MetricPayload(ModelNormal): + @cached_property + def openapi_types(_): + lazy_import() + return { + "series": ([MetricSeries],), + } + + attribute_map = { + "series": "series", + } + + def __init__(self, series, *args, **kwargs): + """ + The metrics' payload. + + :param series: A list of time series to submit to Datadog. + :type series: [MetricSeries] + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + self.series = series + + @classmethod + def _from_openapi_data(cls, series, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(MetricPayload, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + self.series = series + return self diff --git a/src/datadog_api_client/v2/model/metric_point.py b/src/datadog_api_client/v2/model/metric_point.py new file mode 100644 index 0000000000..1f77c81307 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_point.py @@ -0,0 +1,47 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +class MetricPoint(ModelNormal): + @cached_property + def openapi_types(_): + return { + "timestamp": (int,), + "value": (float,), + } + + attribute_map = { + "timestamp": "timestamp", + "value": "value", + } + + def __init__(self, *args, **kwargs): + """ + Array of timeseries points. + + :param timestamp: The timestamp should be in seconds and current. + :type timestamp: int, optional + + :param value: The numeric value format should be a 64bit float gauge-type value. + :type value: float, optional + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(MetricPoint, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + return self diff --git a/src/datadog_api_client/v2/model/metric_resource.py b/src/datadog_api_client/v2/model/metric_resource.py new file mode 100644 index 0000000000..2fe9d28988 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_resource.py @@ -0,0 +1,47 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +class MetricResource(ModelNormal): + @cached_property + def openapi_types(_): + return { + "name": (str,), + "type": (str,), + } + + attribute_map = { + "name": "name", + "type": "type", + } + + def __init__(self, *args, **kwargs): + """ + Metric resource. + + :param name: The name of the metric. + :type name: str, optional + + :param type: The type of metric. + :type type: str, optional + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + @classmethod + def _from_openapi_data(cls, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(MetricResource, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + return self diff --git a/src/datadog_api_client/v2/model/metric_series.py b/src/datadog_api_client/v2/model/metric_series.py new file mode 100644 index 0000000000..006c593dd4 --- /dev/null +++ b/src/datadog_api_client/v2/model/metric_series.py @@ -0,0 +1,101 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. + + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +def lazy_import(): + from datadog_api_client.v2.model.metric_metadata import MetricMetadata + from datadog_api_client.v2.model.metric_point import MetricPoint + from datadog_api_client.v2.model.metric_resource import MetricResource + from datadog_api_client.v2.model.metric_intake_type import MetricIntakeType + + globals()["MetricMetadata"] = MetricMetadata + globals()["MetricPoint"] = MetricPoint + globals()["MetricResource"] = MetricResource + globals()["MetricIntakeType"] = MetricIntakeType + + +class MetricSeries(ModelNormal): + @cached_property + def openapi_types(_): + lazy_import() + return { + "interval": (int,), + "metadata": (MetricMetadata,), + "metric": (str,), + "points": ([MetricPoint],), + "resources": ([MetricResource],), + "source_type_name": (str,), + "tags": ([str],), + "type": (MetricIntakeType,), + "unit": (str,), + } + + attribute_map = { + "interval": "interval", + "metadata": "metadata", + "metric": "metric", + "points": "points", + "resources": "resources", + "source_type_name": "source_type_name", + "tags": "tags", + "type": "type", + "unit": "unit", + } + + def __init__(self, metric, points, *args, **kwargs): + """ + A metric to submit to Datadog. + See [Datadog metrics](https://docs.datadoghq.com/developers/metrics/#custom-metrics-properties). + + :param interval: If the type of the metric is rate or count, define the corresponding interval. + :type interval: int, optional + + :param metadata: Metadata for the metric. + :type metadata: MetricMetadata, optional + + :param metric: The name of the timeseries. + :type metric: str + + :param points: Points relating to a metric. All points must be objects with timestamp and a scalar value (cannot be a string). Timestamps should be in POSIX time in seconds, and cannot be more than ten minutes in the future or more than one hour in the past. + :type points: [MetricPoint] + + :param resources: A list of resources to associate with this metric. + :type resources: [MetricResource], optional + + :param source_type_name: The source type name. + :type source_type_name: str, optional + + :param tags: A list of tags associated with the metric. + :type tags: [str], optional + + :param type: The type of metric. + :type type: MetricIntakeType, optional + + :param unit: The unit of point value. + :type unit: str, optional + """ + super().__init__(kwargs) + + self._check_pos_args(args) + + self.metric = metric + self.points = points + + @classmethod + def _from_openapi_data(cls, metric, points, *args, **kwargs): + """Helper creating a new instance from a response.""" + + self = super(MetricSeries, cls)._from_openapi_data(kwargs) + + self._check_pos_args(args) + + self.metric = metric + self.points = points + return self diff --git a/src/datadog_api_client/v2/models/__init__.py b/src/datadog_api_client/v2/models/__init__.py index 95c5b00f03..7489c902ee 100644 --- a/src/datadog_api_client/v2/models/__init__.py +++ b/src/datadog_api_client/v2/models/__init__.py @@ -179,6 +179,7 @@ from datadog_api_client.v2.model.incident_update_relationships import IncidentUpdateRelationships from datadog_api_client.v2.model.incident_update_request import IncidentUpdateRequest from datadog_api_client.v2.model.incidents_response import IncidentsResponse +from datadog_api_client.v2.model.intake_payload_accepted import IntakePayloadAccepted from datadog_api_client.v2.model.list_application_keys_response import ListApplicationKeysResponse from datadog_api_client.v2.model.log import Log from datadog_api_client.v2.model.log_attributes import LogAttributes @@ -274,6 +275,7 @@ from datadog_api_client.v2.model.metric_bulk_tag_config_status import MetricBulkTagConfigStatus from datadog_api_client.v2.model.metric_bulk_tag_config_status_attributes import MetricBulkTagConfigStatusAttributes from datadog_api_client.v2.model.metric_bulk_tag_config_tag_name_list import MetricBulkTagConfigTagNameList +from datadog_api_client.v2.model.metric_content_encoding import MetricContentEncoding from datadog_api_client.v2.model.metric_custom_aggregation import MetricCustomAggregation from datadog_api_client.v2.model.metric_custom_aggregations import MetricCustomAggregations from datadog_api_client.v2.model.metric_custom_space_aggregation import MetricCustomSpaceAggregation @@ -284,6 +286,13 @@ from datadog_api_client.v2.model.metric_ingested_indexed_volume import MetricIngestedIndexedVolume from datadog_api_client.v2.model.metric_ingested_indexed_volume_attributes import MetricIngestedIndexedVolumeAttributes from datadog_api_client.v2.model.metric_ingested_indexed_volume_type import MetricIngestedIndexedVolumeType +from datadog_api_client.v2.model.metric_intake_type import MetricIntakeType +from datadog_api_client.v2.model.metric_metadata import MetricMetadata +from datadog_api_client.v2.model.metric_origin import MetricOrigin +from datadog_api_client.v2.model.metric_payload import MetricPayload +from datadog_api_client.v2.model.metric_point import MetricPoint +from datadog_api_client.v2.model.metric_resource import MetricResource +from datadog_api_client.v2.model.metric_series import MetricSeries from datadog_api_client.v2.model.metric_tag_configuration import MetricTagConfiguration from datadog_api_client.v2.model.metric_tag_configuration_attributes import MetricTagConfigurationAttributes from datadog_api_client.v2.model.metric_tag_configuration_create_attributes import ( diff --git a/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.frozen b/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.frozen index b02bf6fda9..3032665b44 100644 --- a/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.frozen +++ b/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.frozen @@ -1 +1 @@ -2022-03-29T08:59:44.790Z \ No newline at end of file +2022-03-28T15:06:36.041Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.yaml b/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.yaml index 381fe2e8c4..ea0b4e5054 100644 --- a/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.yaml +++ b/tests/v2/cassettes/test_scenarios/test_aggregate_rum_events_returns_ok_response.yaml @@ -11,7 +11,7 @@ interactions: uri: https://api.datadoghq.com/api/v2/rum/analytics/aggregate response: body: - string: '{"meta":{"status":"done","request_id":"pddv1ChZiX1d1RWNfM1JuaURhSkJ6elFsRHpnIi0KHQJFlSKZaC6T1BR15cquEEJdzvJ8iKfJO5Kr37vkEgyJYfau6iiq_M5ftbo","elapsed":0},"data":{"buckets":[]}} + string: '{"meta":{"status":"done","request_id":"pddv1ChZyS2R0R2cwbFNTR3dXWHE0T1V4SkV3IiwKHO-LyxpZr85euhVxgr_zcJZpbjq-uQVUzkFlD0ISDPnlZXRCg4-gaoMc2w","elapsed":0},"data":{"buckets":[]}} ' headers: diff --git a/tests/v2/cassettes/test_scenarios/test_submit_metrics_returns_payload_accepted_response.frozen b/tests/v2/cassettes/test_scenarios/test_submit_metrics_returns_payload_accepted_response.frozen new file mode 100644 index 0000000000..21def70ba4 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_submit_metrics_returns_payload_accepted_response.frozen @@ -0,0 +1 @@ +2022-04-22T15:23:38.362Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_submit_metrics_returns_payload_accepted_response.yaml b/tests/v2/cassettes/test_scenarios/test_submit_metrics_returns_payload_accepted_response.yaml new file mode 100644 index 0000000000..70f24e4b52 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_submit_metrics_returns_payload_accepted_response.yaml @@ -0,0 +1,20 @@ +interactions: +- request: + body: '{"series":[{"metric":"system.load.1","points":[{"timestamp":1650641018,"value":0.7}],"type":0}]}' + headers: + accept: + - application/json + content-type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v2/series + response: + body: + string: '{"errors":[]}' + headers: + content-type: + - application/json + status: + code: 202 + message: Accepted +version: 1 diff --git a/tests/v2/features/metrics.feature b/tests/v2/features/metrics.feature index 6c385e6c01..a5c5528799 100644 --- a/tests/v2/features/metrics.feature +++ b/tests/v2/features/metrics.feature @@ -11,12 +11,12 @@ Feature: Metrics Background: Given a valid "apiKeyAuth" key in the system - And a valid "appKeyAuth" key in the system And an instance of "Metrics" API @team:DataDog/points-aggregation Scenario: Configure tags for multiple metrics returns "Accepted" response - Given there is a valid "user" in the system + Given a valid "appKeyAuth" key in the system + And there is a valid "user" in the system And new "CreateBulkTagsMetricsConfiguration" request And body with value {"data": {"attributes": {"emails": ["{{ user.data.attributes.email }}"], "tags": ["test", "{{ unique_lower_alnum }}"]}, "id": "system.load.1", "type": "metric_bulk_configure_tags"}} When the request is sent @@ -24,21 +24,24 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: Configure tags for multiple metrics returns "Bad Request" response - Given new "CreateBulkTagsMetricsConfiguration" request + Given a valid "appKeyAuth" key in the system + And new "CreateBulkTagsMetricsConfiguration" request And body with value {"data": {"attributes": {"emails": ["sue@example.com", "bob@example.com"], "tags": ["host", "pod_name", "is_shadow"]}, "id": "kafka.lag", "type": "metric_bulk_configure_tags"}} When the request is sent Then the response status is 400 Bad Request @generated @skip @team:DataDog/points-aggregation Scenario: Configure tags for multiple metrics returns "Not Found" response - Given new "CreateBulkTagsMetricsConfiguration" request + Given a valid "appKeyAuth" key in the system + And new "CreateBulkTagsMetricsConfiguration" request And body with value {"data": {"attributes": {"emails": ["sue@example.com", "bob@example.com"], "tags": ["host", "pod_name", "is_shadow"]}, "id": "kafka.lag", "type": "metric_bulk_configure_tags"}} When the request is sent Then the response status is 404 Not Found @generated @skip @team:DataDog/points-aggregation Scenario: Create a tag configuration returns "Bad Request" response - Given operation "CreateTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "CreateTagConfiguration" enabled And new "CreateTagConfiguration" request And request contains "metric_name" parameter from "REPLACE.ME" And body with value {"data": {"attributes": {"include_percentiles": false, "metric_type": "distribution", "tags": ["app", "datacenter"]}, "id": "http.endpoint.request", "type": "manage_tags"}} @@ -47,7 +50,8 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: Create a tag configuration returns "Conflict" response - Given operation "CreateTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "CreateTagConfiguration" enabled And new "CreateTagConfiguration" request And request contains "metric_name" parameter from "REPLACE.ME" And body with value {"data": {"attributes": {"include_percentiles": false, "metric_type": "distribution", "tags": ["app", "datacenter"]}, "id": "http.endpoint.request", "type": "manage_tags"}} @@ -56,7 +60,8 @@ Feature: Metrics @replay-only @team:DataDog/points-aggregation Scenario: Create a tag configuration returns "Created" response - Given operation "CreateTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "CreateTagConfiguration" enabled And new "CreateTagConfiguration" request And there is a valid "metric" in the system And request contains "metric_name" parameter with value "{{ unique_alnum }}" @@ -68,6 +73,7 @@ Feature: Metrics Scenario: Delete a tag configuration returns "No Content" response Given there is a valid "metric" in the system And there is a valid "metric_tag_configuration" in the system + And a valid "appKeyAuth" key in the system And operation "DeleteTagConfiguration" enabled And new "DeleteTagConfiguration" request And request contains "metric_name" parameter with value "{{ unique_alnum }}" @@ -76,7 +82,8 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: Delete a tag configuration returns "Not found" response - Given operation "DeleteTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "DeleteTagConfiguration" enabled And new "DeleteTagConfiguration" request And request contains "metric_name" parameter from "REPLACE.ME" When the request is sent @@ -84,21 +91,24 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: List distinct metric volumes by metric name returns "Bad Request" response - Given new "ListVolumesByMetricName" request + Given a valid "appKeyAuth" key in the system + And new "ListVolumesByMetricName" request And request contains "metric_name" parameter from "REPLACE.ME" When the request is sent Then the response status is 400 Bad Request @generated @skip @team:DataDog/points-aggregation Scenario: List distinct metric volumes by metric name returns "Not Found" response - Given new "ListVolumesByMetricName" request + Given a valid "appKeyAuth" key in the system + And new "ListVolumesByMetricName" request And request contains "metric_name" parameter from "REPLACE.ME" When the request is sent Then the response status is 404 Not Found @team:DataDog/points-aggregation Scenario: List distinct metric volumes by metric name returns "Success" response - Given there is a valid "metric" in the system + Given a valid "appKeyAuth" key in the system + And there is a valid "metric" in the system And there is a valid "metric_tag_configuration" in the system And new "ListVolumesByMetricName" request And request contains "metric_name" parameter with value "{{ unique_alnum }}" @@ -108,7 +118,8 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: List tag configuration by name returns "Not Found" response - Given operation "ListTagConfigurationByName" enabled + Given a valid "appKeyAuth" key in the system + And operation "ListTagConfigurationByName" enabled And new "ListTagConfigurationByName" request And request contains "metric_name" parameter from "REPLACE.ME" When the request is sent @@ -116,7 +127,8 @@ Feature: Metrics @replay-only @team:DataDog/points-aggregation Scenario: List tag configuration by name returns "Success" response - Given there is a valid "metric" in the system + Given a valid "appKeyAuth" key in the system + And there is a valid "metric" in the system And there is a valid "metric_tag_configuration" in the system And operation "ListTagConfigurationByName" enabled And new "ListTagConfigurationByName" request @@ -127,21 +139,25 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: List tag configurations returns "Bad Request" response - Given operation "ListTagConfigurations" enabled + Given a valid "appKeyAuth" key in the system + And operation "ListTagConfigurations" enabled And new "ListTagConfigurations" request When the request is sent Then the response status is 400 Bad Request @skip @team:DataDog/points-aggregation Scenario: List tag configurations returns "Success" response - Given operation "ListTagConfigurations" enabled + Given a valid "appKeyAuth" key in the system + And there is a valid "metric_tag_configuration" in the system + And operation "ListTagConfigurations" enabled And new "ListTagConfigurations" request When the request is sent Then the response status is 200 Success @team:DataDog/points-aggregation Scenario: List tag configurations with a tag filter returns "Success" response - Given operation "ListTagConfigurations" enabled + Given a valid "appKeyAuth" key in the system + And operation "ListTagConfigurations" enabled And new "ListTagConfigurations" request And request contains "filter[tags]" parameter with value "{{ unique_alnum }}" When the request is sent @@ -157,21 +173,24 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: List tags by metric name returns "Bad Request" response - Given new "ListTagsByMetricName" request + Given a valid "appKeyAuth" key in the system + And new "ListTagsByMetricName" request And request contains "metric_name" parameter from "REPLACE.ME" When the request is sent Then the response status is 400 Bad Request @generated @skip @team:DataDog/points-aggregation Scenario: List tags by metric name returns "Not Found" response - Given new "ListTagsByMetricName" request + Given a valid "appKeyAuth" key in the system + And new "ListTagsByMetricName" request And request contains "metric_name" parameter from "REPLACE.ME" When the request is sent Then the response status is 404 Not Found @replay-only @team:DataDog/points-aggregation Scenario: List tags by metric name returns "Success" response - Given there is a valid "metric" in the system + Given a valid "appKeyAuth" key in the system + And there is a valid "metric" in the system And there is a valid "metric_tag_configuration" in the system And new "ListTagsByMetricName" request And request contains "metric_name" parameter from "metric_tag_configuration.data.id" @@ -179,9 +198,38 @@ Feature: Metrics Then the response status is 200 Success And the response "data.id" has the same value as "metric_tag_configuration.data.id" + @generated @skip @team:DataDog/metrics-intake @team:DataDog/metrics-query + Scenario: Submit metrics returns "Bad Request" response + Given new "SubmitMetrics" request + And body with value {"series": [{"metric": "system.load.1", "points": [{"timestamp": 1475317847, "value": 0.7}]}]} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/metrics-intake @team:DataDog/metrics-query + Scenario: Submit metrics returns "Payload accepted" response + Given new "SubmitMetrics" request + And body with value {"series": [{"metric": "system.load.1", "type": 0, "points": [{"timestamp": {{ timestamp('now') }}, "value": 0.7}]}]} + When the request is sent + Then the response status is 202 Payload accepted + + @generated @skip @team:DataDog/metrics-intake @team:DataDog/metrics-query + Scenario: Submit metrics returns "Payload too large" response + Given new "SubmitMetrics" request + And body with value {"series": [{"metric": "system.load.1", "points": [{"timestamp": 1475317847, "value": 0.7}]}]} + When the request is sent + Then the response status is 413 Payload too large + + @generated @skip @team:DataDog/metrics-intake @team:DataDog/metrics-query + Scenario: Submit metrics returns "Request timeout" response + Given new "SubmitMetrics" request + And body with value {"series": [{"metric": "system.load.1", "points": [{"timestamp": 1475317847, "value": 0.7}]}]} + When the request is sent + Then the response status is 408 Request timeout + @generated @skip @team:DataDog/points-aggregation Scenario: Update a tag configuration returns "Bad Request" response - Given operation "UpdateTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "UpdateTagConfiguration" enabled And new "UpdateTagConfiguration" request And request contains "metric_name" parameter from "REPLACE.ME" And body with value {"data": {"attributes": {"group_by": ["app", "datacenter"], "include_percentiles": false}, "id": "http.endpoint.request", "type": "manage_tags"}} @@ -190,7 +238,8 @@ Feature: Metrics @replay-only @team:DataDog/points-aggregation Scenario: Update a tag configuration returns "OK" response - Given operation "UpdateTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "UpdateTagConfiguration" enabled And there is a valid "metric" in the system And there is a valid "metric_tag_configuration" in the system And new "UpdateTagConfiguration" request @@ -202,7 +251,8 @@ Feature: Metrics @generated @skip @team:DataDog/points-aggregation Scenario: Update a tag configuration returns "Unprocessable Entity" response - Given operation "UpdateTagConfiguration" enabled + Given a valid "appKeyAuth" key in the system + And operation "UpdateTagConfiguration" enabled And new "UpdateTagConfiguration" request And request contains "metric_name" parameter from "REPLACE.ME" And body with value {"data": {"attributes": {"group_by": ["app", "datacenter"], "include_percentiles": false}, "id": "http.endpoint.request", "type": "manage_tags"}} diff --git a/tests/v2/features/undo.json b/tests/v2/features/undo.json index bd26444566..bfddf10607 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -654,6 +654,12 @@ "type": "safe" } }, + "SubmitMetrics": { + "tag": "Metrics", + "undo": { + "type": "safe" + } + }, "CreateServiceAccount": { "tag": "Users", "undo": {