From 5e9a567c2c5e95749f49b96eacd2473f0c610c9d Mon Sep 17 00:00:00 2001 From: Leah Tacke genannt Unterberg <leah.tgu@pads.rwth-aachen.de> Date: Wed, 30 Apr 2025 18:14:35 +0200 Subject: [PATCH] worked on improving request forwarding and inter-service communication via caching backend --- pyproject.toml | 2 +- requirements/development.txt | 4 + superset/commands/mitm/caching/__init__.py | 0 superset/commands/mitm/caching/cache_data.py | 161 +++ .../mitm/caching/service_communication.py | 1 + superset/commands/mitm/caching/utils.py | 64 + .../exec_forwardable_request.py | 35 +- .../exec_forwardable_request_async.py | 6 +- superset/commands/mitm/mitm_dataset/utils.py | 1 + superset/commands/mitm/mitm_service/delete.py | 2 +- .../mitm_service/{export.py => download.py} | 39 +- superset/commands/mitm/mitm_service/get.py | 4 +- .../mitm/mitm_service/schemas/openapi.json | 2 +- .../mitm/mitm_service/schemas/openapi.yaml | 1162 ++++++++++++++--- .../mitm/mitm_service/schemas/schema.py | 396 ++++-- superset/commands/mitm/mitm_service/upload.py | 2 +- superset/commands/mitm/mitm_service/utils.py | 15 + .../customization/ext_service_call/api.py | 8 +- .../external_service_support/common.py | 4 +- .../forwardable_request.py | 298 +++-- .../pydantic_utils.py | 32 + .../service_call_manager.py | 28 +- superset/customization/mitm_datasets/api.py | 30 +- .../customization/mitm_datasets/schemas.py | 8 +- superset/customization/mitm_service/api.py | 78 +- superset/daos/mitm_dataset.py | 3 + superset/tasks/mitm/download_mitm_dataset.py | 10 +- superset/tasks/mitm/drop_mitm_dataset.py | 4 +- 28 files changed, 1863 insertions(+), 536 deletions(-) create mode 100644 superset/commands/mitm/caching/__init__.py create mode 100644 superset/commands/mitm/caching/cache_data.py create mode 100644 superset/commands/mitm/caching/service_communication.py create mode 100644 superset/commands/mitm/caching/utils.py rename superset/commands/mitm/mitm_service/{export.py => download.py} (54%) create mode 100644 superset/commands/mitm/mitm_service/utils.py create mode 100644 superset/customization/external_service_support/pydantic_utils.py diff --git a/pyproject.toml b/pyproject.toml index 286a539cb5..e666af99d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -208,7 +208,7 @@ development = [ # NEW MITM RELATED #"requests>=2.0.0" #"mitm-tooling>=0.3.1" -mitm = ["pydantic>=2.0","psycopg2"] +mitm = ["pydantic>=2.0","psycopg2","requests","requests-toolbelt"] [project.urls] homepage = "https://superset.apache.org/" diff --git a/requirements/development.txt b/requirements/development.txt index 0802dfa87d..24ed0d147d 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -728,6 +728,7 @@ referencing==0.36.2 requests==2.32.3 # via # -c requirements/base.txt + # apache-superset # docker # google-api-core # google-cloud-bigquery @@ -736,6 +737,7 @@ requests==2.32.3 # pyhive # requests-cache # requests-oauthlib + # requests-toolbelt # shillelagh # trino requests-cache==1.2.1 @@ -744,6 +746,8 @@ requests-cache==1.2.1 # shillelagh requests-oauthlib==2.0.0 # via google-auth-oauthlib +requests-toolbelt==1.0.0 + # via apache-superset rfc3339-validator==0.1.4 # via openapi-schema-validator rich==13.9.4 diff --git a/superset/commands/mitm/caching/__init__.py b/superset/commands/mitm/caching/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/superset/commands/mitm/caching/cache_data.py b/superset/commands/mitm/caching/cache_data.py new file mode 100644 index 0000000000..ebdb853583 --- /dev/null +++ b/superset/commands/mitm/caching/cache_data.py @@ -0,0 +1,161 @@ +import contextlib +from abc import ABC, abstractmethod +from typing import Any, Generator, Callable, ContextManager + +from flask_caching import Cache +from flask_caching.backends import NullCache, RedisCache + +from superset.commands.exceptions import CommandException + +from superset import cache_manager +from superset.commands.base import BaseCommand +from .utils import cache_streaming_keys, redis_pipeline + + +def get_default_timeout() -> int: + from flask import current_app + return current_app.config['CACHE_DEFAULT_TIMEOUT'] + + +class SimpleCacheCommand(BaseCommand, ABC): + def __init__(self, + cache_key: str, + cache: Cache | None = None) -> None: + super().__init__() + self.cache_key = cache_key + self.cache = cache or cache_manager.cache + + @abstractmethod + def _run(self): + pass + + def run(self) -> Any: + self.validate() + return self._run() + + def validate(self) -> None: + if not self.cache_key: + raise CommandException('Missing cache key.') + if (not self.cache) or isinstance(self.cache, NullCache): + raise CommandException('Missing cache backend.') + + +class WriteCacheCommand(SimpleCacheCommand): + + def __init__(self, + cache_key: str, + data: Any, + cache: Cache | None = None, + expiry_timeout: int | None = None) -> None: + super().__init__(cache_key, cache=cache) + self.data = data + self.expiry_timeout = expiry_timeout or get_default_timeout() + + def _run(self) -> None: + self.cache.set(self.cache_key, self.data, timeout=self.expiry_timeout) + + +class ReadCacheCommand(SimpleCacheCommand): + + def __init__(self, + cache_key: str, + cache: Cache | None = None) -> None: + super().__init__(cache_key, cache=cache) + + def _run(self, delete_after: bool = False) -> Any | None: + v = self.cache.get(self.cache_key) + if delete_after: + self.cache.delete(self.cache_key) + return v + + +class StreamingCacheCommand(BaseCommand, ABC): + def __init__(self, + base_cache_key: str, + cache: Cache | None = None) -> None: + super().__init__() + self.base_cache_key = base_cache_key + self.cache = cache or cache_manager.cache + + @abstractmethod + def _run(self): + pass + + def run(self) -> Any: + self.validate() + return self._run() + + def validate(self) -> None: + if not isinstance(self.cache, RedisCache): + raise CommandException('Cache must be Redis for streaming into/from cache.') + + +class StreamIntoCacheCommand(StreamingCacheCommand): + + def __init__(self, + base_cache_key: str, + chunk_generator: Callable[[], Generator[Any, None, None]], + cache: Cache | None = None, + expiry_timeout: int | None = None) -> None: + super().__init__(base_cache_key, cache=cache) + self.chunk_generator = chunk_generator + self.expiry_timeout = expiry_timeout or get_default_timeout() + + def _run(self) -> None: + with redis_pipeline(self.cache) as pipe: + total_chunks_key, chunk_key_generator = cache_streaming_keys(self.base_cache_key) + + total_chunks = 0 + for chunk, chunk_key in zip(self.chunk_generator(), + chunk_key_generator()): + if chunk: # Ensure valid chunk + pipe.set(chunk_key, chunk, timeout=self.expiry_timeout) + total_chunks += 1 + # Store metadata about the chunk count for later assembly + pipe.set(total_chunks_key, total_chunks, timeout=self.expiry_timeout) + pipe.execute() + + def run(self) -> None: + return super().run() + + def validate(self) -> None: + super().validate() + if not callable(self.chunk_generator): + raise CommandException( + 'Chunk generator must be a callable that returns a generator.' + ) + + +class ReadStreamedCacheCommand(StreamingCacheCommand): + + def __init__(self, + base_cache_key: str, + cache: Cache | None = None) -> None: + super().__init__(base_cache_key=base_cache_key, cache=cache) + + def _run(self, delete_after: bool = False) -> ContextManager[ + Generator[ + Any, None, None]] | None: + total_chunk_key, chunk_key_generator = cache_streaming_keys(self.base_cache_key) + total_chunks = int(self.cache.get(total_chunk_key) or 0) + if total_chunks > 0: + @contextlib.contextmanager + def ctxt_mngr(): + try: + yield (self.cache.get(k) for k in chunk_key_generator(total_chunks)) + finally: + if delete_after: + self.cache.delete(total_chunk_key) + self.cache.delete_many(list(chunk_key_generator(total_chunks))) + + return ctxt_mngr + else: + raise CommandException('No chunks found.') + + def run(self, delete_after: bool = False) -> ContextManager[ + Generator[ + Any, None, None]] | None: + self.validate() + return self._run(delete_after=delete_after) + + diff --git a/superset/commands/mitm/caching/service_communication.py b/superset/commands/mitm/caching/service_communication.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/superset/commands/mitm/caching/service_communication.py @@ -0,0 +1 @@ + diff --git a/superset/commands/mitm/caching/utils.py b/superset/commands/mitm/caching/utils.py new file mode 100644 index 0000000000..2a8b1cac62 --- /dev/null +++ b/superset/commands/mitm/caching/utils.py @@ -0,0 +1,64 @@ +import contextlib +import io +from typing import Protocol, Generator, Any, IO + +import requests +from flask_caching import Cache +from flask_caching.backends import RedisCache +from redis.client import Pipeline + + +class CacheKeyGenerator(Protocol): + def __call__(self, limit: int | None = None) -> Generator[str, None, None]: + pass + +def cache_streaming_keys(base_cache_key: str) -> tuple[ + str, CacheKeyGenerator]: + def chunk_cache_keys(chunk_limit: int | None = None): + i = 0 + while chunk_limit is None or i < chunk_limit: + yield f'{base_cache_key}:chunk:{i}' + i += 1 + + return f'{base_cache_key}:total_chunks', chunk_cache_keys + +@contextlib.contextmanager +def redis_pipeline(cache: Cache) -> Generator[Pipeline, None, None]: + """Create a pipeline for Redis cache. + + Args: + cache: The Redis cache instance. + + Yields: + A Redis pipeline instance. + """ + if not isinstance(cache, RedisCache): + raise TypeError('Expected a RedisCache instance.') + else: + yield cache._write_client.pipeline(transaction=True) + +def chunked_response_data(response: requests.Response, chunk_size: int | None = 1024 * 32) -> Generator[bytes, None, None]: + """Yield chunks of data from the response. + + Args: + response: The HTTP response object. + chunk_size: The size of each chunk in bytes. Defaults to 32 KB. + + Yields: + Chunks of data from the response. + """ + for chunk in response.iter_content(chunk_size=chunk_size): + yield chunk + + +def collect_chunks( + byte_chunks_generator: Generator[bytes, None, None]) -> bytes: + return b''.join(byte_chunks_generator) + + +def chunked_raw_io(raw_io: io.IOBase | IO[bytes], chunk_size: int = 1024 * 32) -> Generator[bytes, None, None]: + while True: + chunk = raw_io.read(chunk_size) + if not chunk: + break + yield chunk diff --git a/superset/commands/mitm/external_service/exec_forwardable_request.py b/superset/commands/mitm/external_service/exec_forwardable_request.py index 5f39fa1438..b295d91007 100644 --- a/superset/commands/mitm/external_service/exec_forwardable_request.py +++ b/superset/commands/mitm/external_service/exec_forwardable_request.py @@ -14,27 +14,29 @@ from superset.commands.base import BaseCommand from superset.commands.exceptions import CommandException if TYPE_CHECKING: - from superset.customization.external_service_support.forwardable_request import ForwardableRequest, \ - CompleteForwardableRequest - -CACHE_TIMEOUT = app.config['CACHE_DEFAULT_TIMEOUT'] + from superset.customization.external_service_support.forwardable_request import \ + ForwardableRequest, \ + ForwardableRequestBase EXTERNAL_API_TIMEOUT = current_app.config['EXTERNAL_SERVICE_TIMEOUT'] - class ExecuteForwardableRequestCommand(BaseCommand): - def __init__(self, forwardable_request: CompleteForwardableRequest, + def __init__(self, + forwardable_request: ForwardableRequestBase, cache: Cache | None = None, - cache_key: str | None = None) -> None: - self.forwardable_request: CompleteForwardableRequest = forwardable_request + cache_key: str | None = None, + request_timeout: int | None = None) -> None: + self.forwardable_request: ForwardableRequestBase = forwardable_request self.cache: Cache = cache or cache_manager.cache self.cache_key: str | None = cache_key + self.request_timeout: int | None = request_timeout def _run(self) -> requests.Response: req = self.forwardable_request try: - response = req.make_request(timeout=EXTERNAL_API_TIMEOUT) + response = req.make_request(timeout=( + self.request_timeout or EXTERNAL_API_TIMEOUT)) if response.status_code == 200: return response else: @@ -44,16 +46,21 @@ class ExecuteForwardableRequestCommand(BaseCommand): raise CommandException( f'Failed calling {req.url}.') from e - def _cache_result(self, data: requests.Response) -> None: + def _cache_result(self, + data: requests.Response, + cache_timeout: int | None = None) -> None: if self.cache_key: - dttm = datetime.datetime.now(datetime.UTC).isoformat().split('.')[0] - self.cache.set(self.cache_key, data.content, timeout=CACHE_TIMEOUT) + self.cache.set(self.cache_key, + data.content, + timeout=(cache_timeout or CACHE_TIMEOUT)) - def run(self, cache: bool = False) -> requests.Response: + def run(self, + cache: bool = False, + cache_timeout: int | None = None) -> requests.Response: self.validate(cache=cache) data = self._run() if cache: - self._cache_result(data) + self._cache_result(data, cache_timeout=cache_timeout) return data def validate(self, cache: bool = False) -> None: diff --git a/superset/commands/mitm/external_service/exec_forwardable_request_async.py b/superset/commands/mitm/external_service/exec_forwardable_request_async.py index bb30772687..db51ae20ac 100644 --- a/superset/commands/mitm/external_service/exec_forwardable_request_async.py +++ b/superset/commands/mitm/external_service/exec_forwardable_request_async.py @@ -9,7 +9,7 @@ from superset.commands.base import BaseCommand if TYPE_CHECKING: from superset.customization.external_service_support.forwardable_request import \ - CompleteForwardableRequest + ForwardableRequestBase from superset.customization.external_service_support.common import AsyncJobMetadata @@ -17,7 +17,7 @@ class ExecuteForwardableRequestAsyncCommand(BaseCommand): def __init__(self, job_metadata: AsyncJobMetadata, - forwardable_request: CompleteForwardableRequest, + forwardable_request: ForwardableRequestBase, result_base_url: str | None = None) -> None: self.job_metadata = job_metadata self.forwardable_request = forwardable_request @@ -25,7 +25,7 @@ class ExecuteForwardableRequestAsyncCommand(BaseCommand): self.task: celery.Task | None = None def _run(self) -> AsyncResult: - from superset.customization.external_service_support.forwardable_request import \ + from superset.customization.external_service_support.pydantic_utils import \ srzl_support return self.task.delay(self.job_metadata, diff --git a/superset/commands/mitm/mitm_dataset/utils.py b/superset/commands/mitm/mitm_dataset/utils.py index b6d63bdd56..cad86fe4f2 100644 --- a/superset/commands/mitm/mitm_dataset/utils.py +++ b/superset/commands/mitm/mitm_dataset/utils.py @@ -58,3 +58,4 @@ def handle_serialized_fields(properties: dict[str, Any]) -> list[ValidationError if 'mitm_header' in properties: properties['mitm_header'] = json.dumps(properties['mitm_header']) return exceptions + diff --git a/superset/commands/mitm/mitm_service/delete.py b/superset/commands/mitm/mitm_service/delete.py index 6033b10587..384b44b375 100644 --- a/superset/commands/mitm/mitm_service/delete.py +++ b/superset/commands/mitm/mitm_service/delete.py @@ -10,7 +10,7 @@ from superset.extensions import external_service_call_manager from superset.utils.decorators import transaction, on_error -class DeleteUploadedMitMDatasetCommand(MitMDatasetBaseCommand): +class DeleteTrackedMitMDatasetCommand(MitMDatasetBaseCommand): def _run(self) -> None: assert self._model diff --git a/superset/commands/mitm/mitm_service/export.py b/superset/commands/mitm/mitm_service/download.py similarity index 54% rename from superset/commands/mitm/mitm_service/export.py rename to superset/commands/mitm/mitm_service/download.py index b5fca6dac2..0b0a12e1eb 100644 --- a/superset/commands/mitm/mitm_service/export.py +++ b/superset/commands/mitm/mitm_service/download.py @@ -4,8 +4,9 @@ from functools import partial from typing import TYPE_CHECKING from flask_caching import Cache -from flask_caching.backends import NullCache +from flask_caching.backends import NullCache, RedisCache +from superset.customization.external_service_support.common import cache_streaming_keys from superset.customization.external_service_support.forwardable_request import \ ForwardableRequest from superset.customization.external_service_support.service_registry import \ @@ -19,17 +20,20 @@ from ...exceptions import CommandException if TYPE_CHECKING: import requests + import redis -class ExportUploadedMitMDatasetCommand(MitMDatasetBaseCommand): +class DownloadTrackedMitMDatasetCommand(MitMDatasetBaseCommand): def __init__(self, mitm_dataset_id: int, cache: Cache | None = None, - cache_key: str | None = None) -> None: + cache_key: str | None = None, + stream_into_cache: bool = False) -> None: super().__init__(mitm_dataset_id) self.cache: Cache = cache or cache_manager.cache self.cache_key: str | None = cache_key + self.stream_into_cache = stream_into_cache def _run(self) -> requests.Response: assert self._model @@ -46,16 +50,35 @@ class ExportUploadedMitMDatasetCommand(MitMDatasetBaseCommand): return export_response - def _cache_content(self, res: requests.Response) -> None: - # TODO try to stream this into the cache if possible - self.cache.set(self.cache_key, res.content) + def _cache_content(self, res: requests.Response, stream_data: bool = False) -> None: + # TODO try to switch to streaming into and out of the cache as exports can be very large + # ideally, the something similar would be done in the upload command + + if stream_data: + if isinstance(self.cache, RedisCache): + c: redis.Redis = self.cache._write_client + pipe = c.pipeline() + + total_chunks_key, chunk_key_generator = cache_streaming_keys(self.cache_key) + + chunk_size = 1024 * 32 # Fetch 32 KB in each chunk + total_chunks = 0 + for chunk, chunk_key in zip(res.iter_content(chunk_size=chunk_size), chunk_key_generator()): + if chunk: # Ensure valid chunk + pipe.set(chunk_key, chunk) + total_chunks += 1 + # Store metadata about the chunk count for later assembly + pipe.set(total_chunks_key, total_chunks) + pipe.execute() + else: + self.cache.set(self.cache_key, res.content) @transaction(on_error=partial(on_error, reraise=MitMDatasetExportError)) def run(self, cache: bool = False) -> Any: self.validate(cache=cache) res = self._run() if cache: - self._cache_content(res) + self._cache_content(res, stream_data=self.stream_into_cache) return res def validate(self, cache: bool = False) -> None: @@ -63,3 +86,5 @@ class ExportUploadedMitMDatasetCommand(MitMDatasetBaseCommand): raise CommandException('Missing cache backend.') if not self.cache_key: raise CommandException('No cache key set.') + if self.stream_into_cache and not isinstance(self.cache, RedisCache): + raise CommandException('Cache must be Redis for streaming into cache.') diff --git a/superset/commands/mitm/mitm_service/get.py b/superset/commands/mitm/mitm_service/get.py index 092120be75..648af304ac 100644 --- a/superset/commands/mitm/mitm_service/get.py +++ b/superset/commands/mitm/mitm_service/get.py @@ -12,7 +12,7 @@ from ..exceptions import * from ...base import BaseCommand -class GetUploadedMitMDatasetsCommand(BaseCommand): +class ListUploadedMitMDatasetsCommand(BaseCommand): def _run(self) -> list[TrackedMitMDataset]: get_uploads_request = ForwardableRequest(method='GET', @@ -36,7 +36,7 @@ class GetUploadedMitMDatasetsCommand(BaseCommand): pass -class GetUploadedMitMDatasetCommand(MitMDatasetBaseCommand): +class GetTrackedMitMDatasetCommand(MitMDatasetBaseCommand): def _run(self) -> TrackedMitMDataset: assert self._model diff --git a/superset/commands/mitm/mitm_service/schemas/openapi.json b/superset/commands/mitm/mitm_service/schemas/openapi.json index ce6eddd8e1..10e6344132 100644 --- a/superset/commands/mitm/mitm_service/schemas/openapi.json +++ b/superset/commands/mitm/mitm_service/schemas/openapi.json @@ -1 +1 @@ -{"openapi": "3.1.0", "info": {"title": "SupersetMitMService", "version": "0.1.0"}, "paths": {"/mitm_dataset/upload": {"post": {"tags": ["mitm_dataset"], "summary": "Upload Mitm Dataset", "operationId": "upload_mitm_dataset", "parameters": [{"name": "dataset_name", "in": "query", "required": true, "schema": {"type": "string", "title": "Dataset Name"}}, {"name": "mitm", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/MITM", "default": "MAED"}}], "requestBody": {"required": true, "content": {"multipart/form-data": {"schema": {"$ref": "#/components/schemas/Body_upload_mitm_dataset_mitm_dataset_upload_post"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UploadMitMResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/register": {"post": {"tags": ["mitm_dataset"], "summary": "Register Mitm Dataset", "operationId": "register_mitm_dataset", "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegisterExternalMitMDatasetRequest"}}}, "required": true}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegisterMitMResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/": {"get": {"tags": ["mitm_dataset"], "summary": "Get Mitm Datasets", "operationId": "get_mitm_datasets", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TrackedMitMDataset"}, "type": "array", "title": "Response Get Mitm Datasets Mitm Dataset Get"}}}}}}, "post": {"tags": ["mitm_dataset"], "summary": "Post Mitm Dataset", "operationId": "post_mitm_dataset", "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddTrackedMitMDatasetRequest"}}}, "required": true}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/{uuid}": {"get": {"tags": ["mitm_dataset"], "summary": "Get Mitm Dataset", "operationId": "get_mitm_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TrackedMitMDataset"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["mitm_dataset"], "summary": "Delete Mitm Dataset", "operationId": "delete_mitm_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset": {"post": {"tags": ["definitions"], "summary": "Generate Mitm Dataset Bundle", "operationId": "generate_mitm_dataset_bundle", "parameters": [{"name": "dataset_name", "in": "query", "required": true, "schema": {"type": "string", "title": "Dataset Name"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Body_generate_mitm_dataset_bundle_definitions_mitm_dataset_post"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SupersetMitMDatasetBundle"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/import": {"post": {"tags": ["definitions"], "summary": "Generate Mitm Dataset Import", "operationId": "generate_mitm_dataset_import", "parameters": [{"name": "dataset_name", "in": "query", "required": true, "schema": {"type": "string", "title": "Dataset Name"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Body_generate_mitm_dataset_import_definitions_mitm_dataset_import_post"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SupersetMitMDatasetImport"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/import/zip": {"post": {"tags": ["definitions"], "summary": "Generate Mitm Dataset Import Zip", "operationId": "generate_mitm_dataset_import_zip", "parameters": [{"name": "dataset_name", "in": "query", "required": true, "schema": {"type": "string", "title": "Dataset Name"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Body_generate_mitm_dataset_import_zip_definitions_mitm_dataset_import_zip_post"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/zip": {}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/{uuid}/": {"get": {"tags": ["definitions"], "summary": "Generate Uploaded Mitm Dataset Bundle", "operationId": "generate_uploaded_mitm_dataset_bundle", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SupersetMitMDatasetBundle"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/{uuid}/import": {"get": {"tags": ["definitions"], "summary": "Generate Uploaded Mitm Dataset Import", "operationId": "generate_uploaded_mitm_dataset_import", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SupersetMitMDatasetImport"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/{uuid}/import/zip": {"get": {"tags": ["definitions"], "summary": "Generate Uploaded Mitm Dataset Import Zip", "operationId": "generate_uploaded_mitm_dataset_import_zip", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/zip": {}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/": {"get": {"summary": "Root", "operationId": "root__get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/health": {"get": {"summary": "Health", "operationId": "health_health_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}}, "components": {"schemas": {"AddTrackedMitMDatasetRequest": {"properties": {"uuid": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Uuid"}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "schema_name": {"type": "string", "title": "Schema Name"}, "sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri"}, "mitm_header": {"$ref": "#/components/schemas/Header-Input"}}, "type": "object", "required": ["dataset_name", "schema_name", "sql_alchemy_uri", "mitm_header"], "title": "AddTrackedMitMDatasetRequest"}, "AnnotationLayer": {"properties": {"name": {"type": "string", "title": "Name"}, "value": {"type": "integer", "title": "Value"}, "annotationType": {"$ref": "#/components/schemas/AnnotationType"}, "sourceType": {"$ref": "#/components/schemas/AnnotationSource", "default": "table"}, "opacity": {"type": "string", "title": "Opacity", "default": ""}, "overrides": {"$ref": "#/components/schemas/AnnotationOverrides"}, "hideLine": {"type": "boolean", "title": "Hideline", "default": false}, "show": {"type": "boolean", "title": "Show", "default": false}, "showLabel": {"type": "boolean", "title": "Showlabel", "default": false}, "showMarkers": {"type": "boolean", "title": "Showmarkers", "default": false}, "style": {"type": "string", "title": "Style", "default": "solid"}, "width": {"type": "integer", "title": "Width", "default": 1}}, "type": "object", "required": ["name", "value", "annotationType", "overrides"], "title": "AnnotationLayer"}, "AnnotationOverrides": {"properties": {"time_range": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Time Range"}}, "type": "object", "title": "AnnotationOverrides"}, "AnnotationSource": {"type": "string", "enum": ["line", "NATIVE", "table", ""], "title": "AnnotationSource"}, "AnnotationType": {"type": "string", "enum": ["EVENT", "FORMULA", "INTERVAL", "TIME_SERIES"], "title": "AnnotationType"}, "Body_generate_mitm_dataset_bundle_definitions_mitm_dataset_post": {"properties": {"mitm_header": {"$ref": "#/components/schemas/Header-Input"}, "db_conn_info": {"$ref": "#/components/schemas/SupersetDBConnectionInfo"}}, "type": "object", "required": ["mitm_header", "db_conn_info"], "title": "Body_generate_mitm_dataset_bundle_definitions_mitm_dataset_post"}, "Body_generate_mitm_dataset_import_definitions_mitm_dataset_import_post": {"properties": {"mitm_header": {"$ref": "#/components/schemas/Header-Input"}, "db_conn_info": {"$ref": "#/components/schemas/SupersetDBConnectionInfo"}}, "type": "object", "required": ["mitm_header", "db_conn_info"], "title": "Body_generate_mitm_dataset_import_definitions_mitm_dataset_import_post"}, "Body_generate_mitm_dataset_import_zip_definitions_mitm_dataset_import_zip_post": {"properties": {"mitm_header": {"$ref": "#/components/schemas/Header-Input"}, "db_conn_info": {"$ref": "#/components/schemas/SupersetDBConnectionInfo"}}, "type": "object", "required": ["mitm_header", "db_conn_info"], "title": "Body_generate_mitm_dataset_import_zip_definitions_mitm_dataset_import_zip_post"}, "Body_upload_mitm_dataset_mitm_dataset_upload_post": {"properties": {"mitm_zip": {"type": "string", "format": "binary", "title": "Mitm Zip"}}, "type": "object", "required": ["mitm_zip"], "title": "Body_upload_mitm_dataset_mitm_dataset_upload_post"}, "ChartDataResultFormat": {"type": "string", "enum": ["csv", "json", "xlsx"], "title": "ChartDataResultFormat"}, "ChartDataResultType": {"type": "string", "enum": ["columns", "full", "query", "results", "samples", "timegrains", "post_processed", "drill_detail"], "title": "ChartDataResultType"}, "ChartParams": {"properties": {"datasource": {"anyOf": [{"type": "string"}, {"$ref": "#/components/schemas/DatasourceIdentifier"}], "title": "Datasource"}, "viz_type": {"$ref": "#/components/schemas/SupersetVizType"}, "groupby": {"items": {"type": "string"}, "type": "array", "title": "Groupby"}, "adhoc_filters": {"items": {"$ref": "#/components/schemas/SupersetAdhocFilter"}, "type": "array", "title": "Adhoc Filters"}, "row_limit": {"type": "integer", "title": "Row Limit", "default": 10000}, "sort_by_metric": {"type": "boolean", "title": "Sort By Metric", "default": true}, "color_scheme": {"type": "string", "enum": ["blueToGreen", "supersetColors"], "title": "Color Scheme", "default": "supersetColors"}, "show_legend": {"type": "boolean", "title": "Show Legend", "default": true}, "legendType": {"type": "string", "title": "Legendtype", "default": "scroll"}, "legendOrientation": {"type": "string", "title": "Legendorientation", "default": "top"}, "extra_form_data": {"type": "object", "title": "Extra Form Data"}, "slice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Slice Id"}, "dashboards": {"items": {"type": "integer"}, "type": "array", "title": "Dashboards"}}, "type": "object", "required": ["datasource", "viz_type"], "title": "ChartParams"}, "ColName": {"properties": {"name": {"type": "string", "title": "Name"}}, "type": "object", "required": ["name"], "title": "ColName"}, "ColumnOfDataset": {"properties": {"datasetUuid": {"type": "string", "format": "uuid", "title": "Datasetuuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "column": {"$ref": "#/components/schemas/ColName"}}, "type": "object", "required": ["datasetUuid", "column"], "title": "ColumnOfDataset"}, "CompiledVirtualView": {"properties": {"dialect": {"type": "string", "title": "Dialect"}, "compiled_sql": {"type": "string", "title": "Compiled Sql"}, "columns": {"items": {"type": "string"}, "type": "array", "title": "Columns"}, "column_dtypes": {"items": {"anyOf": [{"$ref": "#/components/schemas/WrappedMITMDataType"}, {"type": "string"}]}, "type": "array", "title": "Column Dtypes"}, "name": {"type": "string", "title": "Name"}, "schema_name": {"type": "string", "title": "Schema Name"}}, "type": "object", "required": ["dialect", "compiled_sql", "columns", "column_dtypes", "name", "schema_name"], "title": "CompiledVirtualView"}, "ComponentMeta": {"properties": {}, "type": "object", "title": "ComponentMeta"}, "ConceptMapping": {"properties": {"mitm": {"$ref": "#/components/schemas/MITM"}, "concept": {"type": "string", "title": "Concept"}, "base_table": {"anyOf": [{"$ref": "#/components/schemas/TableIdentifier"}, {"prefixItems": [{"$ref": "#/components/schemas/SourceDBType"}, {"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 3, "minItems": 3}, {"prefixItems": [{"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 2, "minItems": 2}], "title": "Base Table"}, "kind_col": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Kind Col"}, "type_col": {"type": "string", "title": "Type Col"}, "identity_columns": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"items": {"type": "string"}, "type": "array"}], "title": "Identity Columns"}, "inline_relations": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"items": {"type": "string"}, "type": "array"}], "title": "Inline Relations"}, "foreign_relations": {"additionalProperties": {"$ref": "#/components/schemas/ForeignRelation"}, "type": "object", "title": "Foreign Relations"}, "attributes": {"items": {"type": "string"}, "type": "array", "title": "Attributes"}, "attribute_dtypes": {"items": {"$ref": "#/components/schemas/MITMDataType"}, "type": "array", "title": "Attribute Dtypes"}}, "type": "object", "required": ["mitm", "concept", "base_table", "type_col"], "title": "ConceptMapping"}, "ControlValues": {"properties": {"enableEmptyFilter": {"type": "boolean", "title": "Enableemptyfilter", "default": false}, "defaultToFirstItem": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Defaulttofirstitem", "default": false}, "multiSelect": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Multiselect", "default": true}, "searchAllOptions": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Searchalloptions", "default": false}, "inverseSelection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Inverseselection", "default": false}}, "type": "object", "title": "ControlValues"}, "DashboardComponent": {"properties": {"id": {"type": "string", "title": "Id"}, "type": {"$ref": "#/components/schemas/DashboardComponentType"}, "meta": {"anyOf": [{"$ref": "#/components/schemas/ComponentMeta"}, {"type": "null"}]}, "children": {"items": {"type": "string"}, "type": "array", "title": "Children"}}, "type": "object", "required": ["id", "type"], "title": "DashboardComponent"}, "DashboardComponentType": {"type": "string", "enum": ["CHART", "HEADER", "GRID", "ROW", "ROOT"], "title": "DashboardComponentType"}, "DashboardMetadata": {"properties": {"color_scheme": {"type": "string", "title": "Color Scheme", "default": "blueToGreen"}, "cross_filters_enabled": {"type": "boolean", "title": "Cross Filters Enabled", "default": true}, "native_filter_configuration": {"items": {"$ref": "#/components/schemas/NativeFilterConfig"}, "type": "array", "title": "Native Filter Configuration"}}, "type": "object", "title": "DashboardMetadata"}, "DatasetReference": {"properties": {"datasetUuid": {"type": "string", "format": "uuid", "title": "Datasetuuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}}, "type": "object", "required": ["datasetUuid"], "title": "DatasetReference"}, "DatasourceIdentifier": {"properties": {"id": {"type": "integer", "title": "Id", "default": -1}, "type": {"type": "string", "enum": ["table", "annotation"], "title": "Type", "default": "table"}}, "type": "object", "title": "DatasourceIdentifier"}, "ExpressionType": {"type": "string", "enum": ["SIMPLE", "SQL"], "title": "ExpressionType"}, "FilterOperator": {"type": "string", "enum": ["==", "!=", ">", "<", ">=", "<=", "LIKE", "NOT LIKE", "ILIKE", "IS NULL", "IS NOT NULL", "IN", "NOT IN", "IS TRUE", "IS FALSE", "TEMPORAL_RANGE"], "title": "FilterOperator"}, "FilterStringOperators": {"type": "string", "enum": ["EQUALS", "NOT_EQUALS", "LESS_THAN", "GREATER_THAN", "LESS_THAN_OR_EQUAL", "GREATER_THAN_OR_EQUAL", "IN", "NOT_IN", "ILIKE", "LIKE", "IS_NOT_NULL", "IS_NULL", "LATEST_PARTITION", "IS_TRUE", "IS_FALSE"], "title": "FilterStringOperators"}, "FilterType": {"type": "string", "enum": ["filter_select", "filter_timegrain"], "title": "FilterType"}, "ForeignRelation": {"properties": {"fk_columns": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"items": {"type": "string"}, "type": "array"}], "title": "Fk Columns"}, "referred_table": {"anyOf": [{"$ref": "#/components/schemas/TableIdentifier"}, {"prefixItems": [{"$ref": "#/components/schemas/SourceDBType"}, {"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 3, "minItems": 3}, {"prefixItems": [{"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 2, "minItems": 2}], "title": "Referred Table"}}, "type": "object", "required": ["fk_columns", "referred_table"], "title": "ForeignRelation"}, "FormData": {"properties": {}, "type": "object", "title": "FormData"}, "GenericDataType": {"type": "integer", "enum": [0, 1, 2, 3], "title": "GenericDataType"}, "HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "type": "array", "title": "Detail"}}, "type": "object", "title": "HTTPValidationError"}, "Header-Input": {"properties": {"mitm": {"$ref": "#/components/schemas/MITM"}, "header_entries": {"items": {"$ref": "#/components/schemas/HeaderEntry"}, "type": "array", "title": "Header Entries"}}, "type": "object", "required": ["mitm"], "title": "Header"}, "Header-Output": {"properties": {"mitm": {"$ref": "#/components/schemas/MITM"}, "header_entries": {"items": {"$ref": "#/components/schemas/HeaderEntry"}, "type": "array", "title": "Header Entries"}}, "type": "object", "required": ["mitm"], "title": "Header"}, "HeaderEntry": {"properties": {"concept": {"type": "string", "title": "Concept"}, "kind": {"type": "string", "title": "Kind"}, "type_name": {"type": "string", "title": "Type Name"}, "attributes": {"items": {"type": "string"}, "type": "array", "title": "Attributes"}, "attribute_dtypes": {"items": {"$ref": "#/components/schemas/MITMDataType"}, "type": "array", "title": "Attribute Dtypes"}}, "type": "object", "required": ["concept", "kind", "type_name", "attributes", "attribute_dtypes"], "title": "HeaderEntry"}, "MITM": {"type": "string", "enum": ["MAED", "OCEL2"], "title": "MITM"}, "MITMDataType": {"type": "string", "enum": ["text", "json", "integer", "numeric", "boolean", "datetime", "unknown", "infer"], "title": "MITMDataType"}, "MetadataType": {"type": "string", "enum": ["Database", "SqlaTable", "Slice", "Chart", "Dashboard", "Asset", "MitMDataset"], "title": "MetadataType"}, "NativeFilterConfig": {"properties": {"id": {"type": "string", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "targets": {"items": {"anyOf": [{"$ref": "#/components/schemas/DatasetReference"}, {"$ref": "#/components/schemas/ColumnOfDataset"}]}, "type": "array", "title": "Targets"}, "controlValues": {"$ref": "#/components/schemas/ControlValues"}, "filterType": {"$ref": "#/components/schemas/FilterType", "default": "filter_select"}, "type": {"type": "string", "title": "Type", "default": "NATIVE_FILTER"}}, "type": "object", "required": ["id", "name"], "title": "NativeFilterConfig"}, "QueryContext": {"properties": {"datasource": {"$ref": "#/components/schemas/DatasourceIdentifier"}, "queries": {"items": {"$ref": "#/components/schemas/QueryObject"}, "type": "array", "title": "Queries"}, "form_data": {"anyOf": [{"$ref": "#/components/schemas/FormData"}, {"type": "null"}]}, "result_type": {"$ref": "#/components/schemas/ChartDataResultType", "default": "full"}, "result_format": {"$ref": "#/components/schemas/ChartDataResultFormat", "default": "json"}, "force": {"type": "boolean", "title": "Force", "default": false}, "custom_cache_timeout": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Custom Cache Timeout"}}, "type": "object", "required": ["datasource"], "title": "QueryContext"}, "QueryObject": {"properties": {"annotation_layers": {"items": {"$ref": "#/components/schemas/AnnotationLayer"}, "type": "array", "title": "Annotation Layers"}, "applied_time_extras": {"additionalProperties": {"type": "string"}, "type": "object", "title": "Applied Time Extras"}, "columns": {"items": {"anyOf": [{"type": "string"}, {"$ref": "#/components/schemas/SupersetAdhocColumn"}]}, "type": "array", "title": "Columns"}, "datasource": {"anyOf": [{"$ref": "#/components/schemas/DatasourceIdentifier"}, {"type": "null"}]}, "extras": {"$ref": "#/components/schemas/QueryObjectExtras"}, "filters": {"items": {"$ref": "#/components/schemas/QueryObjectFilterClause"}, "type": "array", "title": "Filters"}, "metrics": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetAdhocMetric"}, "type": "array"}, {"type": "null"}], "title": "Metrics"}, "granularity": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Granularity"}, "from_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "From Dttm"}, "to_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "To Dttm"}, "inner_from_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "Inner From Dttm"}, "inner_to_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "Inner To Dttm"}, "is_rowcount": {"type": "boolean", "title": "Is Rowcount", "default": false}, "is_timeseries": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Timeseries"}, "order_desc": {"type": "boolean", "title": "Order Desc", "default": true}, "orderby": {"items": {"prefixItems": [{"anyOf": [{"$ref": "#/components/schemas/SupersetAdhocMetric"}, {"type": "string"}]}, {"type": "boolean"}], "type": "array", "maxItems": 2, "minItems": 2}, "type": "array", "title": "Orderby"}, "post_processing": {"items": {"anyOf": [{"$ref": "#/components/schemas/SupersetPostProcessing"}, {"type": "object"}]}, "type": "array", "title": "Post Processing"}, "result_type": {"anyOf": [{"$ref": "#/components/schemas/ChartDataResultType"}, {"type": "null"}]}, "row_limit": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Row Limit"}, "row_offset": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Row Offset"}, "series_columns": {"items": {"type": "string"}, "type": "array", "title": "Series Columns"}, "series_limit": {"type": "integer", "title": "Series Limit", "default": 0}, "series_limit_metric": {"anyOf": [{"$ref": "#/components/schemas/SupersetAdhocMetric"}, {"type": "null"}]}, "time_offsets": {"items": {"type": "string"}, "type": "array", "title": "Time Offsets"}, "time_shift": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Time Shift"}, "time_range": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Time Range"}, "url_params": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"type": "null"}], "title": "Url Params"}}, "type": "object", "title": "QueryObject"}, "QueryObjectExtras": {"properties": {"having": {"type": "string", "title": "Having", "default": ""}, "where": {"type": "string", "title": "Where", "default": ""}, "time_grain_sqla": {"anyOf": [{"$ref": "#/components/schemas/TimeGrain"}, {"type": "null"}]}}, "type": "object", "title": "QueryObjectExtras"}, "QueryObjectFilterClause": {"properties": {"col": {"type": "string", "title": "Col"}, "op": {"$ref": "#/components/schemas/FilterOperator"}, "val": {"anyOf": [{"type": "boolean"}, {"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "number"}, {"type": "integer"}, {"type": "string"}, {"items": {"anyOf": [{"type": "boolean"}, {"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "number"}, {"type": "integer"}, {"type": "string"}]}, "type": "array"}, {"prefixItems": [{"anyOf": [{"type": "boolean"}, {"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "number"}, {"type": "integer"}, {"type": "string"}]}], "type": "array", "maxItems": 1, "minItems": 1}, {"type": "null"}], "title": "Val"}, "grain": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Grain"}, "isExtra": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Isextra"}}, "type": "object", "required": ["col", "op"], "title": "QueryObjectFilterClause"}, "RegisterExternalMitMDatasetRequest": {"properties": {"dataset_name": {"type": "string", "title": "Dataset Name"}, "sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri"}, "mitm": {"$ref": "#/components/schemas/MITM"}, "cvvs": {"items": {"$ref": "#/components/schemas/CompiledVirtualView"}, "type": "array", "title": "Cvvs"}, "mappings": {"items": {"$ref": "#/components/schemas/ConceptMapping"}, "type": "array", "title": "Mappings"}}, "type": "object", "required": ["dataset_name", "sql_alchemy_uri", "mitm", "cvvs", "mappings"], "title": "RegisterExternalMitMDatasetRequest"}, "RegisterMitMResponse": {"properties": {"status": {"type": "string", "enum": ["success", "failure"], "title": "Status"}, "tracked_mitm_dataset": {"anyOf": [{"$ref": "#/components/schemas/TrackedMitMDataset"}, {"type": "null"}]}, "msg": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Msg"}}, "type": "object", "required": ["status"], "title": "RegisterMitMResponse"}, "RelatedDashboard": {"properties": {"dashboard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Dashboard Id"}, "dashboard_uuid": {"type": "string", "format": "uuid", "title": "Dashboard Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}}, "type": "object", "required": ["dashboard_uuid"], "title": "RelatedDashboard"}, "RelatedSlice": {"properties": {"slice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Slice Id"}, "slice_uuid": {"type": "string", "format": "uuid", "title": "Slice Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}}, "type": "object", "required": ["slice_uuid"], "title": "RelatedSlice"}, "RelatedTable": {"properties": {"table_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Table Id"}, "table_uuid": {"type": "string", "format": "uuid", "title": "Table Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}}, "type": "object", "required": ["table_uuid"], "title": "RelatedTable"}, "SourceDBType": {"type": "string", "enum": ["original", "working", "virtual"], "title": "SourceDBType"}, "SupersetAdhocColumn": {"properties": {"label": {"type": "string", "title": "Label"}, "sqlExpression": {"type": "string", "title": "Sqlexpression"}, "columnType": {"type": "string", "title": "Columntype", "default": "BASE_AXIS"}, "expressionType": {"type": "string", "title": "Expressiontype", "default": "SQL"}, "timeGrain": {"anyOf": [{"$ref": "#/components/schemas/TimeGrain"}, {"type": "null"}]}}, "type": "object", "required": ["label", "sqlExpression"], "title": "SupersetAdhocColumn"}, "SupersetAdhocFilter": {"properties": {"clause": {"type": "string", "title": "Clause", "default": "WHERE"}, "subject": {"type": "string", "title": "Subject"}, "operator": {"$ref": "#/components/schemas/FilterOperator"}, "operatorId": {"anyOf": [{"$ref": "#/components/schemas/FilterStringOperators"}, {"type": "null"}]}, "comparator": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comparator", "default": "No filter"}, "expressionType": {"$ref": "#/components/schemas/ExpressionType", "default": "SIMPLE"}, "isExtra": {"type": "boolean", "title": "Isextra", "default": false}, "isNew": {"type": "boolean", "title": "Isnew", "default": false}, "sqlExpression": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sqlexpression"}}, "type": "object", "required": ["subject", "operator"], "title": "SupersetAdhocFilter"}, "SupersetAdhocMetric": {"properties": {"label": {"type": "string", "title": "Label"}, "column": {"$ref": "#/components/schemas/SupersetColumn"}, "expressionType": {"$ref": "#/components/schemas/ExpressionType", "default": "SIMPLE"}, "aggregate": {"$ref": "#/components/schemas/SupersetAggregate", "default": "COUNT"}, "sqlExpression": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sqlexpression"}, "datasourceWarning": {"type": "boolean", "title": "Datasourcewarning", "default": false}, "hasCustomLabel": {"type": "boolean", "title": "Hascustomlabel", "default": false}, "optionName": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Optionname"}}, "type": "object", "required": ["label", "column"], "title": "SupersetAdhocMetric"}, "SupersetAggregate": {"type": "string", "enum": ["COUNT", "SUM", "MIN", "MAX", "AVG"], "title": "SupersetAggregate"}, "SupersetAssetsImport": {"properties": {"databases": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDatabaseDef"}, "type": "array"}, {"type": "null"}], "title": "Databases"}, "datasets": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDatasetDef"}, "type": "array"}, {"type": "null"}], "title": "Datasets"}, "charts": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetChartDef"}, "type": "array"}, {"type": "null"}], "title": "Charts"}, "dashboards": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDashboardDef"}, "type": "array"}, {"type": "null"}], "title": "Dashboards"}, "metadata": {"$ref": "#/components/schemas/SupersetMetadataDef"}}, "type": "object", "title": "SupersetAssetsImport"}, "SupersetChartDef": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "slice_name": {"type": "string", "title": "Slice Name"}, "viz_type": {"$ref": "#/components/schemas/SupersetVizType"}, "dataset_uuid": {"type": "string", "format": "uuid", "title": "Dataset Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "certified_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certified By"}, "certification_details": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certification Details"}, "params": {"anyOf": [{"$ref": "#/components/schemas/ChartParams"}, {"type": "null"}]}, "query_context": {"anyOf": [{"$ref": "#/components/schemas/QueryContext"}, {"type": "null"}]}, "cache_timeout": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Cache Timeout"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}, "is_managed_externally": {"type": "boolean", "title": "Is Managed Externally", "default": false}, "external_url": {"anyOf": [{"type": "string", "minLength": 1, "format": "uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "External Url"}}, "type": "object", "required": ["uuid", "slice_name", "viz_type", "dataset_uuid"], "title": "SupersetChartDef"}, "SupersetColumn": {"properties": {"column_name": {"type": "string", "title": "Column Name"}, "verbose_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Verbose Name"}, "id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "is_dttm": {"type": "boolean", "title": "Is Dttm", "default": false}, "is_active": {"type": "boolean", "title": "Is Active", "default": true}, "type": {"type": "string", "title": "Type", "default": "VARCHAR"}, "type_generic": {"$ref": "#/components/schemas/GenericDataType", "default": 1}, "advanced_data_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Advanced Data Type"}, "groupby": {"type": "boolean", "title": "Groupby", "default": true}, "filterable": {"type": "boolean", "title": "Filterable", "default": true}, "expression": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Expression"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "python_date_format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Python Date Format"}, "extra": {"type": "object", "title": "Extra"}}, "type": "object", "required": ["column_name"], "title": "SupersetColumn"}, "SupersetDBConnectionInfo": {"properties": {"sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, "explicit_db_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Explicit Db Name"}, "schema_name": {"type": "string", "title": "Schema Name", "default": "main"}}, "type": "object", "required": ["sql_alchemy_uri"], "title": "SupersetDBConnectionInfo"}, "SupersetDashboardDef": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "dashboard_title": {"type": "string", "title": "Dashboard Title"}, "position": {"additionalProperties": {"anyOf": [{"type": "string"}, {"$ref": "#/components/schemas/DashboardComponent"}]}, "type": "object", "title": "Position"}, "metadata": {"$ref": "#/components/schemas/DashboardMetadata"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "css": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Css"}, "slug": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Slug"}, "is_managed_externally": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Managed Externally", "default": false}, "external_url": {"anyOf": [{"type": "string", "minLength": 1, "format": "uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "External Url"}, "certified_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certified By"}, "certification_details": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certification Details"}, "published": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Published", "default": false}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}}, "type": "object", "required": ["uuid", "dashboard_title", "position", "metadata"], "title": "SupersetDashboardDef"}, "SupersetDatabaseDef": {"properties": {"database_name": {"type": "string", "title": "Database Name"}, "sqlalchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sqlalchemy Uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "cache_timeout": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cache Timeout"}, "expose_in_sqllab": {"type": "boolean", "title": "Expose In Sqllab", "default": true}, "allow_run_async": {"type": "boolean", "title": "Allow Run Async", "default": false}, "allow_ctas": {"type": "boolean", "title": "Allow Ctas", "default": false}, "allow_cvas": {"type": "boolean", "title": "Allow Cvas", "default": false}, "allow_dml": {"type": "boolean", "title": "Allow Dml", "default": false}, "allow_file_upload": {"type": "boolean", "title": "Allow File Upload", "default": false}, "extra": {"type": "object", "title": "Extra"}, "impersonate_user": {"type": "boolean", "title": "Impersonate User", "default": false}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}, "ssh_tunnel": {"type": "null", "title": "Ssh Tunnel"}}, "type": "object", "required": ["database_name", "sqlalchemy_uri", "uuid"], "title": "SupersetDatabaseDef"}, "SupersetDatasetDef": {"properties": {"table_name": {"type": "string", "title": "Table Name"}, "schema": {"type": "string", "title": "Schema"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "database_uuid": {"type": "string", "format": "uuid", "title": "Database Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "main_dttm_col": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Main Dttm Col"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "default_endpoint": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Default Endpoint"}, "offset": {"type": "integer", "title": "Offset", "default": 0}, "cache_timeout": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cache Timeout"}, "catalog": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Catalog"}, "sql": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sql"}, "params": {"title": "Params"}, "template_params": {"title": "Template Params"}, "filter_select_enabled": {"type": "boolean", "title": "Filter Select Enabled", "default": true}, "fetch_values_predicate": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Fetch Values Predicate"}, "extra": {"type": "object", "title": "Extra"}, "normalize_columns": {"type": "boolean", "title": "Normalize Columns", "default": false}, "always_filter_main_dttm": {"type": "boolean", "title": "Always Filter Main Dttm", "default": false}, "metrics": {"items": {"$ref": "#/components/schemas/SupersetMetric"}, "type": "array", "title": "Metrics"}, "columns": {"items": {"$ref": "#/components/schemas/SupersetColumn"}, "type": "array", "title": "Columns"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}}, "type": "object", "required": ["table_name", "schema", "uuid", "database_uuid"], "title": "SupersetDatasetDef"}, "SupersetDatasourceBundle": {"properties": {"database": {"$ref": "#/components/schemas/SupersetDatabaseDef"}, "datasets": {"items": {"$ref": "#/components/schemas/SupersetDatasetDef"}, "type": "array", "title": "Datasets"}}, "type": "object", "required": ["database"], "title": "SupersetDatasourceBundle"}, "SupersetMetadataDef": {"properties": {"type": {"$ref": "#/components/schemas/MetadataType"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}, "timestamp": {"type": "string", "format": "date-time", "title": "Timestamp", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}}, "type": "object", "required": ["type"], "title": "SupersetMetadataDef"}, "SupersetMetric": {"properties": {"metric_name": {"type": "string", "title": "Metric Name"}, "verbose_name": {"type": "string", "title": "Verbose Name"}, "expression": {"type": "string", "title": "Expression"}, "metric_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Metric Type"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "d3format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "D3Format"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Currency"}, "extra": {"type": "object", "title": "Extra"}, "warning_text": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Warning Text"}}, "type": "object", "required": ["metric_name", "verbose_name", "expression"], "title": "SupersetMetric"}, "SupersetMitMDatasetBundle": {"properties": {"mitm_dataset": {"$ref": "#/components/schemas/SupersetMitMDatasetDef"}, "datasource_bundle": {"$ref": "#/components/schemas/SupersetDatasourceBundle"}, "visualization_bundle": {"$ref": "#/components/schemas/SupersetVisualizationBundle"}}, "type": "object", "required": ["mitm_dataset", "datasource_bundle"], "title": "SupersetMitMDatasetBundle"}, "SupersetMitMDatasetDef": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "mitm": {"$ref": "#/components/schemas/MITM"}, "mitm_header": {"anyOf": [{"$ref": "#/components/schemas/Header-Output"}, {"type": "null"}]}, "database_uuid": {"type": "string", "format": "uuid", "title": "Database Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "tables": {"anyOf": [{"items": {"$ref": "#/components/schemas/RelatedTable"}, "type": "array"}, {"type": "null"}], "title": "Tables"}, "slices": {"anyOf": [{"items": {"$ref": "#/components/schemas/RelatedSlice"}, "type": "array"}, {"type": "null"}], "title": "Slices"}, "dashboards": {"anyOf": [{"items": {"$ref": "#/components/schemas/RelatedDashboard"}, "type": "array"}, {"type": "null"}], "title": "Dashboards"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}}, "type": "object", "required": ["uuid", "dataset_name", "mitm", "database_uuid"], "title": "SupersetMitMDatasetDef"}, "SupersetMitMDatasetImport": {"properties": {"mitm_datasets": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetMitMDatasetDef"}, "type": "array"}, {"type": "null"}], "title": "Mitm Datasets"}, "base_assets": {"anyOf": [{"$ref": "#/components/schemas/SupersetAssetsImport"}, {"type": "null"}]}, "metadata": {"$ref": "#/components/schemas/SupersetMetadataDef"}}, "type": "object", "required": ["mitm_datasets", "base_assets"], "title": "SupersetMitMDatasetImport"}, "SupersetPostProcessing": {"properties": {"operation": {"type": "string", "title": "Operation", "readOnly": true}}, "type": "object", "required": ["operation"], "title": "SupersetPostProcessing"}, "SupersetVisualizationBundle": {"properties": {"charts": {"items": {"$ref": "#/components/schemas/SupersetChartDef"}, "type": "array", "title": "Charts"}, "dashboards": {"items": {"$ref": "#/components/schemas/SupersetDashboardDef"}, "type": "array", "title": "Dashboards"}}, "type": "object", "title": "SupersetVisualizationBundle"}, "SupersetVizType": {"type": "string", "enum": ["pie", "echarts_timeseries_bar", "echarts_timeseries_line"], "title": "SupersetVizType"}, "TableIdentifier": {"properties": {"source": {"$ref": "#/components/schemas/SourceDBType", "default": "original"}, "schema": {"type": "string", "title": "Schema", "default": "main"}, "name": {"type": "string", "title": "Name"}}, "type": "object", "required": ["name"], "title": "TableIdentifier"}, "TimeGrain": {"type": "string", "enum": ["PT1S", "PT5S", "PT30S", "PT1M", "PT5M", "PT10M", "PT15M", "PT30M", "PT0.5H", "PT1H", "PT6H", "P1D", "P1W", "1969-12-28T00:00:00Z/P1W", "1969-12-29T00:00:00Z/P1W", "P1W/1970-01-03T00:00:00Z", "P1W/1970-01-04T00:00:00Z", "P1M", "P3M", "P0.25Y", "P1Y"], "title": "TimeGrain"}, "TrackedMitMDataset": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid"}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "schema_name": {"type": "string", "title": "Schema Name"}, "is_local": {"type": "boolean", "title": "Is Local", "default": true}, "sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri"}, "mitm_header": {"$ref": "#/components/schemas/Header-Output"}}, "type": "object", "required": ["dataset_name", "schema_name", "sql_alchemy_uri", "mitm_header"], "title": "TrackedMitMDataset"}, "UploadMitMResponse": {"properties": {"status": {"type": "string", "enum": ["success", "failure"], "title": "Status"}, "tracked_mitm_dataset": {"anyOf": [{"$ref": "#/components/schemas/TrackedMitMDataset"}, {"type": "null"}]}, "msg": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Msg"}}, "type": "object", "required": ["status"], "title": "UploadMitMResponse"}, "ValidationError": {"properties": {"loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "type": "array", "title": "Location"}, "msg": {"type": "string", "title": "Message"}, "type": {"type": "string", "title": "Error Type"}}, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError"}, "WrappedMITMDataType": {"properties": {"mitm": {"$ref": "#/components/schemas/MITMDataType"}}, "type": "object", "required": ["mitm"], "title": "WrappedMITMDataType"}}}} \ No newline at end of file +{"openapi": "3.1.0", "info": {"title": "SupersetMitMService", "version": "0.1.0"}, "paths": {"/mitm_dataset/upload": {"post": {"tags": ["mitm_dataset"], "summary": "Upload Mitm Dataset", "operationId": "upload_mitm_dataset", "parameters": [{"name": "dataset_name", "in": "query", "required": true, "schema": {"type": "string", "title": "Dataset Name"}}, {"name": "mitm", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/MITM", "default": "MAED"}}], "requestBody": {"required": true, "content": {"multipart/form-data": {"schema": {"$ref": "#/components/schemas/Body_upload_mitm_dataset_mitm_dataset_upload_post"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UploadMitMResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/register": {"post": {"tags": ["mitm_dataset"], "summary": "Register Mitm Dataset", "operationId": "register_mitm_dataset", "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegisterExternalMitMDatasetRequest"}}}, "required": true}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegisterMitMResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/": {"get": {"tags": ["mitm_dataset"], "summary": "Get Mitm Datasets", "operationId": "get_mitm_datasets", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ListTrackedMitMDataset"}, "type": "array", "title": "Response Get Mitm Datasets Mitm Dataset Get"}}}}}}, "post": {"tags": ["mitm_dataset"], "summary": "Post Mitm Dataset", "operationId": "post_mitm_dataset", "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddTrackedMitMDatasetRequest"}}}, "required": true}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TrackedMitMDataset"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/{uuid}": {"get": {"tags": ["mitm_dataset"], "summary": "Get Mitm Dataset", "operationId": "get_mitm_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TrackedMitMDataset"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["mitm_dataset"], "summary": "Delete Mitm Dataset", "operationId": "delete_mitm_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/mitm_dataset/export/{uuid}": {"post": {"tags": ["mitm_dataset"], "summary": "Export Mitm Dataset", "operationId": "export_mitm_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/zip": {}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset": {"post": {"tags": ["definitions"], "summary": "Generate Mitm Dataset Bundle", "operationId": "generate_mitm_dataset_bundle", "parameters": [{"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateIndependentMitMDatasetDefinitionRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MitMDatasetBundleResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/import": {"post": {"tags": ["definitions"], "summary": "Generate Mitm Dataset Import", "operationId": "generate_mitm_dataset_import", "parameters": [{"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}, {"name": "override_metadata_type", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/MetadataType"}, {"type": "null"}], "title": "Override Metadata Type"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateIndependentMitMDatasetDefinitionRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MitMDatasetImportResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/import/zip": {"post": {"tags": ["definitions"], "summary": "Generate Mitm Dataset Import Zip", "operationId": "generate_mitm_dataset_import_zip", "parameters": [{"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}, {"name": "override_metadata_type", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/MetadataType"}, {"type": "null"}], "title": "Override Metadata Type"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateIndependentMitMDatasetDefinitionRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/zip": {}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/{uuid}": {"get": {"tags": ["definitions"], "summary": "Generate Tracked Mitm Dataset Bundle", "operationId": "generate_tracked_mitm_dataset_bundle", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MitMDatasetBundleResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/{uuid}/import": {"get": {"tags": ["definitions"], "summary": "Generate Tracked Mitm Dataset Import", "operationId": "generate_tracked_mitm_dataset_import", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}, {"name": "override_metadata_type", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/MetadataType"}, {"type": "null"}], "title": "Override Metadata Type"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MitMDatasetImportResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/{uuid}/import/zip": {"get": {"tags": ["definitions"], "summary": "Generate Tracked Mitm Dataset Import Zip", "operationId": "generate_tracked_mitm_dataset_import_zip", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "include_visualizations", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "Include Visualizations"}}, {"name": "override_metadata_type", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/MetadataType"}, {"type": "null"}], "title": "Override Metadata Type"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/zip": {}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/viz/{uuid}": {"post": {"tags": ["definitions"], "summary": "Generate Visualizations For Tracked Dataset", "operationId": "generate_visualizations_for_tracked_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateVisualizationsRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MitMDatasetBundleResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/viz/{uuid}/import": {"post": {"tags": ["definitions"], "summary": "Generate Visualizations Import For Tracked Dataset", "operationId": "generate_visualizations_import_for_tracked_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "as_assets", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "As Assets"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateVisualizationsRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VisualizationImportResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/definitions/mitm_dataset/viz/{uuid}/import/zip": {"post": {"tags": ["definitions"], "summary": "Generate Visualizations Import Zip For Tracked Dataset", "operationId": "generate_visualizations_import_zip_for_tracked_dataset", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}, {"name": "as_assets", "in": "query", "required": false, "schema": {"type": "boolean", "default": false, "title": "As Assets"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateVisualizationsRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/zip": {}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/data/db-meta/{uuid}": {"get": {"tags": ["data"], "summary": "Get Db Meta", "operationId": "get_db_meta", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DBMetaResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/data/db-probe/{uuid}": {"get": {"tags": ["data"], "summary": "Get Db Probe", "operationId": "get_db_probe", "parameters": [{"name": "uuid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Uuid"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DBProbeResponse"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/admin/clear-db": {"post": {"tags": ["admin"], "summary": "Clear Db", "description": "Clear the database.", "operationId": "clear_db", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClearDBResponse"}}}}}}}, "/": {"get": {"summary": "Root", "operationId": "root__get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}, "/health": {"get": {"summary": "Health", "operationId": "health_health_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}}, "components": {"schemas": {"AddTrackedMitMDatasetRequest": {"properties": {"uuid": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Uuid"}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "schema_name": {"type": "string", "title": "Schema Name"}, "sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri"}, "mitm_header": {"$ref": "#/components/schemas/Header-Input"}}, "type": "object", "required": ["dataset_name", "schema_name", "sql_alchemy_uri", "mitm_header"], "title": "AddTrackedMitMDatasetRequest"}, "AnnotationLayer": {"properties": {"name": {"type": "string", "title": "Name"}, "value": {"type": "integer", "title": "Value"}, "annotationType": {"$ref": "#/components/schemas/AnnotationType"}, "sourceType": {"$ref": "#/components/schemas/AnnotationSource", "default": "table"}, "opacity": {"type": "string", "title": "Opacity", "default": ""}, "overrides": {"$ref": "#/components/schemas/AnnotationOverrides"}, "hideLine": {"type": "boolean", "title": "Hideline", "default": false}, "show": {"type": "boolean", "title": "Show", "default": false}, "showLabel": {"type": "boolean", "title": "Showlabel", "default": false}, "showMarkers": {"type": "boolean", "title": "Showmarkers", "default": false}, "style": {"type": "string", "title": "Style", "default": "solid"}, "width": {"type": "integer", "title": "Width", "default": 1}}, "type": "object", "required": ["name", "value", "annotationType", "overrides"], "title": "AnnotationLayer"}, "AnnotationOverrides": {"properties": {"time_range": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Time Range"}}, "type": "object", "title": "AnnotationOverrides"}, "AnnotationSource": {"type": "string", "enum": ["line", "NATIVE", "table", ""], "title": "AnnotationSource"}, "AnnotationType": {"type": "string", "enum": ["EVENT", "FORMULA", "INTERVAL", "TIME_SERIES"], "title": "AnnotationType"}, "Body_upload_mitm_dataset_mitm_dataset_upload_post": {"properties": {"mitm_zip": {"type": "string", "format": "binary", "title": "Mitm Zip"}}, "type": "object", "required": ["mitm_zip"], "title": "Body_upload_mitm_dataset_mitm_dataset_upload_post"}, "CategoricalSummaryStatistics": {"properties": {"count": {"type": "integer", "minimum": 0.0, "title": "Count"}, "unique": {"type": "integer", "minimum": 0.0, "title": "Unique"}, "top": {"type": "string", "title": "Top"}, "freq": {"type": "integer", "minimum": 0.0, "title": "Freq"}}, "type": "object", "required": ["count", "unique", "top", "freq"], "title": "CategoricalSummaryStatistics"}, "ChartDataResultFormat": {"type": "string", "enum": ["csv", "json", "xlsx"], "title": "ChartDataResultFormat"}, "ChartDataResultType": {"type": "string", "enum": ["columns", "full", "query", "results", "samples", "timegrains", "post_processed", "drill_detail"], "title": "ChartDataResultType"}, "ChartDatasource": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "table_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Table Name"}, "type": {"type": "string", "enum": ["table", "annotation"], "title": "Type", "default": "table"}}, "type": "object", "title": "ChartDatasource"}, "ChartIdentifier": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "slice_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Slice Name"}}, "type": "object", "title": "ChartIdentifier"}, "ChartParams": {"properties": {"datasource": {"anyOf": [{"type": "string"}, {"$ref": "#/components/schemas/DatasetIdentifier"}], "title": "Datasource"}, "viz_type": {"$ref": "#/components/schemas/SupersetVizType"}, "groupby": {"items": {"type": "string"}, "type": "array", "title": "Groupby"}, "adhoc_filters": {"items": {"$ref": "#/components/schemas/SupersetAdhocFilter"}, "type": "array", "title": "Adhoc Filters"}, "row_limit": {"type": "integer", "title": "Row Limit", "default": 10000}, "sort_by_metric": {"type": "boolean", "title": "Sort By Metric", "default": true}, "color_scheme": {"type": "string", "enum": ["blueToGreen", "supersetColors"], "title": "Color Scheme", "default": "supersetColors"}, "show_legend": {"type": "boolean", "title": "Show Legend", "default": true}, "legendType": {"type": "string", "title": "Legendtype", "default": "scroll"}, "legendOrientation": {"type": "string", "title": "Legendorientation", "default": "top"}, "extra_form_data": {"additionalProperties": true, "type": "object", "title": "Extra Form Data"}, "slice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Slice Id"}, "dashboards": {"items": {"type": "integer"}, "type": "array", "title": "Dashboards"}}, "type": "object", "required": ["datasource", "viz_type"], "title": "ChartParams"}, "ClearDBResponse": {"properties": {"dropped_mitm_datasets": {"anyOf": [{"items": {"$ref": "#/components/schemas/ListTrackedMitMDataset"}, "type": "array"}, {"type": "null"}], "title": "Dropped Mitm Datasets"}, "dropped_schemas": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Dropped Schemas"}}, "type": "object", "title": "ClearDBResponse", "description": "Response model for clearing the database."}, "ColName": {"properties": {"name": {"type": "string", "title": "Name"}}, "type": "object", "required": ["name"], "title": "ColName"}, "ColumnOfDataset": {"properties": {"datasetUuid": {"type": "string", "format": "uuid", "title": "Datasetuuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "column": {"$ref": "#/components/schemas/ColName"}}, "type": "object", "required": ["datasetUuid", "column"], "title": "ColumnOfDataset"}, "ColumnProperties": {"properties": {"nullable": {"type": "boolean", "title": "Nullable"}, "unique": {"type": "boolean", "title": "Unique"}, "part_of_pk": {"type": "boolean", "title": "Part Of Pk"}, "part_of_fk": {"type": "boolean", "title": "Part Of Fk"}, "part_of_index": {"type": "boolean", "title": "Part Of Index"}, "mitm_data_type": {"$ref": "#/components/schemas/MITMDataType"}}, "type": "object", "required": ["nullable", "unique", "part_of_pk", "part_of_fk", "part_of_index", "mitm_data_type"], "title": "ColumnProperties"}, "CompiledVirtualView": {"properties": {"dialect": {"type": "string", "title": "Dialect"}, "compiled_sql": {"type": "string", "title": "Compiled Sql"}, "columns": {"items": {"type": "string"}, "type": "array", "title": "Columns"}, "column_dtypes": {"items": {"anyOf": [{"$ref": "#/components/schemas/WrappedMITMDataType"}, {"type": "string"}]}, "type": "array", "title": "Column Dtypes"}, "name": {"type": "string", "title": "Name"}, "schema_name": {"type": "string", "title": "Schema Name"}}, "type": "object", "required": ["dialect", "compiled_sql", "columns", "column_dtypes", "name", "schema_name"], "title": "CompiledVirtualView"}, "ComponentMeta": {"properties": {}, "type": "object", "title": "ComponentMeta"}, "ConceptMapping": {"properties": {"mitm": {"$ref": "#/components/schemas/MITM"}, "concept": {"type": "string", "title": "Concept"}, "base_table": {"anyOf": [{"$ref": "#/components/schemas/TableIdentifier"}, {"prefixItems": [{"$ref": "#/components/schemas/SourceDBType"}, {"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 3, "minItems": 3}, {"prefixItems": [{"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 2, "minItems": 2}], "title": "Base Table"}, "kind_col": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Kind Col"}, "type_col": {"type": "string", "title": "Type Col"}, "identity_columns": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"items": {"type": "string"}, "type": "array"}], "title": "Identity Columns"}, "inline_relations": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"items": {"type": "string"}, "type": "array"}], "title": "Inline Relations"}, "foreign_relations": {"additionalProperties": {"$ref": "#/components/schemas/ForeignRelation"}, "type": "object", "title": "Foreign Relations"}, "attributes": {"items": {"type": "string"}, "type": "array", "title": "Attributes"}, "attribute_dtypes": {"items": {"$ref": "#/components/schemas/MITMDataType"}, "type": "array", "title": "Attribute Dtypes"}}, "type": "object", "required": ["mitm", "concept", "base_table", "type_col"], "title": "ConceptMapping"}, "ControlValues": {"properties": {"enableEmptyFilter": {"type": "boolean", "title": "Enableemptyfilter", "default": false}, "defaultToFirstItem": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Defaulttofirstitem", "default": false}, "multiSelect": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Multiselect", "default": true}, "searchAllOptions": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Searchalloptions", "default": false}, "inverseSelection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Inverseselection", "default": false}}, "type": "object", "title": "ControlValues"}, "DBConnectionInfo": {"properties": {"sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, "explicit_db_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Explicit Db Name"}, "schema_name": {"type": "string", "title": "Schema Name", "default": "main"}, "catalog": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Catalog"}}, "type": "object", "required": ["sql_alchemy_uri"], "title": "DBConnectionInfo"}, "DBMetaInfoBase": {"properties": {"db_structure": {"additionalProperties": {"additionalProperties": {"$ref": "#/components/schemas/TableMetaInfoBase"}, "type": "object"}, "type": "object", "title": "Db Structure"}, "tables": {"additionalProperties": {"$ref": "#/components/schemas/TableMetaInfoBase"}, "type": "object", "title": "Tables", "readOnly": true}}, "type": "object", "required": ["db_structure", "tables"], "title": "DBMetaInfoBase"}, "DBMetaResponse": {"properties": {"db_meta": {"anyOf": [{"$ref": "#/components/schemas/DBMetaInfoBase"}, {"type": "null"}]}}, "type": "object", "title": "DBMetaResponse"}, "DBProbeMinimal": {"properties": {"table_probes": {"additionalProperties": {"$ref": "#/components/schemas/TableProbeMinimal"}, "type": "object", "title": "Table Probes"}}, "type": "object", "title": "DBProbeMinimal"}, "DBProbeResponse": {"properties": {"db_probe": {"anyOf": [{"$ref": "#/components/schemas/DBProbeMinimal"}, {"type": "null"}]}}, "type": "object", "title": "DBProbeResponse"}, "DashboardComponent": {"properties": {"id": {"type": "string", "title": "Id"}, "type": {"$ref": "#/components/schemas/DashboardComponentType"}, "meta": {"anyOf": [{"$ref": "#/components/schemas/ComponentMeta"}, {"type": "null"}]}, "children": {"items": {"type": "string"}, "type": "array", "title": "Children"}}, "type": "object", "required": ["id", "type"], "title": "DashboardComponent"}, "DashboardComponentType": {"type": "string", "enum": ["CHART", "HEADER", "GRID", "ROW", "ROOT"], "title": "DashboardComponentType"}, "DashboardIdentifier": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "dashboard_title": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Dashboard Title"}}, "type": "object", "title": "DashboardIdentifier"}, "DashboardMetadata": {"properties": {"color_scheme": {"type": "string", "title": "Color Scheme", "default": "blueToGreen"}, "cross_filters_enabled": {"type": "boolean", "title": "Cross Filters Enabled", "default": true}, "native_filter_configuration": {"items": {"$ref": "#/components/schemas/NativeFilterConfig"}, "type": "array", "title": "Native Filter Configuration"}}, "type": "object", "title": "DashboardMetadata"}, "DatabaseIdentifier": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "database_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Database Name"}}, "type": "object", "title": "DatabaseIdentifier"}, "DatasetIdentifier": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "table_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Table Name"}}, "type": "object", "title": "DatasetIdentifier"}, "DatasetReference": {"properties": {"datasetUuid": {"type": "string", "format": "uuid", "title": "Datasetuuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}}, "type": "object", "required": ["datasetUuid"], "title": "DatasetReference"}, "DatetimeSummaryStatistics": {"properties": {"count": {"type": "integer", "title": "Count"}, "mean": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Mean"}, "min": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Min"}, "max": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Max"}, "percentile_25": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Percentile 25"}, "percentile_50": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Percentile 50"}, "percentile_75": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Percentile 75"}}, "type": "object", "required": ["count"], "title": "DatetimeSummaryStatistics"}, "ExpressionType": {"type": "string", "enum": ["SIMPLE", "SQL"], "title": "ExpressionType"}, "FilterOperator": {"type": "string", "enum": ["==", "!=", ">", "<", ">=", "<=", "LIKE", "NOT LIKE", "ILIKE", "IS NULL", "IS NOT NULL", "IN", "NOT IN", "IS TRUE", "IS FALSE", "TEMPORAL_RANGE"], "title": "FilterOperator"}, "FilterStringOperators": {"type": "string", "enum": ["EQUALS", "NOT_EQUALS", "LESS_THAN", "GREATER_THAN", "LESS_THAN_OR_EQUAL", "GREATER_THAN_OR_EQUAL", "IN", "NOT_IN", "ILIKE", "LIKE", "IS_NOT_NULL", "IS_NULL", "LATEST_PARTITION", "IS_TRUE", "IS_FALSE"], "title": "FilterStringOperators"}, "FilterType": {"type": "string", "enum": ["filter_select", "filter_timegrain"], "title": "FilterType"}, "ForeignKeyConstraintBase": {"properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "table": {"anyOf": [{"$ref": "#/components/schemas/LocalTableIdentifier"}, {"prefixItems": [{"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 2, "minItems": 2}], "title": "Table"}, "columns": {"items": {"type": "string"}, "type": "array", "title": "Columns"}, "target_table": {"anyOf": [{"$ref": "#/components/schemas/LocalTableIdentifier"}, {"prefixItems": [{"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 2, "minItems": 2}], "title": "Target Table"}, "target_columns": {"items": {"type": "string"}, "type": "array", "title": "Target Columns"}}, "type": "object", "required": ["table", "columns", "target_table", "target_columns"], "title": "ForeignKeyConstraintBase"}, "ForeignRelation": {"properties": {"fk_columns": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"items": {"type": "string"}, "type": "array"}], "title": "Fk Columns"}, "referred_table": {"anyOf": [{"$ref": "#/components/schemas/TableIdentifier"}, {"prefixItems": [{"$ref": "#/components/schemas/SourceDBType"}, {"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 3, "minItems": 3}, {"prefixItems": [{"type": "string"}, {"type": "string"}], "type": "array", "maxItems": 2, "minItems": 2}], "title": "Referred Table"}}, "type": "object", "required": ["fk_columns", "referred_table"], "title": "ForeignRelation"}, "FormData": {"properties": {}, "type": "object", "title": "FormData"}, "GenerateIndependentMitMDatasetDefinitionRequest": {"properties": {"dataset_name": {"type": "string", "title": "Dataset Name"}, "mitm_header": {"$ref": "#/components/schemas/Header-Input"}, "db_conn_info": {"$ref": "#/components/schemas/DBConnectionInfo"}, "identifiers": {"anyOf": [{"$ref": "#/components/schemas/MitMDatasetIdentifierBundle"}, {"type": "null"}]}}, "type": "object", "required": ["dataset_name", "mitm_header", "db_conn_info"], "title": "GenerateIndependentMitMDatasetDefinitionRequest"}, "GenerateVisualizationsRequest": {"properties": {"visualization_types": {"items": {"anyOf": [{"$ref": "#/components/schemas/MAEDVisualizationType"}, {"type": "null"}]}, "type": "array", "title": "Visualization Types", "default": ["baseline"]}, "reuse_existing_identifiers": {"type": "boolean", "title": "Reuse Existing Identifiers", "default": true}, "track_identifiers": {"type": "boolean", "title": "Track Identifiers", "default": false}}, "type": "object", "title": "GenerateVisualizationsRequest"}, "HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "type": "array", "title": "Detail"}}, "type": "object", "title": "HTTPValidationError"}, "Header-Input": {"properties": {"mitm": {"$ref": "#/components/schemas/MITM"}, "header_entries": {"items": {"$ref": "#/components/schemas/HeaderEntry"}, "type": "array", "title": "Header Entries"}}, "type": "object", "required": ["mitm"], "title": "Header"}, "Header-Output": {"properties": {"mitm": {"$ref": "#/components/schemas/MITM"}, "header_entries": {"items": {"$ref": "#/components/schemas/HeaderEntry"}, "type": "array", "title": "Header Entries"}}, "type": "object", "required": ["mitm"], "title": "Header"}, "HeaderEntry": {"properties": {"concept": {"type": "string", "title": "Concept"}, "kind": {"type": "string", "title": "Kind"}, "type_name": {"type": "string", "title": "Type Name"}, "attributes": {"items": {"type": "string"}, "type": "array", "title": "Attributes"}, "attribute_dtypes": {"items": {"$ref": "#/components/schemas/MITMDataType"}, "type": "array", "title": "Attribute Dtypes"}}, "type": "object", "required": ["concept", "kind", "type_name", "attributes", "attribute_dtypes"], "title": "HeaderEntry"}, "ListTrackedMitMDataset": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid"}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "mitm": {"$ref": "#/components/schemas/MITM"}}, "type": "object", "required": ["uuid", "dataset_name", "mitm"], "title": "ListTrackedMitMDataset"}, "LocalTableIdentifier": {"properties": {"name": {"type": "string", "title": "Name"}, "schema": {"type": "string", "title": "Schema", "default": "main"}}, "type": "object", "required": ["name"], "title": "LocalTableIdentifier"}, "MAEDVisualizationType": {"type": "string", "enum": ["baseline", "experimental"], "title": "MAEDVisualizationType"}, "MITM": {"type": "string", "enum": ["MAED", "OCEL2"], "title": "MITM"}, "MITMDataType": {"type": "string", "enum": ["text", "json", "integer", "numeric", "boolean", "datetime", "unknown", "infer"], "title": "MITMDataType"}, "MetadataType": {"type": "string", "enum": ["Database", "SqlaTable", "Slice", "Chart", "Dashboard", "Asset", "MitMDataset"], "title": "MetadataType"}, "MitMDatasetBundleResponse": {"properties": {"mitm_dataset": {"$ref": "#/components/schemas/SupersetMitMDatasetDef"}, "datasource_bundle": {"$ref": "#/components/schemas/SupersetDatasourceBundle"}, "visualization_bundle": {"$ref": "#/components/schemas/SupersetVisualizationBundle"}}, "type": "object", "required": ["mitm_dataset", "datasource_bundle"], "title": "MitMDatasetBundleResponse"}, "MitMDatasetIdentifier": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "dataset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Dataset Name"}}, "type": "object", "title": "MitMDatasetIdentifier"}, "MitMDatasetIdentifierBundle": {"properties": {"database": {"anyOf": [{"$ref": "#/components/schemas/DatabaseIdentifier"}, {"type": "null"}]}, "ds_id_map": {"additionalProperties": {"$ref": "#/components/schemas/DatasetIdentifier"}, "type": "object", "title": "Ds Id Map"}, "mitm_dataset": {"anyOf": [{"$ref": "#/components/schemas/MitMDatasetIdentifier"}, {"type": "null"}]}, "viz_id_map": {"additionalProperties": {"additionalProperties": {"$ref": "#/components/schemas/DashboardIdentifier"}, "type": "object"}, "type": "object", "title": "Viz Id Map"}}, "type": "object", "title": "MitMDatasetIdentifierBundle"}, "MitMDatasetImportResponse": {"properties": {"mitm_datasets": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetMitMDatasetDef"}, "type": "array"}, {"type": "null"}], "title": "Mitm Datasets"}, "base_assets": {"anyOf": [{"$ref": "#/components/schemas/SupersetAssetsImport"}, {"type": "null"}]}, "metadata": {"$ref": "#/components/schemas/SupersetMetadataDef"}}, "type": "object", "required": ["mitm_datasets", "base_assets"], "title": "MitMDatasetImportResponse"}, "NativeFilterConfig": {"properties": {"id": {"type": "string", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "targets": {"items": {"anyOf": [{"$ref": "#/components/schemas/DatasetReference"}, {"$ref": "#/components/schemas/ColumnOfDataset"}]}, "type": "array", "title": "Targets"}, "controlValues": {"$ref": "#/components/schemas/ControlValues"}, "filterType": {"$ref": "#/components/schemas/FilterType", "default": "filter_select"}, "type": {"type": "string", "title": "Type", "default": "NATIVE_FILTER"}}, "type": "object", "required": ["id", "name"], "title": "NativeFilterConfig"}, "NumericSummaryStatistics": {"properties": {"count": {"type": "integer", "title": "Count"}, "mean": {"type": "number", "title": "Mean"}, "min": {"type": "number", "title": "Min"}, "max": {"type": "number", "title": "Max"}, "std": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Std"}, "percentile_25": {"type": "number", "title": "Percentile 25"}, "percentile_50": {"type": "number", "title": "Percentile 50"}, "percentile_75": {"type": "number", "title": "Percentile 75"}}, "type": "object", "required": ["count", "mean", "min", "max", "percentile_25", "percentile_50", "percentile_75"], "title": "NumericSummaryStatistics"}, "QueryContext": {"properties": {"datasource": {"$ref": "#/components/schemas/ChartDatasource"}, "queries": {"items": {"$ref": "#/components/schemas/QueryObject"}, "type": "array", "title": "Queries"}, "form_data": {"anyOf": [{"$ref": "#/components/schemas/FormData"}, {"type": "null"}]}, "result_type": {"$ref": "#/components/schemas/ChartDataResultType", "default": "full"}, "result_format": {"$ref": "#/components/schemas/ChartDataResultFormat", "default": "json"}, "force": {"type": "boolean", "title": "Force", "default": false}, "custom_cache_timeout": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Custom Cache Timeout"}}, "type": "object", "required": ["datasource"], "title": "QueryContext"}, "QueryObject": {"properties": {"annotation_layers": {"items": {"$ref": "#/components/schemas/AnnotationLayer"}, "type": "array", "title": "Annotation Layers"}, "applied_time_extras": {"additionalProperties": {"type": "string"}, "type": "object", "title": "Applied Time Extras"}, "columns": {"items": {"anyOf": [{"type": "string"}, {"$ref": "#/components/schemas/SupersetAdhocColumn"}]}, "type": "array", "title": "Columns"}, "datasource": {"anyOf": [{"$ref": "#/components/schemas/ChartDatasource"}, {"type": "null"}]}, "extras": {"$ref": "#/components/schemas/QueryObjectExtras"}, "filters": {"items": {"$ref": "#/components/schemas/QueryObjectFilterClause"}, "type": "array", "title": "Filters"}, "metrics": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetAdhocMetric"}, "type": "array"}, {"type": "null"}], "title": "Metrics"}, "granularity": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Granularity"}, "from_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "From Dttm"}, "to_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "To Dttm"}, "inner_from_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "Inner From Dttm"}, "inner_to_dttm": {"anyOf": [{"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "Inner To Dttm"}, "is_rowcount": {"type": "boolean", "title": "Is Rowcount", "default": false}, "is_timeseries": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Timeseries"}, "order_desc": {"type": "boolean", "title": "Order Desc", "default": true}, "orderby": {"items": {"prefixItems": [{"anyOf": [{"$ref": "#/components/schemas/SupersetAdhocMetric"}, {"type": "string"}]}, {"type": "boolean"}], "type": "array", "maxItems": 2, "minItems": 2}, "type": "array", "title": "Orderby"}, "post_processing": {"items": {"anyOf": [{"$ref": "#/components/schemas/SupersetPostProcessing"}, {"additionalProperties": true, "type": "object"}]}, "type": "array", "title": "Post Processing"}, "result_type": {"anyOf": [{"$ref": "#/components/schemas/ChartDataResultType"}, {"type": "null"}]}, "row_limit": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Row Limit"}, "row_offset": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Row Offset"}, "series_columns": {"items": {"type": "string"}, "type": "array", "title": "Series Columns"}, "series_limit": {"type": "integer", "title": "Series Limit", "default": 0}, "series_limit_metric": {"anyOf": [{"$ref": "#/components/schemas/SupersetAdhocMetric"}, {"type": "null"}]}, "time_offsets": {"items": {"type": "string"}, "type": "array", "title": "Time Offsets"}, "time_shift": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Time Shift"}, "time_range": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Time Range"}, "url_params": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"type": "null"}], "title": "Url Params"}}, "type": "object", "title": "QueryObject"}, "QueryObjectExtras": {"properties": {"having": {"type": "string", "title": "Having", "default": ""}, "where": {"type": "string", "title": "Where", "default": ""}, "time_grain_sqla": {"anyOf": [{"$ref": "#/components/schemas/TimeGrain"}, {"type": "null"}]}}, "type": "object", "title": "QueryObjectExtras"}, "QueryObjectFilterClause": {"properties": {"col": {"type": "string", "title": "Col"}, "op": {"$ref": "#/components/schemas/FilterOperator"}, "val": {"anyOf": [{"type": "boolean"}, {"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "number"}, {"type": "integer"}, {"type": "string"}, {"items": {"anyOf": [{"type": "boolean"}, {"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "number"}, {"type": "integer"}, {"type": "string"}]}, "type": "array"}, {"prefixItems": [{"anyOf": [{"type": "boolean"}, {"type": "string", "format": "date-time", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}, {"type": "number"}, {"type": "integer"}, {"type": "string"}]}], "type": "array", "maxItems": 1, "minItems": 1}, {"type": "null"}], "title": "Val"}, "grain": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Grain"}, "isExtra": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Isextra"}}, "type": "object", "required": ["col", "op"], "title": "QueryObjectFilterClause"}, "RegisterExternalMitMDatasetRequest": {"properties": {"dataset_name": {"type": "string", "title": "Dataset Name"}, "sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri"}, "mitm": {"$ref": "#/components/schemas/MITM"}, "cvvs": {"items": {"$ref": "#/components/schemas/CompiledVirtualView"}, "type": "array", "title": "Cvvs"}, "mappings": {"items": {"$ref": "#/components/schemas/ConceptMapping"}, "type": "array", "title": "Mappings"}}, "type": "object", "required": ["dataset_name", "sql_alchemy_uri", "mitm", "cvvs", "mappings"], "title": "RegisterExternalMitMDatasetRequest"}, "RegisterMitMResponse": {"properties": {"status": {"type": "string", "enum": ["success", "failure"], "title": "Status"}, "tracked_mitm_dataset": {"anyOf": [{"$ref": "#/components/schemas/TrackedMitMDataset"}, {"type": "null"}]}, "msg": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Msg"}}, "type": "object", "required": ["status"], "title": "RegisterMitMResponse"}, "SampleSummary": {"properties": {"sample_size": {"anyOf": [{"type": "integer", "minimum": 0.0}, {"type": "null"}], "title": "Sample Size"}, "na_fraction": {"anyOf": [{"type": "number", "maximum": 1.0, "minimum": 0.0}, {"type": "null"}], "title": "Na Fraction"}, "unique_fraction": {"anyOf": [{"type": "number", "maximum": 1.0, "minimum": 0.0}, {"type": "null"}], "title": "Unique Fraction"}, "value_counts": {"anyOf": [{"additionalProperties": {"type": "integer"}, "type": "object"}, {"type": "null"}], "title": "Value Counts"}, "summary_statistics": {"anyOf": [{"$ref": "#/components/schemas/NumericSummaryStatistics"}, {"$ref": "#/components/schemas/CategoricalSummaryStatistics"}, {"$ref": "#/components/schemas/DatetimeSummaryStatistics"}, {"type": "null"}], "title": "Summary Statistics"}, "json_schema": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Json Schema"}}, "type": "object", "title": "SampleSummary"}, "SourceDBType": {"type": "string", "enum": ["original", "working", "virtual"], "title": "SourceDBType"}, "SupersetAdhocColumn": {"properties": {"label": {"type": "string", "title": "Label"}, "sqlExpression": {"type": "string", "title": "Sqlexpression"}, "columnType": {"type": "string", "title": "Columntype", "default": "BASE_AXIS"}, "expressionType": {"type": "string", "title": "Expressiontype", "default": "SQL"}, "timeGrain": {"anyOf": [{"$ref": "#/components/schemas/TimeGrain"}, {"type": "null"}]}}, "type": "object", "required": ["label", "sqlExpression"], "title": "SupersetAdhocColumn"}, "SupersetAdhocFilter": {"properties": {"clause": {"type": "string", "title": "Clause", "default": "WHERE"}, "subject": {"type": "string", "title": "Subject"}, "operator": {"$ref": "#/components/schemas/FilterOperator"}, "operatorId": {"anyOf": [{"$ref": "#/components/schemas/FilterStringOperators"}, {"type": "null"}]}, "comparator": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comparator", "default": "No filter"}, "expressionType": {"$ref": "#/components/schemas/ExpressionType", "default": "SIMPLE"}, "isExtra": {"type": "boolean", "title": "Isextra", "default": false}, "isNew": {"type": "boolean", "title": "Isnew", "default": false}, "sqlExpression": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sqlexpression"}}, "type": "object", "required": ["subject", "operator"], "title": "SupersetAdhocFilter"}, "SupersetAdhocMetric": {"properties": {"label": {"type": "string", "title": "Label"}, "column": {"$ref": "#/components/schemas/SupersetColumn"}, "expressionType": {"$ref": "#/components/schemas/ExpressionType", "default": "SIMPLE"}, "aggregate": {"$ref": "#/components/schemas/SupersetAggregate", "default": "COUNT"}, "sqlExpression": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sqlexpression"}, "datasourceWarning": {"type": "boolean", "title": "Datasourcewarning", "default": false}, "hasCustomLabel": {"type": "boolean", "title": "Hascustomlabel", "default": false}, "optionName": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Optionname"}}, "type": "object", "required": ["label", "column"], "title": "SupersetAdhocMetric"}, "SupersetAggregate": {"type": "string", "enum": ["COUNT", "SUM", "MIN", "MAX", "AVG"], "title": "SupersetAggregate"}, "SupersetAssetsImport": {"properties": {"databases": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDatabaseDef"}, "type": "array"}, {"type": "null"}], "title": "Databases"}, "datasets": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDatasetDef"}, "type": "array"}, {"type": "null"}], "title": "Datasets"}, "charts": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetChartDef"}, "type": "array"}, {"type": "null"}], "title": "Charts"}, "dashboards": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDashboardDef"}, "type": "array"}, {"type": "null"}], "title": "Dashboards"}, "metadata": {"$ref": "#/components/schemas/SupersetMetadataDef"}}, "type": "object", "title": "SupersetAssetsImport"}, "SupersetChartDef": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "slice_name": {"type": "string", "title": "Slice Name"}, "viz_type": {"$ref": "#/components/schemas/SupersetVizType"}, "dataset_uuid": {"type": "string", "format": "uuid", "title": "Dataset Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "certified_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certified By"}, "certification_details": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certification Details"}, "params": {"anyOf": [{"$ref": "#/components/schemas/ChartParams"}, {"type": "null"}]}, "query_context": {"anyOf": [{}, {"type": "null"}]}, "cache_timeout": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Cache Timeout"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}, "is_managed_externally": {"type": "boolean", "title": "Is Managed Externally", "default": false}, "external_url": {"anyOf": [{"type": "string", "minLength": 1, "format": "uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "External Url"}}, "type": "object", "required": ["uuid", "slice_name", "viz_type", "dataset_uuid"], "title": "SupersetChartDef"}, "SupersetColumn": {"properties": {"column_name": {"type": "string", "title": "Column Name"}, "verbose_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Verbose Name"}, "id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "is_dttm": {"type": "boolean", "title": "Is Dttm", "default": false}, "is_active": {"type": "boolean", "title": "Is Active", "default": true}, "type": {"type": "string", "title": "Type", "default": "VARCHAR"}, "advanced_data_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Advanced Data Type"}, "groupby": {"type": "boolean", "title": "Groupby", "default": true}, "filterable": {"type": "boolean", "title": "Filterable", "default": true}, "expression": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Expression"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "python_date_format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Python Date Format"}, "extra": {"additionalProperties": true, "type": "object", "title": "Extra"}}, "type": "object", "required": ["column_name"], "title": "SupersetColumn"}, "SupersetDashboardDef": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "dashboard_title": {"type": "string", "title": "Dashboard Title"}, "position": {"additionalProperties": {"anyOf": [{"type": "string"}, {"$ref": "#/components/schemas/DashboardComponent"}]}, "type": "object", "title": "Position"}, "metadata": {"$ref": "#/components/schemas/DashboardMetadata"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "css": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Css"}, "slug": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Slug"}, "is_managed_externally": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Managed Externally", "default": false}, "external_url": {"anyOf": [{"type": "string", "minLength": 1, "format": "uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, {"type": "null"}], "title": "External Url"}, "certified_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certified By"}, "certification_details": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Certification Details"}, "published": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Published", "default": false}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}}, "type": "object", "required": ["uuid", "dashboard_title", "position", "metadata"], "title": "SupersetDashboardDef"}, "SupersetDatabaseDef": {"properties": {"database_name": {"type": "string", "title": "Database Name"}, "sqlalchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sqlalchemy Uri", "description": "Better annotation for AnyUrl. Parses from string format, serializes to string format."}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "cache_timeout": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cache Timeout"}, "expose_in_sqllab": {"type": "boolean", "title": "Expose In Sqllab", "default": true}, "allow_run_async": {"type": "boolean", "title": "Allow Run Async", "default": true}, "allow_ctas": {"type": "boolean", "title": "Allow Ctas", "default": false}, "allow_cvas": {"type": "boolean", "title": "Allow Cvas", "default": false}, "allow_dml": {"type": "boolean", "title": "Allow Dml", "default": false}, "allow_file_upload": {"type": "boolean", "title": "Allow File Upload", "default": false}, "extra": {"additionalProperties": true, "type": "object", "title": "Extra"}, "impersonate_user": {"type": "boolean", "title": "Impersonate User", "default": false}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}, "ssh_tunnel": {"type": "null", "title": "Ssh Tunnel"}}, "type": "object", "required": ["database_name", "sqlalchemy_uri", "uuid"], "title": "SupersetDatabaseDef"}, "SupersetDatasetDef": {"properties": {"table_name": {"type": "string", "title": "Table Name"}, "schema": {"type": "string", "title": "Schema"}, "uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "database_uuid": {"type": "string", "format": "uuid", "title": "Database Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "main_dttm_col": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Main Dttm Col"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "default_endpoint": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Default Endpoint"}, "offset": {"type": "integer", "title": "Offset", "default": 0}, "cache_timeout": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cache Timeout"}, "catalog": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Catalog"}, "sql": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sql"}, "params": {"title": "Params"}, "template_params": {"title": "Template Params"}, "is_managed_externally": {"type": "boolean", "title": "Is Managed Externally", "default": true}, "external_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "External Url"}, "filter_select_enabled": {"type": "boolean", "title": "Filter Select Enabled", "default": true}, "fetch_values_predicate": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Fetch Values Predicate"}, "extra": {"additionalProperties": true, "type": "object", "title": "Extra"}, "normalize_columns": {"type": "boolean", "title": "Normalize Columns", "default": false}, "always_filter_main_dttm": {"type": "boolean", "title": "Always Filter Main Dttm", "default": false}, "metrics": {"items": {"$ref": "#/components/schemas/SupersetMetric"}, "type": "array", "title": "Metrics"}, "columns": {"items": {"$ref": "#/components/schemas/SupersetColumn"}, "type": "array", "title": "Columns"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}}, "type": "object", "required": ["table_name", "schema", "uuid", "database_uuid"], "title": "SupersetDatasetDef"}, "SupersetDatasourceBundle": {"properties": {"database": {"$ref": "#/components/schemas/SupersetDatabaseDef"}, "datasets": {"items": {"$ref": "#/components/schemas/SupersetDatasetDef"}, "type": "array", "title": "Datasets"}}, "type": "object", "required": ["database"], "title": "SupersetDatasourceBundle"}, "SupersetMetadataDef": {"properties": {"type": {"$ref": "#/components/schemas/MetadataType"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}, "timestamp": {"type": "string", "format": "date-time", "title": "Timestamp", "description": "Better annotation for datetime. Parses from string format, serializes to string format."}}, "type": "object", "required": ["type"], "title": "SupersetMetadataDef"}, "SupersetMetric": {"properties": {"metric_name": {"type": "string", "title": "Metric Name"}, "verbose_name": {"type": "string", "title": "Verbose Name"}, "expression": {"type": "string", "title": "Expression"}, "metric_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Metric Type"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "d3format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "D3Format"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Currency"}, "extra": {"additionalProperties": true, "type": "object", "title": "Extra"}, "warning_text": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Warning Text"}}, "type": "object", "required": ["metric_name", "verbose_name", "expression"], "title": "SupersetMetric"}, "SupersetMitMDatasetDef": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "mitm": {"$ref": "#/components/schemas/MITM"}, "mitm_header": {"anyOf": [{"$ref": "#/components/schemas/Header-Output"}, {"type": "null"}]}, "database_uuid": {"type": "string", "format": "uuid", "title": "Database Uuid", "description": "Better annotation for UUID. Parses from string format, serializes to string format."}, "tables": {"anyOf": [{"items": {"$ref": "#/components/schemas/DatasetIdentifier"}, "type": "array"}, {"type": "null"}], "title": "Tables"}, "slices": {"anyOf": [{"items": {"$ref": "#/components/schemas/ChartIdentifier"}, "type": "array"}, {"type": "null"}], "title": "Slices"}, "dashboards": {"anyOf": [{"items": {"$ref": "#/components/schemas/DashboardIdentifier"}, "type": "array"}, {"type": "null"}], "title": "Dashboards"}, "version": {"type": "string", "title": "Version", "default": "1.0.0"}}, "type": "object", "required": ["uuid", "dataset_name", "mitm", "database_uuid"], "title": "SupersetMitMDatasetDef"}, "SupersetPostProcessing": {"properties": {"operation": {"type": "string", "title": "Operation"}}, "type": "object", "required": ["operation"], "title": "SupersetPostProcessing"}, "SupersetVisualizationBundle": {"properties": {"charts": {"items": {"$ref": "#/components/schemas/SupersetChartDef"}, "type": "array", "title": "Charts"}, "dashboards": {"items": {"$ref": "#/components/schemas/SupersetDashboardDef"}, "type": "array", "title": "Dashboards"}, "viz_collections": {"anyOf": [{"additionalProperties": {"additionalProperties": {"$ref": "#/components/schemas/DashboardIdentifier"}, "type": "object"}, "type": "object"}, {"type": "null"}], "title": "Viz Collections"}}, "type": "object", "title": "SupersetVisualizationBundle"}, "SupersetVizType": {"type": "string", "enum": ["pie", "echarts_timeseries_bar", "echarts_timeseries_line", "maed_custom"], "title": "SupersetVizType"}, "TableIdentifier": {"properties": {"source": {"$ref": "#/components/schemas/SourceDBType", "default": "original"}, "schema": {"type": "string", "title": "Schema", "default": "main"}, "name": {"type": "string", "title": "Name"}}, "type": "object", "required": ["name"], "title": "TableIdentifier"}, "TableMetaInfoBase": {"properties": {"schema_name": {"type": "string", "title": "Schema Name", "default": "main"}, "name": {"type": "string", "title": "Name"}, "columns": {"items": {"type": "string"}, "type": "array", "title": "Columns"}, "sql_column_types": {"items": {"type": "string"}, "type": "array", "title": "Sql Column Types"}, "primary_key": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Primary Key"}, "indexes": {"anyOf": [{"items": {"items": {"type": "string"}, "type": "array"}, "type": "array"}, {"type": "null"}], "title": "Indexes"}, "foreign_key_constraints": {"items": {"$ref": "#/components/schemas/ForeignKeyConstraintBase"}, "type": "array", "title": "Foreign Key Constraints"}, "column_properties": {"additionalProperties": {"$ref": "#/components/schemas/ColumnProperties"}, "type": "object", "title": "Column Properties"}}, "type": "object", "required": ["name", "columns", "sql_column_types"], "title": "TableMetaInfoBase"}, "TableProbeMinimal": {"properties": {"row_count": {"type": "integer", "minimum": 0.0, "title": "Row Count"}, "inferred_types": {"additionalProperties": {"$ref": "#/components/schemas/MITMDataType"}, "type": "object", "title": "Inferred Types"}, "sample_summaries": {"additionalProperties": {"$ref": "#/components/schemas/SampleSummary"}, "type": "object", "title": "Sample Summaries"}}, "type": "object", "required": ["row_count", "inferred_types", "sample_summaries"], "title": "TableProbeMinimal"}, "TimeGrain": {"type": "string", "enum": ["PT1S", "PT5S", "PT30S", "PT1M", "PT5M", "PT10M", "PT15M", "PT30M", "PT0.5H", "PT1H", "PT6H", "P1D", "P1W", "1969-12-28T00:00:00Z/P1W", "1969-12-29T00:00:00Z/P1W", "P1W/1970-01-03T00:00:00Z", "P1W/1970-01-04T00:00:00Z", "P1M", "P3M", "P0.25Y", "P1Y"], "title": "TimeGrain"}, "TrackedMitMDataset": {"properties": {"uuid": {"type": "string", "format": "uuid", "title": "Uuid"}, "dataset_name": {"type": "string", "title": "Dataset Name"}, "schema_name": {"type": "string", "title": "Schema Name"}, "sql_alchemy_uri": {"type": "string", "minLength": 1, "format": "uri", "title": "Sql Alchemy Uri"}, "mitm_header": {"$ref": "#/components/schemas/Header-Output"}, "is_managed_locally": {"type": "boolean", "title": "Is Managed Locally", "default": true}, "last_edited": {"type": "string", "format": "date-time", "title": "Last Edited"}, "identifier_bundle": {"$ref": "#/components/schemas/MitMDatasetIdentifierBundle"}}, "type": "object", "required": ["dataset_name", "schema_name", "sql_alchemy_uri", "mitm_header", "identifier_bundle"], "title": "TrackedMitMDataset"}, "UploadMitMResponse": {"properties": {"status": {"type": "string", "enum": ["success", "failure"], "title": "Status"}, "tracked_mitm_dataset": {"anyOf": [{"$ref": "#/components/schemas/TrackedMitMDataset"}, {"type": "null"}]}, "msg": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Msg"}}, "type": "object", "required": ["status"], "title": "UploadMitMResponse"}, "ValidationError": {"properties": {"loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "type": "array", "title": "Location"}, "msg": {"type": "string", "title": "Message"}, "type": {"type": "string", "title": "Error Type"}}, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError"}, "VisualizationImportResponse": {"properties": {"databases": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDatabaseDef"}, "type": "array"}, {"type": "null"}], "title": "Databases"}, "datasets": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDatasetDef"}, "type": "array"}, {"type": "null"}], "title": "Datasets"}, "charts": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetChartDef"}, "type": "array"}, {"type": "null"}], "title": "Charts"}, "dashboards": {"anyOf": [{"items": {"$ref": "#/components/schemas/SupersetDashboardDef"}, "type": "array"}, {"type": "null"}], "title": "Dashboards"}, "metadata": {"$ref": "#/components/schemas/SupersetMetadataDef"}}, "type": "object", "title": "VisualizationImportResponse"}, "WrappedMITMDataType": {"properties": {"mitm": {"$ref": "#/components/schemas/MITMDataType"}}, "type": "object", "required": ["mitm"], "title": "WrappedMITMDataType"}}}} \ No newline at end of file diff --git a/superset/commands/mitm/mitm_service/schemas/openapi.yaml b/superset/commands/mitm/mitm_service/schemas/openapi.yaml index abe7fd2c15..0c577a8be6 100644 --- a/superset/commands/mitm/mitm_service/schemas/openapi.yaml +++ b/superset/commands/mitm/mitm_service/schemas/openapi.yaml @@ -103,39 +103,6 @@ components: - TIME_SERIES title: AnnotationType type: string - Body_generate_mitm_dataset_bundle_definitions_mitm_dataset_post: - properties: - db_conn_info: - $ref: '#/components/schemas/SupersetDBConnectionInfo' - mitm_header: - $ref: '#/components/schemas/Header-Input' - required: - - mitm_header - - db_conn_info - title: Body_generate_mitm_dataset_bundle_definitions_mitm_dataset_post - type: object - Body_generate_mitm_dataset_import_definitions_mitm_dataset_import_post: - properties: - db_conn_info: - $ref: '#/components/schemas/SupersetDBConnectionInfo' - mitm_header: - $ref: '#/components/schemas/Header-Input' - required: - - mitm_header - - db_conn_info - title: Body_generate_mitm_dataset_import_definitions_mitm_dataset_import_post - type: object - Body_generate_mitm_dataset_import_zip_definitions_mitm_dataset_import_zip_post: - properties: - db_conn_info: - $ref: '#/components/schemas/SupersetDBConnectionInfo' - mitm_header: - $ref: '#/components/schemas/Header-Input' - required: - - mitm_header - - db_conn_info - title: Body_generate_mitm_dataset_import_zip_definitions_mitm_dataset_import_zip_post - type: object Body_upload_mitm_dataset_mitm_dataset_upload_post: properties: mitm_zip: @@ -146,6 +113,30 @@ components: - mitm_zip title: Body_upload_mitm_dataset_mitm_dataset_upload_post type: object + CategoricalSummaryStatistics: + properties: + count: + minimum: 0.0 + title: Count + type: integer + freq: + minimum: 0.0 + title: Freq + type: integer + top: + title: Top + type: string + unique: + minimum: 0.0 + title: Unique + type: integer + required: + - count + - unique + - top + - freq + title: CategoricalSummaryStatistics + type: object ChartDataResultFormat: enum: - csv @@ -165,6 +156,53 @@ components: - drill_detail title: ChartDataResultType type: string + ChartDatasource: + properties: + id: + anyOf: + - type: integer + - type: 'null' + title: Id + table_name: + anyOf: + - type: string + - type: 'null' + title: Table Name + type: + default: table + enum: + - table + - annotation + title: Type + type: string + uuid: + description: Better annotation for UUID. Parses from string format, serializes + to string format. + format: uuid + title: Uuid + type: string + title: ChartDatasource + type: object + ChartIdentifier: + properties: + id: + anyOf: + - type: integer + - type: 'null' + title: Id + slice_name: + anyOf: + - type: string + - type: 'null' + title: Slice Name + uuid: + description: Better annotation for UUID. Parses from string format, serializes + to string format. + format: uuid + title: Uuid + type: string + title: ChartIdentifier + type: object ChartParams: properties: adhoc_filters: @@ -187,9 +225,10 @@ components: datasource: anyOf: - type: string - - $ref: '#/components/schemas/DatasourceIdentifier' + - $ref: '#/components/schemas/DatasetIdentifier' title: Datasource extra_form_data: + additionalProperties: true title: Extra Form Data type: object groupby: @@ -229,6 +268,25 @@ components: - viz_type title: ChartParams type: object + ClearDBResponse: + description: Response model for clearing the database. + properties: + dropped_mitm_datasets: + anyOf: + - items: + $ref: '#/components/schemas/ListTrackedMitMDataset' + type: array + - type: 'null' + title: Dropped Mitm Datasets + dropped_schemas: + anyOf: + - items: + type: string + type: array + - type: 'null' + title: Dropped Schemas + title: ClearDBResponse + type: object ColName: properties: name: @@ -253,6 +311,34 @@ components: - column title: ColumnOfDataset type: object + ColumnProperties: + properties: + mitm_data_type: + $ref: '#/components/schemas/MITMDataType' + nullable: + title: Nullable + type: boolean + part_of_fk: + title: Part Of Fk + type: boolean + part_of_index: + title: Part Of Index + type: boolean + part_of_pk: + title: Part Of Pk + type: boolean + unique: + title: Unique + type: boolean + required: + - nullable + - unique + - part_of_pk + - part_of_fk + - part_of_index + - mitm_data_type + title: ColumnProperties + type: object CompiledVirtualView: properties: column_dtypes: @@ -396,6 +482,78 @@ components: title: Searchalloptions title: ControlValues type: object + DBConnectionInfo: + properties: + catalog: + anyOf: + - type: string + - type: 'null' + title: Catalog + explicit_db_name: + anyOf: + - type: string + - type: 'null' + title: Explicit Db Name + schema_name: + default: main + title: Schema Name + type: string + sql_alchemy_uri: + description: Better annotation for AnyUrl. Parses from string format, serializes + to string format. + format: uri + minLength: 1 + title: Sql Alchemy Uri + type: string + required: + - sql_alchemy_uri + title: DBConnectionInfo + type: object + DBMetaInfoBase: + properties: + db_structure: + additionalProperties: + additionalProperties: + $ref: '#/components/schemas/TableMetaInfoBase' + type: object + title: Db Structure + type: object + tables: + additionalProperties: + $ref: '#/components/schemas/TableMetaInfoBase' + readOnly: true + title: Tables + type: object + required: + - db_structure + - tables + title: DBMetaInfoBase + type: object + DBMetaResponse: + properties: + db_meta: + anyOf: + - $ref: '#/components/schemas/DBMetaInfoBase' + - type: 'null' + title: DBMetaResponse + type: object + DBProbeMinimal: + properties: + table_probes: + additionalProperties: + $ref: '#/components/schemas/TableProbeMinimal' + title: Table Probes + type: object + title: DBProbeMinimal + type: object + DBProbeResponse: + properties: + db_probe: + anyOf: + - $ref: '#/components/schemas/DBProbeMinimal' + - type: 'null' + title: DBProbeResponse + type: object DashboardComponent: properties: children: @@ -426,6 +584,26 @@ components: - ROOT title: DashboardComponentType type: string + DashboardIdentifier: + properties: + dashboard_title: + anyOf: + - type: string + - type: 'null' + title: Dashboard Title + id: + anyOf: + - type: integer + - type: 'null' + title: Id + uuid: + description: Better annotation for UUID. Parses from string format, serializes + to string format. + format: uuid + title: Uuid + type: string + title: DashboardIdentifier + type: object DashboardMetadata: properties: color_scheme: @@ -443,6 +621,46 @@ components: type: array title: DashboardMetadata type: object + DatabaseIdentifier: + properties: + database_name: + anyOf: + - type: string + - type: 'null' + title: Database Name + id: + anyOf: + - type: integer + - type: 'null' + title: Id + uuid: + description: Better annotation for UUID. Parses from string format, serializes + to string format. + format: uuid + title: Uuid + type: string + title: DatabaseIdentifier + type: object + DatasetIdentifier: + properties: + id: + anyOf: + - type: integer + - type: 'null' + title: Id + table_name: + anyOf: + - type: string + - type: 'null' + title: Table Name + uuid: + description: Better annotation for UUID. Parses from string format, serializes + to string format. + format: uuid + title: Uuid + type: string + title: DatasetIdentifier + type: object DatasetReference: properties: datasetUuid: @@ -455,20 +673,50 @@ components: - datasetUuid title: DatasetReference type: object - DatasourceIdentifier: + DatetimeSummaryStatistics: properties: - id: - default: -1 - title: Id + count: + title: Count type: integer - type: - default: table - enum: - - table - - annotation - title: Type - type: string - title: DatasourceIdentifier + max: + anyOf: + - format: date-time + type: string + - type: 'null' + title: Max + mean: + anyOf: + - format: date-time + type: string + - type: 'null' + title: Mean + min: + anyOf: + - format: date-time + type: string + - type: 'null' + title: Min + percentile_25: + anyOf: + - format: date-time + type: string + - type: 'null' + title: Percentile 25 + percentile_50: + anyOf: + - format: date-time + type: string + - type: 'null' + title: Percentile 50 + percentile_75: + anyOf: + - format: date-time + type: string + - type: 'null' + title: Percentile 75 + required: + - count + title: DatetimeSummaryStatistics type: object ExpressionType: enum: @@ -521,6 +769,50 @@ components: - filter_timegrain title: FilterType type: string + ForeignKeyConstraintBase: + properties: + columns: + items: + type: string + title: Columns + type: array + name: + anyOf: + - type: string + - type: 'null' + title: Name + table: + anyOf: + - $ref: '#/components/schemas/LocalTableIdentifier' + - maxItems: 2 + minItems: 2 + prefixItems: + - type: string + - type: string + type: array + title: Table + target_columns: + items: + type: string + title: Target Columns + type: array + target_table: + anyOf: + - $ref: '#/components/schemas/LocalTableIdentifier' + - maxItems: 2 + minItems: 2 + prefixItems: + - type: string + - type: string + type: array + title: Target Table + required: + - table + - columns + - target_table + - target_columns + title: ForeignKeyConstraintBase + type: object ForeignRelation: properties: fk_columns: @@ -558,14 +850,46 @@ components: properties: {} title: FormData type: object - GenericDataType: - enum: - - 0 - - 1 - - 2 - - 3 - title: GenericDataType - type: integer + GenerateIndependentMitMDatasetDefinitionRequest: + properties: + dataset_name: + title: Dataset Name + type: string + db_conn_info: + $ref: '#/components/schemas/DBConnectionInfo' + identifiers: + anyOf: + - $ref: '#/components/schemas/MitMDatasetIdentifierBundle' + - type: 'null' + mitm_header: + $ref: '#/components/schemas/Header-Input' + required: + - dataset_name + - mitm_header + - db_conn_info + title: GenerateIndependentMitMDatasetDefinitionRequest + type: object + GenerateVisualizationsRequest: + properties: + reuse_existing_identifiers: + default: true + title: Reuse Existing Identifiers + type: boolean + track_identifiers: + default: false + title: Track Identifiers + type: boolean + visualization_types: + default: + - baseline + items: + anyOf: + - $ref: '#/components/schemas/MAEDVisualizationType' + - type: 'null' + title: Visualization Types + type: array + title: GenerateVisualizationsRequest + type: object HTTPValidationError: properties: detail: @@ -630,6 +954,42 @@ components: - attribute_dtypes title: HeaderEntry type: object + ListTrackedMitMDataset: + properties: + dataset_name: + title: Dataset Name + type: string + mitm: + $ref: '#/components/schemas/MITM' + uuid: + format: uuid + title: Uuid + type: string + required: + - uuid + - dataset_name + - mitm + title: ListTrackedMitMDataset + type: object + LocalTableIdentifier: + properties: + name: + title: Name + type: string + schema: + default: main + title: Schema + type: string + required: + - name + title: LocalTableIdentifier + type: object + MAEDVisualizationType: + enum: + - baseline + - experimental + title: MAEDVisualizationType + type: string MITM: enum: - MAED @@ -659,6 +1019,83 @@ components: - MitMDataset title: MetadataType type: string + MitMDatasetBundleResponse: + properties: + datasource_bundle: + $ref: '#/components/schemas/SupersetDatasourceBundle' + mitm_dataset: + $ref: '#/components/schemas/SupersetMitMDatasetDef' + visualization_bundle: + $ref: '#/components/schemas/SupersetVisualizationBundle' + required: + - mitm_dataset + - datasource_bundle + title: MitMDatasetBundleResponse + type: object + MitMDatasetIdentifier: + properties: + dataset_name: + anyOf: + - type: string + - type: 'null' + title: Dataset Name + id: + anyOf: + - type: integer + - type: 'null' + title: Id + uuid: + description: Better annotation for UUID. Parses from string format, serializes + to string format. + format: uuid + title: Uuid + type: string + title: MitMDatasetIdentifier + type: object + MitMDatasetIdentifierBundle: + properties: + database: + anyOf: + - $ref: '#/components/schemas/DatabaseIdentifier' + - type: 'null' + ds_id_map: + additionalProperties: + $ref: '#/components/schemas/DatasetIdentifier' + title: Ds Id Map + type: object + mitm_dataset: + anyOf: + - $ref: '#/components/schemas/MitMDatasetIdentifier' + - type: 'null' + viz_id_map: + additionalProperties: + additionalProperties: + $ref: '#/components/schemas/DashboardIdentifier' + type: object + title: Viz Id Map + type: object + title: MitMDatasetIdentifierBundle + type: object + MitMDatasetImportResponse: + properties: + base_assets: + anyOf: + - $ref: '#/components/schemas/SupersetAssetsImport' + - type: 'null' + metadata: + $ref: '#/components/schemas/SupersetMetadataDef' + mitm_datasets: + anyOf: + - items: + $ref: '#/components/schemas/SupersetMitMDatasetDef' + type: array + - type: 'null' + title: Mitm Datasets + required: + - mitm_datasets + - base_assets + title: MitMDatasetImportResponse + type: object NativeFilterConfig: properties: controlValues: @@ -688,6 +1125,44 @@ components: - name title: NativeFilterConfig type: object + NumericSummaryStatistics: + properties: + count: + title: Count + type: integer + max: + title: Max + type: number + mean: + title: Mean + type: number + min: + title: Min + type: number + percentile_25: + title: Percentile 25 + type: number + percentile_50: + title: Percentile 50 + type: number + percentile_75: + title: Percentile 75 + type: number + std: + anyOf: + - type: number + - type: 'null' + title: Std + required: + - count + - mean + - min + - max + - percentile_25 + - percentile_50 + - percentile_75 + title: NumericSummaryStatistics + type: object QueryContext: properties: custom_cache_timeout: @@ -696,7 +1171,7 @@ components: - type: 'null' title: Custom Cache Timeout datasource: - $ref: '#/components/schemas/DatasourceIdentifier' + $ref: '#/components/schemas/ChartDatasource' force: default: false title: Force @@ -741,7 +1216,7 @@ components: type: array datasource: anyOf: - - $ref: '#/components/schemas/DatasourceIdentifier' + - $ref: '#/components/schemas/ChartDatasource' - type: 'null' extras: $ref: '#/components/schemas/QueryObjectExtras' @@ -815,7 +1290,8 @@ components: items: anyOf: - $ref: '#/components/schemas/SupersetPostProcessing' - - type: object + - additionalProperties: true + type: object title: Post Processing type: array result_type: @@ -1002,56 +1478,49 @@ components: - status title: RegisterMitMResponse type: object - RelatedDashboard: + SampleSummary: properties: - dashboard_id: + json_schema: anyOf: - - type: integer + - additionalProperties: true + type: object - type: 'null' - title: Dashboard Id - dashboard_uuid: - description: Better annotation for UUID. Parses from string format, serializes - to string format. - format: uuid - title: Dashboard Uuid - type: string - required: - - dashboard_uuid - title: RelatedDashboard - type: object - RelatedSlice: - properties: - slice_id: + title: Json Schema + na_fraction: anyOf: - - type: integer + - maximum: 1.0 + minimum: 0.0 + type: number - type: 'null' - title: Slice Id - slice_uuid: - description: Better annotation for UUID. Parses from string format, serializes - to string format. - format: uuid - title: Slice Uuid - type: string - required: - - slice_uuid - title: RelatedSlice - type: object - RelatedTable: - properties: - table_id: + title: Na Fraction + sample_size: anyOf: - - type: integer + - minimum: 0.0 + type: integer - type: 'null' - title: Table Id - table_uuid: - description: Better annotation for UUID. Parses from string format, serializes - to string format. - format: uuid - title: Table Uuid - type: string - required: - - table_uuid - title: RelatedTable + title: Sample Size + summary_statistics: + anyOf: + - $ref: '#/components/schemas/NumericSummaryStatistics' + - $ref: '#/components/schemas/CategoricalSummaryStatistics' + - $ref: '#/components/schemas/DatetimeSummaryStatistics' + - type: 'null' + title: Summary Statistics + unique_fraction: + anyOf: + - maximum: 1.0 + minimum: 0.0 + type: number + - type: 'null' + title: Unique Fraction + value_counts: + anyOf: + - additionalProperties: + type: integer + type: object + - type: 'null' + title: Value Counts + title: SampleSummary type: object SourceDBType: enum: @@ -1253,7 +1722,7 @@ components: - type: 'null' query_context: anyOf: - - $ref: '#/components/schemas/QueryContext' + - {} - type: 'null' slice_name: title: Slice Name @@ -1298,6 +1767,7 @@ components: - type: 'null' title: Expression extra: + additionalProperties: true title: Extra type: object filterable: @@ -1330,9 +1800,6 @@ components: default: VARCHAR title: Type type: string - type_generic: - $ref: '#/components/schemas/GenericDataType' - default: 1 verbose_name: anyOf: - type: string @@ -1342,28 +1809,6 @@ components: - column_name title: SupersetColumn type: object - SupersetDBConnectionInfo: - properties: - explicit_db_name: - anyOf: - - type: string - - type: 'null' - title: Explicit Db Name - schema_name: - default: main - title: Schema Name - type: string - sql_alchemy_uri: - description: Better annotation for AnyUrl. Parses from string format, serializes - to string format. - format: uri - minLength: 1 - title: Sql Alchemy Uri - type: string - required: - - sql_alchemy_uri - title: SupersetDBConnectionInfo - type: object SupersetDashboardDef: properties: certification_details: @@ -1460,7 +1905,7 @@ components: title: Allow File Upload type: boolean allow_run_async: - default: false + default: true title: Allow Run Async type: boolean cache_timeout: @@ -1476,6 +1921,7 @@ components: title: Expose In Sqllab type: boolean extra: + additionalProperties: true title: Extra type: object impersonate_user: @@ -1545,7 +1991,13 @@ components: - type: string - type: 'null' title: Description + external_url: + anyOf: + - type: string + - type: 'null' + title: External Url extra: + additionalProperties: true title: Extra type: object fetch_values_predicate: @@ -1557,6 +2009,10 @@ components: default: true title: Filter Select Enabled type: boolean + is_managed_externally: + default: true + title: Is Managed Externally + type: boolean main_dttm_col: anyOf: - type: string @@ -1659,6 +2115,7 @@ components: title: Expression type: string extra: + additionalProperties: true title: Extra type: object metric_name: @@ -1683,25 +2140,12 @@ components: - expression title: SupersetMetric type: object - SupersetMitMDatasetBundle: - properties: - datasource_bundle: - $ref: '#/components/schemas/SupersetDatasourceBundle' - mitm_dataset: - $ref: '#/components/schemas/SupersetMitMDatasetDef' - visualization_bundle: - $ref: '#/components/schemas/SupersetVisualizationBundle' - required: - - mitm_dataset - - datasource_bundle - title: SupersetMitMDatasetBundle - type: object SupersetMitMDatasetDef: properties: dashboards: anyOf: - items: - $ref: '#/components/schemas/RelatedDashboard' + $ref: '#/components/schemas/DashboardIdentifier' type: array - type: 'null' title: Dashboards @@ -1723,14 +2167,14 @@ components: slices: anyOf: - items: - $ref: '#/components/schemas/RelatedSlice' + $ref: '#/components/schemas/ChartIdentifier' type: array - type: 'null' title: Slices tables: anyOf: - items: - $ref: '#/components/schemas/RelatedTable' + $ref: '#/components/schemas/DatasetIdentifier' type: array - type: 'null' title: Tables @@ -1751,30 +2195,9 @@ components: - database_uuid title: SupersetMitMDatasetDef type: object - SupersetMitMDatasetImport: - properties: - base_assets: - anyOf: - - $ref: '#/components/schemas/SupersetAssetsImport' - - type: 'null' - metadata: - $ref: '#/components/schemas/SupersetMetadataDef' - mitm_datasets: - anyOf: - - items: - $ref: '#/components/schemas/SupersetMitMDatasetDef' - type: array - - type: 'null' - title: Mitm Datasets - required: - - mitm_datasets - - base_assets - title: SupersetMitMDatasetImport - type: object SupersetPostProcessing: properties: operation: - readOnly: true title: Operation type: string required: @@ -1793,6 +2216,15 @@ components: $ref: '#/components/schemas/SupersetDashboardDef' title: Dashboards type: array + viz_collections: + anyOf: + - additionalProperties: + additionalProperties: + $ref: '#/components/schemas/DashboardIdentifier' + type: object + type: object + - type: 'null' + title: Viz Collections title: SupersetVisualizationBundle type: object SupersetVizType: @@ -1800,6 +2232,7 @@ components: - pie - echarts_timeseries_bar - echarts_timeseries_line + - maed_custom title: SupersetVizType type: string TableIdentifier: @@ -1818,6 +2251,79 @@ components: - name title: TableIdentifier type: object + TableMetaInfoBase: + properties: + column_properties: + additionalProperties: + $ref: '#/components/schemas/ColumnProperties' + title: Column Properties + type: object + columns: + items: + type: string + title: Columns + type: array + foreign_key_constraints: + items: + $ref: '#/components/schemas/ForeignKeyConstraintBase' + title: Foreign Key Constraints + type: array + indexes: + anyOf: + - items: + items: + type: string + type: array + type: array + - type: 'null' + title: Indexes + name: + title: Name + type: string + primary_key: + anyOf: + - items: + type: string + type: array + - type: 'null' + title: Primary Key + schema_name: + default: main + title: Schema Name + type: string + sql_column_types: + items: + type: string + title: Sql Column Types + type: array + required: + - name + - columns + - sql_column_types + title: TableMetaInfoBase + type: object + TableProbeMinimal: + properties: + inferred_types: + additionalProperties: + $ref: '#/components/schemas/MITMDataType' + title: Inferred Types + type: object + row_count: + minimum: 0.0 + title: Row Count + type: integer + sample_summaries: + additionalProperties: + $ref: '#/components/schemas/SampleSummary' + title: Sample Summaries + type: object + required: + - row_count + - inferred_types + - sample_summaries + title: TableProbeMinimal + type: object TimeGrain: enum: - PT1S @@ -1848,10 +2354,16 @@ components: dataset_name: title: Dataset Name type: string - is_local: + identifier_bundle: + $ref: '#/components/schemas/MitMDatasetIdentifierBundle' + is_managed_locally: default: true - title: Is Local + title: Is Managed Locally type: boolean + last_edited: + format: date-time + title: Last Edited + type: string mitm_header: $ref: '#/components/schemas/Header-Output' schema_name: @@ -1871,6 +2383,7 @@ components: - schema_name - sql_alchemy_uri - mitm_header + - identifier_bundle title: TrackedMitMDataset type: object UploadMitMResponse: @@ -1915,6 +2428,40 @@ components: - type title: ValidationError type: object + VisualizationImportResponse: + properties: + charts: + anyOf: + - items: + $ref: '#/components/schemas/SupersetChartDef' + type: array + - type: 'null' + title: Charts + dashboards: + anyOf: + - items: + $ref: '#/components/schemas/SupersetDashboardDef' + type: array + - type: 'null' + title: Dashboards + databases: + anyOf: + - items: + $ref: '#/components/schemas/SupersetDatabaseDef' + type: array + - type: 'null' + title: Databases + datasets: + anyOf: + - items: + $ref: '#/components/schemas/SupersetDatasetDef' + type: array + - type: 'null' + title: Datasets + metadata: + $ref: '#/components/schemas/SupersetMetadataDef' + title: VisualizationImportResponse + type: object WrappedMITMDataType: properties: mitm: @@ -1938,16 +2485,78 @@ paths: schema: {} description: Successful Response summary: Root - /definitions/mitm_dataset: + /admin/clear-db: post: - operationId: generate_mitm_dataset_bundle + description: Clear the database. + operationId: clear_db + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ClearDBResponse' + description: Successful Response + summary: Clear Db + tags: + - admin + /data/db-meta/{uuid}: + get: + operationId: get_db_meta parameters: - - in: query - name: dataset_name + - in: path + name: uuid required: true schema: - title: Dataset Name + format: uuid + title: Uuid type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/DBMetaResponse' + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + summary: Get Db Meta + tags: + - data + /data/db-probe/{uuid}: + get: + operationId: get_db_probe + parameters: + - in: path + name: uuid + required: true + schema: + format: uuid + title: Uuid + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/DBProbeResponse' + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + summary: Get Db Probe + tags: + - data + /definitions/mitm_dataset: + post: + operationId: generate_mitm_dataset_bundle + parameters: - in: query name: include_visualizations required: false @@ -1959,14 +2568,14 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Body_generate_mitm_dataset_bundle_definitions_mitm_dataset_post' + $ref: '#/components/schemas/GenerateIndependentMitMDatasetDefinitionRequest' required: true responses: '200': content: application/json: schema: - $ref: '#/components/schemas/SupersetMitMDatasetBundle' + $ref: '#/components/schemas/MitMDatasetBundleResponse' description: Successful Response '422': content: @@ -1981,12 +2590,6 @@ paths: post: operationId: generate_mitm_dataset_import parameters: - - in: query - name: dataset_name - required: true - schema: - title: Dataset Name - type: string - in: query name: include_visualizations required: false @@ -1994,18 +2597,26 @@ paths: default: false title: Include Visualizations type: boolean + - in: query + name: override_metadata_type + required: false + schema: + anyOf: + - $ref: '#/components/schemas/MetadataType' + - type: 'null' + title: Override Metadata Type requestBody: content: application/json: schema: - $ref: '#/components/schemas/Body_generate_mitm_dataset_import_definitions_mitm_dataset_import_post' + $ref: '#/components/schemas/GenerateIndependentMitMDatasetDefinitionRequest' required: true responses: '200': content: application/json: schema: - $ref: '#/components/schemas/SupersetMitMDatasetImport' + $ref: '#/components/schemas/MitMDatasetImportResponse' description: Successful Response '422': content: @@ -2021,23 +2632,136 @@ paths: operationId: generate_mitm_dataset_import_zip parameters: - in: query - name: dataset_name + name: include_visualizations + required: false + schema: + default: false + title: Include Visualizations + type: boolean + - in: query + name: override_metadata_type + required: false + schema: + anyOf: + - $ref: '#/components/schemas/MetadataType' + - type: 'null' + title: Override Metadata Type + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GenerateIndependentMitMDatasetDefinitionRequest' + required: true + responses: + '200': + content: + application/zip: {} + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + summary: Generate Mitm Dataset Import Zip + tags: + - definitions + /definitions/mitm_dataset/viz/{uuid}: + post: + operationId: generate_visualizations_for_tracked_dataset + parameters: + - in: path + name: uuid required: true schema: - title: Dataset Name + format: uuid + title: Uuid + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GenerateVisualizationsRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/MitMDatasetBundleResponse' + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + summary: Generate Visualizations For Tracked Dataset + tags: + - definitions + /definitions/mitm_dataset/viz/{uuid}/import: + post: + operationId: generate_visualizations_import_for_tracked_dataset + parameters: + - in: path + name: uuid + required: true + schema: + format: uuid + title: Uuid type: string - in: query - name: include_visualizations + name: as_assets required: false schema: default: false - title: Include Visualizations + title: As Assets type: boolean requestBody: content: application/json: schema: - $ref: '#/components/schemas/Body_generate_mitm_dataset_import_zip_definitions_mitm_dataset_import_zip_post' + $ref: '#/components/schemas/GenerateVisualizationsRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/VisualizationImportResponse' + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + summary: Generate Visualizations Import For Tracked Dataset + tags: + - definitions + /definitions/mitm_dataset/viz/{uuid}/import/zip: + post: + operationId: generate_visualizations_import_zip_for_tracked_dataset + parameters: + - in: path + name: uuid + required: true + schema: + format: uuid + title: Uuid + type: string + - in: query + name: as_assets + required: false + schema: + default: false + title: As Assets + type: boolean + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GenerateVisualizationsRequest' required: true responses: '200': @@ -2050,12 +2774,12 @@ paths: schema: $ref: '#/components/schemas/HTTPValidationError' description: Validation Error - summary: Generate Mitm Dataset Import Zip + summary: Generate Visualizations Import Zip For Tracked Dataset tags: - definitions - /definitions/mitm_dataset/{uuid}/: + /definitions/mitm_dataset/{uuid}: get: - operationId: generate_uploaded_mitm_dataset_bundle + operationId: generate_tracked_mitm_dataset_bundle parameters: - in: path name: uuid @@ -2076,7 +2800,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/SupersetMitMDatasetBundle' + $ref: '#/components/schemas/MitMDatasetBundleResponse' description: Successful Response '422': content: @@ -2084,12 +2808,12 @@ paths: schema: $ref: '#/components/schemas/HTTPValidationError' description: Validation Error - summary: Generate Uploaded Mitm Dataset Bundle + summary: Generate Tracked Mitm Dataset Bundle tags: - definitions /definitions/mitm_dataset/{uuid}/import: get: - operationId: generate_uploaded_mitm_dataset_import + operationId: generate_tracked_mitm_dataset_import parameters: - in: path name: uuid @@ -2105,12 +2829,20 @@ paths: default: false title: Include Visualizations type: boolean + - in: query + name: override_metadata_type + required: false + schema: + anyOf: + - $ref: '#/components/schemas/MetadataType' + - type: 'null' + title: Override Metadata Type responses: '200': content: application/json: schema: - $ref: '#/components/schemas/SupersetMitMDatasetImport' + $ref: '#/components/schemas/MitMDatasetImportResponse' description: Successful Response '422': content: @@ -2118,12 +2850,12 @@ paths: schema: $ref: '#/components/schemas/HTTPValidationError' description: Validation Error - summary: Generate Uploaded Mitm Dataset Import + summary: Generate Tracked Mitm Dataset Import tags: - definitions /definitions/mitm_dataset/{uuid}/import/zip: get: - operationId: generate_uploaded_mitm_dataset_import_zip + operationId: generate_tracked_mitm_dataset_import_zip parameters: - in: path name: uuid @@ -2139,6 +2871,14 @@ paths: default: false title: Include Visualizations type: boolean + - in: query + name: override_metadata_type + required: false + schema: + anyOf: + - $ref: '#/components/schemas/MetadataType' + - type: 'null' + title: Override Metadata Type responses: '200': content: @@ -2150,7 +2890,7 @@ paths: schema: $ref: '#/components/schemas/HTTPValidationError' description: Validation Error - summary: Generate Uploaded Mitm Dataset Import Zip + summary: Generate Tracked Mitm Dataset Import Zip tags: - definitions /health: @@ -2172,7 +2912,7 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/TrackedMitMDataset' + $ref: '#/components/schemas/ListTrackedMitMDataset' title: Response Get Mitm Datasets Mitm Dataset Get type: array description: Successful Response @@ -2191,7 +2931,8 @@ paths: '200': content: application/json: - schema: {} + schema: + $ref: '#/components/schemas/TrackedMitMDataset' description: Successful Response '422': content: @@ -2202,6 +2943,31 @@ paths: summary: Post Mitm Dataset tags: - mitm_dataset + /mitm_dataset/export/{uuid}: + post: + operationId: export_mitm_dataset + parameters: + - in: path + name: uuid + required: true + schema: + format: uuid + title: Uuid + type: string + responses: + '200': + content: + application/zip: {} + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + summary: Export Mitm Dataset + tags: + - mitm_dataset /mitm_dataset/register: post: operationId: register_mitm_dataset diff --git a/superset/commands/mitm/mitm_service/schemas/schema.py b/superset/commands/mitm/mitm_service/schemas/schema.py index 53ff6643b7..eeb232d4c7 100644 --- a/superset/commands/mitm/mitm_service/schemas/schema.py +++ b/superset/commands/mitm/mitm_service/schemas/schema.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: openapi.yaml -# timestamp: 2025-03-14T11:59:49+00:00 +# timestamp: 2025-04-30T09:16:13+00:00 from __future__ import annotations @@ -9,7 +9,7 @@ from enum import Enum from typing import Any from uuid import UUID -from pydantic import AnyUrl, BaseModel, Field +from pydantic import AnyUrl, BaseModel, confloat, conint, Field class AnnotationOverrides(BaseModel): @@ -34,6 +34,13 @@ class BodyUploadMitmDatasetMitmDatasetUploadPost(BaseModel): mitm_zip: bytes = Field(..., title='Mitm Zip') +class CategoricalSummaryStatistics(BaseModel): + count: conint(ge=0) = Field(..., title='Count') + freq: conint(ge=0) = Field(..., title='Freq') + top: str = Field(..., title='Top') + unique: conint(ge=0) = Field(..., title='Unique') + + class ChartDataResultFormat(str, Enum): CSV = 'csv' JSON = 'json' @@ -51,6 +58,30 @@ class ChartDataResultType(str, Enum): DRILL_DETAIL = 'drill_detail' +class Type(str, Enum): + TABLE = 'table' + ANNOTATION = 'annotation' + + +class ChartDatasource(BaseModel): + id: int | None = Field(None, title='Id') + table_name: str | None = Field(None, title='Table Name') + type: Type | None = Field('table', title='Type') + uuid: UUID | None = Field(None, title='Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + + +class ChartIdentifier(BaseModel): + id: int | None = Field(None, title='Id') + slice_name: str | None = Field(None, title='Slice Name') + uuid: UUID | None = Field(None, title='Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + + class ColorScheme(str, Enum): BLUE_TO_GREEN = 'blueToGreen' SUPERSET_COLORS = 'supersetColors' @@ -80,6 +111,16 @@ class ControlValues(BaseModel): searchAllOptions: bool | None = Field(False, title='Searchalloptions') +class DBConnectionInfo(BaseModel): + catalog: str | None = Field(None, title='Catalog') + explicit_db_name: str | None = Field(None, title='Explicit Db Name') + schema_name: str | None = Field('main', title='Schema Name') + sql_alchemy_uri: AnyUrl = Field(..., title='Sql Alchemy Uri') + """ + Better annotation for AnyUrl. Parses from string format, serializes to string format. + """ + + class DashboardComponentType(str, Enum): CHART = 'CHART' HEADER = 'HEADER' @@ -88,21 +129,48 @@ class DashboardComponentType(str, Enum): ROOT = 'ROOT' -class DatasetReference(BaseModel): - datasetUuid: UUID = Field(..., title='Datasetuuid') +class DashboardIdentifier(BaseModel): + dashboard_title: str | None = Field(None, title='Dashboard Title') + id: int | None = Field(None, title='Id') + uuid: UUID | None = Field(None, title='Uuid') """ Better annotation for UUID. Parses from string format, serializes to string format. """ -class Type(str, Enum): - TABLE = 'table' - ANNOTATION = 'annotation' +class DatabaseIdentifier(BaseModel): + database_name: str | None = Field(None, title='Database Name') + id: int | None = Field(None, title='Id') + uuid: UUID | None = Field(None, title='Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ -class DatasourceIdentifier(BaseModel): - id: int | None = Field(-1, title='Id') - type: Type | None = Field('table', title='Type') +class DatasetIdentifier(BaseModel): + id: int | None = Field(None, title='Id') + table_name: str | None = Field(None, title='Table Name') + uuid: UUID | None = Field(None, title='Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + + +class DatasetReference(BaseModel): + datasetUuid: UUID = Field(..., title='Datasetuuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + + +class DatetimeSummaryStatistics(BaseModel): + count: int = Field(..., title='Count') + max: datetime | None = Field(None, title='Max') + mean: datetime | None = Field(None, title='Mean') + min: datetime | None = Field(None, title='Min') + percentile_25: datetime | None = Field(None, title='Percentile 25') + percentile_50: datetime | None = Field(None, title='Percentile 50') + percentile_75: datetime | None = Field(None, title='Percentile 75') class ExpressionType(str, Enum): @@ -156,11 +224,14 @@ class FormData(BaseModel): pass -class GenericDataType(int, Enum): - INTEGER_0 = 0 - INTEGER_1 = 1 - INTEGER_2 = 2 - INTEGER_3 = 3 +class LocalTableIdentifier(BaseModel): + name: str = Field(..., title='Name') + schema_: str | None = Field('main', alias='schema', title='Schema') + + +class MAEDVisualizationType(str, Enum): + BASELINE = 'baseline' + EXPERIMENTAL = 'experimental' class MITM(str, Enum): @@ -189,6 +260,24 @@ class MetadataType(str, Enum): MIT_M_DATASET = 'MitMDataset' +class MitMDatasetIdentifier(BaseModel): + dataset_name: str | None = Field(None, title='Dataset Name') + id: int | None = Field(None, title='Id') + uuid: UUID | None = Field(None, title='Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + + +class MitMDatasetIdentifierBundle(BaseModel): + database: DatabaseIdentifier | None = None + ds_id_map: dict[str, DatasetIdentifier] | None = Field(None, title='Ds Id Map') + mitm_dataset: MitMDatasetIdentifier | None = None + viz_id_map: dict[str, dict[str, DashboardIdentifier]] | None = Field( + None, title='Viz Id Map' + ) + + class NativeFilterConfig(BaseModel): controlValues: ControlValues | None = None filterType: FilterType | None = 'filter_select' @@ -200,6 +289,17 @@ class NativeFilterConfig(BaseModel): type: str | None = Field('NATIVE_FILTER', title='Type') +class NumericSummaryStatistics(BaseModel): + count: int = Field(..., title='Count') + max: float = Field(..., title='Max') + mean: float = Field(..., title='Mean') + min: float = Field(..., title='Min') + percentile_25: float = Field(..., title='Percentile 25') + percentile_50: float = Field(..., title='Percentile 50') + percentile_75: float = Field(..., title='Percentile 75') + std: float | None = Field(None, title='Std') + + class QueryObjectFilterClause(BaseModel): col: str = Field(..., title='Col') grain: str | None = Field(None, title='Grain') @@ -222,28 +322,20 @@ class Status(str, Enum): FAILURE = 'failure' -class RelatedDashboard(BaseModel): - dashboard_id: int | None = Field(None, title='Dashboard Id') - dashboard_uuid: UUID = Field(..., title='Dashboard Uuid') - """ - Better annotation for UUID. Parses from string format, serializes to string format. - """ - - -class RelatedSlice(BaseModel): - slice_id: int | None = Field(None, title='Slice Id') - slice_uuid: UUID = Field(..., title='Slice Uuid') - """ - Better annotation for UUID. Parses from string format, serializes to string format. - """ - - -class RelatedTable(BaseModel): - table_id: int | None = Field(None, title='Table Id') - table_uuid: UUID = Field(..., title='Table Uuid') - """ - Better annotation for UUID. Parses from string format, serializes to string format. - """ +class SampleSummary(BaseModel): + json_schema: dict[str, Any] | None = Field(None, title='Json Schema') + na_fraction: confloat(ge=0.0, le=1.0) | None = Field(None, title='Na Fraction') + sample_size: conint(ge=0) | None = Field(None, title='Sample Size') + summary_statistics: ( + NumericSummaryStatistics + | CategoricalSummaryStatistics + | DatetimeSummaryStatistics + | None + ) = Field(None, title='Summary Statistics') + unique_fraction: confloat(ge=0.0, le=1.0) | None = Field( + None, title='Unique Fraction' + ) + value_counts: dict[str, int] | None = Field(None, title='Value Counts') class SourceDBType(str, Enum): @@ -285,25 +377,15 @@ class SupersetColumn(BaseModel): is_dttm: bool | None = Field(False, title='Is Dttm') python_date_format: str | None = Field(None, title='Python Date Format') type: str | None = Field('VARCHAR', title='Type') - type_generic: GenericDataType | None = 1 verbose_name: str | None = Field(None, title='Verbose Name') -class SupersetDBConnectionInfo(BaseModel): - explicit_db_name: str | None = Field(None, title='Explicit Db Name') - schema_name: str | None = Field('main', title='Schema Name') - sql_alchemy_uri: AnyUrl = Field(..., title='Sql Alchemy Uri') - """ - Better annotation for AnyUrl. Parses from string format, serializes to string format. - """ - - class SupersetDatabaseDef(BaseModel): allow_ctas: bool | None = Field(False, title='Allow Ctas') allow_cvas: bool | None = Field(False, title='Allow Cvas') allow_dml: bool | None = Field(False, title='Allow Dml') allow_file_upload: bool | None = Field(False, title='Allow File Upload') - allow_run_async: bool | None = Field(False, title='Allow Run Async') + allow_run_async: bool | None = Field(True, title='Allow Run Async') cache_timeout: str | None = Field(None, title='Cache Timeout') database_name: str = Field(..., title='Database Name') expose_in_sqllab: bool | None = Field(True, title='Expose In Sqllab') @@ -350,6 +432,7 @@ class SupersetVizType(str, Enum): PIE = 'pie' ECHARTS_TIMESERIES_BAR = 'echarts_timeseries_bar' ECHARTS_TIMESERIES_LINE = 'echarts_timeseries_line' + MAED_CUSTOM = 'maed_custom' class TableIdentifier(BaseModel): @@ -358,6 +441,12 @@ class TableIdentifier(BaseModel): source: SourceDBType | None = 'original' +class TableProbeMinimal(BaseModel): + inferred_types: dict[str, MITMDataType] = Field(..., title='Inferred Types') + row_count: conint(ge=0) = Field(..., title='Row Count') + sample_summaries: dict[str, SampleSummary] = Field(..., title='Sample Summaries') + + class TimeGrain(str, Enum): PT1_S = 'PT1S' PT5_S = 'PT5S' @@ -411,7 +500,7 @@ class ChartParams(BaseModel): adhoc_filters: list[SupersetAdhocFilter] | None = Field(None, title='Adhoc Filters') color_scheme: ColorScheme | None = Field('supersetColors', title='Color Scheme') dashboards: list[int] | None = Field(None, title='Dashboards') - datasource: str | DatasourceIdentifier = Field(..., title='Datasource') + datasource: str | DatasetIdentifier = Field(..., title='Datasource') extra_form_data: dict[str, Any] | None = Field(None, title='Extra Form Data') groupby: list[str] | None = Field(None, title='Groupby') legendOrientation: str | None = Field('top', title='Legendorientation') @@ -423,6 +512,15 @@ class ChartParams(BaseModel): viz_type: SupersetVizType +class ColumnProperties(BaseModel): + mitm_data_type: MITMDataType + nullable: bool = Field(..., title='Nullable') + part_of_fk: bool = Field(..., title='Part Of Fk') + part_of_index: bool = Field(..., title='Part Of Index') + part_of_pk: bool = Field(..., title='Part Of Pk') + unique: bool = Field(..., title='Unique') + + class CompiledVirtualView(BaseModel): column_dtypes: list[WrappedMITMDataType | str] = Field(..., title='Column Dtypes') columns: list[str] = Field(..., title='Columns') @@ -432,6 +530,16 @@ class CompiledVirtualView(BaseModel): schema_name: str = Field(..., title='Schema Name') +class DBProbeMinimal(BaseModel): + table_probes: dict[str, TableProbeMinimal] | None = Field( + None, title='Table Probes' + ) + + +class DBProbeResponse(BaseModel): + db_probe: DBProbeMinimal | None = None + + class DashboardComponent(BaseModel): children: list[str] | None = Field(None, title='Children') id: str = Field(..., title='Id') @@ -447,11 +555,29 @@ class DashboardMetadata(BaseModel): ) +class ForeignKeyConstraintBase(BaseModel): + columns: list[str] = Field(..., title='Columns') + name: str | None = Field(None, title='Name') + table: LocalTableIdentifier | list = Field(..., title='Table') + target_columns: list[str] = Field(..., title='Target Columns') + target_table: LocalTableIdentifier | list = Field(..., title='Target Table') + + class ForeignRelation(BaseModel): fk_columns: dict[str, str] | list[str] = Field(..., title='Fk Columns') referred_table: TableIdentifier | list = Field(..., title='Referred Table') +class GenerateVisualizationsRequest(BaseModel): + reuse_existing_identifiers: bool | None = Field( + True, title='Reuse Existing Identifiers' + ) + track_identifiers: bool | None = Field(False, title='Track Identifiers') + visualization_types: list[MAEDVisualizationType | None] | None = Field( + ['baseline'], title='Visualization Types' + ) + + class HTTPValidationError(BaseModel): detail: list[ValidationError] | None = Field(None, title='Detail') @@ -464,6 +590,12 @@ class HeaderEntry(BaseModel): type_name: str = Field(..., title='Type Name') +class ListTrackedMitMDataset(BaseModel): + dataset_name: str = Field(..., title='Dataset Name') + mitm: MITM + uuid: UUID = Field(..., title='Uuid') + + class QueryObjectExtras(BaseModel): having: str | None = Field('', title='Having') time_grain_sqla: TimeGrain | None = None @@ -489,6 +621,28 @@ class SupersetAdhocMetric(BaseModel): sqlExpression: str | None = Field(None, title='Sqlexpression') +class SupersetChartDef(BaseModel): + cache_timeout: int | None = Field(None, title='Cache Timeout') + certification_details: str | None = Field(None, title='Certification Details') + certified_by: str | None = Field(None, title='Certified By') + dataset_uuid: UUID = Field(..., title='Dataset Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + description: str | None = Field(None, title='Description') + external_url: AnyUrl | None = Field(None, title='External Url') + is_managed_externally: bool | None = Field(False, title='Is Managed Externally') + params: ChartParams | None = None + query_context: Any = None + slice_name: str = Field(..., title='Slice Name') + uuid: UUID = Field(..., title='Uuid') + """ + Better annotation for UUID. Parses from string format, serializes to string format. + """ + version: str | None = Field('1.0.0', title='Version') + viz_type: SupersetVizType + + class SupersetDashboardDef(BaseModel): certification_details: str | None = Field(None, title='Certification Details') certified_by: str | None = Field(None, title='Certified By') @@ -519,9 +673,11 @@ class SupersetDatasetDef(BaseModel): """ default_endpoint: str | None = Field(None, title='Default Endpoint') description: str | None = Field(None, title='Description') + external_url: str | None = Field(None, title='External Url') extra: dict[str, Any] | None = Field(None, title='Extra') fetch_values_predicate: str | None = Field(None, title='Fetch Values Predicate') filter_select_enabled: bool | None = Field(True, title='Filter Select Enabled') + is_managed_externally: bool | None = Field(True, title='Is Managed Externally') main_dttm_col: str | None = Field(None, title='Main Dttm Col') metrics: list[SupersetMetric] | None = Field(None, title='Metrics') normalize_columns: bool | None = Field(False, title='Normalize Columns') @@ -543,6 +699,44 @@ class SupersetDatasourceBundle(BaseModel): datasets: list[SupersetDatasetDef] | None = Field(None, title='Datasets') +class SupersetVisualizationBundle(BaseModel): + charts: list[SupersetChartDef] | None = Field(None, title='Charts') + dashboards: list[SupersetDashboardDef] | None = Field(None, title='Dashboards') + viz_collections: dict[str, dict[str, DashboardIdentifier]] | None = Field( + None, title='Viz Collections' + ) + + +class TableMetaInfoBase(BaseModel): + column_properties: dict[str, ColumnProperties] | None = Field( + None, title='Column Properties' + ) + columns: list[str] = Field(..., title='Columns') + foreign_key_constraints: list[ForeignKeyConstraintBase] | None = Field( + None, title='Foreign Key Constraints' + ) + indexes: list[list[str]] | None = Field(None, title='Indexes') + name: str = Field(..., title='Name') + primary_key: list[str] | None = Field(None, title='Primary Key') + schema_name: str | None = Field('main', title='Schema Name') + sql_column_types: list[str] = Field(..., title='Sql Column Types') + + +class VisualizationImportResponse(BaseModel): + charts: list[SupersetChartDef] | None = Field(None, title='Charts') + dashboards: list[SupersetDashboardDef] | None = Field(None, title='Dashboards') + databases: list[SupersetDatabaseDef] | None = Field(None, title='Databases') + datasets: list[SupersetDatasetDef] | None = Field(None, title='Datasets') + metadata: SupersetMetadataDef | None = None + + +class ClearDBResponse(BaseModel): + dropped_mitm_datasets: list[ListTrackedMitMDataset] | None = Field( + None, title='Dropped Mitm Datasets' + ) + dropped_schemas: list[str] | None = Field(None, title='Dropped Schemas') + + class ConceptMapping(BaseModel): attribute_dtypes: list[MITMDataType] | None = Field(None, title='Attribute Dtypes') attributes: list[str] | None = Field(None, title='Attributes') @@ -562,6 +756,17 @@ class ConceptMapping(BaseModel): type_col: str = Field(..., title='Type Col') +class DBMetaInfoBase(BaseModel): + db_structure: dict[str, dict[str, TableMetaInfoBase]] = Field( + ..., title='Db Structure' + ) + tables: dict[str, TableMetaInfoBase] = Field(..., title='Tables') + + +class DBMetaResponse(BaseModel): + db_meta: DBMetaInfoBase | None = None + + class HeaderInput(BaseModel): header_entries: list[HeaderEntry] | None = Field(None, title='Header Entries') mitm: MITM @@ -580,7 +785,7 @@ class QueryObject(BaseModel): None, title='Applied Time Extras' ) columns: list[str | SupersetAdhocColumn] | None = Field(None, title='Columns') - datasource: DatasourceIdentifier | None = None + datasource: ChartDatasource | None = None extras: QueryObjectExtras | None = None filters: list[QueryObjectFilterClause] | None = Field(None, title='Filters') from_dttm: datetime | None = Field(None, title='From Dttm') @@ -616,8 +821,16 @@ class RegisterExternalMitMDatasetRequest(BaseModel): sql_alchemy_uri: AnyUrl = Field(..., title='Sql Alchemy Uri') +class SupersetAssetsImport(BaseModel): + charts: list[SupersetChartDef] | None = Field(None, title='Charts') + dashboards: list[SupersetDashboardDef] | None = Field(None, title='Dashboards') + databases: list[SupersetDatabaseDef] | None = Field(None, title='Databases') + datasets: list[SupersetDatasetDef] | None = Field(None, title='Datasets') + metadata: SupersetMetadataDef | None = None + + class SupersetMitMDatasetDef(BaseModel): - dashboards: list[RelatedDashboard] | None = Field(None, title='Dashboards') + dashboards: list[DashboardIdentifier] | None = Field(None, title='Dashboards') database_uuid: UUID = Field(..., title='Database Uuid') """ Better annotation for UUID. Parses from string format, serializes to string format. @@ -625,8 +838,8 @@ class SupersetMitMDatasetDef(BaseModel): dataset_name: str = Field(..., title='Dataset Name') mitm: MITM mitm_header: HeaderOutput | None = None - slices: list[RelatedSlice] | None = Field(None, title='Slices') - tables: list[RelatedTable] | None = Field(None, title='Tables') + slices: list[ChartIdentifier] | None = Field(None, title='Slices') + tables: list[DatasetIdentifier] | None = Field(None, title='Tables') uuid: UUID = Field(..., title='Uuid') """ Better annotation for UUID. Parses from string format, serializes to string format. @@ -636,7 +849,9 @@ class SupersetMitMDatasetDef(BaseModel): class TrackedMitMDataset(BaseModel): dataset_name: str = Field(..., title='Dataset Name') - is_local: bool | None = Field(True, title='Is Local') + identifier_bundle: MitMDatasetIdentifierBundle + is_managed_locally: bool | None = Field(True, title='Is Managed Locally') + last_edited: datetime | None = Field(None, title='Last Edited') mitm_header: HeaderOutput schema_name: str = Field(..., title='Schema Name') sql_alchemy_uri: AnyUrl = Field(..., title='Sql Alchemy Uri') @@ -657,24 +872,30 @@ class AddTrackedMitMDatasetRequest(BaseModel): uuid: UUID | None = Field(None, title='Uuid') -class BodyGenerateMitmDatasetBundleDefinitionsMitmDatasetPost(BaseModel): - db_conn_info: SupersetDBConnectionInfo +class GenerateIndependentMitMDatasetDefinitionRequest(BaseModel): + dataset_name: str = Field(..., title='Dataset Name') + db_conn_info: DBConnectionInfo + identifiers: MitMDatasetIdentifierBundle | None = None mitm_header: HeaderInput -class BodyGenerateMitmDatasetImportDefinitionsMitmDatasetImportPost(BaseModel): - db_conn_info: SupersetDBConnectionInfo - mitm_header: HeaderInput +class MitMDatasetBundleResponse(BaseModel): + datasource_bundle: SupersetDatasourceBundle + mitm_dataset: SupersetMitMDatasetDef + visualization_bundle: SupersetVisualizationBundle | None = None -class BodyGenerateMitmDatasetImportZipDefinitionsMitmDatasetImportZipPost(BaseModel): - db_conn_info: SupersetDBConnectionInfo - mitm_header: HeaderInput +class MitMDatasetImportResponse(BaseModel): + base_assets: SupersetAssetsImport | None = None + metadata: SupersetMetadataDef | None = None + mitm_datasets: list[SupersetMitMDatasetDef] | None = Field( + ..., title='Mitm Datasets' + ) class QueryContext(BaseModel): custom_cache_timeout: int | None = Field(None, title='Custom Cache Timeout') - datasource: DatasourceIdentifier + datasource: ChartDatasource force: bool | None = Field(False, title='Force') form_data: FormData | None = None queries: list[QueryObject] | None = Field(None, title='Queries') @@ -686,52 +907,3 @@ class RegisterMitMResponse(BaseModel): msg: str | None = Field(None, title='Msg') status: Status = Field(..., title='Status') tracked_mitm_dataset: TrackedMitMDataset | None = None - - -class SupersetChartDef(BaseModel): - cache_timeout: int | None = Field(None, title='Cache Timeout') - certification_details: str | None = Field(None, title='Certification Details') - certified_by: str | None = Field(None, title='Certified By') - dataset_uuid: UUID = Field(..., title='Dataset Uuid') - """ - Better annotation for UUID. Parses from string format, serializes to string format. - """ - description: str | None = Field(None, title='Description') - external_url: AnyUrl | None = Field(None, title='External Url') - is_managed_externally: bool | None = Field(False, title='Is Managed Externally') - params: ChartParams | None = None - query_context: QueryContext | None = None - slice_name: str = Field(..., title='Slice Name') - uuid: UUID = Field(..., title='Uuid') - """ - Better annotation for UUID. Parses from string format, serializes to string format. - """ - version: str | None = Field('1.0.0', title='Version') - viz_type: SupersetVizType - - -class SupersetVisualizationBundle(BaseModel): - charts: list[SupersetChartDef] | None = Field(None, title='Charts') - dashboards: list[SupersetDashboardDef] | None = Field(None, title='Dashboards') - - -class SupersetAssetsImport(BaseModel): - charts: list[SupersetChartDef] | None = Field(None, title='Charts') - dashboards: list[SupersetDashboardDef] | None = Field(None, title='Dashboards') - databases: list[SupersetDatabaseDef] | None = Field(None, title='Databases') - datasets: list[SupersetDatasetDef] | None = Field(None, title='Datasets') - metadata: SupersetMetadataDef | None = None - - -class SupersetMitMDatasetBundle(BaseModel): - datasource_bundle: SupersetDatasourceBundle - mitm_dataset: SupersetMitMDatasetDef - visualization_bundle: SupersetVisualizationBundle | None = None - - -class SupersetMitMDatasetImport(BaseModel): - base_assets: SupersetAssetsImport | None = None - metadata: SupersetMetadataDef | None = None - mitm_datasets: list[SupersetMitMDatasetDef] | None = Field( - ..., title='Mitm Datasets' - ) diff --git a/superset/commands/mitm/mitm_service/upload.py b/superset/commands/mitm/mitm_service/upload.py index c38830dc1c..d48b32306d 100644 --- a/superset/commands/mitm/mitm_service/upload.py +++ b/superset/commands/mitm/mitm_service/upload.py @@ -55,7 +55,7 @@ class UploadMitMDatasetCommand(BaseCommand): definition_response = external_service_call_manager.sync_service_call( ExternalService.MITM, generate_import_request) contents = None - if definition_response.status_code == 200 and definition_response.content: + if definition_response.status_code == 200 and definition_response.content is not None: with zipfile.ZipFile(definition_response.content) as bundle: contents = get_contents_from_bundle(bundle) if contents: diff --git a/superset/commands/mitm/mitm_service/utils.py b/superset/commands/mitm/mitm_service/utils.py new file mode 100644 index 0000000000..cc3b2ba833 --- /dev/null +++ b/superset/commands/mitm/mitm_service/utils.py @@ -0,0 +1,15 @@ +from superset.exceptions import SupersetSecurityException + +from superset import security_manager +from ..exceptions import MitMDatasetForbiddenError + +def test_access(mitm_dataset_id: int) -> bool: + from superset.daos.mitm_dataset import MitMDatasetDAO + model = MitMDatasetDAO.find_by_id(mitm_dataset_id) + if not model: + return False + try: + security_manager.raise_for_ownership(model) + return True + except SupersetSecurityException as exc: + raise MitMDatasetForbiddenError() from exc diff --git a/superset/customization/ext_service_call/api.py b/superset/customization/ext_service_call/api.py index f7c02b1ecf..f4c181d4db 100644 --- a/superset/customization/ext_service_call/api.py +++ b/superset/customization/ext_service_call/api.py @@ -23,7 +23,7 @@ class CallExternalService(BaseSupersetApi): # @permission_name('post') def call_service(self, ext_service: str, subpath: str = '', **kwargs): from superset.customization.external_service_support.forwardable_request import \ - ForwardableRequest + ForwardableRequestBase, forward_to_endpoint from superset.customization.external_service_support.service_registry import \ ExternalService try: @@ -31,10 +31,10 @@ class CallExternalService(BaseSupersetApi): except KeyError as exc: raise UnknownExternalServiceError() from exc - forwarded_request = ForwardableRequest.with_werkzeug_request_data(subpath, - request) + forwardable_request = forward_to_endpoint(subpath, request, file_handling='raw') + job_metadata = external_service_call_manager.submit_async_service_call( - ext_service, forwarded_request, user_id=get_user_id()) + ext_service, forwardable_request, user_id=get_user_id()) return self.response( 202, diff --git a/superset/customization/external_service_support/common.py b/superset/customization/external_service_support/common.py index 7a23036d61..0254dc3238 100644 --- a/superset/customization/external_service_support/common.py +++ b/superset/customization/external_service_support/common.py @@ -1,4 +1,5 @@ -from typing import Literal, TypedDict +from collections.abc import Callable +from typing import Literal, TypedDict, Generator, Optional, Protocol AsyncResultStatusValue = Literal['pending', 'running', 'error', 'done'] @@ -29,3 +30,4 @@ def _add_user_metadata(job_metadata: AsyncJobMetadata) -> AsyncJobMetadata: from superset import security_manager return {**job_metadata, "guest_token": guest_user.guest_token} if ( guest_user := security_manager.get_current_guest_user_if_guest()) else job_metadata + diff --git a/superset/customization/external_service_support/forwardable_request.py b/superset/customization/external_service_support/forwardable_request.py index da737e990d..da642ad825 100644 --- a/superset/customization/external_service_support/forwardable_request.py +++ b/superset/customization/external_service_support/forwardable_request.py @@ -1,71 +1,92 @@ +import io import os import shutil import tempfile import urllib.parse -from typing import Any, Self, TypeVar, Type +import uuid +from abc import abstractmethod, ABC +from typing import Any, Self, Generator, Iterator, Iterable, Callable, Literal, IO import pydantic import requests import werkzeug.utils from flask import Request from pydantic import ConfigDict +from superset.utils.cache import generate_cache_key from werkzeug.datastructures import Headers +from superset.commands.mitm.caching.utils import collect_chunks, chunked_raw_io -class ForwardableRequest(pydantic.BaseModel): + +class ChunkedStream: + def __init__(self, chunk_gen: Iterable[bytes]): + self.chunk_gen = chunk_gen + self.iterator = iter(chunk_gen) + + def __iter__(self): + return self.iterator + + def read(self, size=-1) -> bytes: + try: + return next(self.iterator) + except StopIteration: + return b"" + + +CachedFile = tuple[str, int] +CacheKey = str + + +def stream_cached_bytes(base_cache_key: str) -> Generator[bytes, None, None]: + from superset.commands.mitm.caching.cache_data import ReadStreamedCacheCommand + with ReadStreamedCacheCommand(base_cache_key).run(delete_after=True) as chunks: + for chunk in chunks: + yield chunk + +def cache_raw_io(base_cache_key: str, raw_io: io.IOBase | IO[bytes]) -> CacheKey: + from superset.commands.mitm.caching.cache_data import StreamIntoCacheCommand + StreamIntoCacheCommand(base_cache_key, lambda: chunked_raw_io(raw_io), expiry_timeout=180).run() + return base_cache_key + +def with_file_meta(k: str, + f: Any, + fms: dict[str, tuple[ + str, str | None, dict[str, str]]] | None = None) -> tuple[ + str, Any, str | None, dict[str, str]]: + if (fm := fms.get(k)) is not None: + fn, ct, h = fm + return fn, f, ct, h + else: + return k, f, None, {} + + +class TempDirMixin(pydantic.BaseModel): + tempdir: os.PathLike[str] | None = None + + @property + def post_actions(self) -> list[Callable[[], ...]]: + def del_tempdir(): + if self.tempdir: + shutil.rmtree(self.tempdir, ignore_errors=True) + return [del_tempdir] + +class ForwardableRequestBase(pydantic.BaseModel, ABC): model_config = ConfigDict(arbitrary_types_allowed=True) headers: list[tuple[str, str]] path: str method: str - encoding: str | None = None base_url: str | None = None query: str | None = None url_params: dict[str, Any] | None = None - data: bytes | None = None - form_data: dict[str, Any] | None = None - json_data: dict[str, Any] | None = None - files: dict[str, tuple[ - str, os.PathLike[str] | bytes, str | None, dict[str, str]]] | None = None - tempdir: os.PathLike[str] | None = None - request_kwargs: dict[str, Any] | None = None - - @classmethod - def with_werkzeug_request_data(cls, subpath: str, request: Request, - save_files: bool = True) -> Self: - kwargs = dict(headers=list(request.headers.items()), method=str(request.method), - encoding=str(request.content_encoding), path=subpath) - if request.content_encoding == 'multipart/form-data': - form_data = request.form.to_dict() - files = {} - td = None - if len(request.files) > 0 and save_files: - td = tempfile.mkdtemp(prefix='forwarded_request') - for n, f in request.files.items(): - secure_name = werkzeug.utils.secure_filename(f.filename) - path = os.path.join(td, secure_name) - f.save(path) - files[n] = ( - f.filename, path, f.content_type, - dict(f.headers.to_wsgi_list())) - else: - for n, f in request.files.items(): - files[n] = (f.filename, f.stream.read(), f.content_type, - dict(f.headers.to_wsgi_list())) - - kwargs |= dict(form_data=form_data, files=files, tempdir=td) - elif request.content_encoding == 'application/json': - kwargs |= dict(json_data=request.json) - else: - kwargs |= dict(data=request.get_data()) - return cls(**kwargs) + encoding: str | None = None + request_kwarg_overrides: dict[str, Any] | None = None @classmethod def from_dict(cls, dic: dict[str, Any]) -> Self: return cls.model_validate(dic, strict=False) - @property - def url(self) -> str: + def build_url(self) -> str: base_url = self.base_url or '' rel_url = (self.path or '') + (f'?{self.query}' if self.query else '') return urllib.parse.urljoin(base_url, rel_url) @@ -73,63 +94,156 @@ class ForwardableRequest(pydantic.BaseModel): def to_dict(self) -> dict[str, Any]: return self.model_dump(mode='python', round_trip=True, by_alias=True) - def make_request(self, override_base_url: str = None, **kwargs) -> requests.Response: - url = urllib.parse.urljoin(override_base_url, self.url) if override_base_url else self.url - full_kwargs = dict(headers=Headers(self.headers), params=self.url_params) - if self.encoding == 'multipart/form-data': - def open_if_needed(f): - if isinstance(f, os.PathLike): - return open(f, 'rb') - else: - return f - - opened_files = {n: (fn, open_if_needed(path), content_type, headers) for - n, (fn, path, content_type, headers) in self.files.items()} - full_kwargs |= dict(data=self.form_data, files=opened_files) - elif self.encoding == 'application/json': - full_kwargs['json'] = self.json_data - else: - full_kwargs['data'] = self.data - full_kwargs |= kwargs - if self.request_kwargs: - full_kwargs |= self.request_kwargs - response = requests.request(self.method, url, **full_kwargs) - if self.tempdir: - shutil.rmtree(self.tempdir, ignore_errors=True) - return response - - def as_complete(self, **kwargs) -> 'CompleteForwardableRequest': - obj = self.model_dump(round_trip=True) | kwargs - return CompleteForwardableRequest.model_validate(obj) - + def mk_request_kwargs(self) -> dict[str, Any]: + return { + 'method': self.method, + 'url': self.build_url(), + 'headers': Headers(self.headers), + 'params': self.url_params} -class CompleteForwardableRequest(ForwardableRequest): - base_url: str - - -PT = TypeVar('PT', bound=pydantic.BaseModel) + def build_request(self) -> requests.Request: + kwargs = self.mk_request_kwargs() + if self.request_kwarg_overrides: + kwargs |= self.request_kwarg_overrides + return requests.Request(**kwargs) +class JsonRequest(ForwardableRequestBase): + json_data: dict[str, Any] | None = None -def _make_pydantic_serializable(obj: PT) -> dict[str, Any]: - return obj.model_dump(mode='python', round_trip=True) + def mk_request_kwargs(self) -> dict[str, Any]: + return super().mk_request_kwargs() | {'json': self.json_data} -def _revive_serialized_pydantic(obj: dict, cls: Type[PT]) -> PT: - return cls.model_validate(obj) +class FormDataRequest(TempDirMixin, ForwardableRequestBase): + model_config = ConfigDict(arbitrary_types_allowed=True) + form_data: dict[str, Any] | None = None -class SerializationSupport: - @staticmethod - def dump(obj: pydantic.BaseModel | dict) -> dict[str, Any] | None: - if isinstance(obj, pydantic.BaseModel): - return _make_pydantic_serializable(obj) - elif isinstance(obj, dict): - return obj + raw_files: dict[str, bytes] + filesystem_files: dict[str, str | os.PathLike[str]] + cached_files: dict[str, CacheKey] + + files_meta: dict[str, tuple[str, str | None, dict[str, str]]] = pydantic.Field( + default_factory=dict) + + stream: bool = False + + def mk_request_kwargs(self) -> dict[str, Any]: + base_kwargs = super().mk_request_kwargs() + + from requests_toolbelt import MultipartEncoder + fd = self.form_data or {} + + raw_files = {k: with_file_meta(k, v, self.files_meta) for k, v in + self.raw_files.items()} + filesystem_files = {k: with_file_meta(k, open(v, 'rb'), self.files_meta) for + k, v in self.filesystem_files.items()} + cached_files = { + k: with_file_meta(k, stream_cached_bytes(v), self.files_meta) for k, v + in self.cached_files.items()} + multipart_data = MultipartEncoder( + fields=fd | raw_files | filesystem_files | cached_files, + ) + headers = Headers(self.headers) + headers.add_header('Content-Type', multipart_data.content_type) + return base_kwargs | { + 'data': multipart_data if self.stream else multipart_data.to_string(), + 'headers': headers} - @staticmethod - def read_as(obj: dict, cls: Type[PT]) -> PT | None: - if isinstance(obj, dict): - return _revive_serialized_pydantic(obj, cls) + @property + def post_actions(self) -> list[Callable[[], ...]]: + return super().post_actions + + +class RawDataRequest(TempDirMixin, ForwardableRequestBase): + raw_data: bytes | None = None + filesystem_data: str | os.PathLike[str] | None = None + cached_data: CacheKey | None = None + stream: bool = False + + def mk_request_kwargs(self) -> dict[str, Any]: + assert not (self.raw_data is None and self.filesystem_data is None and self.cached_data is None), 'one form of data must be provided' + assert not (self.raw_data is not None and self.filesystem_data is not None and self.cached_data is not None), 'only one form of data can be provided' + + data = self.raw_data + if self.filesystem_data: + data = open(self.filesystem_data, 'rb') + if not self.stream: + x = data.read() + data.close() + data = x + if self.cached_data: + data = stream_cached_bytes(self.cached_data) + if not self.stream: + data = collect_chunks(data) + + return super().mk_request_kwargs() | {'data': data } + @property + def post_actions(self) -> list[Callable[[], ...]]: + return super().post_actions + +def tempsave_raw_io(raw_io: io.IOBase | IO[bytes]) -> tuple[str, str | os.PathLike[str]]: + td = tempfile.mkdtemp(prefix='forwarded_request') + path = os.path.join(td, 'raw_data') + with open(path, 'wb') as f: + f.write(raw_io.read()) + return td, path + +def tempsave_request_files(flask_request: Request) -> tuple[str | None, dict[str, str| os.PathLike[str]]]: + td = None + filesystem_files = {} + if len(flask_request.files) > 0: + td = tempfile.mkdtemp(prefix='forwarded_request') + for n, f in flask_request.files.items(): + secure_name = werkzeug.utils.secure_filename(f.filename) + path = os.path.join(td, secure_name) + f.save(path) + filesystem_files[n] = path + return td, filesystem_files + +def raw_request_files(flask_request: Request) -> dict[str, bytes]: + return {n: f.stream.read() for n, f in flask_request.files.items()} + +def cache_request_files(base_cache_key:str, flask_request: Request) -> dict[str, CacheKey]: + cached_files= {} + for n, f in flask_request.files.items(): + file_specific_base_cache_key = f'{base_cache_key}:{n}' + cached_files[n] = cache_raw_io(file_specific_base_cache_key, f.stream) + return cached_files + +def get_file_meta(flask_request: Request) -> dict[str, tuple[str, str | None, dict[str, str]]]: + return {n: (f.filename, f.content_type, dict(f.headers.to_wsgi_list())) for n, f in flask_request.files.items() } + +def forward_to_endpoint(endpoint: str, flask_request: Request, file_handling: Literal['raw', 'cache', 'filesystem'] = 'raw') -> ForwardableRequestBase: + kwargs = dict(headers=list(flask_request.headers.items()), method=str(flask_request.method), + path=endpoint) + if flask_request.content_encoding == 'multipart/form-data': + kwargs |= dict(files_meta=get_file_meta(flask_request)) + if file_handling == 'filesystem': + td, filesystem_files = tempsave_request_files(flask_request) + kwargs |= dict(tempdir=td, filesystem_files=filesystem_files) + elif file_handling == 'cache': + cached_files = cache_request_files(f'forwarded-request:files:{uuid.uuid4()}', flask_request) + kwargs |= dict(cached_files=cached_files) + elif file_handling == 'raw': + kwargs |= dict(raw_files=raw_request_files(flask_request)) + else: + raise ValueError(f'unknown file handling mode: {file_handling}') + + return FormDataRequest(**kwargs, form_data=flask_request.form.to_dict()) + elif flask_request.content_encoding == 'application/json': + return JsonRequest(**kwargs, json_data=flask_request.json) + else: + if file_handling == 'filesystem': + td, filesystem_files = tempsave_raw_io(flask_request.stream) + kwargs |= dict(tempdir=td, filesystem_files=filesystem_files) + elif file_handling == 'cache': + cached_data = cache_raw_io(f'forwarded-request:data:{uuid.uuid4()}', flask_request.stream) + kwargs |= dict(cached_data=cached_data) + elif file_handling == 'raw': + kwargs |= dict(raw_data=flask_request.get_data(cache=False)) + else: + raise ValueError(f'unknown file handling mode: {file_handling}') + return RawDataRequest(**kwargs) -srzl_support = SerializationSupport() diff --git a/superset/customization/external_service_support/pydantic_utils.py b/superset/customization/external_service_support/pydantic_utils.py new file mode 100644 index 0000000000..5e01a449cc --- /dev/null +++ b/superset/customization/external_service_support/pydantic_utils.py @@ -0,0 +1,32 @@ +from typing import TypeVar, Any, Type + +import pydantic + +PT = TypeVar('PT', bound=pydantic.BaseModel) + + +def _make_pydantic_serializable(obj: PT) -> dict[str, Any]: + return obj.model_dump(mode='python', round_trip=True) + + +def _revive_serialized_pydantic(obj: dict, cls: Type[PT]) -> PT: + return cls.model_validate(obj) + + +class SerializationSupport: + @staticmethod + def dump(obj: pydantic.BaseModel | dict) -> dict[str, Any] | None: + if isinstance(obj, pydantic.BaseModel): + return _make_pydantic_serializable(obj) + elif isinstance(obj, dict): + return obj + return None + + @staticmethod + def read_as(obj: dict, cls: Type[PT]) -> PT | None: + if isinstance(obj, dict): + return _revive_serialized_pydantic(obj, cls) + return None + + +srzl_support = SerializationSupport() diff --git a/superset/customization/external_service_support/service_call_manager.py b/superset/customization/external_service_support/service_call_manager.py index ee35e3af80..2fde64d942 100644 --- a/superset/customization/external_service_support/service_call_manager.py +++ b/superset/customization/external_service_support/service_call_manager.py @@ -2,14 +2,14 @@ from __future__ import annotations import logging from json import JSONDecodeError -from typing import Any, TYPE_CHECKING +from typing import Any, TYPE_CHECKING, Generator from flask import Flask from flask_caching import Cache from superset.utils import json from .common import _add_user_metadata, AsyncResultStatus, AsyncResultStatusValue, \ - AsyncEventError, AsyncJobMetadata + AsyncEventError, AsyncJobMetadata, cache_streaming_keys if TYPE_CHECKING: from superset.async_events.async_query_manager import AsyncQueryManager @@ -17,7 +17,7 @@ if TYPE_CHECKING: AsyncInternalHandler, AsyncForwardableRequestHandler, \ SyncForwardableRequestHandler from requests import Response - from .forwardable_request import ForwardableRequest, CompleteForwardableRequest + from .forwardable_request import ForwardableRequestBase logger = logging.getLogger(__name__) @@ -53,13 +53,13 @@ class ExternalServiceCallManager: return _add_user_metadata(job_metadata) def complete_request(self, service: ExternalService, - forwardable_request: ForwardableRequest) -> CompleteForwardableRequest: + forwardable_request: ForwardableRequestBase) -> ForwardableRequestBase: service_properties = self._external_services[service] - return forwardable_request.as_complete(base_url=service_properties.base_url) + return forwardable_request.model_copy(update=dict(base_url=service_properties.base_url)) def sync_service_call(self, service: ExternalService, - forwardable_request: ForwardableRequest, + forwardable_request: ForwardableRequestBase, **kwargs) -> Response: return self._sync_call_handler(self.complete_request(service, forwardable_request), @@ -68,7 +68,7 @@ class ExternalServiceCallManager: def submit_async_service_call( self, service: ExternalService, - forwardable_request: ForwardableRequest, + forwardable_request: ForwardableRequestBase, user_id: int | None = None) -> AsyncJobMetadata: job_metadata = self._init_job(str(service), user_id) @@ -89,9 +89,9 @@ class ExternalServiceCallManager: return job_metadata def complete_self_handled(self, - service: ExternalService, - job_metadata: AsyncJobMetadata, - cache_key: str | None = None): + service: ExternalService, + job_metadata: AsyncJobMetadata, + cache_key: str | None = None): service_properties = self._external_services[service] result_url = None if cache_key and service_properties.result_base_url: @@ -122,14 +122,18 @@ class ExternalServiceCallManager: if v := self.cache.get(cache_key): return v else: - logger.error(f'Retrieval of job result failed: {cache_key}') + logger.error(f'Retrieval of job result failed for cache key: {cache_key}') + return None def retrieve_job_result_json(self, cache_key: str) -> str | int | float | \ dict[str, Any] | None: - if v := self.cache.get(cache_key): + if v := self.retrieve_job_result(cache_key): try: if v is not None: return json.loads(v, encoding='utf-8') + return None except JSONDecodeError as ex: logger.error( f'JSON decoding of job result failed: {cache_key} with {ex.msg}') + return None + return None diff --git a/superset/customization/mitm_datasets/api.py b/superset/customization/mitm_datasets/api.py index 4b95dc09d9..e5a8a21285 100644 --- a/superset/customization/mitm_datasets/api.py +++ b/superset/customization/mitm_datasets/api.py @@ -113,7 +113,6 @@ class MitMDatasetRestApi(BaseSupersetModelRestApi): 'owners.id', 'owners.first_name', 'owners.last_name', - 'owners.full_name', 'tables.id', 'tables.uuid', 'tables.table_name', @@ -571,3 +570,32 @@ class MitMDatasetRestApi(BaseSupersetModelRestApi): ExternalService.MITM, handler, user_id=get_user_id()) return self.response(202, **job_metadata) + + @expose('/download/<pk>', methods=('POST',)) + @statsd_metrics + @protect(allow_browser_login=True) + @handle_api_exception + @event_logger.log_this_with_context( + action=lambda self, *args, **kwargs: f'{self.__class__.__name__}.download', + log_to_statsd=False, + ) + def download(self, pk: int, **kwargs: Any) -> Response: + if not _is_accessible(pk): + return self.response_404() + + from superset.customization.external_service_support.service_registry import \ + ExternalService + from superset.extensions import external_service_call_manager + from superset.tasks.mitm.download_mitm_dataset import download_mitm_dataset_task + result_base_url = external_service_call_manager.external_services.get( + ExternalService.MITM).result_base_url + + def handler(jm): + return download_mitm_dataset_task.delay(jm, + pk, + result_base_url=result_base_url) + + job_metadata = external_service_call_manager.submit_self_handled( + ExternalService.MITM, handler, user_id=get_user_id()) + + return self.response(202, **job_metadata) diff --git a/superset/customization/mitm_datasets/schemas.py b/superset/customization/mitm_datasets/schemas.py index b46b891cdc..d87c9dadb1 100644 --- a/superset/customization/mitm_datasets/schemas.py +++ b/superset/customization/mitm_datasets/schemas.py @@ -10,7 +10,6 @@ class UserSchema(Schema): username = fields.String() first_name = fields.String() last_name = fields.String() - full_name = fields.String() class RolesSchema(Schema): @@ -66,13 +65,12 @@ class MitMDatasetShowSchema(Schema): changed_by_name = fields.String() changed_by = fields.Nested(UserSchema, - only=['id', 'first_name', 'last_name', 'full_name']) + only=['id', 'first_name', 'last_name']) changed_on = fields.DateTime() created_by = fields.Nested(UserSchema, - only=['id', 'first_name', 'last_name', 'full_name']) + only=['id', 'first_name', 'last_name']) owners = fields.List(fields.Nested(UserSchema, - only=['id', 'first_name', 'last_name', - 'full_name'])) + only=['id', 'first_name', 'last_name'])) class MitMDatasetPostSchema(Schema): diff --git a/superset/customization/mitm_service/api.py b/superset/customization/mitm_service/api.py index 3783414e65..25dcd62f28 100644 --- a/superset/customization/mitm_service/api.py +++ b/superset/customization/mitm_service/api.py @@ -4,90 +4,19 @@ from flask import request, Response from flask_appbuilder import expose from flask_appbuilder.security.decorators import protect -from superset import security_manager -from superset.commands.mitm.exceptions import MitMDatasetForbiddenError -from superset.exceptions import SupersetSecurityException from superset.extensions import external_service_call_manager, event_logger from superset.utils.core import get_user_id from superset.views.base_api import BaseSupersetApi, statsd_metrics from superset.views.error_handling import handle_api_exception -def _is_accessible(mitm_dataset_id: int) -> bool: - from superset.daos.mitm_dataset import MitMDatasetDAO - model = MitMDatasetDAO.find_by_id(mitm_dataset_id) - if not model: - return False - try: - security_manager.raise_for_ownership(model) - return True - except SupersetSecurityException as exc: - raise MitMDatasetForbiddenError() from exc - - class CallMitMService(BaseSupersetApi): resource_name = 'mitm_service' allow_browser_login = True class_permission_name = 'MitMDataset' - method_permission_name = {'upload': 'write', 'delete': 'write', 'download': 'read'} - - @expose('/upload/', methods=('POST',)) - @statsd_metrics - @protect(allow_browser_login=True) - @handle_api_exception - @event_logger.log_this_with_context( - action=lambda self, *args, **kwargs: f'{self.__class__.__name__}.upload', - log_to_statsd=False, - ) - def upload(self, **kwargs: Any) -> Response: - dataset_name = request.form.get('dataset_name') - mitm_name = request.form.get('mitm_name') - mitm_zip = request.files.get('mitm_zip') - if not mitm_zip or mitm_zip.mimetype != 'application/zip': - return self.response_400() - - mitm_bytes = mitm_zip.read() - - from superset.customization.external_service_support.service_registry import \ - ExternalService - from superset.tasks.mitm.upload_mitm_dataset import upload_mitm_dataset_task - - def handler(jm): - return upload_mitm_dataset_task.delay(jm, dataset_name, mitm_name, - mitm_bytes) - - job_metadata = external_service_call_manager.submit_self_handled( - ExternalService.MITM, handler, user_id=get_user_id()) - - return self.response(202, **job_metadata) + include_route_methods = {'upload', 'download', 'drop'} + method_permission_name = {'upload': 'write', 'drop': 'write', 'download': 'read'} - @expose('/download/<pk>', methods=('POST',)) - @statsd_metrics - @protect(allow_browser_login=True) - @handle_api_exception - @event_logger.log_this_with_context( - action=lambda self, *args, **kwargs: f'{self.__class__.__name__}.download', - log_to_statsd=False, - ) - def download(self, pk: int, **kwargs: Any) -> Response: - if not _is_accessible(pk): - return self.response_404() - - from superset.customization.external_service_support.service_registry import \ - ExternalService - from superset.tasks.mitm.download_mitm_dataset import download_mitm_dataset_task - result_base_url = external_service_call_manager.external_services.get( - ExternalService.MITM).result_base_url - - def handler(jm): - return download_mitm_dataset_task.delay(jm, - pk, - result_base_url=result_base_url) - - job_metadata = external_service_call_manager.submit_self_handled( - ExternalService.MITM, handler, user_id=get_user_id()) - - return self.response(202, **job_metadata) @expose('/drop/<pk>', methods=('DELETE',)) @statsd_metrics @@ -98,7 +27,8 @@ class CallMitMService(BaseSupersetApi): log_to_statsd=False, ) def drop(self, pk: int, **kwargs: Any) -> Response: - if not _is_accessible(pk): + from superset.commands.mitm.mitm_service.utils import test_access + if not test_access(pk): return self.response_404() from superset.customization.external_service_support.service_registry import \ diff --git a/superset/daos/mitm_dataset.py b/superset/daos/mitm_dataset.py index 03dbdda219..cdf02646e7 100644 --- a/superset/daos/mitm_dataset.py +++ b/superset/daos/mitm_dataset.py @@ -19,3 +19,6 @@ class MitMDatasetDAO(BaseDAO[MitMDataset]): ['tables', 'slices', 'dashboards'] } + @staticmethod + def is_accessible(): + ... diff --git a/superset/tasks/mitm/download_mitm_dataset.py b/superset/tasks/mitm/download_mitm_dataset.py index b42ce2c983..e8f6d57b05 100644 --- a/superset/tasks/mitm/download_mitm_dataset.py +++ b/superset/tasks/mitm/download_mitm_dataset.py @@ -26,16 +26,16 @@ def download_mitm_dataset_task(job_metadata: AsyncJobMetadata, mitm_dataset_id: int, result_base_url: str) -> None: external_service_call_manager.call_started(job_metadata) - from superset.commands.mitm.mitm_service.export import \ - ExportUploadedMitMDatasetCommand + from superset.commands.mitm.mitm_service.download import \ + DownloadTrackedMitMDatasetCommand with override_user(_load_user_from_job_metadata(job_metadata), force=False): try: cache_key = generate_cache_key(job_metadata, 'mitm-service-download-') - ExportUploadedMitMDatasetCommand(mitm_dataset_id, - cache=external_service_call_manager.cache, - cache_key=cache_key).run(cache=True) + DownloadTrackedMitMDatasetCommand(mitm_dataset_id, + cache=external_service_call_manager.cache, + cache_key=cache_key).run(cache=True) result_url = result_base_url + '/' + cache_key external_service_call_manager.call_completed(job_metadata, result_url=result_url) diff --git a/superset/tasks/mitm/drop_mitm_dataset.py b/superset/tasks/mitm/drop_mitm_dataset.py index ac2073a514..5a5c184dbb 100644 --- a/superset/tasks/mitm/drop_mitm_dataset.py +++ b/superset/tasks/mitm/drop_mitm_dataset.py @@ -25,11 +25,11 @@ def drop_mitm_dataset_task(job_metadata: AsyncJobMetadata, mitm_dataset_id: int) -> None: external_service_call_manager.call_started(job_metadata) - from ...commands.mitm.mitm_service.delete import DeleteUploadedMitMDatasetCommand + from ...commands.mitm.mitm_service.delete import DeleteTrackedMitMDatasetCommand with override_user(_load_user_from_job_metadata(job_metadata), force=False): try: - DeleteUploadedMitMDatasetCommand(mitm_dataset_id).run() + DeleteTrackedMitMDatasetCommand(mitm_dataset_id).run() external_service_call_manager.call_completed(job_metadata) except CommandException as ex: logger.error( -- GitLab