Beispiel #1
0
    def get_data_response(
        self, command: ChartDataCommand, force_cached: bool = False
    ) -> Response:
        try:
            result = command.run(force_cached=force_cached)
        except ChartDataCacheLoadError as exc:
            return self.response_422(message=exc.message)
        except ChartDataQueryFailedError as exc:
            return self.response_400(message=exc.message)

        result_format = result["query_context"].result_format
        if result_format == ChartDataResultFormat.CSV:
            # Verify user has permission to export CSV file
            if not security_manager.can_access("can_csv", "Superset"):
                return self.response_403()

            # return the first result
            data = result["queries"][0]["data"]
            return CsvResponse(data, headers=generate_download_headers("csv"))

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps(
                {"result": result["queries"]},
                default=json_int_dttm_ser,
                ignore_nan=True,
            )
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        return self.response_400(message=f"Unsupported result_format: {result_format}")
Beispiel #2
0
    def get_data_response(self,
                          command: ChartDataCommand,
                          force_cached: bool = False) -> Response:
        try:
            result = command.run(force_cached=force_cached)
        except ChartDataCacheLoadError as exc:
            return self.response_422(message=exc.message)
        except ChartDataQueryFailedError as exc:
            return self.response_400(message=exc.message)

        result_format = result["query_context"].result_format
        if result_format == ChartDataResultFormat.CSV:
            # return the first result
            data = result["queries"][0]["data"]
            return CsvResponse(data, headers=generate_download_headers("csv"))

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps(
                {"result": result["queries"]},
                default=json_int_dttm_ser,
                ignore_nan=True,
            )
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        if result_format == ChartDataResultFormat.XLSX:

            sio = BytesIO()
            df = pandas.DataFrame(result["queries"][0]["data"])
            writer = pandas.ExcelWriter(sio, engine='xlsxwriter')
            df.to_excel(writer, sheet_name="Лист 1", index=None)
            writer.save()

            sio.seek(0)
            workbook = sio.getvalue()

            return CsvResponse(workbook,
                               headers=generate_download_headers("xlsx"))

        return self.response_400(
            message=f"Unsupported result_format: {result_format}")
Beispiel #3
0
    def send_chart_response(
        self,
        result: Dict[Any, Any],
        form_data: Optional[Dict[str, Any]] = None,
    ) -> Response:
        result_type = result["query_context"].result_type
        result_format = result["query_context"].result_format

        # Post-process the data so it matches the data presented in the chart.
        # This is needed for sending reports based on text charts that do the
        # post-processing of data, eg, the pivot table.
        if (result_type == ChartDataResultType.POST_PROCESSED
                and result_format == ChartDataResultFormat.CSV):
            result = apply_post_process(result, form_data)

        if result_format == ChartDataResultFormat.CSV:
            # Verify user has permission to export CSV file
            if not security_manager.can_access("can_csv", "Superset"):
                return self.response_403()

            # return the first result
            data = result["queries"][0]["data"]
            return CsvResponse(data, headers=generate_download_headers("csv"))

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps(
                {"result": result["queries"]},
                default=json_int_dttm_ser,
                ignore_nan=True,
            )
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        return self.response_400(
            message=f"Unsupported result_format: {result_format}")
Beispiel #4
0
    def send_chart_response(self, result: Dict[Any, Any]) -> Response:
        result_format = result["query_context"].result_format

        if result_format == ChartDataResultFormat.CSV:
            # Verify user has permission to export CSV file
            if not security_manager.can_access("can_csv", "Superset"):
                return self.response_403()

            # return the first result
            data = result["queries"][0]["data"]
            return CsvResponse(data, headers=generate_download_headers("csv"))

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps(
                {"result": result["queries"]},
                default=json_int_dttm_ser,
                ignore_nan=True,
            )
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        return self.response_400(
            message=f"Unsupported result_format: {result_format}")
Beispiel #5
0
    def data(self) -> Response:  # pylint: disable=too-many-return-statements
        """
        Takes a query context constructed in the client and returns payload
        data response for the given query.
        ---
        post:
          description: >-
            Takes a query context constructed in the client and returns payload data
            response for the given query.
          requestBody:
            description: >-
              A query context consists of a datasource from which to fetch data
              and one or many query objects.
            required: true
            content:
              application/json:
                schema:
                  $ref: "#/components/schemas/ChartDataQueryContextSchema"
          responses:
            200:
              description: Query result
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/ChartDataResponseSchema"
            400:
              $ref: '#/components/responses/400'
            500:
              $ref: '#/components/responses/500'
        """
        if request.is_json:
            json_body = request.json
        elif request.form.get("form_data"):
            # CSV export submits regular form data
            json_body = json.loads(request.form["form_data"])
        else:
            return self.response_400(message="Request is not JSON")
        try:
            query_context = ChartDataQueryContextSchema().load(json_body)
        except KeyError:
            return self.response_400(message="Request is incorrect")
        except ValidationError as error:
            return self.response_400(message=_(
                "Request is incorrect: %(error)s", error=error.messages))
        try:
            query_context.raise_for_access()
        except SupersetSecurityException:
            return self.response_401()
        payload = query_context.get_payload()
        for query in payload:
            if query.get("error"):
                return self.response_400(message=f"Error: {query['error']}")
        result_format = query_context.result_format
        if result_format == ChartDataResultFormat.CSV:
            # return the first result
            result = payload[0]["data"]
            return CsvResponse(
                result,
                status=200,
                headers=generate_download_headers("csv"),
                mimetype="application/csv",
            )

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps({"result": payload},
                                             default=json_int_dttm_ser,
                                             ignore_nan=True)
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        return self.response_400(
            message=f"Unsupported result_format: {result_format}")