コード例 #1
0
ファイル: api.py プロジェクト: milindgv94/incubator-superset
    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}")
コード例 #2
0
ファイル: data.py プロジェクト: ws1993/superset
class ChartDataCommand(BaseCommand):
    def __init__(self) -> None:
        self._form_data: Dict[str, Any]
        self._query_context: QueryContext
        self._async_channel_id: str

    def run(self, **kwargs: Any) -> Dict[str, Any]:
        # caching is handled in query_context.get_df_payload
        # (also evals `force` property)
        cache_query_context = kwargs.get("cache", False)
        force_cached = kwargs.get("force_cached", False)
        try:
            payload = self._query_context.get_payload(
                cache_query_context=cache_query_context, force_cached=force_cached
            )
        except CacheLoadError as ex:
            raise ChartDataCacheLoadError(ex.message) from ex

        # TODO: QueryContext should support SIP-40 style errors
        for query in payload["queries"]:
            if query.get("error"):
                raise ChartDataQueryFailedError(f"Error: {query['error']}")

        return_value = {
            "query_context": self._query_context,
            "queries": payload["queries"],
        }
        if cache_query_context:
            return_value.update(cache_key=payload["cache_key"])

        return return_value

    def run_async(self, user_id: Optional[str]) -> Dict[str, Any]:
        job_metadata = async_query_manager.init_job(self._async_channel_id, user_id)
        load_chart_data_into_cache.delay(job_metadata, self._form_data)

        return job_metadata

    def set_query_context(self, form_data: Dict[str, Any]) -> QueryContext:
        self._form_data = form_data
        try:
            self._query_context = ChartDataQueryContextSchema().load(self._form_data)
        except KeyError as ex:
            raise ValidationError("Request is incorrect") from ex
        except ValidationError as error:
            raise error

        return self._query_context

    def validate(self) -> None:
        self._query_context.raise_for_access()

    def validate_async_request(self, request: Request) -> None:
        jwt_data = async_query_manager.parse_jwt_from_request(request)
        self._async_channel_id = jwt_data["channel"]

    def load_query_context_from_cache(  # pylint: disable=no-self-use
        self, cache_key: str
    ) -> Dict[str, Any]:
        cache_value = cache.get(cache_key)
        if not cache_value:
            raise ChartDataCacheLoadError("Cached data not found")

        return cache_value["data"]