def post(self):
    'Validates data parameter and add task to queue to process points.\n\n    The row data comes from a "data" parameter, which is a JSON encoding of a\n    list of dictionaries, each of which represents one performance result\n    (one point in a graph) and associated data.\n\n      [\n        {\n          "master": "ChromiumPerf",\n          "bot": "xp-release-dual-core",\n          "test": "dromaeo/dom/modify",\n          "revision": 123456789,\n          "value": 24.66,\n          "error": 2.33,\n          "units": "ms",\n          "supplemental_columns": {\n            "d_median": 24234.12,\n            "d_mean": 23.553,\n            "r_webkit": 423340,\n            ...\n          },\n          ...\n        },\n        ...\n      ]\n\n    In general, the required fields are "master", "bot", "test" (which together\n    form the test path which identifies the series that this point belongs to),\n    and "revision" and "value", which are the X and Y values for the point.\n\n    This API also supports the Dashboard JSON v1.0 format (go/telemetry-json),\n    the first producer of which is Telemetry. Telemetry provides lightweight\n    serialization of values it produces, as JSON. If a dashboard JSON object is\n    passed, it will be a single dict rather than a list, with the test,\n    value, error, and units fields replaced by a chart_data field containing a\n    Chart JSON dict (see design doc, and example below). Dashboard JSON v1.0 is\n    processed by converting it into rows (which can be viewed as Dashboard JSON\n    v0).\n\n    {\n      "master": "ChromiumPerf",\n      <other row fields>,\n      "chart_data": {\n        "foo": {\n          "bar": {\n            "type": "scalar",\n            "name": "foo.bar",\n            "units": "ms",\n            "value": 4.2,\n          },\n          "summary": {\n            "type": "list_of_scalar_values",\n            "name": "foo",\n            "units": "ms",\n            "values": [4.2, 5.7, 6.8],\n            "std": 1.30512,\n          },\n      },\n    }\n\n    Request parameters:\n      data: JSON encoding of a list of dictionaries.\n\n    Outputs:\n      Empty 200 response with if successful,\n      200 response with warning message if optional data is invalid,\n      403 response with error message if sender IP is not white-listed,\n      400 response with error message if required data is invalid.\n      500 with error message otherwise.\n    '
    datastore_hooks.SetPrivilegedRequest()
    if (not self._CheckIpAgainstWhitelist()):
        return
    data = self.request.get('data')
    if (not data):
        self.ReportError('Missing "data" parameter.', status=400)
        return
    try:
        data = json.loads(self.request.get('data'))
    except ValueError:
        self.ReportError('Invalid JSON string.', status=400)
        return
    logging.info('Received data: %s', data)
    try:
        if (type(data) is dict):
            if data.get('chart_data'):
                data = _DashboardJsonToRawRows(data)
                if (not data):
                    return
            else:
                self.ReportError('Data should be a list of rows or a Dashboard JSON v1.0 dict.', status=400)
                return
        test_map = _ConstructTestPathMap(data)
        for row_dict in data:
            _ValidateRowDict(row_dict, test_map)
        _AddTasks(data)
    except BadRequestError as error:
        self.ReportError(error.message, status=400)
Validates data parameter and add task to queue to process points.

The row data comes from a "data" parameter, which is a JSON encoding of a
list of dictionaries, each of which represents one performance result
(one point in a graph) and associated data.

  [
    {
      "master": "ChromiumPerf",
      "bot": "xp-release-dual-core",
      "test": "dromaeo/dom/modify",
      "revision": 123456789,
      "value": 24.66,
      "error": 2.33,
      "units": "ms",
      "supplemental_columns": {
        "d_median": 24234.12,
        "d_mean": 23.553,
        "r_webkit": 423340,
        ...
      },
      ...
    },
    ...
  ]

In general, the required fields are "master", "bot", "test" (which together
form the test path which identifies the series that this point belongs to),
and "revision" and "value", which are the X and Y values for the point.

This API also supports the Dashboard JSON v1.0 format (go/telemetry-json),
the first producer of which is Telemetry. Telemetry provides lightweight
serialization of values it produces, as JSON. If a dashboard JSON object is
passed, it will be a single dict rather than a list, with the test,
value, error, and units fields replaced by a chart_data field containing a
Chart JSON dict (see design doc, and example below). Dashboard JSON v1.0 is
processed by converting it into rows (which can be viewed as Dashboard JSON
v0).

{
  "master": "ChromiumPerf",
  <other row fields>,
  "chart_data": {
    "foo": {
      "bar": {
        "type": "scalar",
        "name": "foo.bar",
        "units": "ms",
        "value": 4.2,
      },
      "summary": {
        "type": "list_of_scalar_values",
        "name": "foo",
        "units": "ms",
        "values": [4.2, 5.7, 6.8],
        "std": 1.30512,
      },
  },
}

Request parameters:
  data: JSON encoding of a list of dictionaries.

Outputs:
  Empty 200 response with if successful,
  200 response with warning message if optional data is invalid,
  403 response with error message if sender IP is not white-listed,
  400 response with error message if required data is invalid.
  500 with error message otherwise.
def post(self):
    'Validates data parameter and add task to queue to process points.\n\n    The row data comes from a "data" parameter, which is a JSON encoding of a\n    list of dictionaries, each of which represents one performance result\n    (one point in a graph) and associated data.\n\n      [\n        {\n          "master": "ChromiumPerf",\n          "bot": "xp-release-dual-core",\n          "test": "dromaeo/dom/modify",\n          "revision": 123456789,\n          "value": 24.66,\n          "error": 2.33,\n          "units": "ms",\n          "supplemental_columns": {\n            "d_median": 24234.12,\n            "d_mean": 23.553,\n            "r_webkit": 423340,\n            ...\n          },\n          ...\n        },\n        ...\n      ]\n\n    In general, the required fields are "master", "bot", "test" (which together\n    form the test path which identifies the series that this point belongs to),\n    and "revision" and "value", which are the X and Y values for the point.\n\n    This API also supports the Dashboard JSON v1.0 format (go/telemetry-json),\n    the first producer of which is Telemetry. Telemetry provides lightweight\n    serialization of values it produces, as JSON. If a dashboard JSON object is\n    passed, it will be a single dict rather than a list, with the test,\n    value, error, and units fields replaced by a chart_data field containing a\n    Chart JSON dict (see design doc, and example below). Dashboard JSON v1.0 is\n    processed by converting it into rows (which can be viewed as Dashboard JSON\n    v0).\n\n    {\n      "master": "ChromiumPerf",\n      <other row fields>,\n      "chart_data": {\n        "foo": {\n          "bar": {\n            "type": "scalar",\n            "name": "foo.bar",\n            "units": "ms",\n            "value": 4.2,\n          },\n          "summary": {\n            "type": "list_of_scalar_values",\n            "name": "foo",\n            "units": "ms",\n            "values": [4.2, 5.7, 6.8],\n            "std": 1.30512,\n          },\n      },\n    }\n\n    Request parameters:\n      data: JSON encoding of a list of dictionaries.\n\n    Outputs:\n      Empty 200 response with if successful,\n      200 response with warning message if optional data is invalid,\n      403 response with error message if sender IP is not white-listed,\n      400 response with error message if required data is invalid.\n      500 with error message otherwise.\n    '
    datastore_hooks.SetPrivilegedRequest()
    if (not self._CheckIpAgainstWhitelist()):
        return
    data = self.request.get('data')
    if (not data):
        self.ReportError('Missing "data" parameter.', status=400)
        return
    try:
        data = json.loads(self.request.get('data'))
    except ValueError:
        self.ReportError('Invalid JSON string.', status=400)
        return
    logging.info('Received data: %s', data)
    try:
        if (type(data) is dict):
            if data.get('chart_data'):
                data = _DashboardJsonToRawRows(data)
                if (not data):
                    return
            else:
                self.ReportError('Data should be a list of rows or a Dashboard JSON v1.0 dict.', status=400)
                return
        test_map = _ConstructTestPathMap(data)
        for row_dict in data:
            _ValidateRowDict(row_dict, test_map)
        _AddTasks(data)
    except BadRequestError as error:
        self.ReportError(error.message, status=400)