diff --git a/packages/gooddata-dbt/src/gooddata_dbt/dbt/metrics.py b/packages/gooddata-dbt/src/gooddata_dbt/dbt/metrics.py index 972088bfd..cb0c90240 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/dbt/metrics.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/dbt/metrics.py @@ -1,7 +1,6 @@ # (C) 2023 GoodData Corporation import json import re -from typing import Optional import attrs from gooddata_sdk import CatalogDeclarativeMetric, CatalogDeclarativeModel @@ -26,8 +25,8 @@ @attrs.define(auto_attribs=True, kw_only=True) class DbtModelMetaGoodDataMetricProps(Base): - model_id: Optional[str] = None - format: Optional[str] = None + model_id: str | None = None + format: str | None = None @attrs.define(auto_attribs=True, kw_only=True) @@ -49,11 +48,11 @@ class DbtModelMetric(DbtModelBase): model: str calculation_method: str expression: str - filters: Optional[list[DbtModelMetricFilter]] = None + filters: list[DbtModelMetricFilter] | None = None class DbtModelMetrics: - def __init__(self, model_ids: Optional[list[str]], ldm: CatalogDeclarativeModel) -> None: + def __init__(self, model_ids: list[str] | None, ldm: CatalogDeclarativeModel) -> None: self.model_ids = model_ids self.ldm = ldm with open(DBT_PATH_TO_MANIFEST) as fp: @@ -104,7 +103,7 @@ def get_entity_type(self, table_name: str, expression_entity: str) -> str: else: raise Exception(f"Unsupported entity type {table_name=} {expression_entity=}") - def make_entity_id(self, table_name: str, token: str) -> Optional[str]: + def make_entity_id(self, table_name: str, token: str) -> str | None: entity_type = self.get_entity_type(table_name, token) if not entity_type: return None @@ -125,7 +124,7 @@ def resolve_entities_in_expression(self, expression: str, table_name: str) -> st result_tokens.append(entity_id or token) return " ".join(result_tokens) - def make_gooddata_filter(self, table_name: str, dbt_filters: Optional[list[DbtModelMetricFilter]] = None) -> str: + def make_gooddata_filter(self, table_name: str, dbt_filters: list[DbtModelMetricFilter] | None = None) -> str: # TODO - Quite naive implementation # e.g. missing polishing of values (e.g. SQL vs MAQL enclosers) gd_maql_filters = [] diff --git a/packages/gooddata-dbt/src/gooddata_dbt/dbt/profiles.py b/packages/gooddata-dbt/src/gooddata_dbt/dbt/profiles.py index 8236840db..c50733ae0 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/dbt/profiles.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/dbt/profiles.py @@ -2,7 +2,7 @@ import argparse import os import re -from typing import Optional, Union +from typing import Union from urllib.parse import quote_plus import attrs @@ -97,7 +97,7 @@ class DbtOutputSnowflake(Base): database: str warehouse: str schema: str - query_tag: Optional[str] = None + query_tag: str | None = None def to_gooddata(self, data_source_id: str, schema_name: str) -> CatalogDataSourceSnowflake: return CatalogDataSourceSnowflake( @@ -222,7 +222,7 @@ def inject_env_vars(output_def: dict) -> None: # else do nothing, real value seems to be stored in dbt profile @staticmethod - def to_data_class(output: str, output_def: dict) -> Optional[DbtOutput]: + def to_data_class(output: str, output_def: dict) -> DbtOutput | None: db_type = output_def["type"] if db_type == "postgres": return DbtOutputPostgreSQL.from_dict({"name": output, **output_def}) diff --git a/packages/gooddata-dbt/src/gooddata_dbt/dbt/tables.py b/packages/gooddata-dbt/src/gooddata_dbt/dbt/tables.py index 36aa971e2..36f1dcddf 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/dbt/tables.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/dbt/tables.py @@ -3,7 +3,7 @@ import json import re from pathlib import Path -from typing import Optional, Union +from typing import Union import attrs from gooddata_sdk import CatalogDeclarativeColumn, CatalogDeclarativeTable, CatalogDeclarativeTables @@ -27,22 +27,22 @@ @attrs.define(auto_attribs=True, kw_only=True) class DbtModelMetaGoodDataTableProps(Base): - model_id: Optional[str] = None + model_id: str | None = None @attrs.define(auto_attribs=True, kw_only=True) class DbtModelMetaGoodDataColumnProps(Base): - id: Optional[str] = None - ldm_type: Optional[GoodDataLdmType] = None - referenced_table: Optional[str] = None - label_type: Optional[GoodDataLabelType] = None - attribute_column: Optional[str] = None - sort_column: Optional[str] = None - sort_direction: Optional[GoodDataSortDirection] = None - default_view: Optional[bool] = None + id: str | None = None + ldm_type: GoodDataLdmType | None = None + referenced_table: str | None = None + label_type: GoodDataLabelType | None = None + attribute_column: str | None = None + sort_column: str | None = None + sort_direction: GoodDataSortDirection | None = None + default_view: bool | None = None @property - def gooddata_ref_table_ldm_id(self) -> Optional[str]: + def gooddata_ref_table_ldm_id(self) -> str | None: if self.referenced_table: return self.referenced_table.lower() return None @@ -73,7 +73,7 @@ class DbtModelBase(Base): tags: list[str] # If 2+ references point to the same table, the table plays multiple roles, # it must be generated as multiple datasets - role_name: Optional[str] = None + role_name: str | None = None # TODO - duplicate of backend logic. # Solution: use result of generateLdm as a master template, and override based on dbt metadata only if necessary @@ -120,7 +120,7 @@ def upper_case_name(self) -> None: @attrs.define(auto_attribs=True, kw_only=True) class DbtModelColumn(DbtModelBase): - data_type: Optional[str] + data_type: str | None meta: DbtModelMetaGoodDataColumn = attrs.field(factory=DbtModelMetaGoodDataColumn) # Enable to override LDM ID for LDM entities derived from columns (attributes, ...) @@ -130,21 +130,21 @@ def ldm_id(self) -> str: return self.meta.gooddata.id or self.gooddata_ldm_id @property - def ldm_type(self) -> Optional[str]: + def ldm_type(self) -> str | None: if self.meta.gooddata.ldm_type is None: return None else: return self.meta.gooddata.ldm_type.value @property - def label_type(self) -> Optional[str]: + def label_type(self) -> str | None: if self.meta.gooddata.label_type is None: return None else: return self.meta.gooddata.label_type.value @property - def sort_direction(self) -> Optional[str]: + def sort_direction(self) -> str | None: if self.meta.gooddata.sort_direction is None: return None else: @@ -387,7 +387,7 @@ def make_facts(table: DbtModelTable) -> list[dict]: return facts @staticmethod - def make_labels(table: DbtModelTable, attribute_column: DbtModelColumn) -> tuple[list[dict], Optional[dict]]: + def make_labels(table: DbtModelTable, attribute_column: DbtModelColumn) -> tuple[list[dict], dict | None]: labels = [] default_view = None for column in table.columns.values(): @@ -507,7 +507,7 @@ def populate_role_playing_tables(tables: list[DbtModelTable], role_playing_table result.append(table) return result - def make_declarative_datasets(self, data_source_id: str, model_ids: Optional[list[str]]) -> dict: + def make_declarative_datasets(self, data_source_id: str, model_ids: list[str] | None) -> dict: result: dict[str, list] = {"datasets": [], "date_instances": []} model_tables = [t for t in self.tables if not model_ids or t.meta.gooddata.model_id in model_ids] role_playing_tables = self.find_role_playing_tables(model_tables) @@ -517,7 +517,7 @@ def make_declarative_datasets(self, data_source_id: str, model_ids: Optional[lis result = self.make_dataset(data_source_id, table, role_playing_tables, result) return result - def get_entity_type(self, table_name: str, column_name: str) -> Optional[str]: + def get_entity_type(self, table_name: str, column_name: str) -> str | None: comp_table_name = table_name if self.upper_case: comp_table_name = table_name.upper() diff --git a/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py b/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py index 5dfe103ab..6b67030b3 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py @@ -5,7 +5,6 @@ from asyncio import Semaphore from pathlib import Path from time import time -from typing import Optional import tabulate import yaml @@ -36,7 +35,7 @@ def generate_and_put_ldm( data_source_id: str, workspace_id: str, dbt_tables: DbtModelTables, - model_ids: Optional[list[str]], + model_ids: list[str] | None, ) -> None: scan_request = CatalogScanModelRequest(scan_tables=True, scan_views=True) logger.info(f"Scan data source {data_source_id=}") @@ -68,7 +67,7 @@ def deploy_ldm( args: Namespace, all_model_ids: list[str], sdk_wrapper: GoodDataSdkWrapper, - model_ids: Optional[list[str]], + model_ids: list[str] | None, workspace_id: str, ) -> None: logger.info("Generate and put LDM") @@ -186,7 +185,7 @@ async def test_visualizations( logger: logging.Logger, sdk_wrapper: GoodDataSdkWrapper, workspace_id: str, - skip_tests: Optional[list[str]], + skip_tests: list[str] | None, test_visualizations_parallelism: int = 1, ) -> None: start = time() @@ -334,7 +333,7 @@ def process_organization( logger: logging.Logger, sdk_wrapper: GoodDataSdkWrapper, gd_config: GoodDataConfig, - organization: Optional[GoodDataConfigOrganization] = None, + organization: GoodDataConfigOrganization | None = None, ) -> None: if args.method == "upload_notification": dbt_profiles = DbtProfiles(args) diff --git a/packages/gooddata-dbt/src/gooddata_dbt/gooddata/config.py b/packages/gooddata-dbt/src/gooddata_dbt/gooddata/config.py index 0e02a9d61..5e675ad78 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/gooddata/config.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/gooddata/config.py @@ -1,5 +1,4 @@ # (C) 2023 GoodData Corporation -from typing import Optional import attr import attrs @@ -37,8 +36,8 @@ class GoodDataConfigProduct(Base): name: str environment_setup_id: str model_ids: list[str] = attr.field(factory=list) - localization: Optional[GoodDataConfigLocalization] = None - skip_tests: Optional[list[str]] = None + localization: GoodDataConfigLocalization | None = None + skip_tests: list[str] | None = None @attrs.define(auto_attribs=True, kw_only=True) @@ -49,7 +48,7 @@ class GoodDataConfigOrganization(Base): @attrs.define(auto_attribs=True, kw_only=True) class GoodDataGlobalConfig(Base): - test_visualizations_parallelism: Optional[int] = 1 + test_visualizations_parallelism: int | None = 1 @attrs.define(auto_attribs=True, kw_only=True) diff --git a/packages/gooddata-dbt/src/gooddata_dbt/sdk_wrapper.py b/packages/gooddata-dbt/src/gooddata_dbt/sdk_wrapper.py index bec10a40f..7b3db8b53 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/sdk_wrapper.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/sdk_wrapper.py @@ -1,7 +1,6 @@ # (C) 2023 GoodData Corporation import argparse from logging import Logger -from typing import Optional from gooddata_sdk import GoodDataSdk @@ -11,7 +10,7 @@ class GoodDataSdkWrapper: # Timeout=600 because supporting waiting for GoodData services to start def __init__( - self, args: argparse.Namespace, logger: Logger, profile: Optional[str] = None, timeout: int = 600 + self, args: argparse.Namespace, logger: Logger, profile: str | None = None, timeout: int = 600 ) -> None: self.args = args self.logger = logger @@ -22,7 +21,7 @@ def __init__( if not self.args.dry_run: self.wait_for_gooddata_is_up(self.timeout) - def get_host_from_sdk(self) -> Optional[str]: + def get_host_from_sdk(self) -> str | None: # TODO - make _hostname public in gooddata_sdk return self.sdk.client._hostname @@ -54,7 +53,7 @@ def wait_for_gooddata_is_up(self, timeout: int) -> None: self.sdk.support.wait_till_available(timeout=timeout) self.logger.info(f"Host {host} is up") - def pre_cache_visualizations(self, workspaces: Optional[list] = None) -> None: + def pre_cache_visualizations(self, workspaces: list | None = None) -> None: if not workspaces: workspaces = [w.id for w in self.sdk.catalog_workspace.list_workspaces()] for workspace_id in workspaces: diff --git a/packages/gooddata-fdw/src/gooddata_fdw/column_utils.py b/packages/gooddata-fdw/src/gooddata_fdw/column_utils.py index 095a6a184..2dbda909e 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/column_utils.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/column_utils.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional, Union +from typing import Union import gooddata_sdk as sdk from gooddata_sdk import Attribute, CatalogAttribute, Metric @@ -26,7 +26,7 @@ def table_col_as_computable(col: ColumnDefinition) -> Union[Attribute, Metric]: ) -def column_data_type_for(attribute: Optional[CatalogAttribute]) -> str: +def column_data_type_for(attribute: CatalogAttribute | None) -> str: """ Determine what postgres type should be used for `attribute`. diff --git a/packages/gooddata-fdw/src/gooddata_fdw/environment.py b/packages/gooddata-fdw/src/gooddata_fdw/environment.py index 8369ced64..33e216689 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/environment.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/environment.py @@ -14,7 +14,7 @@ from __future__ import annotations -from typing import Any, Optional, Union +from typing import Any, Union try: import multicorn @@ -88,12 +88,12 @@ def import_schema( schema: str, srv_options: dict[str, str], options: dict[str, str], - restriction_type: Optional[str], + restriction_type: str | None, restricts: list[str], ) -> list[TableDefinition]: return NotImplemented - def execute(self, quals: list[Qual], columns: list[str], sortkeys: Optional[list[Any]] = None): + def execute(self, quals: list[Qual], columns: list[str], sortkeys: list[Any] | None = None): pass ForeignDataWrapper = ForeignDataWrapperStub diff --git a/packages/gooddata-fdw/src/gooddata_fdw/executor.py b/packages/gooddata-fdw/src/gooddata_fdw/executor.py index 8e79a91e8..f884a377c 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/executor.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/executor.py @@ -2,7 +2,7 @@ from __future__ import annotations from collections.abc import Generator -from typing import Any, NamedTuple, Optional +from typing import Any, NamedTuple from gooddata_sdk import GoodDataSdk @@ -37,7 +37,7 @@ def validate_columns_def(self) -> None: validator.validate(column_name, column_def) def execute( - self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None + self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None ) -> Generator[dict[str, Any], None, None]: raise NotImplementedError() @@ -59,7 +59,7 @@ def can_react(cls, inputs: InitData) -> bool: return inputs.table_options.insight is not None def execute( - self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None + self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None ) -> Generator[dict[str, Any], None, None]: results_reader = InsightTableResultReader(self._table_columns, columns) insight = self._sdk.visualizations.get_visualization(self._workspace, self._insight) @@ -81,7 +81,7 @@ def can_react(cls, inputs: InitData) -> bool: return inputs.table_options.compute is not None def execute( - self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None + self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None ) -> Generator[dict[str, Any], None, None]: col_val.validate_columns_in_table_def(self._table_columns, columns) items = [column_utils.table_col_as_computable(self._table_columns[col_name]) for col_name in columns] @@ -105,7 +105,7 @@ def can_react(cls, inputs: InitData) -> bool: return True def execute( - self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None + self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None ) -> Generator[dict[str, Any], None, None]: items = [column_utils.table_col_as_computable(col) for col in self._table_columns.values()] # TODO: pushdown more filters that are included in quals diff --git a/packages/gooddata-fdw/src/gooddata_fdw/fdw.py b/packages/gooddata-fdw/src/gooddata_fdw/fdw.py index 46596b532..d0ad831eb 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/fdw.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/fdw.py @@ -2,7 +2,7 @@ from __future__ import annotations import traceback -from typing import Any, Optional +from typing import Any from gooddata_sdk import GoodDataSdk @@ -34,7 +34,7 @@ def __init__(self, options: dict[str, str], columns: dict[str, ColumnDefinition] self._executor = ExecutorFactory.create(InitData(gd_sdk, self._server_options, self._table_options, columns)) self._executor.validate_columns_def() - def execute(self, quals: list[Qual], columns: list[str], sortkeys: Optional[list[Any]] = None): + def execute(self, quals: list[Qual], columns: list[str], sortkeys: list[Any] | None = None): _log_debug(f"query in fdw with {self._server_options}; {self._table_options}; columns {columns}; quals={quals}") try: return self._executor.execute(quals, columns, sortkeys) @@ -48,7 +48,7 @@ def import_schema( schema: str, srv_options: dict[str, str], options: dict[str, str], - restriction_type: Optional[str], + restriction_type: str | None, restricts: list[str], ) -> list[TableDefinition]: _log_info( diff --git a/packages/gooddata-fdw/src/gooddata_fdw/import_workspace.py b/packages/gooddata-fdw/src/gooddata_fdw/import_workspace.py index f0a2a4c56..3d32c7829 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/import_workspace.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/import_workspace.py @@ -2,7 +2,7 @@ from __future__ import annotations import re -from typing import NamedTuple, Optional +from typing import NamedTuple from gooddata_sdk import ( CatalogWorkspaceContent, @@ -24,7 +24,7 @@ from gooddata_fdw.pg_logging import _log_debug, _log_info, _log_warn -def _metric_format_to_precision(metric_format: Optional[str]) -> Optional[str]: +def _metric_format_to_precision(metric_format: str | None) -> str | None: if metric_format: re_decimal_places = re.compile(r"^[^.]+\.([#0]+)") match = re_decimal_places.search(metric_format) @@ -39,7 +39,7 @@ class ImporterInitData(NamedTuple): workspace: str server_options: options.ServerOptions import_options: options.ImportSchemaOptions - restriction_type: Optional[str] + restriction_type: str | None restricts: list[str] @@ -165,7 +165,7 @@ def _metric_to_table_column( # InsightMetric do not contain format in case of stored metrics @staticmethod - def _get_insight_metric_format(metric: VisualizationMetric, catalog: CatalogWorkspaceContent) -> Optional[str]: + def _get_insight_metric_format(metric: VisualizationMetric, catalog: CatalogWorkspaceContent) -> str | None: if metric.format: return metric.format elif metric.item_id: diff --git a/packages/gooddata-fdw/src/gooddata_fdw/naming.py b/packages/gooddata-fdw/src/gooddata_fdw/naming.py index eb5077a63..fc8cce043 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/naming.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/naming.py @@ -1,12 +1,10 @@ # (C) 2021 GoodData Corporation from __future__ import annotations -from typing import Optional - import gooddata_sdk as sdk -def _sanitize_str_for_postgres(string: str, used_names: Optional[dict[str, bool]] = None) -> str: +def _sanitize_str_for_postgres(string: str, used_names: dict[str, bool] | None = None) -> str: # replace non-alpha-num stuff with underscores with_underscores = "".join(char if char.isalnum() else "_" for char in string.lower()) diff --git a/packages/gooddata-fdw/src/gooddata_fdw/options.py b/packages/gooddata-fdw/src/gooddata_fdw/options.py index fbe81db7a..905657514 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/options.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/options.py @@ -1,11 +1,11 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Any, Optional, Union +from typing import Any, Union class BaseOptions: - def __init__(self, validate: bool = True, skip_attributes: Optional[list[str]] = None) -> None: + def __init__(self, validate: bool = True, skip_attributes: list[str] | None = None) -> None: if skip_attributes is None: self._skip_attributes = [] else: @@ -124,6 +124,6 @@ def _validate_object_type(value: str) -> None: def numeric_max_size(self) -> str: return self._options.get("numeric_max_size", self.METRIC_DIGITS_BEFORE_DEC_POINT_DEFAULT) - def metric_data_type(self, precision: Optional[str] = None) -> str: + def metric_data_type(self, precision: str | None = None) -> str: digits_after = precision if precision else self.METRIC_DIGITS_AFTER_DEC_POINT_DEFAULT return f"DECIMAL({self.numeric_max_size}, {digits_after})" diff --git a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/data_source_messages.py b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/data_source_messages.py index a90186099..20aa3a361 100644 --- a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/data_source_messages.py +++ b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/data_source_messages.py @@ -1,7 +1,7 @@ # (C) 2025 GoodData Corporation from collections.abc import Iterable from dataclasses import dataclass -from typing import Any, Optional +from typing import Any import orjson import pyarrow @@ -33,7 +33,7 @@ class DataSourceMessage: Type of the message, currently free-form, we might define some enum for these in the future. """ - data: Optional[Any] = None + data: Any | None = None """ Optional message-specific data. This can be anything that can be JSON-serialized. Try to keep this as small as possible: the backend has a quite strict size limit on the messages. @@ -47,7 +47,7 @@ def to_dict(self) -> dict[str, Any]: def add_data_source_messages_metadata( - data_source_messages: Iterable[DataSourceMessage], original_metadata: Optional[dict] = None + data_source_messages: Iterable[DataSourceMessage], original_metadata: dict | None = None ) -> dict[bytes, bytes]: """ Given a list of DataSourceMessages, creates a PyArrow-compatible metadata dictionary. diff --git a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/execution_context.py b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/execution_context.py index ba6d7136e..3e7047b18 100644 --- a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/execution_context.py +++ b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/execution_context.py @@ -21,13 +21,13 @@ TResult = TypeVar("TResult") -def none_safe(func: Callable[[TInput], TResult]) -> Callable[[Optional[TInput]], Optional[TResult]]: +def none_safe(func: Callable[[TInput], TResult]) -> Callable[[TInput | None], TResult | None]: """ Decorator that makes the unary function safe for None input. If the only argument is None, the function returns None. """ - def wrapper(arg: Optional[TInput]) -> Optional[TResult]: + def wrapper(arg: TInput | None) -> TResult | None: if arg is None: return None return func(arg) @@ -114,18 +114,18 @@ class ExecutionContextAttribute: Title of the particular label used. """ - date_granularity: Optional[str] + date_granularity: str | None """ Date granularity of the attribute if it is a date attribute. """ - sorting: Optional[ExecutionContextAttributeSorting] + sorting: ExecutionContextAttributeSorting | None """ Sorting of the attribute. If not present, the attribute is not sorted. """ @staticmethod - def from_dict(d: Optional[dict]) -> Optional["ExecutionContextAttribute"]: + def from_dict(d: dict | None) -> Optional["ExecutionContextAttribute"]: """ Create ExecutionContextAttribute from a dictionary. :param d: the dictionary to parse @@ -153,7 +153,7 @@ class ExecutionContextPositiveAttributeFilter: Identifier of the label used. """ - values: list[Optional[str]] + values: list[str | None] """ Values of the filter. """ @@ -170,7 +170,7 @@ class ExecutionContextNegativeAttributeFilter: Identifier of the label used. """ - values: list[Optional[str]] + values: list[str | None] """ Values of the filter. """ @@ -366,17 +366,17 @@ class LabelElementsExecutionRequest: The label to get the elements for. """ - offset: Optional[int] + offset: int | None """ The number of elements to skip before returning. """ - limit: Optional[int] + limit: int | None """ The maximum number of elements to return. """ - exclude_primary_label: Optional[bool] + exclude_primary_label: bool | None """ Excludes items from the result that differ only by primary label @@ -384,33 +384,33 @@ class LabelElementsExecutionRequest: * true - return items with distinct requested label """ - exact_filter: Optional[list[str]] + exact_filter: list[str] | None """ Exact values to filter the elements by. """ - pattern_filter: Optional[str] + pattern_filter: str | None """ Filter the elements by a pattern. The pattern is matched against the element values in a case-insensitive way. """ - complement_filter: Optional[bool] + complement_filter: bool | None """ Whether to invert the effects of exact_filter amd pattern_filter. """ - depends_on: Optional[list[DependsOn]] + depends_on: list[DependsOn] | None """ Other labels or date filters that should be used to limit the elements. """ - filter_by: Optional[CatalogFilterBy] + filter_by: CatalogFilterBy | None """ Which label is used for filtering - primary or requested. If omitted the server will use the default value of "REQUESTED". """ - validate_by: Optional[list[CatalogValidateByItem]] + validate_by: list[CatalogValidateByItem] | None """ Other metrics, attributes, labels or facts used to validate the elements. """ @@ -504,18 +504,18 @@ class ExecutionContext: The ID of the user that invoked the FlexConnect function. """ - timestamp: Optional[str] + timestamp: str | None """ The timestamp of the execution used as "now" in date filters. For example 2020-06-03T10:15:30+01:00. """ - timezone: Optional[str] + timezone: str | None """ The timezone of the execution. """ - week_start: Optional[str] + week_start: str | None """ The start of the week. Either "monday" or "sunday". """ @@ -530,13 +530,13 @@ class ExecutionContext: All the attribute and date filters that are part of the execution request. """ - report_execution_request: Optional[ReportExecutionRequest] + report_execution_request: ReportExecutionRequest | None """ The report execution request that the FlexConnect function should process. Only present if the execution type is "REPORT". """ - label_elements_execution_request: Optional[LabelElementsExecutionRequest] + label_elements_execution_request: LabelElementsExecutionRequest | None """ The label elements execution request that the FlexConnect function should process. Only present if the execution type is "LABEL_ELEMENTS". diff --git a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/flight_methods.py b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/flight_methods.py index 863f992b3..739bb2354 100644 --- a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/flight_methods.py +++ b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/flight_methods.py @@ -1,7 +1,6 @@ # (C) 2024 GoodData Corporation import time from collections.abc import Generator -from typing import Optional import orjson import pyarrow.flight @@ -59,7 +58,7 @@ def __init__( self._poll_interval = poll_interval_ms / 1000 @staticmethod - def _create_descriptor(fun_name: str, metadata: Optional[dict]) -> pyarrow.flight.FlightDescriptor: + def _create_descriptor(fun_name: str, metadata: dict | None) -> pyarrow.flight.FlightDescriptor: cmd = { "functionName": fun_name, "metadata": metadata, @@ -98,7 +97,7 @@ def _prepare_task( ) def _prepare_flight_info( - self, task_id: str, task_result: Optional[TaskExecutionResult] + self, task_id: str, task_result: TaskExecutionResult | None ) -> pyarrow.flight.FlightInfo: if task_result is None: raise ErrorInfo.for_reason( @@ -142,7 +141,7 @@ def _get_flight_info_no_polling( structlog.contextvars.bind_contextvars(peer=context.peer()) invocation = extract_submit_invocation_from_descriptor(descriptor) - task: Optional[FlexConnectFunctionTask] = None + task: FlexConnectFunctionTask | None = None try: task = self._prepare_task(context, invocation) @@ -192,7 +191,7 @@ def _get_flight_info_polling( invocation = extract_pollable_invocation_from_descriptor(descriptor) task_id: str - fun_name: Optional[str] = None + fun_name: str | None = None if isinstance(invocation, CancelInvocation): # cancel the given task and raise cancellation exception diff --git a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function.py b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function.py index 8929d57fd..31f5043b8 100644 --- a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function.py +++ b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function.py @@ -1,6 +1,5 @@ # (C) 2024 GoodData Corporation import abc -from typing import Optional import pyarrow from gooddata_flight_server import ArrowData, ServerContext @@ -37,17 +36,17 @@ class FlexConnectFunction(abc.ABC): for every call using the `create` method. """ - Name: Optional[str] = None + Name: str | None = None """ Function MUST define a unique name """ - Schema: Optional[pyarrow.Schema] = None + Schema: pyarrow.Schema | None = None """ Function MUST define schema describing its data. """ - Metadata: Optional[dict] = None + Metadata: dict | None = None """ Function MAY provide additional metadata about themselves. These then influence how the function is used by and called from GoodData Cloud & FlexQuery. @@ -79,7 +78,7 @@ def create(cls) -> "FlexConnectFunction": def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: """ diff --git a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_invocation.py b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_invocation.py index 8647bf0ac..2a16f6590 100644 --- a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_invocation.py +++ b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_invocation.py @@ -1,6 +1,6 @@ # (C) 2025 GoodData Corporation from dataclasses import dataclass -from typing import Optional, Union +from typing import Union import orjson import pyarrow.flight @@ -46,7 +46,7 @@ class SubmitInvocation: Parameters to pass to the FlexConnect function. """ - columns: Optional[tuple[str, ...]] + columns: tuple[str, ...] | None """ Columns to get from the FlexConnect function result. This may be used for column trimming by the function: the function must return at least those columns. diff --git a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_task.py b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_task.py index 0da016a3a..06a00f6df 100644 --- a/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_task.py +++ b/packages/gooddata-flexconnect/src/gooddata_flexconnect/function/function_task.py @@ -1,5 +1,5 @@ # (C) 2024 GoodData Corporation -from typing import Optional, Union +from typing import Union import structlog from gooddata_flight_server import FlightDataTaskResult, Task, TaskError, TaskResult @@ -16,11 +16,11 @@ def __init__( self, fun: FlexConnectFunction, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], cmd: bytes, cancellable: bool = True, - task_id: Optional[str] = None, + task_id: str | None = None, ): super().__init__(cmd, cancellable, task_id) @@ -32,7 +32,7 @@ def __init__( _LOGGER.info("flexconnect_task_created", fun=fun.Name, task_id=self._task_id) @property - def fun_name(self) -> Optional[str]: + def fun_name(self) -> str | None: return self._fun.Name def run(self) -> Union[TaskResult, TaskError]: diff --git a/packages/gooddata-flexconnect/tests/function/testing_funs.py b/packages/gooddata-flexconnect/tests/function/testing_funs.py index f9e03aa3b..cc62aa581 100644 --- a/packages/gooddata-flexconnect/tests/function/testing_funs.py +++ b/packages/gooddata-flexconnect/tests/function/testing_funs.py @@ -1,5 +1,4 @@ # (C) 2024 GoodData Corporation -from typing import Optional import pyarrow from gooddata_flexconnect.function.function import FlexConnectFunction @@ -13,7 +12,7 @@ class Fun1(FlexConnectFunction): def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: pass @@ -28,7 +27,7 @@ class Fun2(FlexConnectFunction): def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: pass diff --git a/packages/gooddata-flexconnect/tests/server/funs/fun1.py b/packages/gooddata-flexconnect/tests/server/funs/fun1.py index c2518b464..be2c5db17 100644 --- a/packages/gooddata-flexconnect/tests/server/funs/fun1.py +++ b/packages/gooddata-flexconnect/tests/server/funs/fun1.py @@ -1,5 +1,4 @@ # (C) 2024 GoodData Corporation -from typing import Optional import pyarrow from gooddata_flexconnect.function.function import FlexConnectFunction @@ -19,7 +18,7 @@ class _SimpleFun1(FlexConnectFunction): def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: return pyarrow.table( diff --git a/packages/gooddata-flexconnect/tests/server/funs/fun2.py b/packages/gooddata-flexconnect/tests/server/funs/fun2.py index b4d8b3864..4d91cc496 100644 --- a/packages/gooddata-flexconnect/tests/server/funs/fun2.py +++ b/packages/gooddata-flexconnect/tests/server/funs/fun2.py @@ -1,11 +1,10 @@ # (C) 2024 GoodData Corporation -from typing import Optional import pyarrow from gooddata_flexconnect.function.function import FlexConnectFunction from gooddata_flight_server import ArrowData, ServerContext -_DATA: Optional[pyarrow.Table] = None +_DATA: pyarrow.Table | None = None class _SimpleFun2(FlexConnectFunction): @@ -21,7 +20,7 @@ class _SimpleFun2(FlexConnectFunction): def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: assert _DATA is not None diff --git a/packages/gooddata-flexconnect/tests/server/funs/fun3.py b/packages/gooddata-flexconnect/tests/server/funs/fun3.py index c5634c8c3..fbe5c62b7 100644 --- a/packages/gooddata-flexconnect/tests/server/funs/fun3.py +++ b/packages/gooddata-flexconnect/tests/server/funs/fun3.py @@ -1,12 +1,11 @@ # (C) 2024 GoodData Corporation import time -from typing import Optional import pyarrow from gooddata_flexconnect.function.function import FlexConnectFunction from gooddata_flight_server import ArrowData -_DATA: Optional[pyarrow.Table] = None +_DATA: pyarrow.Table | None = None class _LongRunningFun(FlexConnectFunction): @@ -22,7 +21,7 @@ class _LongRunningFun(FlexConnectFunction): def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: # sleep is intentionally setup to be longer than the deadline for diff --git a/packages/gooddata-flexconnect/tests/server/funs/fun4.py b/packages/gooddata-flexconnect/tests/server/funs/fun4.py index 6e32b7298..049ae3c1e 100644 --- a/packages/gooddata-flexconnect/tests/server/funs/fun4.py +++ b/packages/gooddata-flexconnect/tests/server/funs/fun4.py @@ -1,12 +1,11 @@ # (C) 2024 GoodData Corporation import time -from typing import Optional import pyarrow from gooddata_flexconnect.function.function import FlexConnectFunction from gooddata_flight_server import ArrowData -_DATA: Optional[pyarrow.Table] = None +_DATA: pyarrow.Table | None = None class _PollableFun(FlexConnectFunction): @@ -22,7 +21,7 @@ class _PollableFun(FlexConnectFunction): def call( self, parameters: dict, - columns: Optional[tuple[str, ...]], + columns: tuple[str, ...] | None, headers: dict[str, list[str]], ) -> ArrowData: # sleep is intentionally setup to be longer than one polling interval diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/cli.py b/packages/gooddata-flight-server/src/gooddata_flight_server/cli.py index ebb0f6ecb..c11a50a83 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/cli.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/cli.py @@ -2,7 +2,7 @@ import argparse import sys import traceback -from typing import Optional, TypeVar +from typing import TypeVar from dynaconf import ValidationError @@ -85,7 +85,7 @@ def _create_server(args: argparse.Namespace) -> GoodDataFlightServer: # not really needed to be global, keeping it here so that instance of server is reachable # easily from the debugger -_SERVER: Optional[GoodDataFlightServer] = None +_SERVER: GoodDataFlightServer | None = None def server_cli() -> None: diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/config/config.py b/packages/gooddata-flight-server/src/gooddata_flight_server/config/config.py index 9b06a7ae2..1f8a3013a 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/config/config.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/config/config.py @@ -5,7 +5,7 @@ import platform import socket from dataclasses import dataclass -from typing import Any, Optional +from typing import Any from dynaconf import Dynaconf, ValidationError, Validator @@ -34,10 +34,10 @@ class AuthenticationMethod(enum.Enum): @dataclass(frozen=True) class OtelConfig: - exporter_type: Optional[OtelExporterType] + exporter_type: OtelExporterType | None service_name: str - service_namespace: Optional[str] - service_instance_id: Optional[str] + service_namespace: str | None + service_instance_id: str | None extract_context_from_headers: bool @@ -50,21 +50,21 @@ class ServerConfig: use_tls: bool use_mutual_tls: bool - tls_cert_and_key: Optional[tuple[bytes, bytes]] - tls_root_cert: Optional[bytes] + tls_cert_and_key: tuple[bytes, bytes] | None + tls_root_cert: bytes | None authentication_method: AuthenticationMethod - token_header_name: Optional[str] - token_verification: Optional[str] + token_header_name: str | None + token_verification: str | None task_threads: int task_close_threads: int task_result_ttl_sec: int - metrics_host: Optional[str] + metrics_host: str | None metrics_port: int - health_check_host: Optional[str] + health_check_host: str | None health_check_port: int malloc_trim_interval_sec: int @@ -77,8 +77,8 @@ def without_tls(self) -> "ServerConfig": def _basic_sanity(val: bytes) -> bytes: return val[0:38] + b"..." + val[-38:] - sanitized_root_cert: Optional[bytes] = None - sanitized_cert_and_key: Optional[tuple[bytes, bytes]] = None + sanitized_root_cert: bytes | None = None + sanitized_cert_and_key: tuple[bytes, bytes] | None = None if self.tls_root_cert is not None: sanitized_root_cert = _basic_sanity(self.tls_root_cert) @@ -422,7 +422,7 @@ def _validate_boolean(val: Any) -> bool: ] -def _read_tls_setting(settings: Dynaconf, setting: str) -> Optional[bytes]: +def _read_tls_setting(settings: Dynaconf, setting: str) -> bytes | None: value: str = settings.get(setting) if value is None: return None @@ -448,8 +448,8 @@ def _create_server_config(settings: Dynaconf) -> ServerConfig: advertise_port = server_settings.get(_Settings.AdvertisePort) or server_settings.get(_Settings.ListenPort) use_tls = server_settings.get(_Settings.UseTls) - tls_cert_and_key: Optional[tuple[bytes, bytes]] = None - tls_root_cert: Optional[bytes] = None + tls_cert_and_key: tuple[bytes, bytes] | None = None + tls_root_cert: bytes | None = None if use_tls: cert = _read_tls_setting(server_settings, _Settings.TlsCertificate) @@ -471,7 +471,7 @@ def _create_server_config(settings: Dynaconf) -> ServerConfig: tls_root_cert = _read_tls_setting(server_settings, _Settings.TlsRoot) _auth_method = AuthenticationMethod(server_settings.get(_Settings.AuthenticationMethod)) - _token_verification: Optional[str] = None + _token_verification: str | None = None if _auth_method == AuthenticationMethod.Token: _token_verification = server_settings.get(_Settings.TokenVerification) or _DEFAULT_TOKEN_VERIFICATION diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_code.py b/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_code.py index a8b6ea3cf..c78edbda3 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_code.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_code.py @@ -1,5 +1,5 @@ # (C) 2024 GoodData Corporation -from typing import Any, Literal, Optional +from typing import Any, Literal from typing_extensions import TypeAlias @@ -36,13 +36,13 @@ def _init_names(cls: Any) -> Any: } -def _get_flags(retry: Optional[_RetryFlagsLiteral] = None) -> int: +def _get_flags(retry: _RetryFlagsLiteral | None = None) -> int: if retry is None: return 0x0 return _FlagsMapping.get(retry, 0x0) -def _error_code(code: int, retry: Optional[_RetryFlagsLiteral] = None) -> int: +def _error_code(code: int, retry: _RetryFlagsLiteral | None = None) -> int: return _get_flags(retry) | code diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_info.py b/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_info.py index 998e95baa..65325fd4c 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_info.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/errors/error_info.py @@ -12,7 +12,7 @@ _ERROR_INFO_MAX_DETAIL = 512 -def _truncate_str_value(val: Optional[str], max_len: int) -> Optional[str]: +def _truncate_str_value(val: str | None, max_len: int) -> str | None: if val is None: return None @@ -34,13 +34,13 @@ class ErrorInfo: def __init__( self, msg: str, - detail: Optional[str] = None, - body: Optional[bytes] = None, + detail: str | None = None, + body: bytes | None = None, code: int = 0, ) -> None: self._msg = cast(str, _truncate_str_value(msg, _ERROR_INFO_MAX_MSG)) - self._detail: Optional[str] = _truncate_str_value(detail, _ERROR_INFO_MAX_DETAIL) - self._body: Optional[bytes] = body + self._detail: str | None = _truncate_str_value(detail, _ERROR_INFO_MAX_DETAIL) + self._body: bytes | None = body self._code: int = code @property @@ -58,14 +58,14 @@ def code(self) -> int: return self._code @property - def detail(self) -> Optional[str]: + def detail(self) -> str | None: """ :return: a human-readable error detail; if included may help with error diagnostics """ return self._detail @property - def body(self) -> Optional[bytes]: + def body(self) -> bytes | None: """ :return: error body, suitable for programmatic consumption; used by server to send structured information which the client code may want to work with @@ -83,7 +83,7 @@ def with_msg(self, msg: str) -> "ErrorInfo": return self - def with_detail(self, detail: Optional[str] = None) -> "ErrorInfo": + def with_detail(self, detail: str | None = None) -> "ErrorInfo": """ Updates or resets the error detail. @@ -95,7 +95,7 @@ def with_detail(self, detail: Optional[str] = None) -> "ErrorInfo": return self - def with_body(self, body: Optional[Union[bytes, str]]) -> "ErrorInfo": + def with_body(self, body: Union[bytes, str] | None) -> "ErrorInfo": """ Updates or resets the error body. @@ -200,7 +200,7 @@ def to_unauthorized_error(self) -> pyarrow.flight.FlightUnauthorizedError: def to_flight_error( self, - error_factory: Callable[[str, Optional[bytes]], pyarrow.flight.FlightError], + error_factory: Callable[[str, bytes | None], pyarrow.flight.FlightError], ) -> pyarrow.flight.FlightError: """ Uses the provided error factory - which can be for example the FlightError subclass, to create an @@ -221,7 +221,7 @@ def from_bytes(val: bytes) -> "ErrorInfo": """ try: _json = orjson.loads(val) - body: Optional[bytes] = base64.b64decode(_json["body"]) if _json.get("body") is not None else None + body: bytes | None = base64.b64decode(_json["body"]) if _json.get("body") is not None else None return ErrorInfo( msg=_json.get("msg"), @@ -283,7 +283,7 @@ def maybe_from_pyarrow_error( def for_exc( code: int, e: BaseException, - extra_msg: Optional[str] = None, + extra_msg: str | None = None, include_traceback: bool = True, ) -> "ErrorInfo": """ @@ -314,7 +314,7 @@ def for_exc( msg = f"{extra_msg}: {msg}" if include_traceback: - detail: Optional[str] = "".join(traceback.format_exception(None, e, e.__traceback__)) + detail: str | None = "".join(traceback.format_exception(None, e, e.__traceback__)) else: detail = None @@ -362,9 +362,9 @@ def bad_argument(msg: str) -> pyarrow.flight.FlightError: @staticmethod def poll( - flight_info: Optional[pyarrow.flight.FlightInfo] = None, - retry_descriptor: Optional[pyarrow.flight.FlightDescriptor] = None, - cancel_descriptor: Optional[pyarrow.flight.FlightDescriptor] = None, + flight_info: pyarrow.flight.FlightInfo | None = None, + retry_descriptor: pyarrow.flight.FlightDescriptor | None = None, + cancel_descriptor: pyarrow.flight.FlightDescriptor | None = None, ) -> pyarrow.flight.FlightTimedOutError: """ Convenience factory that creates FlightTimedOut error with POLL error code and `RetryInfo` which @@ -402,16 +402,16 @@ class RetryInfo: def __init__( self, - flight_info: Optional[pyarrow.flight.FlightInfo] = None, - retry_descriptor: Optional[pyarrow.flight.FlightDescriptor] = None, - cancel_descriptor: Optional[pyarrow.flight.FlightDescriptor] = None, + flight_info: pyarrow.flight.FlightInfo | None = None, + retry_descriptor: pyarrow.flight.FlightDescriptor | None = None, + cancel_descriptor: pyarrow.flight.FlightDescriptor | None = None, ) -> None: self._flight_info = flight_info self._retry_descriptor = retry_descriptor self._cancel_descriptor = cancel_descriptor @property - def flight_info(self) -> Optional[pyarrow.flight.FlightInfo]: + def flight_info(self) -> pyarrow.flight.FlightInfo | None: """ FlightInfo available at the time of the poll timeout. The information may be incomplete. The full FlightInfo is built in cumulative fashion - the subsequent @@ -425,7 +425,7 @@ def flight_info(self) -> Optional[pyarrow.flight.FlightInfo]: return self._flight_info @property - def retry_descriptor(self) -> Optional[pyarrow.flight.FlightDescriptor]: + def retry_descriptor(self) -> pyarrow.flight.FlightDescriptor | None: """ Returns descriptor that the client should use to retry the GetFlightInfo call in order to see whether the command has completed. @@ -437,7 +437,7 @@ def retry_descriptor(self) -> Optional[pyarrow.flight.FlightDescriptor]: return self._retry_descriptor @property - def cancel_descriptor(self) -> Optional[pyarrow.flight.FlightDescriptor]: + def cancel_descriptor(self) -> pyarrow.flight.FlightDescriptor | None: """ Returns descriptor that the client can use to cancel the command that is in progress. diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/server/auth/auth_middleware.py b/packages/gooddata-flight-server/src/gooddata_flight_server/server/auth/auth_middleware.py index 1887f8eb1..b386d9e99 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/server/auth/auth_middleware.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/server/auth/auth_middleware.py @@ -1,5 +1,5 @@ # (C) 2024 GoodData Corporation -from typing import Any, Optional +from typing import Any import pyarrow.flight import structlog @@ -31,7 +31,7 @@ def token_data(self) -> Any: class TokenAuthMiddlewareFactory(pyarrow.flight.ServerMiddlewareFactory): def __init__( self, - token_header_name: Optional[str], + token_header_name: str | None, strategy: TokenVerificationStrategy, ): super().__init__() @@ -69,7 +69,7 @@ def _auth_header_value(lookup: str) -> str: token = _auth_header_value(self._token_header_name) return token.strip() - def start_call(self, info: pyarrow.flight.CallInfo, headers: dict[str, list[str]]) -> Optional[TokenAuthMiddleware]: + def start_call(self, info: pyarrow.flight.CallInfo, headers: dict[str, list[str]]) -> TokenAuthMiddleware | None: try: token = self._extract_token(headers) result = self._strategy.verify(call_info=info, token=token) diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_middleware.py b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_middleware.py index fa4a983f6..9874c9b2b 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_middleware.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_middleware.py @@ -1,5 +1,5 @@ # (C) 2024 GoodData Corporation -from typing import Any, Callable, Optional +from typing import Any, Callable import opentelemetry.context as otelctx import opentelemetry.propagate as otelpropagate @@ -46,7 +46,7 @@ def headers(self) -> dict[str, list[str]]: return self._headers -OnEndCallbackFn: TypeAlias = Callable[[Optional[pyarrow.ArrowException]], Any] +OnEndCallbackFn: TypeAlias = Callable[[pyarrow.ArrowException | None], Any] class CallFinalizer(pyarrow.flight.ServerMiddleware): @@ -85,7 +85,7 @@ def register_on_end(self, fun: OnEndCallbackFn) -> None: """ self._on_end.append(fun) - def call_completed(self, exception: Optional[pyarrow.lib.ArrowException]) -> None: + def call_completed(self, exception: pyarrow.lib.ArrowException | None) -> None: try: for fun in self._on_end: fun(exception) @@ -132,7 +132,7 @@ def call_tracing(self) -> tuple[otelctx.Context, trace.Span]: """ return self._otel_ctx, self._otel_span - def call_completed(self, exception: Optional[pyarrow.lib.ArrowException]) -> None: + def call_completed(self, exception: pyarrow.lib.ArrowException | None) -> None: # OpenTelemetry context/span restore; # # this has to happen because this method is done from thread managed diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_server.py b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_server.py index 6e116d68c..ba974668a 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_server.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_server.py @@ -10,7 +10,7 @@ """ from collections.abc import Generator -from typing import Any, Callable, Optional, TypeVar, Union +from typing import Any, Callable, TypeVar, Union import opentelemetry.context as otelctx import opentelemetry.trace as oteltrace @@ -22,7 +22,7 @@ FlightServerMethods, ) -FlightServerLocation: TypeAlias = Union[str, bytes, Optional[tuple[str, int]], pyarrow.flight.Location] +FlightServerLocation: TypeAlias = Union[str, bytes, tuple[str, int] | None, pyarrow.flight.Location] FlightTlsCertificates: TypeAlias = list[tuple[bytes, bytes]] FlightMiddlewares: TypeAlias = dict[str, pyarrow.flight.ServerMiddlewareFactory] @@ -82,13 +82,13 @@ class FlightServer(pyarrow.flight.FlightServerBase): def __init__( self, - methods: Optional[FlightServerMethods] = None, - location: Optional[FlightServerLocation] = None, - auth_handler: Optional[pyarrow.flight.ServerAuthHandler] = None, - tls_certificates: Optional[FlightTlsCertificates] = None, - verify_client: Optional[bool] = None, - root_certificates: Optional[bytes] = None, - middleware: Optional[FlightMiddlewares] = None, + methods: FlightServerMethods | None = None, + location: FlightServerLocation | None = None, + auth_handler: pyarrow.flight.ServerAuthHandler | None = None, + tls_certificates: FlightTlsCertificates | None = None, + verify_client: bool | None = None, + root_certificates: bytes | None = None, + middleware: FlightMiddlewares | None = None, ): """ Create Flight server diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_service.py b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_service.py index a0c10fb67..36f1d534d 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_service.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/flight_service.py @@ -3,7 +3,6 @@ # mypy: no-strict-optional from threading import Thread -from typing import Optional import pyarrow.flight import structlog @@ -41,14 +40,14 @@ class _AvailabilityMiddlewareFactory(pyarrow.flight.ServerMiddlewareFactory): If unavailable_reason is set -> reject. Otherwise, let the request through. """ - def __init__(self, unavailable_reason: Optional[ErrorInfo] = None): + def __init__(self, unavailable_reason: ErrorInfo | None = None): super().__init__() - self.unavailable_reason: Optional[ErrorInfo] = unavailable_reason + self.unavailable_reason: ErrorInfo | None = unavailable_reason def start_call( self, info: pyarrow.flight.CallInfo, headers: dict[str, list[str]] - ) -> Optional[pyarrow.flight.ServerMiddleware]: + ) -> pyarrow.flight.ServerMiddleware | None: if self.unavailable_reason is None: return None @@ -58,14 +57,14 @@ def start_call( class _CallInfoMiddlewareFactory(pyarrow.flight.ServerMiddlewareFactory): def start_call( self, info: pyarrow.flight.CallInfo, headers: dict[str, list[str]] - ) -> Optional[pyarrow.flight.ServerMiddleware]: + ) -> pyarrow.flight.ServerMiddleware | None: return CallInfo(info, headers) class _CallFinalizerMiddlewareFactory(pyarrow.flight.ServerMiddlewareFactory): def start_call( self, info: pyarrow.flight.CallInfo, headers: dict[str, list[str]] - ) -> Optional[pyarrow.flight.ServerMiddleware]: + ) -> pyarrow.flight.ServerMiddleware | None: return CallFinalizer() @@ -76,7 +75,7 @@ def __init__(self, extract_context: bool) -> None: def start_call( self, info: pyarrow.flight.CallInfo, headers: dict[str, list[str]] - ) -> Optional[pyarrow.flight.ServerMiddleware]: + ) -> pyarrow.flight.ServerMiddleware | None: return OtelMiddleware(info, headers, self._extract_context) @@ -110,13 +109,13 @@ def __init__( # internal mutable state # server starts immediately when constructed (PyArrow stuff); thus defer # construction until start() is called - self._server: Optional[FlightServer] = None - self._flight_shutdown_thread: Optional[Thread] = None + self._server: FlightServer | None = None + self._flight_shutdown_thread: Thread | None = None self._stopped = False def _initialize_authentication( self, ctx: ServerContext - ) -> Optional[tuple[str, pyarrow.flight.ServerMiddlewareFactory]]: + ) -> tuple[str, pyarrow.flight.ServerMiddlewareFactory] | None: if self._config.authentication_method == AuthenticationMethod.NoAuth: if self._config.use_mutual_tls: return None @@ -141,7 +140,7 @@ def _initialize_authentication( def _initialize_otel_tracing( self, ctx: ServerContext - ) -> Optional[tuple[str, pyarrow.flight.ServerMiddlewareFactory]]: + ) -> tuple[str, pyarrow.flight.ServerMiddlewareFactory] | None: if self._config.otel_config.exporter_type is None: return None @@ -262,7 +261,7 @@ def _shutdown_server(self) -> None: self._server.shutdown() self._logger.info("flight_service_finished") - def wait_for_stop(self, timeout: Optional[float] = None) -> bool: + def wait_for_stop(self, timeout: float | None = None) -> bool: if self._flight_shutdown_thread is None: # this is really some mess in the caller code.. did not call stop() but tries to wait for it.. raise AssertionError("Flight server stop() was not issued yet attempting to wait for the server to stop.") diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/server_methods.py b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/server_methods.py index b83001506..958979732 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/server_methods.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/server/flight_rpc/server_methods.py @@ -1,6 +1,5 @@ # (C) 2024 GoodData Corporation from collections.abc import Generator -from typing import Optional import pyarrow.flight import structlog @@ -104,7 +103,7 @@ def do_get_task_result( rlock, data = result.acquire_data() - def _on_end(_: Optional[pyarrow.ArrowException]) -> None: + def _on_end(_: pyarrow.ArrowException | None) -> None: """ Once the request that streams the data out is done, make sure to release the read-lock. Single-use results are closed at diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/server/server_base.py b/packages/gooddata-flight-server/src/gooddata_flight_server/server/server_base.py index f9d24ccf3..ecd3067a1 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/server/server_base.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/server/server_base.py @@ -5,7 +5,7 @@ import signal from abc import abstractmethod from threading import Condition, Thread -from typing import Any, Optional +from typing import Any import pyarrow import structlog @@ -61,7 +61,7 @@ def __init__( # main server notifies on this condition once all sub-services are started self._start_cond = Condition() self._started = False - self._startup_interrupted: Optional[Exception] = None + self._startup_interrupted: Exception | None = None self._stop = False self._abort = False @@ -233,7 +233,7 @@ def aborted(self) -> bool: """ return self._abort - def wait_for_start(self, timeout: Optional[float] = None) -> bool: + def wait_for_start(self, timeout: float | None = None) -> bool: """ Waits until server and all its services are up and running. @@ -253,7 +253,7 @@ def wait_for_start(self, timeout: Optional[float] = None) -> bool: return True - def wait_for_stop(self, timeout: Optional[float] = None) -> bool: + def wait_for_stop(self, timeout: float | None = None) -> bool: """ Waits until the main server thread stops. If the server startup encountered error (and never started), then that error will be raised. diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task.py b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task.py index 86f384213..d432fbe45 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task.py @@ -3,7 +3,7 @@ import threading import uuid from concurrent.futures import CancelledError -from typing import Optional, Union, final +from typing import Union, final from gooddata_flight_server.tasks.task_error import TaskError from gooddata_flight_server.tasks.task_result import TaskResult @@ -46,7 +46,7 @@ def __init__( self, cmd: bytes, cancellable: bool = True, - task_id: Optional[str] = None, + task_id: str | None = None, ): self._task_id = task_id or uuid.uuid4().hex self._cmd = cmd @@ -142,7 +142,7 @@ def on_task_cancel(self) -> None: """ return - def on_task_error(self, error: TaskError) -> Optional[TaskError]: + def on_task_error(self, error: TaskError) -> TaskError | None: """ This method will be called when a task fails with and raises an exception. It will be called after executor creates an instance of TaskError from the diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_error.py b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_error.py index 9573e0f5e..e20ee3e5a 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_error.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_error.py @@ -1,7 +1,7 @@ # (C) 2024 GoodData Corporation import dataclasses from dataclasses import dataclass -from typing import Callable, Optional +from typing import Callable import pyarrow.flight @@ -36,7 +36,7 @@ class TaskError: """ error_info: ErrorInfo - error_factory: Callable[[str, Optional[bytes]], pyarrow.flight.FlightError] + error_factory: Callable[[str, bytes | None], pyarrow.flight.FlightError] client_error: bool = False """ diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_executor.py b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_executor.py index 58ef99fd1..53970f537 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_executor.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_executor.py @@ -1,6 +1,5 @@ # (C) 2024 GoodData Corporation import abc -from typing import Optional from gooddata_flight_server.tasks.task import Task from gooddata_flight_server.tasks.task_result import TaskExecutionResult @@ -55,7 +54,7 @@ def submit( raise NotImplementedError @abc.abstractmethod - def get_task_submitted_timestamp(self, task_id: str) -> Optional[float]: + def get_task_submitted_timestamp(self, task_id: str) -> float | None: """ Returns the timestamp of when the task with the given id was submitted. :param task_id: task id to get the timestamp for @@ -64,7 +63,7 @@ def get_task_submitted_timestamp(self, task_id: str) -> Optional[float]: raise NotImplementedError @abc.abstractmethod - def wait_for_result(self, task_id: str, timeout: Optional[float] = None) -> Optional[TaskExecutionResult]: + def wait_for_result(self, task_id: str, timeout: float | None = None) -> TaskExecutionResult | None: """ Wait for the task with the provided task id to finish. diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_result.py b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_result.py index a0772bd4d..e5ecf4ab2 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_result.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/task_result.py @@ -3,7 +3,7 @@ import threading from collections.abc import Generator, Iterable from dataclasses import dataclass -from typing import Callable, Optional, Union, final +from typing import Callable, Union, final import pyarrow.flight import structlog @@ -49,7 +49,7 @@ def __init__(self, single_use_data: bool = False) -> None: self._claimed = False self._closed = False - def _acquire_reader(self) -> Optional[rwlock.Lockable]: + def _acquire_reader(self) -> rwlock.Lockable | None: rlock = self._data_lock.gen_rlock() if not rlock.acquire(blocking=False): # lock cannot be acquired -> means write lock is taken -> means data is being closed @@ -181,7 +181,7 @@ def close(self) -> None: self._close() @staticmethod - def for_table(table: pyarrow.Table, on_close: Optional[OnCloseCallback] = None) -> "FlightDataTaskResult": + def for_table(table: pyarrow.Table, on_close: OnCloseCallback | None = None) -> "FlightDataTaskResult": """ Factory to create result for an Arrow table. This result allows for repeated reads. @@ -196,7 +196,7 @@ def for_table(table: pyarrow.Table, on_close: Optional[OnCloseCallback] = None) @staticmethod def for_reader( - reader: pyarrow.RecordBatchReader, on_close: Optional[OnCloseCallback] = None + reader: pyarrow.RecordBatchReader, on_close: OnCloseCallback | None = None ) -> "FlightDataTaskResult": """ Factory to create result for an RecordBatchReader. The created result will @@ -212,7 +212,7 @@ def for_reader( return _ReaderTaskResult(reader, on_close=on_close) @staticmethod - def for_data(data: ArrowData, on_close: Optional[OnCloseCallback] = None) -> "FlightDataTaskResult": + def for_data(data: ArrowData, on_close: OnCloseCallback | None = None) -> "FlightDataTaskResult": """ Convenience factory function to create result from either Arrow Table or RecordBatchReader. @@ -262,9 +262,9 @@ def __init__( self, task_id: str, cmd: bytes, - result: Optional[TaskResult], + result: TaskResult | None, cancelled: bool, - error: Optional[TaskError], + error: TaskError | None, ): self._task_id = task_id self._cmd = cmd @@ -288,7 +288,7 @@ def cmd(self) -> bytes: return self._cmd @property - def result(self) -> Optional[TaskResult]: + def result(self) -> TaskResult | None: """ :return: result of task's successful execution; None if the task failed or was cancelled """ @@ -302,7 +302,7 @@ def cancelled(self) -> bool: return self._cancelled @property - def error(self) -> Optional[TaskError]: + def error(self) -> TaskError | None: """ :return: error that caused the task to fail; None if the task has not failed """ @@ -313,7 +313,7 @@ def error(self) -> Optional[TaskError]: class _TableTaskResult(FlightDataTaskResult): - def __init__(self, table: pyarrow.Table, on_close: Optional[OnCloseCallback] = None) -> None: + def __init__(self, table: pyarrow.Table, on_close: OnCloseCallback | None = None) -> None: super().__init__(single_use_data=False) self._table: pyarrow.Table = table @@ -336,7 +336,7 @@ def _close(self) -> None: class _ReaderTaskResult(FlightDataTaskResult): - def __init__(self, reader: pyarrow.RecordBatchReader, on_close: Optional[OnCloseCallback] = None) -> None: + def __init__(self, reader: pyarrow.RecordBatchReader, on_close: OnCloseCallback | None = None) -> None: super().__init__(single_use_data=True) self._reader = reader diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/temporal_container.py b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/temporal_container.py index f72284c17..5aeda34ee 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/temporal_container.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/temporal_container.py @@ -3,7 +3,7 @@ import time from collections.abc import Iterator from dataclasses import dataclass -from typing import Any, Callable, Generic, Optional, TypeVar +from typing import Any, Callable, Generic, TypeVar import structlog from readerwriterlock import rwlock @@ -153,7 +153,7 @@ def start_collector(self) -> None: if self._thread.is_alive(): self._thread.start() - def get_entry(self, entry_id: str) -> Optional[T]: + def get_entry(self, entry_id: str) -> T | None: """ :param entry_id: entry identifier :return: entry or None if not found @@ -185,7 +185,7 @@ def evict_entry(self, entry_id: str) -> bool: self._entry_evict_fun(entry.value) return True - def pop_entry(self, entry_id: str) -> Optional[T]: + def pop_entry(self, entry_id: str) -> T | None: """ Pops an entry out of the container. This will take the entry out and will not run the eviction function. diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/thread_task_executor.py b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/thread_task_executor.py index a4a23e115..bc2773278 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/thread_task_executor.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/tasks/thread_task_executor.py @@ -6,7 +6,7 @@ from concurrent.futures import CancelledError, Future, ThreadPoolExecutor from contextlib import contextmanager from dataclasses import dataclass -from typing import Any, Optional, Union +from typing import Any, Union import opentelemetry.context as otelctx import pyarrow.flight @@ -47,22 +47,22 @@ class _TaskExecutionStats: time when the task was created """ - run_submitted: Optional[float] = None + run_submitted: float | None = None """ time when task was submitted to thread pool to invoke the run() """ - run_started: Optional[float] = None + run_started: float | None = None """ time when some thread actually started the run() """ - run_completed: Optional[float] = None + run_completed: float | None = None """ time when the run() completed (regardless of the result) """ - completed: Optional[float] = None + completed: float | None = None """ time when all work for task execution completed. if the task was actually run, then this value is same as `run_completed`. if the task failed/was cancelled @@ -187,7 +187,7 @@ def __init__( self._lock = threading.RLock() # all these are protected using the lock - self._result_future: Optional[Future[Union[TaskResult, TaskError]]] = None + self._result_future: Future[Union[TaskResult, TaskError]] | None = None self._completed: threading.Condition = threading.Condition(self._lock) @property @@ -289,7 +289,7 @@ def cancel(self) -> bool: # may not be possible return self._task.cancel() - def wait_for_completion(self, timeout: Optional[float] = None) -> None: + def wait_for_completion(self, timeout: float | None = None) -> None: with self._lock: completed = self._completed.wait(timeout=timeout) @@ -566,7 +566,7 @@ def submit( execution.start() self._metrics.queue_size.set(self._queue_size) - def get_task_submitted_timestamp(self, task_id: str) -> Optional[float]: + def get_task_submitted_timestamp(self, task_id: str) -> float | None: with self._task_lock: execution = self._executions.get(task_id) @@ -574,7 +574,7 @@ def get_task_submitted_timestamp(self, task_id: str) -> Optional[float]: return execution.stats.created return None - def wait_for_result(self, task_id: str, timeout: Optional[float] = None) -> Optional[TaskExecutionResult]: + def wait_for_result(self, task_id: str, timeout: float | None = None) -> TaskExecutionResult | None: with self._task_lock: execution = self._executions.get(task_id) result = self._results.get_entry(task_id) @@ -621,7 +621,7 @@ def close_result(self, task_id: str) -> bool: self._on_finished_task_evicted(result) return True - def stop(self, cancel_running: bool = True, timeout: Optional[float] = None) -> None: + def stop(self, cancel_running: bool = True, timeout: float | None = None) -> None: """ Stops the service. Any pending tasks will be immediately cancelled. Tasks that are already executing are allowed to complete. diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/logging.py b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/logging.py index f7d0e9d83..7b96d2a99 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/logging.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/logging.py @@ -5,7 +5,7 @@ import os from logging.config import fileConfig -from typing import Any, Optional, Union +from typing import Any, Union import orjson import structlog @@ -13,7 +13,7 @@ from structlog.typing import EventDict, WrappedLogger -def _resolve_config(logging_ini: str, for_module: Optional[str]) -> str: +def _resolve_config(logging_ini: str, for_module: str | None) -> str: if os.path.isabs(logging_ini): return logging_ini else: @@ -47,7 +47,7 @@ class _OtelTraceContextInjector: __slots__ = ("_trace_id_key", "_span_id_key", "_parent_span_id_key") - def __init__(self, trace_ctx_keys: Optional[dict[str, str]] = None) -> None: + def __init__(self, trace_ctx_keys: dict[str, str] | None = None) -> None: _keys = trace_ctx_keys or {} # do one-time lookup of the actual key names under which the different @@ -76,7 +76,7 @@ def __call__(self, _: WrappedLogger, __: str, event_dict: EventDict) -> EventDic event_dict[self._trace_id_key] = f"{span_ctx.trace_id:x}" event_dict[self._span_id_key] = f"{span_ctx.span_id:x}" - parent_ctx: Optional[trace.SpanContext] = getattr(span, "parent", None) + parent_ctx: trace.SpanContext | None = getattr(span, "parent", None) if parent_ctx: event_dict[self._parent_span_id_key] = f"{parent_ctx.span_id:x}" @@ -87,7 +87,7 @@ def _configure_structlog( dev_log: bool, event_key: str, add_trace_ctx: bool = False, - trace_ctx_keys: Optional[dict[str, str]] = None, + trace_ctx_keys: dict[str, str] | None = None, ) -> None: common_processors: list[Any] = [ structlog.stdlib.filter_by_level, @@ -129,9 +129,9 @@ def init_logging( logging_ini: str, dev_log: bool = False, event_key: str = "event", - for_module: Optional[str] = None, + for_module: str | None = None, add_trace_ctx: bool = False, - trace_ctx_keys: Optional[dict[str, str]] = None, + trace_ctx_keys: dict[str, str] | None = None, ) -> str: """ Initializes python logging from the file on the provided path. If the path is absolute, then it is diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/methods_discovery.py b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/methods_discovery.py index fb2bf6746..1fa7ca379 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/methods_discovery.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/methods_discovery.py @@ -2,7 +2,6 @@ import importlib from functools import wraps from inspect import signature -from typing import Optional from gooddata_flight_server.exceptions import FlightMethodsModuleError from gooddata_flight_server.server.base import ( @@ -74,7 +73,7 @@ def _only_valid_flight_methods_factory( return factory -def get_methods_factory(module_name: str, root: Optional[str] = None) -> FlightServerMethodsFactory: +def get_methods_factory(module_name: str, root: str | None = None) -> FlightServerMethodsFactory: """ Get the method factory from the given module. The module should contain exactly one method decorated with @flight_server_methods. diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py index cfa1dc2dc..330d87402 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py @@ -3,7 +3,6 @@ import platform import socket import sys -from typing import Optional from opentelemetry import trace from opentelemetry.sdk.resources import ( @@ -111,7 +110,7 @@ def _create_resource(config: OtelConfig) -> Resource: ) -def initialize_otel_tracing(config: Optional[OtelConfig]) -> None: +def initialize_otel_tracing(config: OtelConfig | None) -> None: """ Initializes OpenTelemetry tracing according to the provided `config`: diff --git a/packages/gooddata-pandas/src/gooddata_pandas/data_access.py b/packages/gooddata-pandas/src/gooddata_pandas/data_access.py index e33f6d340..5e9865288 100644 --- a/packages/gooddata-pandas/src/gooddata_pandas/data_access.py +++ b/packages/gooddata-pandas/src/gooddata_pandas/data_access.py @@ -1,7 +1,7 @@ # (C) 2021 GoodData Corporation from __future__ import annotations -from typing import Any, Callable, Optional, Union, cast +from typing import Any, Callable, Union, cast from gooddata_sdk import ( Attribute, @@ -33,7 +33,7 @@ class ExecutionDefinitionBuilder: _DEFAULT_INDEX_NAME: str = "0" - def __init__(self, columns: ColumnsDef, index_by: Optional[IndexDef] = None, is_cancellable: bool = False) -> None: + def __init__(self, columns: ColumnsDef, index_by: IndexDef | None = None, is_cancellable: bool = False) -> None: """ Initializes the ExecutionDefinitionBuilder instance with columns and an optional index_by definition. Processes the given columns and index_by @@ -105,7 +105,7 @@ def _add_column(self, column_name: str, column_def: Union[str, Attribute, Metric self._col_to_metric_idx[column_name] = len(self._metrics) self._metrics.append(item) - def _process_index(self, index_by: Optional[IndexDef] = None) -> None: + def _process_index(self, index_by: IndexDef | None = None) -> None: """ Processes the given index definition (index_by) to determine whether to reference attributes or raise an error when attempting to reference metrics. Updates the internal index-to-attribute mapping @@ -186,7 +186,7 @@ def _process_index_item_without_col_ref(self, index_name: str, index_def: LabelI self._index_to_attr_idx[index_name] = len(self._attributes) self._attributes.append(attr_item) - def _update_filter_ids(self, filter_by: Optional[Union[Filter, list[Filter]]] = None) -> Optional[list[Filter]]: + def _update_filter_ids(self, filter_by: Union[Filter, list[Filter]] | None = None) -> list[Filter] | None: """ Updates the filter IDs for the given filters. If a filter references a metric/attribute by a string, it is converted to the corresponding internal ID. @@ -225,7 +225,7 @@ def _update_filter_ids(self, filter_by: Optional[Union[Filter, list[Filter]]] = return filters def build_execution_definition( - self, filter_by: Optional[Union[Filter, list[Filter]]] = None + self, filter_by: Union[Filter, list[Filter]] | None = None ) -> ExecutionDefinition: """ Builds an ExecutionDefinition instance with the current configuration of metrics, attributes, and filters. @@ -262,8 +262,8 @@ def _compute( sdk: GoodDataSdk, workspace_id: str, columns: ColumnsDef, - index_by: Optional[IndexDef] = None, - filter_by: Optional[Union[Filter, list[Filter]]] = None, + index_by: IndexDef | None = None, + filter_by: Union[Filter, list[Filter]] | None = None, is_cancellable: bool = False, ) -> tuple[Execution, dict[str, int], dict[str, int], dict[str, int]]: """ @@ -360,8 +360,8 @@ def _extract_from_attributes_and_maybe_metrics( cols: list[str], col_to_attr_idx: dict[str, int], col_to_metric_idx: dict[str, int], - index_to_attr_idx: Optional[dict[str, int]] = None, - result_page_len: Optional[int] = None, + index_to_attr_idx: dict[str, int] | None = None, + result_page_len: int | None = None, ) -> tuple[dict, dict]: """ Internal function that extracts data from execution response with attributes columns and @@ -424,11 +424,11 @@ def compute_and_extract( sdk: GoodDataSdk, workspace_id: str, columns: ColumnsDef, - index_by: Optional[IndexDef] = None, - filter_by: Optional[Union[Filter, list[Filter]]] = None, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + index_by: IndexDef | None = None, + filter_by: Union[Filter, list[Filter]] | None = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> tuple[dict, dict]: """ Convenience function that computes and extracts data from the execution response. diff --git a/packages/gooddata-pandas/src/gooddata_pandas/dataframe.py b/packages/gooddata-pandas/src/gooddata_pandas/dataframe.py index 196a18555..2074a6526 100644 --- a/packages/gooddata-pandas/src/gooddata_pandas/dataframe.py +++ b/packages/gooddata-pandas/src/gooddata_pandas/dataframe.py @@ -1,7 +1,7 @@ # (C) 2021 GoodData Corporation from __future__ import annotations -from typing import Callable, Literal, Optional, Union +from typing import Callable, Literal, Union import pandas from gooddata_api_client import models @@ -72,10 +72,10 @@ def indexed( self, index_by: IndexDef, columns: ColumnsDef, - filter_by: Optional[Union[Filter, list[Filter]]] = None, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + filter_by: Union[Filter, list[Filter]] | None = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> pandas.DataFrame: """ Creates a data frame indexed by values of the label. The data frame columns will be created from either @@ -115,10 +115,10 @@ def indexed( def not_indexed( self, columns: ColumnsDef, - filter_by: Optional[Union[Filter, list[Filter]]] = None, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + filter_by: Union[Filter, list[Filter]] | None = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> pandas.DataFrame: """ Creates a data frame with columns created from metrics and or labels. @@ -152,11 +152,11 @@ def not_indexed( def for_items( self, items: ColumnsDef, - filter_by: Optional[Union[Filter, list[Filter]]] = None, + filter_by: Union[Filter, list[Filter]] | None = None, auto_index: bool = True, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> pandas.DataFrame: """ Creates a data frame for named items. This is a convenience method that will create DataFrame with or @@ -214,9 +214,9 @@ def for_visualization( self, visualization_id: str, auto_index: bool = True, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> pandas.DataFrame: """ Creates a data frame with columns based on the content of the visualization with the provided identifier. @@ -256,10 +256,10 @@ def for_visualization( def for_created_visualization( self, created_visualizations_response: dict, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, optimized: bool = False, - grand_totals_position: Optional[Literal["pinnedBottom", "pinnedTop", "bottom", "top"]] = "bottom", + grand_totals_position: Literal["pinnedBottom", "pinnedTop", "bottom", "top"] | None = "bottom", ) -> tuple[pandas.DataFrame, DataFrameMetadata]: """ Creates a data frame using a created visualization. @@ -305,13 +305,13 @@ def result_cache_metadata_for_exec_result_id(self, result_id: str) -> ResultCach def for_exec_def( self, exec_def: ExecutionDefinition, - label_overrides: Optional[LabelOverrides] = None, + label_overrides: LabelOverrides | None = None, result_size_dimensions_limits: ResultSizeDimensions = (), - result_size_bytes_limit: Optional[int] = None, + result_size_bytes_limit: int | None = None, page_size: int = _DEFAULT_PAGE_SIZE, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + on_execution_submitted: Callable[[Execution], None] | None = None, optimized: bool = False, - grand_totals_position: Optional[Literal["pinnedBottom", "pinnedTop", "bottom", "top"]] = "bottom", + grand_totals_position: Literal["pinnedBottom", "pinnedTop", "bottom", "top"] | None = "bottom", ) -> tuple[pandas.DataFrame, DataFrameMetadata]: """ Creates a data frame using an execution definition. @@ -378,15 +378,15 @@ def for_exec_def( def for_exec_result_id( self, result_id: str, - label_overrides: Optional[LabelOverrides] = None, - result_cache_metadata: Optional[ResultCacheMetadata] = None, + label_overrides: LabelOverrides | None = None, + result_cache_metadata: ResultCacheMetadata | None = None, result_size_dimensions_limits: ResultSizeDimensions = (), - result_size_bytes_limit: Optional[int] = None, + result_size_bytes_limit: int | None = None, use_local_ids_in_headers: bool = False, use_primary_labels_in_attributes: bool = False, page_size: int = _DEFAULT_PAGE_SIZE, optimized: bool = False, - grand_totals_position: Optional[Literal["pinnedBottom", "pinnedTop", "bottom", "top"]] = "bottom", + grand_totals_position: Literal["pinnedBottom", "pinnedTop", "bottom", "top"] | None = "bottom", ) -> tuple[pandas.DataFrame, DataFrameMetadata]: """ Retrieves a DataFrame and DataFrame metadata for a given execution result identifier. diff --git a/packages/gooddata-pandas/src/gooddata_pandas/good_pandas.py b/packages/gooddata-pandas/src/gooddata_pandas/good_pandas.py index 1ae224068..23a99b9ca 100644 --- a/packages/gooddata-pandas/src/gooddata_pandas/good_pandas.py +++ b/packages/gooddata-pandas/src/gooddata_pandas/good_pandas.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional from gooddata_sdk import GoodDataSdk from gooddata_sdk.utils import PROFILES_FILE_PATH, good_pandas_profile_content @@ -24,8 +23,8 @@ def __init__( self, host: str, token: str, - headers_host: Optional[str] = None, - **custom_headers_: Optional[str], + headers_host: str | None = None, + **custom_headers_: str | None, ) -> None: """ Initializes GoodPandas instance. diff --git a/packages/gooddata-pandas/src/gooddata_pandas/result_convertor.py b/packages/gooddata-pandas/src/gooddata_pandas/result_convertor.py index 46a3959d0..552496de4 100644 --- a/packages/gooddata-pandas/src/gooddata_pandas/result_convertor.py +++ b/packages/gooddata-pandas/src/gooddata_pandas/result_convertor.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod from collections.abc import Iterator from functools import cached_property -from typing import Any, Callable, Literal, Optional, Union, cast +from typing import Any, Callable, Literal, Union, cast import pandas from attrs import define, field, frozen @@ -31,7 +31,7 @@ class _Header(ABC): def _dict(self) -> dict[str, Any]: pass - def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]: + def get(self, key: str, default: Any | None = None) -> Any | None: return self._dict.get(key, default) @@ -89,7 +89,7 @@ def _dict(self) -> dict[str, Any]: return {"totalHeader": {"function": self.function}} -def _header_from_dict(d: dict[str, Any]) -> Optional[_Header]: +def _header_from_dict(d: dict[str, Any]) -> _Header | None: """ Convert dict representation to _Header object. :param d: dictionary representation of a header @@ -167,7 +167,7 @@ def __getitem__(self, index: int) -> _Header: # Optimized version of _DataWithHeaders uses _HeaderContainer instead of list of headers _HeadersByAxis = tuple[ - Union[_DataHeaders, _DataHeaderContainers], Union[Optional[_DataHeaders], Optional[_DataHeaderContainers]] + Union[_DataHeaders, _DataHeaderContainers], Union[_DataHeaders | None, _DataHeaderContainers | None] ] @@ -188,8 +188,8 @@ class _DataWithHeaders: data: list[_DataArray] data_headers: _HeadersByAxis - grand_totals: tuple[Optional[list[_DataArray]], Optional[list[_DataArray]]] - grand_total_headers: tuple[Optional[list[dict[str, _DataHeaders]]], Optional[list[dict[str, _DataHeaders]]]] + grand_totals: tuple[list[_DataArray] | None, list[_DataArray] | None] + grand_total_headers: tuple[list[dict[str, _DataHeaders]] | None, list[dict[str, _DataHeaders]] | None] @define @@ -209,10 +209,10 @@ class _AbstractAccumulatedData(ABC): """ data: list[_DataArray] = field(init=False, factory=list) - data_headers: list[Optional[Any]] = field(init=False, factory=lambda: [None, None]) - grand_totals: list[Optional[list[_DataArray]]] = field(init=False, factory=lambda: [None, None]) + data_headers: list[Any | None] = field(init=False, factory=lambda: [None, None]) + grand_totals: list[list[_DataArray] | None] = field(init=False, factory=lambda: [None, None]) total_of_grant_totals_processed: bool = field(init=False, default=False) - grand_totals_headers: list[Optional[list[dict[str, _DataHeaders]]]] = field( + grand_totals_headers: list[list[dict[str, _DataHeaders]] | None] = field( init=False, factory=lambda: [None, None] ) @@ -473,7 +473,7 @@ def from_data( ) @staticmethod - def _get_totals_indexes(headers: Optional[Any]) -> list[list[int]]: + def _get_totals_indexes(headers: Any | None) -> list[list[int]]: if headers is None: return [] return [ @@ -486,7 +486,7 @@ def _read_complete_execution_result( execution_response: BareExecutionResponse, result_cache_metadata: ResultCacheMetadata, result_size_dimensions_limits: ResultSizeDimensions, - result_size_bytes_limit: Optional[int] = None, + result_size_bytes_limit: int | None = None, page_size: int = _DEFAULT_PAGE_SIZE, optimized: bool = False, ) -> _DataWithHeaders: @@ -569,10 +569,10 @@ def _create_header_mapper( response: BareExecutionResponse, dim: int, primary_attribute_labels_mapping: dict[int, dict[str, str]], - label_overrides: Optional[LabelOverrides] = None, + label_overrides: LabelOverrides | None = None, use_local_ids_in_headers: bool = False, use_primary_labels_in_attributes: bool = False, -) -> Callable[[Any, Optional[int]], Optional[str]]: +) -> Callable[[Any, int | None], str | None]: """ Prepares a header mapper function which translates header structures into appropriate labels used in a dataframe. @@ -597,7 +597,7 @@ def _create_header_mapper( attribute_labels = label_overrides.get("labels", {}) measure_labels = label_overrides.get("metrics", {}) - def _mapper(header: Union[dict, _Header, None], header_idx: Optional[int]) -> Optional[str]: + def _mapper(header: Union[dict, _Header, None], header_idx: int | None) -> str | None: label = None if header is None: pass @@ -655,7 +655,7 @@ def _headers_to_index( label_overrides: LabelOverrides, use_local_ids_in_headers: bool = False, use_primary_labels_in_attributes: bool = False, -) -> tuple[Optional[pandas.Index], dict[int, dict[str, str]]]: +) -> tuple[pandas.Index | None, dict[int, dict[str, str]]]: """Converts headers to a pandas MultiIndex. This function converts the headers present in the response to a pandas MultiIndex (can be used in pandas dataframes) @@ -700,7 +700,7 @@ def _headers_to_index( def _merge_grand_totals_into_data( extract: _DataWithHeaders, - grand_totals_position: Optional[Literal["pinnedBottom", "pinnedTop", "bottom", "top"]] = "bottom", + grand_totals_position: Literal["pinnedBottom", "pinnedTop", "bottom", "top"] | None = "bottom", ) -> Union[_DataArray, list[_DataArray]]: """ Merges grand totals into the extracted data. This function will mutate the extracted data, @@ -767,12 +767,12 @@ def convert_execution_response_to_dataframe( result_cache_metadata: ResultCacheMetadata, label_overrides: LabelOverrides, result_size_dimensions_limits: ResultSizeDimensions, - result_size_bytes_limit: Optional[int] = None, + result_size_bytes_limit: int | None = None, use_local_ids_in_headers: bool = False, use_primary_labels_in_attributes: bool = False, page_size: int = _DEFAULT_PAGE_SIZE, optimized: bool = False, - grand_totals_position: Optional[Literal["pinnedBottom", "pinnedTop", "bottom", "top"]] = "bottom", + grand_totals_position: Literal["pinnedBottom", "pinnedTop", "bottom", "top"] | None = "bottom", ) -> tuple[pandas.DataFrame, DataFrameMetadata]: """ Converts execution result to a pandas dataframe, maintaining the dimensionality of the result. diff --git a/packages/gooddata-pandas/src/gooddata_pandas/series.py b/packages/gooddata-pandas/src/gooddata_pandas/series.py index e7e938a8a..664f17186 100644 --- a/packages/gooddata-pandas/src/gooddata_pandas/series.py +++ b/packages/gooddata-pandas/src/gooddata_pandas/series.py @@ -1,7 +1,7 @@ # (C) 2021 GoodData Corporation from __future__ import annotations -from typing import Callable, Optional, Union +from typing import Callable, Union import pandas from gooddata_sdk import Attribute, Execution, Filter, GoodDataSdk, ObjId, SimpleMetric @@ -27,10 +27,10 @@ def indexed( self, index_by: IndexDef, data_by: Union[SimpleMetric, str, ObjId, Attribute], - filter_by: Optional[Union[Filter, list[Filter]]] = None, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + filter_by: Union[Filter, list[Filter]] | None = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> pandas.Series: """Creates pandas Series from data points calculated from a single `data_by`. @@ -94,11 +94,11 @@ def indexed( def not_indexed( self, data_by: Union[SimpleMetric, str, ObjId, Attribute], - granularity: Optional[Union[list[LabelItemDef], IndexDef]] = None, - filter_by: Optional[Union[Filter, list[Filter]]] = None, - on_execution_submitted: Optional[Callable[[Execution], None]] = None, + granularity: Union[list[LabelItemDef], IndexDef] | None = None, + filter_by: Union[Filter, list[Filter]] | None = None, + on_execution_submitted: Callable[[Execution], None] | None = None, is_cancellable: bool = False, - result_page_len: Optional[int] = None, + result_page_len: int | None = None, ) -> pandas.Series: """ Creates a pandas.Series from data points calculated from a single `data_by` without constructing an index. @@ -136,7 +136,7 @@ def not_indexed( """ if isinstance(granularity, list): - _index: Optional[IndexDef] = {str(idx): label for idx, label in enumerate(granularity)} + _index: IndexDef | None = {str(idx): label for idx, label in enumerate(granularity)} else: _index = granularity diff --git a/packages/gooddata-pandas/src/gooddata_pandas/utils.py b/packages/gooddata-pandas/src/gooddata_pandas/utils.py index fb8fd8b16..f8789925e 100644 --- a/packages/gooddata-pandas/src/gooddata_pandas/utils.py +++ b/packages/gooddata-pandas/src/gooddata_pandas/utils.py @@ -3,7 +3,7 @@ import hashlib import uuid -from typing import Any, Optional, Union +from typing import Any, Union import pandas from gooddata_sdk import ( @@ -74,7 +74,7 @@ def _val_to_hash(val: str) -> str: return hash_object.hexdigest() -def _str_to_obj_id(val: DataItemDef) -> Optional[ObjId]: +def _str_to_obj_id(val: DataItemDef) -> ObjId | None: """ Convert a value to ObjId if it is in one of ["label", "metric", "fact"] types. @@ -110,7 +110,7 @@ def _try_obj_id(val: DataItemDef) -> DataItemDef: return val -def _to_item(val: DataItemDef, local_id: Optional[str] = None) -> Union[Attribute, Metric]: +def _to_item(val: DataItemDef, local_id: str | None = None) -> Union[Attribute, Metric]: """ Convert a DataItemDef value to either an Attribute or a Metric based on its type. @@ -136,7 +136,7 @@ def _to_item(val: DataItemDef, local_id: Optional[str] = None) -> Union[Attribut raise ValueError(f"Invalid column_by item {val}") -def _to_attribute(val: LabelItemDef, local_id: Optional[str] = None) -> Attribute: +def _to_attribute(val: LabelItemDef, local_id: str | None = None) -> Attribute: """ Convert a LabelItemDef value to an Attribute. @@ -169,7 +169,7 @@ def _typed_attribute_value(ct_attr: CatalogAttribute, value: Any) -> Any: return converter.to_external_type(value) -def make_pandas_index(index: dict) -> Optional[Union[Index, MultiIndex]]: +def make_pandas_index(index: dict) -> Union[Index, MultiIndex] | None: """ Create a pandas index or multi-index based on the input index dictionary. diff --git a/packages/gooddata-pandas/tests/dataframe/test_dataframe_for_exec_def.py b/packages/gooddata-pandas/tests/dataframe/test_dataframe_for_exec_def.py index fb2a8de61..a131657c0 100644 --- a/packages/gooddata-pandas/tests/dataframe/test_dataframe_for_exec_def.py +++ b/packages/gooddata-pandas/tests/dataframe/test_dataframe_for_exec_def.py @@ -1,6 +1,6 @@ # (C) 2022 GoodData Corporation from pathlib import Path -from typing import Literal, Optional +from typing import Literal import pytest from gooddata_pandas import DataFrameFactory @@ -27,11 +27,11 @@ def _run_and_validate_results( gdf: DataFrameFactory, exec_def: ExecutionDefinition, expected: tuple[int, int], - expected_row_totals: Optional[list[list[int]]] = None, - expected_column_totals: Optional[list[list[int]]] = None, + expected_row_totals: list[list[int]] | None = None, + expected_column_totals: list[list[int]] | None = None, page_size: int = 100, optimized: bool = False, - grand_totals_position: Optional[Literal["pinnedBottom", "pinnedTop", "bottom", "top"]] = "bottom", + grand_totals_position: Literal["pinnedBottom", "pinnedTop", "bottom", "top"] | None = "bottom", ) -> str: # generate dataframe from exec_def result, result_metadata = gdf.for_exec_def( diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py index dc6c73a3d..124a1b464 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py @@ -2,7 +2,7 @@ from __future__ import annotations import builtins -from typing import Any, Optional, TypeVar +from typing import Any, TypeVar import attr from cattrs import structure @@ -14,7 +14,7 @@ def value_in_allowed( - instance: type[Base], attribute: attr.Attribute, value: str, client_class: Optional[Any] = None + instance: type[Base], attribute: attr.Attribute, value: str, client_class: Any | None = None ) -> None: if client_class is None: client_class = instance.client_class() @@ -77,9 +77,9 @@ class JsonApiEntityBase: id: str type: str attributes: dict[str, Any] = attr.field(repr=False) - relationships: Optional[dict[str, Any]] = attr.field(repr=False, default=None) - meta: Optional[dict[str, Any]] = attr.field(repr=False, default=None) - links: Optional[dict[str, Any]] = attr.field(repr=False, default=None) + relationships: dict[str, Any] | None = attr.field(repr=False, default=None) + meta: dict[str, Any] | None = attr.field(repr=False, default=None) + links: dict[str, Any] | None = attr.field(repr=False, default=None) related_entities_data: list[dict[str, Any]] = attr.field(repr=False, factory=list) related_entities_side_loads: list[dict[str, Any]] = attr.field(repr=False, factory=list) side_loads: list[dict[str, Any]] = attr.field(repr=False, factory=list) @@ -88,8 +88,8 @@ class JsonApiEntityBase: def from_api( cls, entity: dict[str, Any], - side_loads: Optional[list[Any]] = None, - related_entities: Optional[AllPagedEntities] = None, + side_loads: list[Any] | None = None, + related_entities: AllPagedEntities | None = None, ) -> JsonApiEntityBase: """ Creates object from entity passed by client class, which represents it as dictionary. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py index 67053621d..e44fed7d2 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py @@ -1,8 +1,6 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.generate_ldm_request import GenerateLdmRequest from gooddata_api_client.model.pdm_ldm_request import PdmLdmRequest @@ -26,8 +24,8 @@ def client_class() -> type[PdmSql]: @attr.s(auto_attribs=True, kw_only=True) class CatalogPdmLdmRequest(Base): - sqls: Optional[list[CatalogPdmSql]] = None - tables: Optional[list[CatalogDeclarativeTable]] = None + sqls: list[CatalogPdmSql] | None = None + tables: list[CatalogDeclarativeTable] | None = None @staticmethod def client_class() -> type[PdmLdmRequest]: @@ -37,21 +35,21 @@ def client_class() -> type[PdmLdmRequest]: @attr.s(auto_attribs=True, kw_only=True) class CatalogGenerateLdmRequest(Base): separator: str = "__" - generate_long_ids: Optional[bool] = None - table_prefix: Optional[str] = None - view_prefix: Optional[str] = None - primary_label_prefix: Optional[str] = None - secondary_label_prefix: Optional[str] = None - fact_prefix: Optional[str] = None - date_granularities: Optional[str] = None - grain_prefix: Optional[str] = None - reference_prefix: Optional[str] = None - grain_reference_prefix: Optional[str] = None - denorm_prefix: Optional[str] = None - wdf_prefix: Optional[str] = None - pdm: Optional[CatalogPdmLdmRequest] = None - workspace_id: Optional[str] = None - translation_prefix: Optional[str] = None + generate_long_ids: bool | None = None + table_prefix: str | None = None + view_prefix: str | None = None + primary_label_prefix: str | None = None + secondary_label_prefix: str | None = None + fact_prefix: str | None = None + date_granularities: str | None = None + grain_prefix: str | None = None + reference_prefix: str | None = None + grain_reference_prefix: str | None = None + denorm_prefix: str | None = None + wdf_prefix: str | None = None + pdm: CatalogPdmLdmRequest | None = None + workspace_id: str | None = None + translation_prefix: str | None = None @staticmethod def client_class() -> type[GenerateLdmRequest]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/scan_model_request.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/scan_model_request.py index 38cdf0e7e..1bbeaca30 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/scan_model_request.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/scan_model_request.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Any, Optional +from typing import Any import attr from attr import field @@ -20,9 +20,9 @@ class CatalogScanModelRequest(Base): separator: str = "__" scan_tables: bool = field(default=True, validator=one_scan_true) scan_views: bool = field(default=False, validator=one_scan_true) - table_prefix: Optional[str] = None - view_prefix: Optional[str] = None - schemata: Optional[list[str]] = None + table_prefix: str | None = None + view_prefix: str | None = None + schemata: list[str] | None = None @staticmethod def client_class() -> type[ScanRequest]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/responses/scan_sql_response.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/responses/scan_sql_response.py index 1dbcb0be9..d050738b1 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/responses/scan_sql_response.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/responses/scan_sql_response.py @@ -1,8 +1,6 @@ # (C) 2023 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.scan_sql_response import ScanSqlResponse as ApiScanSqlResponse @@ -13,7 +11,7 @@ @attr.s(auto_attribs=True, kw_only=True) class ScanSqlResponse(Base): columns: list[SqlColumn] - data_preview: Optional[list[list[Optional[str]]]] = None + data_preview: list[list[str | None]] | None = None @staticmethod def client_class() -> type[ApiScanSqlResponse]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/data_source.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/data_source.py index c5a805cfd..68382c0bf 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/data_source.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/data_source.py @@ -3,7 +3,7 @@ import builtins from pathlib import Path -from typing import Any, Optional, Union +from typing import Any, Union from warnings import warn import attr @@ -90,7 +90,7 @@ def _inject_credentials_aac(self, config_file: Union[str, Path]) -> DeclarativeD return self._inject_base(credentials) def to_api( - self, credentials: Optional[dict[str, Any]] = None, config_file: Optional[Union[str, Path]] = None + self, credentials: dict[str, Any] | None = None, config_file: Union[str, Path] | None = None ) -> DeclarativeDataSources: client_class = self.client_class() if credentials is not None and config_file is not None: @@ -132,24 +132,24 @@ class CatalogDeclarativeDataSource(Base): id: str name: str type: str = attr.field(validator=value_in_allowed) - url: Optional[str] = None + url: str | None = None schema: str - cache_strategy: Optional[str] = None - username: Optional[str] = None - parameters: Optional[list[CatalogParameter]] = None - decoded_parameters: Optional[list[CatalogParameter]] = None + cache_strategy: str | None = None + username: str | None = None + parameters: list[CatalogParameter] | None = None + decoded_parameters: list[CatalogParameter] | None = None permissions: list[CatalogDeclarativeDataSourcePermission] = attr.field(factory=list) - client_id: Optional[str] = None - authentication_type: Optional[str] = None - alternative_data_source_id: Optional[str] = None + client_id: str | None = None + authentication_type: str | None = None + alternative_data_source_id: str | None = None def to_test_request( self, - password: Optional[str] = None, - token: Optional[str] = None, - private_key: Optional[str] = None, - private_key_passphrase: Optional[str] = None, - client_secret: Optional[str] = None, + password: str | None = None, + token: str | None = None, + private_key: str | None = None, + private_key_passphrase: str | None = None, + client_secret: str | None = None, ) -> TestDefinitionRequest: kwargs: dict[str, Any] = {"schema": self.schema} if password is not None: @@ -183,11 +183,11 @@ def data_source_folder(data_sources_folder: Path, data_source_id: str) -> Path: def to_api( self, - password: Optional[str] = None, - token: Optional[str] = None, - private_key: Optional[str] = None, - private_key_passphrase: Optional[str] = None, - client_secret: Optional[str] = None, + password: str | None = None, + token: str | None = None, + private_key: str | None = None, + private_key_passphrase: str | None = None, + client_secret: str | None = None, ) -> DeclarativeDataSource: dictionary = self._get_snake_dict() if password is not None: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py index 45ccb6a15..2edec80c5 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py @@ -1,8 +1,6 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.declarative_column import DeclarativeColumn @@ -13,11 +11,11 @@ class CatalogDeclarativeColumn(Base): name: str data_type: str - is_primary_key: Optional[bool] = None - referenced_table_id: Optional[str] = None - referenced_table_column: Optional[str] = None - is_nullable: Optional[bool] = None - null_value: Optional[str] = None + is_primary_key: bool | None = None + referenced_table_id: str | None = None + referenced_table_column: str | None = None + is_nullable: bool | None = None + null_value: str | None = None @staticmethod def client_class() -> type[DeclarativeColumn]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/table.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/table.py index ea80d4a15..4afa48f2f 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/table.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/table.py @@ -3,7 +3,6 @@ import builtins from pathlib import Path -from typing import Optional import attr from gooddata_api_client.model.declarative_table import DeclarativeTable @@ -19,7 +18,7 @@ class CatalogDeclarativeTable(Base): type: str path: list[str] columns: list[CatalogDeclarativeColumn] - name_prefix: Optional[str] = None + name_prefix: str | None = None @staticmethod def client_class() -> builtins.type[DeclarativeTable]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/entity_model/data_source.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/entity_model/data_source.py index 84f4f0272..c4a63cfcc 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/entity_model/data_source.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/entity_model/data_source.py @@ -2,7 +2,7 @@ from __future__ import annotations import builtins -from typing import Any, ClassVar, Optional, TypeVar +from typing import Any, ClassVar, TypeVar import attr from cattrs import structure @@ -55,12 +55,12 @@ class CatalogDataSourceBase(Base): name: str type: str = attr.field() schema: str - url: Optional[str] = None - cache_strategy: Optional[str] = None - parameters: Optional[list[dict[str, str]]] = None - decoded_parameters: Optional[list[dict[str, str]]] = None + url: str | None = None + cache_strategy: str | None = None + parameters: list[dict[str, str]] | None = None + decoded_parameters: list[dict[str, str]] | None = None credentials: Credentials = attr.field(repr=False) - alternative_data_source_id: Optional[str] = None + alternative_data_source_id: str | None = None @type.validator # type: ignore[attr-defined] def _check_allowed_values(self, attribute: attr.Attribute, value: str) -> None: @@ -105,18 +105,18 @@ def __eq__(self, other: Any) -> bool: @attr.s(auto_attribs=True, kw_only=True, eq=False) class CatalogDataSource(CatalogDataSourceBase): - _URL_TMPL: ClassVar[Optional[str]] = None - _DATA_SOURCE_TYPE: ClassVar[Optional[str]] = None + _URL_TMPL: ClassVar[str | None] = None + _DATA_SOURCE_TYPE: ClassVar[str | None] = None - db_vendor: Optional[str] = attr.field(default=None, init=False) - db_specific_attributes: Optional[DatabaseAttributes] = attr.field(default=None, validator=db_attrs_with_template) - url_params: Optional[list[tuple[str, str]]] = None + db_vendor: str | None = attr.field(default=None, init=False) + db_specific_attributes: DatabaseAttributes | None = attr.field(default=None, validator=db_attrs_with_template) + url_params: list[tuple[str, str]] | None = None def __attrs_post_init__(self) -> None: self.db_vendor = self.db_vendor or self.type.lower() self.url = self._make_url() - def _make_url(self) -> Optional[str]: + def _make_url(self) -> str | None: parameters = self._join_params() if self.url: return f"{self.url}?{parameters}" if parameters else self.url @@ -132,13 +132,13 @@ def _make_url(self) -> Optional[str]: else: return None - def _join_params(self) -> Optional[str]: + def _join_params(self) -> str | None: if self.url_params: return self._DELIMITER.join([f"{p[0]}={p[1]}" for p in self.url_params]) return None @property - def url_template(self) -> Optional[str]: + def url_template(self) -> str | None: return self._URL_TMPL diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/service.py index e3e0b88fb..9be59722e 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/service.py @@ -3,7 +3,7 @@ import functools from pathlib import Path -from typing import Any, Optional, Union +from typing import Any, Union from gooddata_api_client.exceptions import NotFoundException @@ -153,8 +153,8 @@ def get_declarative_data_sources(self) -> CatalogDeclarativeDataSources: def put_declarative_data_sources( self, declarative_data_sources: CatalogDeclarativeDataSources, - credentials_path: Optional[Path] = None, - config_file: Optional[Union[str, Path]] = None, + credentials_path: Path | None = None, + config_file: Union[str, Path] | None = None, test_data_sources: bool = False, ) -> None: """Set all data sources, including their related physical data model. @@ -221,8 +221,8 @@ def load_declarative_data_sources(self, layout_root_path: Path = Path.cwd()) -> def load_and_put_declarative_data_sources( self, layout_root_path: Path = Path.cwd(), - credentials_path: Optional[Path] = None, - config_file: Optional[Union[str, Path]] = None, + credentials_path: Path | None = None, + config_file: Union[str, Path] | None = None, test_data_sources: bool = False, ) -> None: """Loads and sets layouts stored using `store_declarative_data_sources`. @@ -307,7 +307,7 @@ def generate_logical_model( def scan_pdm_and_generate_logical_model( self, data_source_id: str, - generate_ldm_request: Optional[CatalogGenerateLdmRequest] = None, + generate_ldm_request: CatalogGenerateLdmRequest | None = None, scan_request: CatalogScanModelRequest = CatalogScanModelRequest(), report_warnings: bool = False, ) -> tuple[CatalogDeclarativeModel, CatalogScanResultPdm]: @@ -432,8 +432,8 @@ def scan_sql(self, data_source_id: str, sql_request: ScanSqlRequest) -> ScanSqlR def test_data_sources_connection( self, declarative_data_sources: CatalogDeclarativeDataSources, - credentials_path: Optional[Path] = None, - config_file: Optional[Union[str, Path]] = None, + credentials_path: Path | None = None, + config_file: Union[str, Path] | None = None, ) -> None: """Tests connection to declarative data sources. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/entity.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/entity.py index e9067d51f..2562dad13 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/entity.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/entity.py @@ -5,7 +5,7 @@ import builtins import os from pathlib import Path -from typing import Any, ClassVar, Optional, TypeVar, Union +from typing import Any, ClassVar, TypeVar, Union import attr @@ -32,10 +32,10 @@ def _get_type(self) -> str: # Optional, because write use case - # we need to pass only ID and some properties in attributes when creating an instance of this class - json_api_entity: Optional[JsonApiEntityBase] = None - title: Optional[str] = None - description: Optional[str] = None - tags: Optional[list[str]] = None + json_api_entity: JsonApiEntityBase | None = None + title: str | None = None + description: str | None = None + tags: list[str] | None = None @property def json_api_attributes(self) -> dict[str, Any]: @@ -65,8 +65,8 @@ def obj_id(self) -> ObjId: def from_api( cls: builtins.type[T], entity: dict[str, Any], - side_loads: Optional[list[Any]] = None, - related_entities: Optional[AllPagedEntities] = None, + side_loads: list[Any] | None = None, + related_entities: AllPagedEntities | None = None, ) -> T: """ Creates GoodData object from AttrCatalogEntityJsonApi. @@ -104,12 +104,12 @@ def type(self) -> str: return self._entity["type"] @property - def title(self) -> Optional[str]: + def title(self) -> str | None: # Optional, not all metadata objects contain title return self._e.get("title") @property - def description(self) -> Optional[str]: + def description(self) -> str | None: # Optional, not all metadata objects contain description return self._e.get("description") @@ -270,7 +270,7 @@ def from_api(cls, attributes: dict[str, Any]) -> BasicCredentials: # type: igno class KeyPairCredentials(Credentials): username: str private_key: str = attr.field(repr=lambda value: "***") - private_key_passphrase: Optional[str] = attr.field(repr=lambda value: "***", default=None) + private_key_passphrase: str | None = attr.field(repr=lambda value: "***", default=None) @classmethod def is_part_of_api(cls, entity: dict[str, Any]) -> bool: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/request.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/request.py index d2a2a783f..2efddd6d6 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/request.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/request.py @@ -1,5 +1,5 @@ # (C) 2023 GoodData Corporation -from typing import Literal, Optional +from typing import Literal from attrs import define from gooddata_api_client.model.custom_label import CustomLabel as ApiCustomLabel @@ -34,8 +34,8 @@ def client_class() -> type[ApiCustomMetric]: @define(auto_attribs=True, kw_only=True) class ExportCustomOverride(Base): - labels: Optional[dict[str, ExportCustomLabel]] = None - metrics: Optional[dict[str, ExportCustomMetric]] = None + labels: dict[str, ExportCustomLabel] | None = None + metrics: dict[str, ExportCustomMetric] | None = None @staticmethod def client_class() -> type[ApiCustomOverride]: @@ -66,10 +66,10 @@ class ExportRequest(Base): format: str file_name: str - execution_result: Optional[str] = None - visualization_object: Optional[str] = None - settings: Optional[ExportSettings] = None - custom_override: Optional[ExportCustomOverride] = None + execution_result: str | None = None + visualization_object: str | None = None + settings: ExportSettings | None = None + custom_override: ExportCustomOverride | None = None def __attrs_post_init__(self) -> None: """ @@ -112,7 +112,7 @@ class VisualExportRequest(Base): dashboard_id: str file_name: str - metadata: Optional[dict] = None + metadata: dict | None = None @staticmethod def client_class() -> type[VisualExportRequestApi]: @@ -136,11 +136,11 @@ class SlidesExportRequest(Base): file_name: str format: Literal["PDF", "PPTX"] - dashboard_id: Optional[str] = None - widget_ids: Optional[list[str]] = None - visualization_ids: Optional[list[str]] = None - metadata: Optional[dict] = None - templateId: Optional[str] = None + dashboard_id: str | None = None + widget_ids: list[str] | None = None + visualization_ids: list[str] | None = None + metadata: dict | None = None + templateId: str | None = None @staticmethod def client_class() -> type[SlidesExportRequestApi]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/service.py index 8774b3c98..0207fc1a7 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/export/service.py @@ -1,7 +1,7 @@ # (C) 2023 GoodData Corporation import time from pathlib import Path -from typing import Any, Callable, Optional, Union +from typing import Any, Callable, Union from gooddata_api_client.exceptions import NotFoundException from gooddata_api_client.model.slides_export_request import SlidesExportRequest as SlidesExportRequestApi @@ -186,7 +186,7 @@ def export_pdf( timeout: float = 60.0, retry: float = 0.2, max_retry: float = 5.0, - metadata: Optional[dict[str, Any]] = None, + metadata: dict[str, Any] | None = None, ) -> None: """ Export a PDF of the specified GoodData Dashboard and save it to the specified file path. @@ -275,8 +275,8 @@ def export_tabular_by_visualization_id( workspace_id: str, visualization_id: str, file_format: str, - file_name: Optional[str] = None, - settings: Optional[ExportSettings] = None, + file_name: str | None = None, + settings: ExportSettings | None = None, store_path: Union[str, Path] = Path.cwd(), timeout: float = 60.0, retry: float = 0.2, diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/filter_by.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/filter_by.py index c6961c7c6..3da33a93a 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/filter_by.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/filter_by.py @@ -1,8 +1,6 @@ # (C) 2024 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.filter_by import FilterBy @@ -11,7 +9,7 @@ @attr.s(auto_attribs=True, kw_only=True) class CatalogFilterBy(Base): - label_type: Optional[str] + label_type: str | None @staticmethod def client_class() -> type[FilterBy]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/dashboard_slides_template.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/dashboard_slides_template.py index 726aca216..2a4fc7503 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/dashboard_slides_template.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/dashboard_slides_template.py @@ -1,5 +1,5 @@ # (C) 2025 GoodData Corporation -from typing import Literal, Optional +from typing import Literal from attrs import define @@ -14,7 +14,7 @@ @define class CatalogDashboardSlidesTemplate: applied_on: list[Literal["PDF", "PPTX"]] - cover_slide: Optional[CatalogCoverSlideTemplate] = None - intro_slide: Optional[CatalogIntroSlideTemplate] = None - section_slide: Optional[CatalogSectionSlideTemplate] = None - content_slide: Optional[CatalogContentSlideTemplate] = None + cover_slide: CatalogCoverSlideTemplate | None = None + intro_slide: CatalogIntroSlideTemplate | None = None + section_slide: CatalogSectionSlideTemplate | None = None + content_slide: CatalogContentSlideTemplate | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/running_section.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/running_section.py index 1fdfd65e7..d00b54b6a 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/running_section.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/running_section.py @@ -1,10 +1,9 @@ # (C) 2025 GoodData Corporation -from typing import Optional from attrs import define @define class CatalogRunningSection: - left: Optional[str] = None - right: Optional[str] = None + left: str | None = None + right: str | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/slide_template.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/slide_template.py index 42af27bfa..6df7545e5 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/slide_template.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/slide_template.py @@ -1,5 +1,4 @@ # (C) 2025 GoodData Corporation -from typing import Optional from attrs import define @@ -10,29 +9,29 @@ @define class CatalogCoverSlideTemplate(Base): background_image: bool - description_field: Optional[str] = None - header: Optional[CatalogRunningSection] = None - footer: Optional[CatalogRunningSection] = None + description_field: str | None = None + header: CatalogRunningSection | None = None + footer: CatalogRunningSection | None = None @define class CatalogIntroSlideTemplate(Base): background_image: bool - title_field: Optional[str] = None - description_field: Optional[str] = None - header: Optional[CatalogRunningSection] = None - footer: Optional[CatalogRunningSection] = None + title_field: str | None = None + description_field: str | None = None + header: CatalogRunningSection | None = None + footer: CatalogRunningSection | None = None @define class CatalogSectionSlideTemplate(Base): background_image: bool - header: Optional[CatalogRunningSection] = None - footer: Optional[CatalogRunningSection] = None + header: CatalogRunningSection | None = None + footer: CatalogRunningSection | None = None @define class CatalogContentSlideTemplate(Base): - description_field: Optional[str] = None - header: Optional[CatalogRunningSection] = None - footer: Optional[CatalogRunningSection] = None + description_field: str | None = None + header: CatalogRunningSection | None = None + footer: CatalogRunningSection | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/widget_slides_template.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/widget_slides_template.py index 0db000922..14a073fc6 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/widget_slides_template.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/common/widget_slides_template.py @@ -1,5 +1,5 @@ # (C) 2025 GoodData Corporation -from typing import Literal, Optional +from typing import Literal from attrs import define @@ -9,4 +9,4 @@ @define class CatalogWidgetSlidesTemplate: applied_on: list[Literal["PDF", "PPTX"]] - content_slide: Optional[CatalogContentSlideTemplate] = None + content_slide: CatalogContentSlideTemplate | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/export_template.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/export_template.py index f66734682..3bd3d3e01 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/export_template.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/export_template.py @@ -2,7 +2,6 @@ from __future__ import annotations import builtins -from typing import Optional from attrs import define from gooddata_api_client.model.json_api_export_template_in_attributes import JsonApiExportTemplateInAttributes @@ -16,7 +15,7 @@ @define(auto_attribs=True, kw_only=True) class CatalogExportTemplate(Base): id: str - attributes: Optional[CatalogExportTemplateAttributes] = None + attributes: CatalogExportTemplateAttributes | None = None @staticmethod def client_class() -> builtins.type[JsonApiExportTemplatePostOptionalId]: @@ -26,8 +25,8 @@ def client_class() -> builtins.type[JsonApiExportTemplatePostOptionalId]: @define(auto_attribs=True, kw_only=True) class CatalogExportTemplateAttributes(Base): name: str - dashboard_slides_template: Optional[CatalogDashboardSlidesTemplate] = None - widget_slides_template: Optional[CatalogWidgetSlidesTemplate] = None + dashboard_slides_template: CatalogDashboardSlidesTemplate | None = None + widget_slides_template: CatalogWidgetSlidesTemplate | None = None @staticmethod def client_class() -> builtins.type[JsonApiExportTemplateInAttributes]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/identity_provider.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/identity_provider.py index 0e850ff3e..c59de601d 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/identity_provider.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/identity_provider.py @@ -1,7 +1,7 @@ # (C) 2024 GoodData Corporation from __future__ import annotations -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.json_api_identity_provider_in import JsonApiIdentityProviderIn @@ -26,7 +26,7 @@ def client_class() -> type[JsonApiIdentityProviderInDocument]: @attr.s(auto_attribs=True, kw_only=True) class CatalogIdentityProvider(Base): id: str - attributes: Optional[CatalogIdentityProviderAttributes] = None + attributes: CatalogIdentityProviderAttributes | None = None @staticmethod def client_class() -> type[JsonApiIdentityProviderIn]: @@ -36,17 +36,17 @@ def client_class() -> type[JsonApiIdentityProviderIn]: def init( cls, identity_provider_id: str, - custom_claim_mapping: Optional[dict[str, str]] = None, - identifiers: Optional[list[str]] = None, - oauth_client_id: Optional[str] = None, - oauth_client_secret: Optional[str] = None, - oauth_issuer_location: Optional[str] = None, - saml_metadata: Optional[str] = None, - idp_type: Optional[str] = None, - oauth_issuer_id: Optional[str] = None, - oauth_subject_id_claim: Optional[str] = None, - oauth_custom_auth_attributes: Optional[dict[str, str]] = None, - oauth_custom_scopes: Optional[list[str]] = None, + custom_claim_mapping: dict[str, str] | None = None, + identifiers: list[str] | None = None, + oauth_client_id: str | None = None, + oauth_client_secret: str | None = None, + oauth_issuer_location: str | None = None, + saml_metadata: str | None = None, + idp_type: str | None = None, + oauth_issuer_id: str | None = None, + oauth_subject_id_claim: str | None = None, + oauth_custom_auth_attributes: dict[str, str] | None = None, + oauth_custom_scopes: list[str] | None = None, ) -> CatalogIdentityProvider: return cls( id=identity_provider_id, @@ -97,17 +97,17 @@ def to_api_patch(cls, identity_provider_id: str, attributes: dict) -> JsonApiIde @attr.s(auto_attribs=True, kw_only=True) class CatalogIdentityProviderAttributes(Base): - custom_claim_mapping: Optional[dict[str, str]] = None - identifiers: Optional[list[str]] = None - oauth_client_id: Optional[str] = None - oauth_client_secret: Optional[str] = None - oauth_issuer_location: Optional[str] = None - saml_metadata: Optional[str] = None - idp_type: Optional[str] = None - oauth_issuer_id: Optional[str] = None - oauth_subject_id_claim: Optional[str] = None - oauth_custom_auth_attributes: Optional[dict[str, str]] = None - oauth_custom_scopes: Optional[list[str]] = None + custom_claim_mapping: dict[str, str] | None = None + identifiers: list[str] | None = None + oauth_client_id: str | None = None + oauth_client_secret: str | None = None + oauth_issuer_location: str | None = None + saml_metadata: str | None = None + idp_type: str | None = None + oauth_issuer_id: str | None = None + oauth_subject_id_claim: str | None = None + oauth_custom_auth_attributes: dict[str, str] | None = None + oauth_custom_scopes: list[str] | None = None @staticmethod def client_class() -> type[JsonApiIdentityProviderInAttributes]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/jwk.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/jwk.py index bf93c4b71..2fe9bbe11 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/jwk.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/jwk.py @@ -1,8 +1,6 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.json_api_jwk_in import JsonApiJwkIn from gooddata_api_client.model.json_api_jwk_in_attributes import JsonApiJwkInAttributes @@ -24,7 +22,7 @@ def client_class() -> type[JsonApiJwkInDocument]: @attr.s(auto_attribs=True, kw_only=True) class CatalogJwk(Base): id: str - attributes: Optional[CatalogJwkAttributes] = None + attributes: CatalogJwkAttributes | None = None @staticmethod def client_class() -> type[JsonApiJwkIn]: @@ -34,14 +32,14 @@ def client_class() -> type[JsonApiJwkIn]: def init( cls, jwk_id: str, - rsa_spec: Optional[CatalogRsaSpecification] = None, + rsa_spec: CatalogRsaSpecification | None = None, ) -> CatalogJwk: return cls(id=jwk_id, attributes=CatalogJwkAttributes(content=rsa_spec)) @attr.s(auto_attribs=True, kw_only=True) class CatalogJwkAttributes(Base): - content: Optional[CatalogRsaSpecification] = None + content: CatalogRsaSpecification | None = None @staticmethod def client_class() -> type[JsonApiJwkInAttributes]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_endpoint.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_endpoint.py index 24dbd9295..2d4297a21 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_endpoint.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_endpoint.py @@ -1,7 +1,7 @@ # (C) 2024 GoodData Corporation from __future__ import annotations -from typing import Any, Optional +from typing import Any from attr import define from gooddata_api_client.model.json_api_llm_endpoint_in import JsonApiLlmEndpointIn @@ -36,7 +36,7 @@ def client_class() -> type[JsonApiLlmEndpointPatchDocument]: @define(kw_only=True) class CatalogLlmEndpoint(Base): id: str - attributes: Optional[CatalogLlmEndpointAttributes] = None + attributes: CatalogLlmEndpointAttributes | None = None @staticmethod def client_class() -> type[JsonApiLlmEndpointIn]: @@ -48,10 +48,10 @@ def init( id: str, title: str, token: str, - provider: Optional[str] = None, - base_url: Optional[str] = None, - llm_organization: Optional[str] = None, - llm_model: Optional[str] = None, + provider: str | None = None, + base_url: str | None = None, + llm_organization: str | None = None, + llm_model: str | None = None, ) -> CatalogLlmEndpoint: return cls( id=id, @@ -85,7 +85,7 @@ def from_api(cls, entity: dict[str, Any]) -> CatalogLlmEndpoint: @define(kw_only=True) class CatalogLlmEndpointPatch(Base): id: str - attributes: Optional[CatalogLlmEndpointPatchAttributes] = None + attributes: CatalogLlmEndpointPatchAttributes | None = None @staticmethod def client_class() -> type[JsonApiLlmEndpointPatch]: @@ -95,12 +95,12 @@ def client_class() -> type[JsonApiLlmEndpointPatch]: def init( cls, id: str, - title: Optional[str] = None, - token: Optional[str] = None, - provider: Optional[str] = None, - base_url: Optional[str] = None, - llm_organization: Optional[str] = None, - llm_model: Optional[str] = None, + title: str | None = None, + token: str | None = None, + provider: str | None = None, + base_url: str | None = None, + llm_organization: str | None = None, + llm_model: str | None = None, ) -> CatalogLlmEndpointPatch: return cls( id=id, @@ -119,10 +119,10 @@ def init( class CatalogLlmEndpointAttributes(Base): title: str token: str - provider: Optional[str] = None - base_url: Optional[str] = None - llm_organization: Optional[str] = None - llm_model: Optional[str] = None + provider: str | None = None + base_url: str | None = None + llm_organization: str | None = None + llm_model: str | None = None @staticmethod def client_class() -> type[JsonApiLlmEndpointInAttributes]: @@ -131,12 +131,12 @@ def client_class() -> type[JsonApiLlmEndpointInAttributes]: @define(kw_only=True) class CatalogLlmEndpointPatchAttributes(Base): - title: Optional[str] = None - token: Optional[str] = None - provider: Optional[str] = None - base_url: Optional[str] = None - llm_organization: Optional[str] = None - llm_model: Optional[str] = None + title: str | None = None + token: str | None = None + provider: str | None = None + base_url: str | None = None + llm_organization: str | None = None + llm_model: str | None = None @staticmethod def client_class() -> type[JsonApiLlmEndpointPatchAttributes]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/organization.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/organization.py index 765afc3fc..2142005e0 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/organization.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/organization.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.json_api_identity_provider_to_one_linkage import JsonApiIdentityProviderToOneLinkage @@ -25,7 +25,7 @@ class CatalogOrganizationDocument(Base): def client_class() -> type[JsonApiOrganizationInDocument]: return JsonApiOrganizationInDocument - def to_api(self, oauth_client_secret: Optional[str] = None) -> JsonApiOrganizationInDocument: + def to_api(self, oauth_client_secret: str | None = None) -> JsonApiOrganizationInDocument: dictionary = self._get_snake_dict() if oauth_client_secret is not None: dictionary["data"]["attributes"]["oauth_client_secret"] = oauth_client_secret @@ -36,7 +36,7 @@ def to_api(self, oauth_client_secret: Optional[str] = None) -> JsonApiOrganizati class CatalogOrganization(Base): id: str attributes: CatalogOrganizationAttributes - identity_provider_id: Optional[str] = None + identity_provider_id: str | None = None @staticmethod def client_class() -> type[JsonApiOrganizationIn]: @@ -82,11 +82,11 @@ def to_api(self) -> JsonApiOrganizationIn: @attr.s(auto_attribs=True, kw_only=True) class CatalogOrganizationAttributes(Base): - name: Optional[str] = None - hostname: Optional[str] = None - allowed_origins: Optional[list[str]] = None - oauth_issuer_location: Optional[str] = None - oauth_client_id: Optional[str] = None + name: str | None = None + hostname: str | None = None + allowed_origins: list[str] | None = None + oauth_issuer_location: str | None = None + oauth_client_id: str | None = None @staticmethod def client_class() -> type[JsonApiOrganizationInAttributes]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/setting.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/setting.py index fa4fc8f23..763bac01d 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/setting.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/setting.py @@ -2,7 +2,7 @@ from __future__ import annotations import builtins -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.json_api_organization_setting_in import JsonApiOrganizationSettingIn @@ -27,7 +27,7 @@ def client_class() -> type[JsonApiOrganizationSettingIn]: @attr.s(auto_attribs=True, kw_only=True) class CatalogOrganizationSettingAttributes(Base): - type: Optional[str] + type: str | None content: dict[str, Any] @staticmethod diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/export_template.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/export_template.py index ae1fb57dd..8a9ac3217 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/export_template.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/export_template.py @@ -1,6 +1,5 @@ # (C) 2025 GoodData Corporation import builtins -from typing import Optional from attrs import define from gooddata_api_client.model.declarative_export_template import DeclarativeExportTemplate @@ -14,8 +13,8 @@ class CatalogDeclarativeExportTemplate(Base): id: str name: str - dashboard_slides_template: Optional[CatalogDashboardSlidesTemplate] = None - widget_slides_template: Optional[CatalogWidgetSlidesTemplate] = None + dashboard_slides_template: CatalogDashboardSlidesTemplate | None = None + widget_slides_template: CatalogWidgetSlidesTemplate | None = None @staticmethod def client_class() -> builtins.type[DeclarativeExportTemplate]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/identity_provider.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/identity_provider.py index 1a403e7e5..1459db73f 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/identity_provider.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/identity_provider.py @@ -1,6 +1,5 @@ # (C) 2024 GoodData Corporation import builtins -from typing import Optional import attr from gooddata_api_client.model.declarative_identity_provider import DeclarativeIdentityProvider @@ -11,17 +10,17 @@ @attr.s(auto_attribs=True, kw_only=True) class CatalogDeclarativeIdentityProvider(Base): id: str - custom_claim_mapping: Optional[dict[str, str]] = None - identifiers: Optional[list[str]] = None - oauth_client_id: Optional[str] = None - oauth_client_secret: Optional[str] = None - oauth_issuer_location: Optional[str] = None - saml_metadata: Optional[str] = None - idp_type: Optional[str] = None - oauth_issuer_id: Optional[str] = None - oauth_subject_id_claim: Optional[str] = None - oauth_custom_auth_attributes: Optional[dict[str, str]] = None - oauth_custom_scopes: Optional[list[str]] = None + custom_claim_mapping: dict[str, str] | None = None + identifiers: list[str] | None = None + oauth_client_id: str | None = None + oauth_client_secret: str | None = None + oauth_issuer_location: str | None = None + saml_metadata: str | None = None + idp_type: str | None = None + oauth_issuer_id: str | None = None + oauth_subject_id_claim: str | None = None + oauth_custom_auth_attributes: dict[str, str] | None = None + oauth_custom_scopes: list[str] | None = None @staticmethod def client_class() -> builtins.type[DeclarativeIdentityProvider]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/notification_channel.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/notification_channel.py index a74e8d0b1..c133e3d67 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/notification_channel.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/layout/notification_channel.py @@ -1,6 +1,5 @@ # (C) 2024 GoodData Corporation import builtins -from typing import Optional from attrs import define, field from gooddata_api_client.model.declarative_notification_channel import DeclarativeNotificationChannel @@ -38,8 +37,8 @@ class CatalogWebhook(Base): type: str = field(default="WEBHOOK", init=False) url: str - token: Optional[str] = field(default=None, eq=False) - has_token: Optional[bool] = field(default=None, eq=False) + token: str | None = field(default=None, eq=False) + has_token: bool | None = field(default=None, eq=False) @staticmethod def client_class() -> builtins.type[Webhook]: @@ -49,13 +48,13 @@ def client_class() -> builtins.type[Webhook]: @define(auto_attribs=True, kw_only=True) class CatalogDeclarativeNotificationChannel(Base): id: str - name: Optional[str] = None - description: Optional[str] = None - destination_type: Optional[str] = None - custom_dashboard_url: Optional[str] = None - allowed_recipients: Optional[str] = None + name: str | None = None + description: str | None = None + destination_type: str | None = None + custom_dashboard_url: str | None = None + allowed_recipients: str | None = None # destination: Optional[Union[CatalogDefaultSmtp, CatalogSmtp, CatalogWebhook]] = None - destination: Optional[CatalogWebhook] = None + destination: CatalogWebhook | None = None @staticmethod def client_class() -> builtins.type[DeclarativeNotificationChannel]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py index eedc3dc92..615ef4529 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py @@ -2,7 +2,7 @@ from __future__ import annotations import functools -from typing import Any, Optional +from typing import Any from gooddata_api_client.exceptions import NotFoundException from gooddata_api_client.model.declarative_export_templates import DeclarativeExportTemplates @@ -513,11 +513,11 @@ def get_llm_endpoint(self, id: str) -> CatalogLlmEndpoint: def list_llm_endpoints( self, - filter: Optional[str] = None, - page: Optional[int] = None, - size: Optional[int] = None, - sort: Optional[list[str]] = None, - meta_include: Optional[list[str]] = None, + filter: str | None = None, + page: int | None = None, + size: int | None = None, + sort: list[str] | None = None, + meta_include: list[str] | None = None, ) -> list[CatalogLlmEndpoint]: """ List all LLM endpoints. @@ -556,10 +556,10 @@ def create_llm_endpoint( id: str, title: str, token: str, - provider: Optional[str] = None, - base_url: Optional[str] = None, - llm_organization: Optional[str] = None, - llm_model: Optional[str] = None, + provider: str | None = None, + base_url: str | None = None, + llm_organization: str | None = None, + llm_model: str | None = None, ) -> CatalogLlmEndpoint: """ Create a new LLM endpoint. @@ -594,12 +594,12 @@ def create_llm_endpoint( def update_llm_endpoint( self, id: str, - title: Optional[str] = None, - token: Optional[str] = None, - provider: Optional[str] = None, - base_url: Optional[str] = None, - llm_organization: Optional[str] = None, - llm_model: Optional[str] = None, + title: str | None = None, + token: str | None = None, + provider: str | None = None, + base_url: str | None = None, + llm_organization: str | None = None, + llm_model: str | None = None, ) -> CatalogLlmEndpoint: """ Update an existing LLM endpoint. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_assignees.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_assignees.py index d3cd217d6..cf9fc2da5 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_assignees.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_assignees.py @@ -1,5 +1,4 @@ # (C) 2023 GoodData Corporation -from typing import Optional import attr from gooddata_api_client.model.available_assignees import AvailableAssignees @@ -12,8 +11,8 @@ @attr.s(auto_attribs=True, kw_only=True) class CatalogUserAssignee(Base): id: str - name: Optional[str] = None - email: Optional[str] = None + name: str | None = None + email: str | None = None @staticmethod def client_class() -> type[UserAssignee]: @@ -23,7 +22,7 @@ def client_class() -> type[UserAssignee]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserGroupAssignee(Base): id: str - name: Optional[str] = None + name: str | None = None @staticmethod def client_class() -> type[UserGroupAssignee]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_permissions.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_permissions.py index 1dac059bc..85001c505 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_permissions.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/permission/declarative_model/dashboard_permissions.py @@ -1,6 +1,5 @@ # (C) 2023 GoodData Corporation import builtins -from typing import Optional import attr from gooddata_api_client.model.dashboard_permissions import DashboardPermissions @@ -25,9 +24,9 @@ def client_class() -> type[GrantedPermission]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserPermission(Base): id: str - name: Optional[str] = None - email: Optional[str] = None - permissions: Optional[list[CatalogGrantedPermission]] = None + name: str | None = None + email: str | None = None + permissions: list[CatalogGrantedPermission] | None = None @staticmethod def client_class() -> type[UserPermission]: @@ -37,8 +36,8 @@ def client_class() -> type[UserPermission]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserGroupPermission(Base): id: str - name: Optional[str] = None - permissions: Optional[list[CatalogGrantedPermission]] = None + name: str | None = None + permissions: list[CatalogGrantedPermission] | None = None @staticmethod def client_class() -> type[UserGroupPermission]: @@ -48,7 +47,7 @@ def client_class() -> type[UserGroupPermission]: @attr.s(auto_attribs=True, kw_only=True) class CatalogRulePermission(Base): type: str - permissions: Optional[list[str]] = None + permissions: list[str] | None = None @staticmethod def client_class() -> builtins.type[RulePermission]: # noqa: UP006 diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/setting.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/setting.py index eda818e14..500480784 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/setting.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/setting.py @@ -2,7 +2,7 @@ from __future__ import annotations import builtins -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.declarative_custom_application_setting import DeclarativeCustomApplicationSetting @@ -15,7 +15,7 @@ class CatalogDeclarativeSetting(Base): id: str type: str = attr.field(validator=value_in_allowed) - content: Optional[dict[str, Any]] = None + content: dict[str, Any] | None = None @staticmethod def client_class() -> builtins.type[DeclarativeSetting]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user.py index ebabafd0b..e9702e2b5 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional import attr from gooddata_api_client.model.declarative_user import DeclarativeUser @@ -45,10 +44,10 @@ def store_to_disk(self, layout_organization_folder: Path, sort: bool = False) -> @attr.s(auto_attribs=True, kw_only=True) class CatalogDeclarativeUser(Base): id: str - email: Optional[str] = None - firstname: Optional[str] = None - lastname: Optional[str] = None - auth_id: Optional[str] = None + email: str | None = None + firstname: str | None = None + lastname: str | None = None + auth_id: str | None = None user_groups: list[CatalogDeclarativeUserGroupIdentifier] = attr.field(factory=list) settings: list[CatalogDeclarativeSetting] = attr.field(factory=list) permissions: list[CatalogDeclarativeUserPermission] = attr.field(factory=list) diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user_group.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user_group.py index da514ca8d..0d4c34f5c 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user_group.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/declarative_model/user_group.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional import attr from gooddata_api_client.model.declarative_user_group import DeclarativeUserGroup @@ -44,8 +43,8 @@ def store_to_disk(self, layout_organization_folder: Path, sort: bool = False) -> @attr.s(auto_attribs=True, kw_only=True) class CatalogDeclarativeUserGroup(Base): id: str - name: Optional[str] = None - parents: Optional[list[CatalogDeclarativeUserGroupIdentifier]] = None + name: str | None = None + parents: list[CatalogDeclarativeUserGroupIdentifier] | None = None permissions: list[CatalogDeclarativeUserGroupPermission] = attr.field(factory=list) @staticmethod diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/api_token.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/api_token.py index 9fcac8f5f..e1d32beb1 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/api_token.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/api_token.py @@ -1,5 +1,4 @@ # (C) 2024 GoodData Corporation -from typing import Optional from attrs import define @@ -9,4 +8,4 @@ @define(auto_attribs=True, kw_only=True) class CatalogApiToken(Base): id: str - bearer_token: Optional[str] = None + bearer_token: str | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user.py index cd35fa770..b7998dba9 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user.py @@ -1,8 +1,6 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.json_api_user_in import JsonApiUserIn from gooddata_api_client.model.json_api_user_in_document import JsonApiUserInDocument @@ -23,11 +21,11 @@ def client_class() -> type[JsonApiUserInDocument]: def init( cls, user_id: str, - firstname: Optional[str] = None, - lastname: Optional[str] = None, - email: Optional[str] = None, - authentication_id: Optional[str] = None, - user_group_ids: Optional[list[str]] = None, + firstname: str | None = None, + lastname: str | None = None, + email: str | None = None, + authentication_id: str | None = None, + user_group_ids: list[str] | None = None, ) -> CatalogUserDocument: user = CatalogUser.init( user_id=user_id, @@ -42,11 +40,11 @@ def init( def update_user( self, - firstname: Optional[str] = None, - lastname: Optional[str] = None, - email: Optional[str] = None, - authentication_id: Optional[str] = None, - user_group_ids: Optional[list[str]] = None, + firstname: str | None = None, + lastname: str | None = None, + email: str | None = None, + authentication_id: str | None = None, + user_group_ids: list[str] | None = None, ) -> None: attributes = CatalogUserAttributes( firstname=firstname, lastname=lastname, email=email, authentication_id=authentication_id @@ -59,8 +57,8 @@ def update_user( @attr.s(auto_attribs=True, kw_only=True) class CatalogUser(Base): id: str - attributes: Optional[CatalogUserAttributes] = None - relationships: Optional[CatalogUserRelationships] = None + attributes: CatalogUserAttributes | None = None + relationships: CatalogUserRelationships | None = None @staticmethod def client_class() -> type[JsonApiUserIn]: @@ -70,11 +68,11 @@ def client_class() -> type[JsonApiUserIn]: def init( cls, user_id: str, - firstname: Optional[str] = None, - lastname: Optional[str] = None, - email: Optional[str] = None, - authentication_id: Optional[str] = None, - user_group_ids: Optional[list[str]] = None, + firstname: str | None = None, + lastname: str | None = None, + email: str | None = None, + authentication_id: str | None = None, + user_group_ids: list[str] | None = None, ) -> CatalogUser: attributes = CatalogUserAttributes( firstname=firstname, lastname=lastname, email=email, authentication_id=authentication_id @@ -148,15 +146,15 @@ def replace_user_groups(self, user_groups: list[CatalogUserGroup]) -> None: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserAttributes(Base): - firstname: Optional[str] = None - lastname: Optional[str] = None - email: Optional[str] = None - authentication_id: Optional[str] = None + firstname: str | None = None + lastname: str | None = None + email: str | None = None + authentication_id: str | None = None @attr.s(auto_attribs=True, kw_only=True) class CatalogUserRelationships(Base): - user_groups: Optional[CatalogUserGroupsData] = None + user_groups: CatalogUserGroupsData | None = None def add_user_groups(self, user_groups: list[CatalogUserGroup]) -> None: """Appends the User Groups to the existing list. @@ -187,7 +185,7 @@ def replace_user_groups(self, user_groups: list[CatalogUserGroup]) -> None: self.user_groups.data = user_groups @classmethod - def create_user_relationships(cls, user_group_ids: Optional[list[str]]) -> CatalogUserRelationships: + def create_user_relationships(cls, user_group_ids: list[str] | None) -> CatalogUserRelationships: user_groups = None if user_group_ids is not None: user_groups = CatalogUserGroupsData( diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user_group.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user_group.py index 03dd40e03..1287bd5be 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user_group.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/entity_model/user_group.py @@ -1,8 +1,6 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional - import attr from gooddata_api_client.model.json_api_user_group_in import JsonApiUserGroupIn from gooddata_api_client.model.json_api_user_group_in_document import JsonApiUserGroupInDocument @@ -19,10 +17,10 @@ def client_class() -> type[JsonApiUserGroupInDocument]: return JsonApiUserGroupInDocument @classmethod - def init(cls, user_group_id: str, user_group_parent_ids: Optional[list[str]] = None) -> CatalogUserGroupDocument: + def init(cls, user_group_id: str, user_group_parent_ids: list[str] | None = None) -> CatalogUserGroupDocument: return cls(data=CatalogUserGroup.init(user_group_id=user_group_id, user_group_parent_ids=user_group_parent_ids)) - def update_user_group(self, user_group_parents_id: Optional[list[str]] = None) -> None: + def update_user_group(self, user_group_parents_id: list[str] | None = None) -> None: relationships = CatalogUserGroupRelationships.create_user_group_relationships(user_group_parents_id) self.data.relationships = relationships @@ -30,8 +28,8 @@ def update_user_group(self, user_group_parents_id: Optional[list[str]] = None) - @attr.s(auto_attribs=True, kw_only=True) class CatalogUserGroup(Base): id: str - attributes: Optional[CatalogUserGroupAttributes] = None - relationships: Optional[CatalogUserGroupRelationships] = None + attributes: CatalogUserGroupAttributes | None = None + relationships: CatalogUserGroupRelationships | None = None @staticmethod def client_class() -> type[JsonApiUserGroupIn]: @@ -41,8 +39,8 @@ def client_class() -> type[JsonApiUserGroupIn]: def init( cls, user_group_id: str, - user_group_name: Optional[str] = None, - user_group_parent_ids: Optional[list[str]] = None, + user_group_name: str | None = None, + user_group_parent_ids: list[str] | None = None, ) -> CatalogUserGroup: attributes = CatalogUserGroupAttributes(name=user_group_name) relationships = CatalogUserGroupRelationships.create_user_group_relationships(user_group_parent_ids) @@ -53,7 +51,7 @@ def get_parents(self) -> list[str]: return self.relationships.get_parents if self.relationships is not None else [] @property - def name(self) -> Optional[str]: + def name(self) -> str | None: if self.attributes is not None: return self.attributes.name return None @@ -61,11 +59,11 @@ def name(self) -> Optional[str]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserGroupRelationships(Base): - parents: Optional[CatalogUserGroupParents] = None + parents: CatalogUserGroupParents | None = None @classmethod def create_user_group_relationships( - cls, user_group_parent_ids: Optional[list[str]] + cls, user_group_parent_ids: list[str] | None ) -> CatalogUserGroupRelationships: parents = None if user_group_parent_ids is not None: @@ -81,12 +79,12 @@ def get_parents(self) -> list[str]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserGroupAttributes(Base): - name: Optional[str] = None + name: str | None = None @attr.s(auto_attribs=True, kw_only=True) class CatalogUserGroupParents(Base): - data: Optional[list[CatalogUserGroup]] = None + data: list[CatalogUserGroup] | None = None @property def get_parents(self) -> list[str]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/management_model/management.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/management_model/management.py index 24ff3f6b1..231a90984 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/management_model/management.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/user/management_model/management.py @@ -1,6 +1,5 @@ # (C) 2024 GoodData Corporation -from typing import Optional import attrs from gooddata_api_client.model.permissions_assignment import PermissionsAssignment @@ -20,7 +19,7 @@ class CatalogDataSourcePermissionAssignment(Base): id: str permissions: list[str] = attrs.field(factory=list) - name: Optional[str] = None + name: str | None = None @staticmethod def client_class() -> type[UserManagementDataSourcePermissionAssignment]: @@ -32,7 +31,7 @@ class CatalogWorkspacePermissionAssignment(Base): id: str permissions: list[str] = attrs.field(factory=list) hierarchy_permissions: list[str] = attrs.field(factory=list) - name: Optional[str] = None + name: str | None = None @staticmethod def client_class() -> type[UserManagementWorkspacePermissionAssignment]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py index 3ef308bfe..7be97bee2 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py @@ -4,7 +4,7 @@ import copy import functools from pathlib import Path -from typing import Literal, Optional, Union, cast +from typing import Literal, Union, cast import gooddata_api_client.models as afm_models from gooddata_api_client.model.elements_request import ElementsRequest @@ -105,7 +105,7 @@ def get_full_catalog(self, workspace_id: str, inject_valid_objects_func: bool = return CatalogWorkspaceContent.create_workspace_content_catalog(valid_obj_fun, datasets, attributes, metrics) def get_attributes_catalog( - self, workspace_id: str, include: Optional[list[str]] = None, rsql_filter: Optional[str] = None + self, workspace_id: str, include: list[str] | None = None, rsql_filter: str | None = None ) -> list[CatalogAttribute]: """Retrieve all attributes in a given workspace. @@ -270,7 +270,7 @@ def put_declarative_ldm( self, workspace_id: str, ldm: CatalogDeclarativeModel, - validator: Optional[DataSourceValidator] = None, + validator: DataSourceValidator | None = None, standalone_copy: bool = False, ) -> None: """Set declarative logical data model for a given workspace. @@ -334,7 +334,7 @@ def load_and_put_declarative_ldm( self, workspace_id: str, layout_root_path: Path = Path.cwd(), - validator: Optional[DataSourceValidator] = None, + validator: DataSourceValidator | None = None, standalone_copy: bool = False, ) -> None: """This method combines load_declarative_ldm and put_declarative_ldm @@ -393,7 +393,7 @@ def load_ldm_from_disk(path: Path = Path.cwd()) -> CatalogDeclarativeModel: # Declarative methods for analytics model def get_declarative_analytics_model( - self, workspace_id: str, exclude: Optional[list[str]] = None + self, workspace_id: str, exclude: list[str] | None = None ) -> CatalogDeclarativeAnalytics: """Retrieves declarative analytics model. The model is tied to the workspace and organization. @@ -481,7 +481,7 @@ def load_and_put_declarative_analytics_model(self, workspace_id: str, layout_roo self.put_declarative_analytics_model(workspace_id, declarative_analytics_model) def store_analytics_model_to_disk( - self, workspace_id: str, path: Path = Path.cwd(), exclude: Optional[list[str]] = None, sort: bool = False + self, workspace_id: str, path: Path = Path.cwd(), exclude: list[str] | None = None, sort: bool = False ) -> None: """Store analytics model for a given workspace in directory hierarchy.This method does not tie the declarative analytics model to the workspace and organization, thus it is recommended for migration between workspaces. @@ -600,15 +600,15 @@ def get_label_elements( self, workspace_id: str, label_id: LabelElementsInputType, - depends_on: Optional[list[DependsOnItem]] = None, - validate_by: Optional[list[CatalogValidateByItem]] = None, - exact_filter: Optional[list[str]] = None, - filter_by: Optional[CatalogFilterBy] = None, - pattern_filter: Optional[str] = None, - complement_filter: Optional[bool] = False, - sort_order: Optional[Literal["ASC", "DESC"]] = None, - offset: Optional[int] = None, - limit: Optional[int] = None, + depends_on: list[DependsOnItem] | None = None, + validate_by: list[CatalogValidateByItem] | None = None, + exact_filter: list[str] | None = None, + filter_by: CatalogFilterBy | None = None, + pattern_filter: str | None = None, + complement_filter: bool | None = False, + sort_order: Literal["ASC", "DESC"] | None = None, + offset: int | None = None, + limit: int | None = None, ) -> list[str]: """ Get existing values for a label. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py index 879f08a57..cec604d81 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from typing import Any, Optional, Union +from typing import Any, Union import attr from attrs import define @@ -55,7 +55,7 @@ @attr.s(auto_attribs=True, kw_only=True) class CatalogDeclarativeAnalytics(Base): - analytics: Optional[CatalogDeclarativeAnalyticsLayer] = None + analytics: CatalogDeclarativeAnalyticsLayer | None = None @staticmethod def client_class() -> type[DeclarativeAnalytics]: @@ -257,13 +257,7 @@ def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeAnalyticsLa @define(auto_attribs=True, kw_only=True) class CatalogDeclarativeAnalyticalDashboard(CatalogAnalyticsBase): - permissions: Optional[ - list[ - Union[ - CatalogDeclarativeDashboardPermissionsForAssignee, CatalogDeclarativeDashboardPermissionsForAssigneeRule - ] - ] - ] = None + permissions: list[Union[CatalogDeclarativeDashboardPermissionsForAssignee, CatalogDeclarativeDashboardPermissionsForAssigneeRule]] | None = None @staticmethod def client_class() -> type[DeclarativeAnalyticalDashboard]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/base.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/base.py index d5e9fd9f7..28f5e1ff9 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/base.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/base.py @@ -1,6 +1,6 @@ # (C) 2024 GoodData Corporation from pathlib import Path -from typing import Any, Optional, TypeVar +from typing import Any, TypeVar from attrs import define @@ -27,16 +27,16 @@ def load_from_disk(cls: type[T], analytics_file: Path) -> T: @define(auto_attribs=True, kw_only=True) class CatalogAnalyticsBaseMeta(CatalogAnalyticsObjectBase): - created_at: Optional[str] = None - created_by: Optional[CatalogUserIdentifier] = None - modified_at: Optional[str] = None - modified_by: Optional[CatalogUserIdentifier] = None + created_at: str | None = None + created_by: CatalogUserIdentifier | None = None + modified_at: str | None = None + modified_by: CatalogUserIdentifier | None = None @define(auto_attribs=True, kw_only=True) class CatalogAnalyticsBase(CatalogAnalyticsBaseMeta): title: str content: dict[str, Any] - description: Optional[str] = None - tags: Optional[list[str]] = None - is_hidden: Optional[bool] = None + description: str | None = None + tags: list[str] | None = None + is_hidden: bool | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/export_definition.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/export_definition.py index 2baf7862a..310ab9a43 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/export_definition.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/export_definition.py @@ -1,5 +1,4 @@ # (C) 2024 GoodData Corporation -from typing import Optional from attrs import define from gooddata_api_client.model.declarative_export_definition import DeclarativeExportDefinition @@ -14,16 +13,16 @@ @define(auto_attribs=True, kw_only=True) class CatalogDeclarativeExportDefinitionRequestPayload(Base): - custom_override: Optional[ExportCustomOverride] = None - execution_result: Optional[str] = None - metadata: Optional[dict] = None - related_dashboard_id: Optional[str] = None - settings: Optional[ExportSettings] = None - visualization_object: Optional[str] = None - visualization_object_custom_filters: Optional[list[dict]] = None - file_name: Optional[str] = None - format: Optional[str] = None - dashboard_id: Optional[str] = None + custom_override: ExportCustomOverride | None = None + execution_result: str | None = None + metadata: dict | None = None + related_dashboard_id: str | None = None + settings: ExportSettings | None = None + visualization_object: str | None = None + visualization_object_custom_filters: list[dict] | None = None + file_name: str | None = None + format: str | None = None + dashboard_id: str | None = None @staticmethod def client_class() -> type[DeclarativeExportDefinitionRequestPayload]: @@ -35,8 +34,8 @@ class CatalogDeclarativeExportDefinition(CatalogAnalyticsBaseMeta): id: str title: str request_payload: CatalogDeclarativeExportDefinitionRequestPayload - description: Optional[str] = None - tags: Optional[list[str]] = None + description: str | None = None + tags: list[str] | None = None @staticmethod def client_class() -> type[DeclarativeExportDefinition]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/automation.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/automation.py index c837cf10b..cb44bead0 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/automation.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/automation.py @@ -1,6 +1,6 @@ # (C) 2024 GoodData Corporation import builtins -from typing import Any, Optional +from typing import Any from attrs import define, field from gooddata_api_client.model.automation_schedule import AutomationSchedule @@ -24,9 +24,9 @@ @define(auto_attribs=True, kw_only=True) class CatalogAutomationSchedule(Base): cron: str - cron_description: Optional[str] = field(default=None, eq=False) - first_run: Optional[str] = None - timezone: Optional[str] = "UTC" + cron_description: str | None = field(default=None, eq=False) + first_run: str | None = None + timezone: str | None = "UTC" @staticmethod def client_class() -> builtins.type[AutomationSchedule]: @@ -53,18 +53,18 @@ def client_class() -> builtins.type[AutomationVisualExport]: @define(auto_attribs=True, kw_only=True) class CatalogDeclarativeAutomation(CatalogAnalyticsBaseMeta): - description: Optional[str] = None - details: Optional[dict[str, Any]] = None - state: Optional[str] = None - tags: Optional[list[str]] = None - title: Optional[str] = None - recipients: Optional[list[CatalogUserIdentifier]] = None - metadata: Optional[dict] = None - export_definitions: Optional[list[CatalogExportDefinitionIdentifier]] = None - notification_channel: Optional[CatalogNotificationChannelIdentifier] = None - schedule: Optional[CatalogAutomationSchedule] = None - tabular_exports: Optional[list[CatalogAutomationTabularExport]] = None - visual_exports: Optional[list[CatalogAutomationVisualExport]] = None + description: str | None = None + details: dict[str, Any] | None = None + state: str | None = None + tags: list[str] | None = None + title: str | None = None + recipients: list[CatalogUserIdentifier] | None = None + metadata: dict | None = None + export_definitions: list[CatalogExportDefinitionIdentifier] | None = None + notification_channel: CatalogNotificationChannelIdentifier | None = None + schedule: CatalogAutomationSchedule | None = None + tabular_exports: list[CatalogAutomationTabularExport] | None = None + visual_exports: list[CatalogAutomationVisualExport] | None = None @staticmethod def client_class() -> builtins.type[DeclarativeAutomation]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/dataset.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/dataset.py index be37191c2..5b74dac14 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/dataset.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/dataset.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional import attr import attrs @@ -43,16 +42,16 @@ class CatalogDeclarativeDataset(Base): title: str grain: list[CatalogGrainIdentifier] references: list[CatalogDeclarativeReference] - description: Optional[str] = None - attributes: Optional[list[CatalogDeclarativeAttribute]] = None - facts: Optional[list[CatalogDeclarativeFact]] = None - aggregated_facts: Optional[list[CatalogDeclarativeAggregatedFact]] = attrs.field(factory=list) - precedence: Optional[int] = None - data_source_table_id: Optional[CatalogDataSourceTableIdentifier] = None - sql: Optional[CatalogDeclarativeDatasetSql] = None - tags: Optional[list[str]] = None - workspace_data_filter_columns: Optional[list[CatalogDeclarativeWorkspaceDataFilterColumn]] = None - workspace_data_filter_references: Optional[list[CatalogDeclarativeWorkspaceDataFilterReferences]] = None + description: str | None = None + attributes: list[CatalogDeclarativeAttribute] | None = None + facts: list[CatalogDeclarativeFact] | None = None + aggregated_facts: list[CatalogDeclarativeAggregatedFact] | None = attrs.field(factory=list) + precedence: int | None = None + data_source_table_id: CatalogDataSourceTableIdentifier | None = None + sql: CatalogDeclarativeDatasetSql | None = None + tags: list[str] | None = None + workspace_data_filter_columns: list[CatalogDeclarativeWorkspaceDataFilterColumn] | None = None + workspace_data_filter_references: list[CatalogDeclarativeWorkspaceDataFilterReferences] | None = None @staticmethod def client_class() -> type[DeclarativeDataset]: @@ -74,16 +73,16 @@ class CatalogDeclarativeAttribute(Base): title: str source_column: str labels: list[CatalogDeclarativeLabel] - source_column_data_type: Optional[str] = None - default_view: Optional[CatalogLabelIdentifier] = None - sort_column: Optional[str] = None - sort_direction: Optional[str] = None - description: Optional[str] = None - tags: Optional[list[str]] = None - is_hidden: Optional[bool] = None - locale: Optional[str] = None - is_nullable: Optional[bool] = None - null_value: Optional[str] = None + source_column_data_type: str | None = None + default_view: CatalogLabelIdentifier | None = None + sort_column: str | None = None + sort_direction: str | None = None + description: str | None = None + tags: list[str] | None = None + is_hidden: bool | None = None + locale: str | None = None + is_nullable: bool | None = None + null_value: str | None = None @staticmethod def client_class() -> type[DeclarativeAttribute]: @@ -95,12 +94,12 @@ class CatalogDeclarativeFact(Base): id: str title: str source_column: str - source_column_data_type: Optional[str] = None - description: Optional[str] = None - tags: Optional[list[str]] = None - is_hidden: Optional[bool] = None - is_nullable: Optional[bool] = None - null_value: Optional[str] = None + source_column_data_type: str | None = None + description: str | None = None + tags: list[str] | None = None + is_hidden: bool | None = None + is_nullable: bool | None = None + null_value: str | None = None @staticmethod def client_class() -> type[DeclarativeFact]: @@ -121,12 +120,12 @@ def client_class() -> type[DeclarativeSourceFactReference]: class CatalogDeclarativeAggregatedFact(Base): id: str source_column: str - source_fact_reference: Optional[CatalogDeclarativeSourceFactReference] = None - source_column_data_type: Optional[str] = None - description: Optional[str] = None - tags: Optional[list[str]] = None - is_nullable: Optional[bool] = None - null_value: Optional[str] = None + source_fact_reference: CatalogDeclarativeSourceFactReference | None = None + source_column_data_type: str | None = None + description: str | None = None + tags: list[str] | None = None + is_nullable: bool | None = None + null_value: str | None = None @staticmethod def client_class() -> type[DeclarativeAggregatedFact]: @@ -137,7 +136,7 @@ def client_class() -> type[DeclarativeAggregatedFact]: class CatalogDataSourceTableIdentifier(Base): id: str data_source_id: str - path: Optional[list[str]] = None + path: list[str] | None = None @staticmethod def client_class() -> type[DataSourceTableIdentifier]: @@ -169,16 +168,16 @@ class CatalogDeclarativeLabel(Base): id: str title: str source_column: str - source_column_data_type: Optional[str] = None - description: Optional[str] = None - tags: Optional[list[str]] = None - value_type: Optional[str] = None - is_hidden: Optional[bool] = None - locale: Optional[str] = None - translations: Optional[list[CatalogDeclarativeLabelTranslation]] = None - geo_area_config: Optional[CatalogGeoAreaConfig] = None - is_nullable: Optional[bool] = None - null_value: Optional[str] = None + source_column_data_type: str | None = None + description: str | None = None + tags: list[str] | None = None + value_type: str | None = None + is_hidden: bool | None = None + locale: str | None = None + translations: list[CatalogDeclarativeLabelTranslation] | None = None + geo_area_config: CatalogGeoAreaConfig | None = None + is_nullable: bool | None = None + null_value: str | None = None @staticmethod def client_class() -> type[DeclarativeLabel]: @@ -197,7 +196,7 @@ def client_class() -> type[GeoAreaConfig]: @define(auto_attribs=True, kw_only=True) class CatalogGeoCollectionIdentifier(Base): id: str - kind: Optional[str] = None + kind: str | None = None @staticmethod def client_class() -> type[GeoCollectionIdentifier]: @@ -208,11 +207,11 @@ def client_class() -> type[GeoCollectionIdentifier]: class CatalogDeclarativeReference(Base): identifier: CatalogReferenceIdentifier multivalue: bool - source_columns: Optional[list[str]] = None - source_column_data_types: Optional[list[str]] = None - sources: Optional[list[CatalogDeclarativeReferenceSource]] = None - is_nullable: Optional[bool] = None - null_value: Optional[str] = None + source_columns: list[str] | None = None + source_column_data_types: list[str] | None = None + sources: list[CatalogDeclarativeReferenceSource] | None = None + is_nullable: bool | None = None + null_value: str | None = None @staticmethod def client_class() -> type[DeclarativeReference]: @@ -233,7 +232,7 @@ def client_class() -> type[DeclarativeWorkspaceDataFilterColumn]: class CatalogDeclarativeReferenceSource(Base): column: str target: CatalogGrainIdentifier - data_type: Optional[str] = None + data_type: str | None = None @staticmethod def client_class() -> type[DeclarativeReferenceSource]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/date_dataset/date_dataset.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/date_dataset/date_dataset.py index 7a2270581..a33bd93e4 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/date_dataset/date_dataset.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/date_dataset/date_dataset.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional import attr from gooddata_api_client.model.declarative_date_dataset import DeclarativeDateDataset @@ -20,8 +19,8 @@ class CatalogDeclarativeDateDataset(Base): title: str granularities_formatting: CatalogGranularitiesFormatting granularities: list[str] - description: Optional[str] = None - tags: Optional[list[str]] = None + description: str | None = None + tags: list[str] | None = None @staticmethod def client_class() -> type[DeclarativeDateDataset]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/ldm.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/ldm.py index 2436c9939..5d02a657f 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/ldm.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/ldm.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional import attr from gooddata_api_client.model.declarative_ldm import DeclarativeLdm @@ -28,7 +27,7 @@ @attr.s(auto_attribs=True, kw_only=True) class CatalogDeclarativeModel(Base): - ldm: Optional[CatalogDeclarativeLdm] = None + ldm: CatalogDeclarativeLdm | None = None @staticmethod def client_class() -> type[DeclarativeModel]: @@ -56,7 +55,7 @@ def change_wdf_refs_id(self, mapping: dict[str, str]) -> None: class CatalogDeclarativeLdm(Base): datasets: list[CatalogDeclarativeDataset] = attr.field(factory=list) date_instances: list[CatalogDeclarativeDateDataset] = attr.field(factory=list) - dataset_extensions: Optional[list[CatalogDeclarativeDatasetExtension]] = None + dataset_extensions: list[CatalogDeclarativeDatasetExtension] | None = None @staticmethod def client_class() -> type[DeclarativeLdm]: @@ -147,7 +146,7 @@ def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeLdm: ) return cls(datasets=datasets, date_instances=date_instances, dataset_extensions=dataset_extensions) - def modify_mapped_data_source(self, data_source_mapping: Optional[dict]) -> CatalogDeclarativeLdm: + def modify_mapped_data_source(self, data_source_mapping: dict | None) -> CatalogDeclarativeLdm: """LDM contains data source ID - is mapped to this data source. You may decide to migrate to different data source containing the same physical data model (e.g. change the DB engine, but keep the model). @@ -201,7 +200,7 @@ def _change_case(object_name: str, upper_case: bool) -> str: else: return object_name.lower() - def change_tables_columns_case(self, upper_case: Optional[bool] = None) -> CatalogDeclarativeLdm: + def change_tables_columns_case(self, upper_case: bool | None = None) -> CatalogDeclarativeLdm: """Change case (to lower/upper-case) of all physical objects mapped in the LDM. Namely mapped table names and column names. Default is to change everything to upper-case. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/workspace.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/workspace.py index d131fa8fb..a6d0c0738 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/workspace.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/workspace.py @@ -3,7 +3,7 @@ import copy from pathlib import Path -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.declarative_filter_view import DeclarativeFilterView @@ -47,8 +47,8 @@ def get_workspace_folder(workspace_id: str, layout_organization_folder: Path) -> @attr.s(auto_attribs=True, kw_only=True) class CatalogDeclarativeWorkspaceModel(Base): - ldm: Optional[CatalogDeclarativeLdm] = None - analytics: Optional[CatalogDeclarativeAnalyticsLayer] = None + ldm: CatalogDeclarativeLdm | None = None + analytics: CatalogDeclarativeAnalyticsLayer | None = None @staticmethod def client_class() -> type[DeclarativeWorkspaceModel]: @@ -79,12 +79,12 @@ def change_wdf_refs_id(self, mapping: dict[str, str]) -> None: class CatalogDeclarativeWorkspace(Base): id: str name: str - description: Optional[str] = None - model: Optional[CatalogDeclarativeWorkspaceModel] = None - parent: Optional[CatalogWorkspaceIdentifier] = None + description: str | None = None + model: CatalogDeclarativeWorkspaceModel | None = None + parent: CatalogWorkspaceIdentifier | None = None permissions: list[CatalogDeclarativeSingleWorkspacePermission] = attr.field(factory=list) hierarchy_permissions: list[CatalogDeclarativeWorkspaceHierarchyPermission] = attr.field(factory=list) - early_access: Optional[str] = None + early_access: str | None = None settings: list[CatalogDeclarativeSetting] = attr.field(factory=list) user_data_filters: list[CatalogDeclarativeUserDataFilter] = attr.field(factory=list) custom_application_settings: list[CatalogDeclarativeCustomApplicationSetting] = attr.field(factory=list) @@ -130,7 +130,7 @@ class CatalogDeclarativeWorkspaceDataFilterSetting(Base): title: str filter_values: list[str] workspace: CatalogWorkspaceIdentifier - description: Optional[str] = None + description: str | None = None @staticmethod def client_class() -> type[DeclarativeWorkspaceDataFilterSetting]: @@ -197,8 +197,8 @@ class CatalogDeclarativeWorkspaceDataFilter(Base): title: str column_name: str workspace_data_filter_settings: list[CatalogDeclarativeWorkspaceDataFilterSetting] - description: Optional[str] = None - workspace: Optional[CatalogWorkspaceIdentifier] = None + description: str | None = None + workspace: CatalogWorkspaceIdentifier | None = None @staticmethod def client_class() -> type[DeclarativeWorkspaceDataFilter]: @@ -259,9 +259,9 @@ class CatalogDeclarativeUserDataFilter(Base): id: str title: str maql: str - user: Optional[CatalogUserIdentifier] = None - user_group: Optional[CatalogDeclarativeUserGroupIdentifier] = None - description: Optional[str] = None + user: CatalogUserIdentifier | None = None + user_group: CatalogDeclarativeUserGroupIdentifier | None = None + description: str | None = None @staticmethod def client_class() -> type[DeclarativeUserDataFilter]: @@ -295,12 +295,12 @@ def from_dict(cls, data: dict[str, Any], camel_case: bool = True) -> CatalogDecl class CatalogDeclarativeFilterView(Base): id: str title: str - analytical_dashboard: Optional[CatalogDeclarativeAnalyticalDashboardIdentifier] = None - content: Optional[dict[str, Any]] = None - description: Optional[str] = None - is_default: Optional[bool] = None - tags: Optional[list[str]] = None - user: Optional[CatalogUserIdentifier] = None + analytical_dashboard: CatalogDeclarativeAnalyticalDashboardIdentifier | None = None + content: dict[str, Any] | None = None + description: str | None = None + is_default: bool | None = None + tags: list[str] | None = None + user: CatalogUserIdentifier | None = None @staticmethod def client_class() -> type[DeclarativeFilterView]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/dataset.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/dataset.py index 2bbf3320e..e88de77d7 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/dataset.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/dataset.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Any, Optional, Union, cast +from typing import Any, Union, cast import attr import attrs @@ -33,15 +33,15 @@ def value_type(self) -> bool: return safeget(self.json_api_attributes, ["valueType"]) @property - def is_hidden(self) -> Optional[bool]: + def is_hidden(self) -> bool | None: return safeget(self.json_api_attributes, ["isHidden"]) @property - def locale(self) -> Optional[str]: + def locale(self) -> str | None: return safeget(self.json_api_attributes, ["locale"]) @property - def translations(self) -> Optional[list[dict[str, str]]]: + def translations(self) -> list[dict[str, str]] | None: return safeget(self.json_api_attributes, ["translations"]) def as_computable(self) -> Attribute: @@ -78,11 +78,11 @@ def granularity(self) -> Union[str, None]: return self.json_api_attributes.get("granularity") @property - def is_hidden(self) -> Optional[bool]: + def is_hidden(self) -> bool | None: return safeget(self.json_api_attributes, ["isHidden"]) @property - def locale(self) -> Optional[bool]: + def locale(self) -> bool | None: return safeget(self.json_api_attributes, ["locale"]) def primary_label(self) -> Union[CatalogLabel, None]: @@ -115,7 +115,7 @@ def client_class() -> Any: return JsonApiFactOut @property - def is_hidden(self) -> Optional[bool]: + def is_hidden(self) -> bool | None: return safeget(self.json_api_attributes, ["isHidden"]) def as_computable(self) -> Metric: @@ -159,38 +159,38 @@ def generate_attributes_from_api(self) -> list[CatalogAttribute]: lambda self: self._relation_entity_from_side_loads(CatalogFact, ["facts", "data"]), takes_self=True ), ) - aggregated_facts: Optional[list[CatalogAggregatedFact]] = attr.field( + aggregated_facts: list[CatalogAggregatedFact] | None = attr.field( repr=False, default=attr.Factory( lambda self: self._relation_entity_from_side_loads(CatalogAggregatedFact, ["aggregatedFacts", "data"]), takes_self=True, ), ) - precedence: Optional[int] = attr.field( + precedence: int | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("precedence"), takes_self=True) ) - grain: Optional[list] = attr.field( + grain: list | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("grain"), takes_self=True) ) - reference_properties: Optional[list] = attr.field( + reference_properties: list | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("referenceProperties"), takes_self=True) ) - data_source_table_id: Optional[str] = attr.field( + data_source_table_id: str | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("dataSourceTableId"), takes_self=True) ) - data_source_table_path: Optional[list] = attr.field( + data_source_table_path: list | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("dataSourceTablePath"), takes_self=True) ) - sql: Optional[dict] = attr.field( + sql: dict | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("sql"), takes_self=True) ) - are_relations_valid: Optional[bool] = attr.field( + are_relations_valid: bool | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("areRelationsValid"), takes_self=True) ) - workspace_data_filter_columns: Optional[list] = attr.field( + workspace_data_filter_columns: list | None = attr.field( default=attr.Factory(lambda self: self.json_api_attributes.get("workspaceDataFilterColumns"), takes_self=True) ) - workspace_data_filter_references: Optional[list] = attr.field( + workspace_data_filter_references: list | None = attr.field( default=attr.Factory( lambda self: self.json_api_attributes.get("workspaceDataFilterReferences"), takes_self=True ) @@ -207,7 +207,7 @@ def find_label_attribute(self, id_obj: IdObjType) -> Union[CatalogAttribute, Non return None - def filter_dataset(self, valid_objects: ValidObjects) -> Optional[CatalogDataset]: + def filter_dataset(self, valid_objects: ValidObjects) -> CatalogDataset | None: """ Filters dataset so that it contains only attributes and facts that are part of the provided valid objects structure. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/metric.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/metric.py index d50dc5185..27b762116 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/metric.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/content_objects/metric.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.json_api_metric_out import JsonApiMetricOut @@ -18,11 +18,11 @@ def client_class() -> Any: return JsonApiMetricOut @property - def format(self) -> Optional[str]: + def format(self) -> str | None: return safeget(self.json_api_attributes, ["content", "format"]) @property - def is_hidden(self) -> Optional[bool]: + def is_hidden(self) -> bool | None: return safeget(self.json_api_attributes, ["isHidden"]) def as_computable(self) -> Metric: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/filter_view.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/filter_view.py index 87364998e..8c508f061 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/filter_view.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/filter_view.py @@ -1,7 +1,7 @@ # (C) 2024 GoodData Corporation from __future__ import annotations -from typing import Any, Optional, Union +from typing import Any, Union import attr from gooddata_api_client.model.json_api_filter_view_in import JsonApiFilterViewIn @@ -31,9 +31,9 @@ def _data_entity(value: Any) -> dict[str, Any]: @attr.s(auto_attribs=True, kw_only=True) class CatalogFilterView(Base): - id: Optional[str] = None + id: str | None = None attributes: CatalogFilterViewAttributes - relationships: Optional[CatalogFilterViewRelationships] = None + relationships: CatalogFilterViewRelationships | None = None @staticmethod def client_class() -> type[JsonApiFilterViewIn]: @@ -45,12 +45,12 @@ def init( filter_view_id: str, content: dict[str, Any], title: str, - are_relations_valid: Optional[bool] = None, - description: Optional[str] = None, - is_default: Optional[bool] = None, - tags: Optional[list[str]] = None, - user_id: Optional[str] = None, - analytical_dashboard_id: Optional[str] = None, + are_relations_valid: bool | None = None, + description: str | None = None, + is_default: bool | None = None, + tags: list[str] | None = None, + user_id: str | None = None, + analytical_dashboard_id: str | None = None, ) -> CatalogFilterView: attributes = CatalogFilterViewAttributes( content=content, @@ -110,10 +110,10 @@ def clean_relationships(self) -> None: class CatalogFilterViewAttributes(Base): content: dict[str, Any] title: str - are_relations_valid: Optional[bool] = None - description: Optional[str] = None - is_default: Optional[bool] = None - tags: Optional[list[str]] = None + are_relations_valid: bool | None = None + description: str | None = None + is_default: bool | None = None + tags: list[str] | None = None @staticmethod def client_class() -> type[JsonApiFilterViewInAttributes]: @@ -122,8 +122,8 @@ def client_class() -> type[JsonApiFilterViewInAttributes]: @attr.s(auto_attribs=True, kw_only=True) class CatalogFilterViewRelationships(Base): - user: Optional[dict[str, CatalogUserIdentifier]] = None - analytical_dashboard: Optional[dict[str, CatalogDeclarativeAnalyticalDashboardIdentifier]] = None + user: dict[str, CatalogUserIdentifier] | None = None + analytical_dashboard: dict[str, CatalogDeclarativeAnalyticalDashboardIdentifier] | None = None @staticmethod def client_class() -> type[JsonApiFilterViewInRelationships]: @@ -131,7 +131,7 @@ def client_class() -> type[JsonApiFilterViewInRelationships]: @classmethod def create_user_analytical_dashboard_relationship( - cls, user_id: Optional[str] = None, analytical_dashboard_id: Optional[str] = None + cls, user_id: str | None = None, analytical_dashboard_id: str | None = None ) -> CatalogFilterViewRelationships | None: if user_id is None and analytical_dashboard_id is None: return None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/graph_objects/graph.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/graph_objects/graph.py index 936bffa2c..6ccf78762 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/graph_objects/graph.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/graph_objects/graph.py @@ -2,7 +2,6 @@ from __future__ import annotations import builtins -from typing import Optional import attr from gooddata_api_client.model.dependent_entities_graph import DependentEntitiesGraph @@ -46,7 +45,7 @@ def client_class() -> builtins.type[DependentEntitiesGraph]: class CatalogDependentEntitiesNode(Base): id: str type: str - title: Optional[str] = None + title: str | None = None @staticmethod def client_class() -> builtins.type[DependentEntitiesNode]: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/user_data_filter.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/user_data_filter.py index 428d55754..6e33774d0 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/user_data_filter.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/user_data_filter.py @@ -1,7 +1,7 @@ # (C) 2023 GoodData Corporation from __future__ import annotations -from typing import Any, Optional, Union +from typing import Any, Union import attr from gooddata_api_client.model.json_api_user_data_filter_in import JsonApiUserDataFilterIn @@ -38,7 +38,7 @@ def to_post_api(self) -> JsonApiUserDataFilterPostOptionalIdDocument: return JsonApiUserDataFilterPostOptionalIdDocument.from_dict(dictionary, camel_case=False) -def _proces_entity_list_output(list_entity_data: Optional[dict[str, list[CatalogEntityIdentifier]]]) -> list[str]: +def _proces_entity_list_output(list_entity_data: dict[str, list[CatalogEntityIdentifier]] | None) -> list[str]: if list_entity_data: return list(map(lambda x: x.id, list_entity_data["data"])) return [] @@ -50,9 +50,9 @@ def _data_entity(value: Any) -> dict[str, Any]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserDataFilter(Base): - id: Optional[str] = None + id: str | None = None attributes: CatalogUserDataFilterAttributes - relationships: Optional[CatalogUserDataFilterRelationships] = None + relationships: CatalogUserDataFilterRelationships | None = None @staticmethod def client_class() -> type[JsonApiUserDataFilterIn]: @@ -63,12 +63,12 @@ def init( cls, user_data_filter_id: str, maql: str, - are_relations_valid: Optional[bool] = None, - title: Optional[str] = None, - description: Optional[str] = None, - tags: Optional[list[str]] = None, - user_id: Optional[str] = None, - user_group_id: Optional[str] = None, + are_relations_valid: bool | None = None, + title: str | None = None, + description: str | None = None, + tags: list[str] | None = None, + user_id: str | None = None, + user_group_id: str | None = None, ) -> CatalogUserDataFilter: attributes = CatalogUserDataFilterAttributes( maql=maql, title=title, are_relations_valid=are_relations_valid, tags=tags, description=description @@ -155,10 +155,10 @@ def clean_assignments(self) -> None: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserDataFilterAttributes(Base): maql: str - are_relations_valid: Optional[bool] = None - title: Optional[str] = None - description: Optional[str] = None - tags: Optional[list[str]] = None + are_relations_valid: bool | None = None + title: str | None = None + description: str | None = None + tags: list[str] | None = None @staticmethod def client_class() -> type[JsonApiUserDataFilterInAttributes]: @@ -167,13 +167,13 @@ def client_class() -> type[JsonApiUserDataFilterInAttributes]: @attr.s(auto_attribs=True, kw_only=True) class CatalogUserDataFilterRelationships(Base): - user: Optional[dict[str, CatalogEntityIdentifier]] = None - user_group: Optional[dict[str, CatalogEntityIdentifier]] = None - attributes: Optional[dict[str, list[CatalogEntityIdentifier]]] = None - labels: Optional[dict[str, list[CatalogEntityIdentifier]]] = None - datasets: Optional[dict[str, list[CatalogEntityIdentifier]]] = None - facts: Optional[dict[str, list[CatalogEntityIdentifier]]] = None - metrics: Optional[dict[str, list[CatalogEntityIdentifier]]] = None + user: dict[str, CatalogEntityIdentifier] | None = None + user_group: dict[str, CatalogEntityIdentifier] | None = None + attributes: dict[str, list[CatalogEntityIdentifier]] | None = None + labels: dict[str, list[CatalogEntityIdentifier]] | None = None + datasets: dict[str, list[CatalogEntityIdentifier]] | None = None + facts: dict[str, list[CatalogEntityIdentifier]] | None = None + metrics: dict[str, list[CatalogEntityIdentifier]] | None = None @staticmethod def client_class() -> type[JsonApiUserDataFilterInRelationships]: @@ -181,7 +181,7 @@ def client_class() -> type[JsonApiUserDataFilterInRelationships]: @classmethod def create_user_user_group_relationship( - cls, user_id: Optional[str] = None, user_group_id: Optional[str] = None + cls, user_id: str | None = None, user_group_id: str | None = None ) -> CatalogUserDataFilterRelationships | None: if user_id is None and user_group_id is None: return None @@ -195,4 +195,4 @@ def create_user_user_group_relationship( @attr.s(auto_attribs=True, kw_only=True) class CatalogEntityIdentifier(Base): id: str - type: Optional[str] = None + type: str | None = None diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/workspace.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/workspace.py index b3e06f9f4..836be81e3 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/workspace.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/workspace.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Any, Optional +from typing import Any import attr from gooddata_api_client.model.json_api_workspace_automation_out_relationships_workspace import ( @@ -22,8 +22,8 @@ class CatalogWorkspace(Base): workspace_id: str id: str = attr.field(init=False, default=attr.Factory(lambda self: self.workspace_id, takes_self=True)) name: str - parent_id: Optional[str] = attr.field(default=None) - description: Optional[str] = attr.field(default=None) + parent_id: str | None = attr.field(default=None) + description: str | None = attr.field(default=None) @classmethod def from_api(cls, entity: dict[str, Any]) -> CatalogWorkspace: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/model_container.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/model_container.py index 289647e48..c92a457c3 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/model_container.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/model_container.py @@ -2,7 +2,7 @@ from __future__ import annotations import functools -from typing import Optional, Union +from typing import Union from gooddata_sdk.catalog.types import ValidObjects from gooddata_sdk.catalog.workspace.entity_model.content_objects.dataset import ( @@ -29,7 +29,7 @@ class CatalogWorkspaceContent: def __init__( self, - valid_obj_fun: Optional[functools.partial[dict[str, set[str]]]], + valid_obj_fun: functools.partial[dict[str, set[str]]] | None, datasets: list[CatalogDataset], metrics: list[CatalogMetric], ) -> None: @@ -166,7 +166,7 @@ def catalog_with_valid_objects(self, ctx: ValidObjectsInputType) -> CatalogWorks @classmethod def create_workspace_content_catalog( cls, - valid_obj_fun: Optional[functools.partial[dict[str, set[str]]]], + valid_obj_fun: functools.partial[dict[str, set[str]]] | None, datasets: AllPagedEntities, attributes: AllPagedEntities, metrics: AllPagedEntities, diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py index 6719afaef..931463bbf 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py @@ -9,7 +9,7 @@ from math import ceil from pathlib import Path from time import time -from typing import Any, Callable, Optional +from typing import Any, Callable from xml.etree import ElementTree as ET import attrs @@ -190,13 +190,14 @@ def list_workspace_settings(self, workspace_id: str) -> list[CatalogWorkspaceSet workspace_settings = load_all_entities(get_workspace_settings).data return [CatalogWorkspaceSetting.from_api(ws) for ws in workspace_settings] - def resolve_all_workspace_settings(self, workspace_id: str) -> dict: + def resolve_all_workspace_settings(self, workspace_id: str, exclude_user_settings: bool = False) -> dict: """ Resolves values for all settings in a workspace by current user, workspace, organization, or default settings and return them as a dictionary. Proper parsing is up to the caller. TODO: long-term we should return a proper entity object. :param workspace_id: Workspace ID + :param exclude_user_settings: If true, user-level settings are excluded from resolution. :return: Dict of settings """ # note: in case some settings were recently added and the API client was not regenerated it can fail on @@ -205,12 +206,15 @@ def resolve_all_workspace_settings(self, workspace_id: str) -> dict: setting.to_dict() for setting in self._client.actions_api.workspace_resolve_all_settings( workspace_id, + exclude_user_settings=exclude_user_settings, _check_return_type=False, ) ] return {setting["type"]: setting for setting in resolved_workspace_settings} - def resolve_workspace_settings(self, workspace_id: str, settings: list) -> dict: + def resolve_workspace_settings( + self, workspace_id: str, settings: list, exclude_user_settings: bool = False + ) -> dict: """ Resolves values for given settings in a workspace by current user, workspace, organization, or default settings and return them as a dictionary. Proper parsing is up to the caller. @@ -218,6 +222,7 @@ def resolve_workspace_settings(self, workspace_id: str, settings: list) -> dict: :param workspace_id: Workspace ID :param settings: List of settings to resolve + :param exclude_user_settings: If true, user-level settings are excluded from resolution. :return: Dict of settings """ resolved_workspace_settings = [ @@ -225,6 +230,7 @@ def resolve_workspace_settings(self, workspace_id: str, settings: list) -> dict: for setting in self._client.actions_api.workspace_resolve_settings( workspace_id, ResolveSettingsRequest(settings=settings), + exclude_user_settings=exclude_user_settings, _check_return_type=False, ) ] @@ -232,7 +238,7 @@ def resolve_workspace_settings(self, workspace_id: str, settings: list) -> dict: # Declarative methods - workspaces - def get_declarative_workspaces(self, exclude: Optional[list[str]] = None) -> CatalogDeclarativeWorkspaces: + def get_declarative_workspaces(self, exclude: list[str] | None = None) -> CatalogDeclarativeWorkspaces: """Get all workspaces in the current organization in a declarative form. Args: @@ -305,7 +311,7 @@ def load_and_put_declarative_workspaces(self, layout_root_path: Path = Path.cwd( # Declarative methods - workspace def get_declarative_workspace( - self, workspace_id: str, exclude: Optional[list[str]] = None + self, workspace_id: str, exclude: list[str] | None = None ) -> CatalogDeclarativeWorkspaceModel: """Retrieve a workspace layout. @@ -348,7 +354,7 @@ def put_declarative_workspace( self._layout_api.put_workspace_layout(workspace_id, workspace.to_api()) def store_declarative_workspace( - self, workspace_id: str, layout_root_path: Path = Path.cwd(), exclude: Optional[list[str]] = None + self, workspace_id: str, layout_root_path: Path = Path.cwd(), exclude: list[str] | None = None ) -> None: """Store workspace layout in a directory hierarchy. @@ -410,11 +416,11 @@ def load_and_put_declarative_workspace(self, workspace_id: str, layout_root_path def clone_workspace( self, source_workspace_id: str, - target_workspace_id: Optional[str] = None, - target_workspace_name: Optional[str] = None, - overwrite_existing: Optional[bool] = None, - data_source_mapping: Optional[dict] = None, - upper_case: Optional[bool] = True, + target_workspace_id: str | None = None, + target_workspace_name: str | None = None, + overwrite_existing: bool | None = None, + data_source_mapping: dict | None = None, + upper_case: bool | None = True, place_in_hierarchy: bool = True, ) -> None: """Clone workspace from existing workspace. @@ -513,10 +519,10 @@ def generate_localized_workspaces( to_lang: str, to_locale: str, from_lang: str = "en", - translator_func: Optional[Callable] = None, - layout_root_path: Optional[Path] = None, - provision_workspace: Optional[bool] = False, - store_layouts: Optional[bool] = False, + translator_func: Callable | None = None, + layout_root_path: Path | None = None, + provision_workspace: bool | None = False, + store_layouts: bool | None = False, place_in_hierarchy: bool = True, ) -> None: """ @@ -577,7 +583,7 @@ def generate_localized_workspaces( if provision_workspace: self.provision_workspace_with_locales(workspace_id, new_workspace, new_workspace_content, to_locale) - def create_custom_workspace_folder(self, workspace_id: str, layout_root_path: Optional[Path]) -> Path: + def create_custom_workspace_folder(self, workspace_id: str, layout_root_path: Path | None) -> Path: if layout_root_path: workspace_folder = layout_root_path else: @@ -661,7 +667,7 @@ def provision_workspace_with_locales( def translate_if_requested( self, to_translate: set[str], - translator_func: Optional[Callable], + translator_func: Callable | None, to_lang: str, from_lang: str, already_translated: dict[str, str], @@ -691,14 +697,14 @@ def translate_if_requested( return translated @staticmethod - def add_title_description(to_translate: set[str], title: Optional[str], description: Optional[str]) -> None: + def add_title_description(to_translate: set[str], title: str | None, description: str | None) -> None: if title: to_translate.add(title) if description: to_translate.add(description) def add_title_description_tags( - self, to_translate: set[str], title: Optional[str], description: Optional[str], tags: Optional[list[str]] + self, to_translate: set[str], title: str | None, description: str | None, tags: list[str] | None ) -> None: self.add_title_description(to_translate, title, description) if tags: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/client.py b/packages/gooddata-sdk/src/gooddata_sdk/client.py index b1ac3197e..62bc12b9b 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/client.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/client.py @@ -4,7 +4,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional import gooddata_api_client as api_client import requests @@ -23,10 +22,10 @@ def __init__( self, host: str, token: str, - custom_headers: Optional[dict[str, str]] = None, - extra_user_agent: Optional[str] = None, + custom_headers: dict[str, str] | None = None, + extra_user_agent: str | None = None, executions_cancellable: bool = False, - ssl_ca_cert: Optional[str] = None, + ssl_ca_cert: str | None = None, ) -> None: """Take url, token for connecting to GoodData.CN. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/attribute.py b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/attribute.py index 64b9f1fce..595226d13 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/attribute.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/attribute.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional, Union +from typing import Union import gooddata_api_client.models as afm_models @@ -9,7 +9,7 @@ class Attribute(ExecModelEntity): - def __init__(self, local_id: str, label: Union[ObjId, str], show_all_values: Optional[bool] = None) -> None: + def __init__(self, local_id: str, label: Union[ObjId, str], show_all_values: bool | None = None) -> None: """ Creates new attribute that can be used to slice or dice metric values during computation. @@ -33,7 +33,7 @@ def label(self) -> ObjId: return self._label @property - def show_all_values(self) -> Optional[bool]: + def show_all_values(self) -> bool | None: return self._show_all_values def has_same_label(self, other: ExecModelEntity) -> bool: diff --git a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/base.py b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/base.py index 753897313..a354bdf74 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/base.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/base.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional, Union +from typing import Union import gooddata_api_client.models as afm_models from gooddata_api_client.model_utils import OpenApiModel @@ -71,7 +71,7 @@ def as_api_model(self) -> OpenApiModel: class Filter(ExecModelEntity): - def __init__(self, _apply_on_result: Optional[bool] = None) -> None: + def __init__(self, _apply_on_result: bool | None = None) -> None: super().__init__() self._apply_on_result = _apply_on_result @@ -86,7 +86,7 @@ def is_noop(self) -> bool: def as_api_model(self) -> OpenApiModel: raise NotImplementedError() - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: """ Description of the filter as it's visible for customer in UI. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/execution.py b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/execution.py index 7f2d9cf92..86c927fa9 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/execution.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/execution.py @@ -2,7 +2,7 @@ from __future__ import annotations import logging -from typing import Any, Optional, Union +from typing import Any, Union from attr.setters import frozen as frozen_attr from attrs import define, field @@ -46,7 +46,7 @@ class TotalDefinition: class TableDimension: """Dataclass used during total and dimension computation.""" - item_ids: Optional[list[str]] = field(on_setattr=frozen_attr) + item_ids: list[str] | None = field(on_setattr=frozen_attr) """table dimension item local identifiers""" sorting: list[dict] = field(default=[]) @@ -56,11 +56,11 @@ class TableDimension: class ExecutionDefinition: def __init__( self, - attributes: Optional[list[Attribute]], - metrics: Optional[list[Metric]], - filters: Optional[list[Filter]], + attributes: list[Attribute] | None, + metrics: list[Metric] | None, + filters: list[Filter] | None, dimensions: list[TableDimension], - totals: Optional[list[TotalDefinition]] = None, + totals: list[TotalDefinition] | None = None, is_cancellable: bool = False, ) -> None: self._attributes = attributes or [] @@ -165,7 +165,7 @@ def _create_dimensions(self) -> list[models.Dimension]: return dimensions - def _create_totals(self) -> Optional[list[models.Total]]: + def _create_totals(self) -> list[models.Total] | None: if not self._totals: return None @@ -205,7 +205,7 @@ def as_api_model(self) -> models.AfmExecution: return models.AfmExecution(execution=execution, result_spec=result_spec) -ResultSizeDimensions = tuple[Optional[int], ...] +ResultSizeDimensions = tuple[int | None, ...] class ResultSizeDimensionsLimitsExceeded(Exception): @@ -308,7 +308,7 @@ def __init__( api_client: GoodDataApiClient, workspace_id: str, execution_response: models.AfmExecutionResponse, - cancel_token: Optional[str] = None, + cancel_token: str | None = None, ): self._api_client = api_client self._actions_api = self._api_client.actions_api @@ -331,14 +331,14 @@ def dimensions(self) -> Any: return self._exec_response["dimensions"] @property - def cancel_token(self) -> Optional[str]: + def cancel_token(self) -> str | None: return self._cancel_token def read_result( self, limit: Union[int, list[int]], offset: Union[None, int, list[int]] = None, - timeout: Optional[Union[int, float, tuple]] = None, + timeout: Union[int, float, tuple] | None = None, ) -> ExecutionResult: """ Reads from the execution result. @@ -402,7 +402,7 @@ def __init__( workspace_id: str, exec_def: ExecutionDefinition, response: models.AfmExecutionResponse, - cancel_token: Optional[str] = None, + cancel_token: str | None = None, ): self._exec_def = exec_def self._bare_exec_response = BareExecutionResponse( @@ -430,7 +430,7 @@ def dimensions(self) -> Any: return self.bare_exec_response._exec_response["dimensions"] @property - def cancel_token(self) -> Optional[str]: + def cancel_token(self) -> str | None: return self.bare_exec_response.cancel_token def get_labels_and_formats(self) -> tuple[dict[str, str], dict[str, str]]: @@ -460,7 +460,7 @@ def read_result( self, limit: Union[int, list[int]], offset: Union[None, int, list[int]] = None, - timeout: Optional[Union[int, float, tuple]] = None, + timeout: Union[int, float, tuple] | None = None, ) -> ExecutionResult: return self.bare_exec_response.read_result(limit, offset, timeout) @@ -516,7 +516,7 @@ def result_size(self) -> int: def result_spec(self) -> ResultSpec: return self._result_cache_metadata.result_spec - def check_bytes_size_limit(self, result_size_bytes_limit: Optional[int] = None) -> None: + def check_bytes_size_limit(self, result_size_bytes_limit: int | None = None) -> None: if result_size_bytes_limit is not None and self.result_size > result_size_bytes_limit: raise ResultSizeBytesLimitExceeded( result_size_bytes_limit=result_size_bytes_limit, @@ -525,9 +525,9 @@ def check_bytes_size_limit(self, result_size_bytes_limit: Optional[int] = None) def compute_model_to_api_model( - attributes: Optional[list[Attribute]] = None, - metrics: Optional[list[Metric]] = None, - filters: Optional[list[Filter]] = None, + attributes: list[Attribute] | None = None, + metrics: list[Metric] | None = None, + filters: list[Filter] | None = None, ) -> models.AFM: """ Transforms categorized execution model entities (attributes, metrics, facts) into an API model diff --git a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/filter.py b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/filter.py index 9816034a9..b9bdcf9ed 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/filter.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/filter.py @@ -3,7 +3,7 @@ from datetime import datetime from importlib.util import find_spec -from typing import Any, Literal, Optional, TypeAlias, Union, cast +from typing import Any, Literal, TypeAlias, Union, cast import attrs from gooddata_api_client.model.inline_filter_definition_inline import InlineFilterDefinitionInline @@ -95,7 +95,7 @@ def _to_identifier(val: Union[ObjId, str]) -> Union[afm_models.AfmLocalIdentifie class AttributeFilter(Filter): - def __init__(self, label: Union[ObjId, str, Attribute], values: Optional[list[str]] = None) -> None: + def __init__(self, label: Union[ObjId, str, Attribute], values: list[str] | None = None) -> None: super().__init__() self._label = _extract_id_or_local_id(label) @@ -130,7 +130,7 @@ def as_api_model(self) -> afm_models.PositiveAttributeFilter: body = PositiveAttributeFilterBody(label=label_id, _in=elements, _check_type=False) return afm_models.PositiveAttributeFilter(body, _check_type=False) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: label_id = self.label.id if isinstance(self.label, ObjId) else self.label values = ", ".join(self.values) if len(self.values) else "All" return f"{labels.get(label_id, label_id)}: {values}" @@ -146,7 +146,7 @@ def as_api_model(self) -> afm_models.NegativeAttributeFilter: body = NegativeAttributeFilterBody(label=label_id, not_in=elements, _check_type=False) return afm_models.NegativeAttributeFilter(body) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: label_id = self.label.id if isinstance(self.label, ObjId) else self.label values = "All except " + ", ".join(self.values) if len(self.values) else "All" return f"{labels.get(label_id, label_id)}: {values}" @@ -177,8 +177,8 @@ def description(self, labels: dict[str, str], format_locale: Optional[str] = Non @attrs.define class BoundedFilter: granularity: str - from_shift: Optional[int] = None - to_shift: Optional[int] = None + from_shift: int | None = None + to_shift: int | None = None def __attrs_post_init__(self) -> None: # Validate that exactly one of from_shift or to_shift is set @@ -201,8 +201,8 @@ def __init__( granularity: str, from_shift: int, to_shift: int, - bounded_filter: Optional[BoundedFilter] = None, - empty_value_handling: Optional[EmptyValueHandling] = None, + bounded_filter: BoundedFilter | None = None, + empty_value_handling: EmptyValueHandling | None = None, ) -> None: super().__init__() @@ -241,11 +241,11 @@ def to_shift(self) -> int: return self._to_shift @property - def bounded_filter(self) -> Optional[BoundedFilter]: + def bounded_filter(self) -> BoundedFilter | None: return self._bounded_filter @property - def empty_value_handling(self) -> Optional[EmptyValueHandling]: + def empty_value_handling(self) -> EmptyValueHandling | None: return self._empty_value_handling def is_noop(self) -> bool: @@ -269,7 +269,7 @@ def as_api_model(self) -> afm_models.RelativeDateFilter: body = RelativeDateFilterBody(**body_params) return afm_models.RelativeDateFilter(body) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: # TODO compare with other period is not implemented as it's not defined in the filter but in measures from_shift = self.from_shift to_shift = self.to_shift @@ -313,8 +313,8 @@ class AllTimeDateFilter(Filter): def __init__( self, dataset: ObjId, - granularity: Optional[str] = None, - empty_value_handling: Optional[EmptyValueHandling] = None, + granularity: str | None = None, + empty_value_handling: EmptyValueHandling | None = None, ) -> None: super().__init__() @@ -338,11 +338,11 @@ def dataset(self) -> ObjId: return self._dataset @property - def granularity(self) -> Optional[str]: + def granularity(self) -> str | None: return self._granularity @property - def empty_value_handling(self) -> Optional[EmptyValueHandling]: + def empty_value_handling(self) -> EmptyValueHandling | None: return self._empty_value_handling def is_noop(self) -> bool: @@ -363,7 +363,7 @@ def as_api_model(self) -> afm_models.AllTimeDateFilter: body = AllTimeDateFilterBody(**body_params) return afm_models.AllTimeDateFilter(body, _check_type=False) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: return f"{labels.get(self.dataset.id, self.dataset.id)}: All time" @@ -373,7 +373,7 @@ def __init__( dataset: ObjId, from_date: str, to_date: str, - empty_value_handling: Optional[EmptyValueHandling] = None, + empty_value_handling: EmptyValueHandling | None = None, ) -> None: super().__init__() @@ -401,7 +401,7 @@ def to_date(self) -> str: return self._to_date @property - def empty_value_handling(self) -> Optional[EmptyValueHandling]: + def empty_value_handling(self) -> EmptyValueHandling | None: return self._empty_value_handling def is_noop(self) -> bool: @@ -428,7 +428,7 @@ def __eq__(self, other: object) -> bool: and self._to_date == other._to_date ) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: if format_locale is not None and find_spec("icu") is not None: src_parser = SimpleDateFormat(_ICU_DATE_FORMAT_INPUT) dest_formatter = SimpleDateFormat( @@ -470,7 +470,7 @@ def metric(self) -> Union[ObjId, str]: def is_noop(self) -> bool: return True - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: metric_id = self.metric.id if isinstance(self.metric, ObjId) else self.metric return f"{labels.get(metric_id, metric_id)}: All" @@ -554,7 +554,7 @@ def as_api_model(self) -> Union[afm_models.ComparisonMeasureValueFilter, afm_mod body = RangeMeasureValueFilterBody(**kwargs) return afm_models.RangeMeasureValueFilter(body) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: metric_id = self.metric.id if isinstance(self.metric, ObjId) else self.metric if self.operator in ["BETWEEN", "NOT_BETWEEN"] and len(self.values) == 2: not_between = "not" if self.operator == "NOT_BETWEEN" else "" @@ -658,7 +658,7 @@ def as_api_model(self) -> afm_models.CompoundMeasureValueFilter: body = CompoundMeasureValueFilterBody(**kwargs) return afm_models.CompoundMeasureValueFilter(body, _check_type=False) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: metric_id = self.metric.id if isinstance(self.metric, ObjId) else self.metric if not self.conditions: return f"{labels.get(metric_id, metric_id)}: All" @@ -675,7 +675,7 @@ def __init__( metrics: list[Union[ObjId, Metric, str]], operator: str, value: int, - dimensionality: Optional[list[Union[str, ObjId, Attribute, Metric]]], + dimensionality: list[Union[str, ObjId, Attribute, Metric]] | None, ) -> None: super().__init__() @@ -702,7 +702,7 @@ def value(self) -> int: return self._value @property - def dimensionality(self) -> Optional[list[Union[ObjId, str]]]: + def dimensionality(self) -> list[Union[ObjId, str]] | None: return self._dimensionality def is_noop(self) -> bool: @@ -718,7 +718,7 @@ def as_api_model(self) -> afm_models.RankingFilter: ) return afm_models.RankingFilter(body) - def description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> str: + def description(self, labels: dict[str, str], format_locale: str | None = None) -> str: # TODO more metrics and dimensions not supported now as it's not supported on FE as well dimensionality_ids = ( [d.id if isinstance(d, ObjId) else d for d in self.dimensionality] if self.dimensionality else [] @@ -755,7 +755,7 @@ class InlineFilter(Filter): """ def __init__( - self, maql: str, apply_on_result: Optional[bool] = None, local_identifier: Optional[Union[ObjId, str]] = None + self, maql: str, apply_on_result: bool | None = None, local_identifier: Union[ObjId, str] | None = None ) -> None: super().__init__(apply_on_result) diff --git a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/metric.py b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/metric.py index 8f8b44887..3e671f4ca 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/compute/model/metric.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/compute/model/metric.py @@ -1,7 +1,7 @@ # (C) 2022 GoodData Corporation from __future__ import annotations -from typing import Optional, Union +from typing import Union import gooddata_api_client.models as afm_models from gooddata_api_client.model_utils import OpenApiModel @@ -53,9 +53,9 @@ def __init__( self, local_id: str, item: ObjId, - aggregation: Optional[str] = None, + aggregation: str | None = None, compute_ratio: bool = False, - filters: Optional[list[Filter]] = None, + filters: list[Filter] | None = None, ) -> None: super().__init__(local_id) @@ -86,7 +86,7 @@ def item(self) -> ObjId: return self._item @property - def aggregation(self) -> Optional[str]: + def aggregation(self) -> str | None: return self._aggregation @property diff --git a/packages/gooddata-sdk/src/gooddata_sdk/compute/service.py b/packages/gooddata-sdk/src/gooddata_sdk/compute/service.py index cd9a5d522..6163798b9 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/compute/service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/compute/service.py @@ -4,7 +4,7 @@ import json import logging from collections.abc import Iterator -from typing import Any, Optional, Union +from typing import Any, Union from gooddata_api_client import ApiException from gooddata_api_client.model.afm_cancel_tokens import AfmCancelTokens @@ -44,7 +44,7 @@ def for_exec_def( self, workspace_id: str, exec_def: ExecutionDefinition, - timeout: Optional[Union[int, float, tuple]] = None, + timeout: Union[int, float, tuple] | None = None, ) -> Execution: """ Starts computation in GoodData.CN workspace, using the provided execution definition. @@ -275,11 +275,11 @@ def search_ai( self, workspace_id: str, question: str, - deep_search: Optional[bool] = None, - limit: Optional[int] = None, - object_types: Optional[list[str]] = None, - relevant_score_threshold: Optional[float] = None, - title_to_descriptor_ratio: Optional[float] = None, + deep_search: bool | None = None, + limit: int | None = None, + object_types: list[str] | None = None, + relevant_score_threshold: float | None = None, + title_to_descriptor_ratio: float | None = None, ) -> SearchResult: """ Search for metadata objects using similarity search. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/config.py b/packages/gooddata-sdk/src/gooddata_sdk/config.py index 06b8d1e5e..d0db7b68c 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/config.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/config.py @@ -1,6 +1,6 @@ # (C) 2024 GoodData Corporation import os -from typing import Any, Optional, TypeVar +from typing import Any, TypeVar import attrs from attrs import define @@ -33,9 +33,9 @@ def can_structure(cls: type[T], data: dict[str, Any]) -> bool: class Profile(ConfigBase): host: str token: str - custom_headers: Optional[dict[str, str]] = None - extra_user_agent: Optional[str] = None - ssl_ca_cert: Optional[str] = None + custom_headers: dict[str, str] | None = None + extra_user_agent: str | None = None + ssl_ca_cert: str | None = None def to_dict(self, use_env: bool = False) -> dict[str, str]: load_dotenv() diff --git a/packages/gooddata-sdk/src/gooddata_sdk/sdk.py b/packages/gooddata-sdk/src/gooddata_sdk/sdk.py index 5e7587464..8c6ea5c48 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/sdk.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/sdk.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import Optional from gooddata_sdk.catalog.data_source.service import CatalogDataSourceService from gooddata_sdk.catalog.export.service import ExportService @@ -45,11 +44,11 @@ def create( cls, host_: str, token_: str, - extra_user_agent_: Optional[str] = None, + extra_user_agent_: str | None = None, *, - ssl_ca_cert: Optional[str] = None, + ssl_ca_cert: str | None = None, executions_cancellable: bool = False, - **custom_headers_: Optional[str], + **custom_headers_: str | None, ) -> GoodDataSdk: """ Create common GoodDataApiClient and return new GoodDataSdk instance. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/table.py b/packages/gooddata-sdk/src/gooddata_sdk/table.py index 10f297fa1..f27d3d112 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/table.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/table.py @@ -4,7 +4,7 @@ import logging from collections.abc import Generator from operator import attrgetter -from typing import Any, Callable, Optional, Union +from typing import Any, Callable, Union from attrs import define, field, frozen from attrs.setters import frozen as frozen_attr @@ -243,7 +243,7 @@ def _prepare_tabular_definition( def _as_table( response: ExecutionResponse, always_two_dimensional: bool = False, - timeout: Optional[Union[int, float, tuple]] = None, + timeout: Union[int, float, tuple] | None = None, ) -> ExecutionTable: first_page_offset = [0, 0] first_page_limit = [_TABLE_ROW_BATCH_SIZE, _MAX_METRICS] @@ -361,7 +361,7 @@ def _create_data_col_locators(locators: list[VisualizationSortLocator]) -> list[ def _get_dim_idx_for_predicate( dims: list[TableDimension], predicate: Callable[[TableDimension], bool] -) -> Optional[int]: +) -> int | None: for dim_idx, dim in enumerate(dims): if predicate(dim): return dim_idx @@ -391,8 +391,8 @@ def _append_attribute_sort_key( def _append_measure_sort_key( - measure_dim: Optional[TableDimension], - non_measure_dim_idx: Optional[int], + measure_dim: TableDimension | None, + non_measure_dim_idx: int | None, sort_item: VisualizationSort, sorting: list[list[SortKey]], ) -> None: @@ -472,7 +472,7 @@ def _vis_is_transposed(visualization: Visualization) -> bool: return controls.get("measureGroupDimension") == "rows" -def _create_dimension(bucket: VisualizationBucket, measures_item_identifier: Optional[str] = None) -> TableDimension: +def _create_dimension(bucket: VisualizationBucket, measures_item_identifier: str | None = None) -> TableDimension: item_ids = [a.local_id for a in bucket.attributes] if measures_item_identifier is not None: item_ids.append(measures_item_identifier) @@ -800,8 +800,8 @@ def for_items( self, workspace_id: str, items: list[Union[Attribute, Metric]], - filters: Optional[list[Filter]] = None, - timeout: Optional[Union[int, float, tuple]] = None, + filters: list[Filter] | None = None, + timeout: Union[int, float, tuple] | None = None, ) -> ExecutionTable: if filters is None: filters = [] diff --git a/packages/gooddata-sdk/src/gooddata_sdk/type_converter.py b/packages/gooddata-sdk/src/gooddata_sdk/type_converter.py index 6f6e14a41..10fcee4fb 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/type_converter.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/type_converter.py @@ -2,7 +2,7 @@ from __future__ import annotations from datetime import date, datetime -from typing import Any, Callable, Optional +from typing import Any, Callable from dateutil.parser import parse @@ -15,7 +15,7 @@ class Converter: DEFAULT_DB_DATA_TYPE = "VARCHAR(255)" - _EXTERNAL_CONVERSION_FNC: Optional[Callable[[object, Any], Any]] = None + _EXTERNAL_CONVERSION_FNC: Callable[[object, Any], Any] | None = None @classmethod def set_external_fnc(cls, fnc: Callable[[object, Any], Any]) -> None: @@ -126,9 +126,9 @@ def __init__(self, type_name: str): """ self._type_name = type_name self._converters: dict[str, Converter] = {} - self._default_converter: Optional[Converter] = None + self._default_converter: Converter | None = None - def register(self, converter: Converter, sub_type: Optional[str]) -> None: + def register(self, converter: Converter, sub_type: str | None) -> None: """ Register converter instance for given sub-type (granularity). If sub-type is not specified, converter is registered as the default one for the whole type. Default converter can be registered only once. @@ -174,7 +174,7 @@ def _register_default(self, converter: Converter) -> None: ) self._default_converter = converter - def converter(self, sub_type: Optional[str]) -> Converter: + def converter(self, sub_type: str | None) -> Converter: """ Find and return converter instance for a given sub-type. Default converter instance is returned if the sub-type is not found or not provided. When a default converter is not registered, ValueError @@ -230,7 +230,7 @@ def _get_registry(cls, type_name: str) -> TypeConverterRegistry: return cls._TYPE_REGISTRIES[type_name] @classmethod - def register(cls, type_name: str, class_converter: type[Converter], sub_types: Optional[list[str]] = None) -> None: + def register(cls, type_name: str, class_converter: type[Converter], sub_types: list[str] | None = None) -> None: """ Register Converter instance created from provided Converter class to given type and list of sub types. When sub types are not provided, converter is registered as the default one for given type. @@ -247,7 +247,7 @@ def register(cls, type_name: str, class_converter: type[Converter], sub_types: O registry.register(class_converter(), sub_type) @classmethod - def find_converter(cls, type_name: str, sub_type: Optional[str] = None) -> Converter: + def find_converter(cls, type_name: str, sub_type: str | None = None) -> Converter: """ Find Converter for given type and sub type. diff --git a/packages/gooddata-sdk/src/gooddata_sdk/visualization.py b/packages/gooddata-sdk/src/gooddata_sdk/visualization.py index b4d369d2f..6b00da4db 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/visualization.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/visualization.py @@ -4,7 +4,7 @@ import functools from collections import defaultdict from enum import Enum -from typing import Any, Optional, Union, cast +from typing import Any, Union, cast from gooddata_sdk.client import GoodDataApiClient from gooddata_sdk.compute.model.attribute import Attribute @@ -350,31 +350,31 @@ def local_id(self) -> str: return self._m["localIdentifier"] @property - def alias(self) -> Optional[str]: + def alias(self) -> str | None: return self._m.get("alias") @property - def title(self) -> Optional[str]: + def title(self) -> str | None: return self._m.get("title") @property - def format(self) -> Optional[str]: + def format(self) -> str | None: return self._m.get("format") @property - def item(self) -> Optional[dict[str, Any]]: + def item(self) -> dict[str, Any] | None: return safeget(self._d, ["measureDefinition", "item"]) @property - def aggregation(self) -> Optional[str]: + def aggregation(self) -> str | None: return safeget(self._d, ["measureDefinition", "aggregation"]) @property - def item_id(self) -> Optional[str]: + def item_id(self) -> str | None: return safeget(self.item, ["identifier", "id"]) @property - def item_type(self) -> Optional[str]: + def item_type(self) -> str | None: return safeget(self.item, ["identifier", "type"]) @property @@ -382,7 +382,7 @@ def is_time_comparison(self) -> bool: return "popMeasureDefinition" in self._d or "previousPeriodMeasure" in self._d @property - def time_comparison_master(self) -> Optional[str]: + def time_comparison_master(self) -> str | None: """ If this is a time comparison metric, return local_id of the master metric from which it is derived. @@ -417,7 +417,7 @@ def label_id(self) -> str: return self._a["displayForm"]["identifier"]["id"] @property - def alias(self) -> Optional[str]: + def alias(self) -> str | None: return self._a.get("alias") @property @@ -425,7 +425,7 @@ def label(self) -> dict[str, Any]: return self._a["displayForm"] @property - def show_all_values(self) -> Optional[bool]: + def show_all_values(self) -> bool | None: return self._a.get("showAllValues") def as_computable(self) -> Attribute: @@ -522,7 +522,7 @@ def __init__(self, sort: dict[str, Any]) -> None: sort_keys = list(sort.keys()) sort_key = sort_keys[0] if sort_keys else "" self._sort = sort[sort_key] if sort_key else {} - self._locators: Optional[list[VisualizationSortLocator]] = None + self._locators: list[VisualizationSortLocator] | None = None self.type = _SORT_KEY_TO_SORT_TYPE[sort_key] @property @@ -534,7 +534,7 @@ def attribute_identifier(self) -> str: return self._sort["attributeIdentifier"] if self.type == SortType.ATTRIBUTE else "" @property - def aggregation(self) -> Optional[str]: + def aggregation(self) -> str | None: return self._sort.get("aggregation") @property @@ -565,9 +565,9 @@ def locators(self) -> list[VisualizationSortLocator]: class VisualizationBucket: def __init__(self, bucket: dict[str, Any]) -> None: self._b = bucket - self._metrics: Optional[list[VisualizationMetric]] = None - self._attributes: Optional[list[VisualizationAttribute]] = None - self._totals: Optional[list[VisualizationTotal]] = None + self._metrics: list[VisualizationMetric] | None = None + self._attributes: list[VisualizationAttribute] | None = None + self._totals: list[VisualizationTotal] | None = None self.type = _LOCAL_ID_TO_BUCKET_TYPE[self.local_id] @property @@ -610,13 +610,13 @@ class Visualization: def __init__( self, from_vis_obj: dict[str, Any], - side_loads: Optional[SideLoads] = None, + side_loads: SideLoads | None = None, ) -> None: self._vo = from_vis_obj - self._attribute_filter_configs: Optional[list[VisualizationAttributeFilterConfig]] = None - self._buckets: Optional[list[VisualizationBucket]] = None - self._filters: Optional[list[VisualizationFilter]] = None - self._sorts: Optional[list[VisualizationSort]] = None + self._attribute_filter_configs: list[VisualizationAttributeFilterConfig] | None = None + self._buckets: list[VisualizationBucket] | None = None + self._filters: list[VisualizationFilter] | None = None + self._sorts: list[VisualizationSort] | None = None self._side_loads = SideLoads([]) if side_loads is None else side_loads @property @@ -637,7 +637,7 @@ def are_relations_valid(self) -> str: return self._vo["attributes"].get("areRelationsValid", "true") @property - def attribute_filter_configs(self) -> Optional[list[VisualizationAttributeFilterConfig]]: + def attribute_filter_configs(self) -> list[VisualizationAttributeFilterConfig] | None: visualization_attribute_filter_configs = safeget(self._vo, ["attributes", "content", "attributeFilterConfigs"]) if self._attribute_filter_configs is None and visualization_attribute_filter_configs is not None: self._attribute_filter_configs = [ @@ -706,7 +706,7 @@ def has_row_and_col_totals(self) -> bool: def side_loads(self) -> SideLoads: return self._side_loads - def get_metadata(self, id_obj: IdObjType) -> Optional[Any]: + def get_metadata(self, id_obj: IdObjType) -> Any | None: if not self._side_loads: return None @@ -731,7 +731,7 @@ def get_labels_and_formats(self) -> tuple[dict[str, str], dict[str, str]]: formats[item_values["localIdentifier"]] = item_values["format"] return labels, formats - def get_filters_description(self, labels: dict[str, str], format_locale: Optional[str] = None) -> list[str]: + def get_filters_description(self, labels: dict[str, str], format_locale: str | None = None) -> list[str]: return [f.as_computable().description(labels, format_locale) for f in self.filters] def __str__(self) -> str: @@ -792,7 +792,7 @@ def get_visualizations(self, workspace_id: str) -> list[Visualization]: return [Visualization(vis_obj, side_loads) for vis_obj in vis_objects.data] def get_visualization( - self, workspace_id: str, visualization_id: str, timeout: Optional[Union[int, float, tuple]] = None + self, workspace_id: str, visualization_id: str, timeout: Union[int, float, tuple] | None = None ) -> Visualization: """Gets a single visualization from a workspace. diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_data_source.py b/packages/gooddata-sdk/tests/catalog/test_catalog_data_source.py index ccc6ee09e..67f9f42d0 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_data_source.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_data_source.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from typing import Optional, Union +from typing import Union from unittest import mock from unittest.mock import MagicMock @@ -252,7 +252,7 @@ def _create_default_data_source(sdk: GoodDataSdk, data_source_id: str = "test"): assert expected_data_source == data_source -def _get_data_source(data_sources: list[CatalogDataSource], data_source_id: str) -> Optional[CatalogDataSource]: +def _get_data_source(data_sources: list[CatalogDataSource], data_source_id: str) -> CatalogDataSource | None: for data_source in data_sources: if data_source.id == data_source_id: return data_source @@ -869,8 +869,8 @@ def test_jdbc_urls_creation( db_class: type[CatalogDataSource], attributes: type[DatabaseAttributes], url: str, - parameters: Optional[list], - url_params: Optional[list], + parameters: list | None, + url_params: list | None, ): data_source = db_class( id="test", diff --git a/packages/gooddata-sdk/tests/compute_model/test_compute_model.py b/packages/gooddata-sdk/tests/compute_model/test_compute_model.py index f747af146..1f83f96eb 100644 --- a/packages/gooddata-sdk/tests/compute_model/test_compute_model.py +++ b/packages/gooddata-sdk/tests/compute_model/test_compute_model.py @@ -3,7 +3,6 @@ import json import os -from typing import Optional import pytest from gooddata_sdk.compute.model.attribute import Attribute @@ -90,9 +89,9 @@ def _scenario_to_snapshot_name(scenario: str): @pytest.mark.parametrize("scenario,attributes,metrics,filters", test_inputs) def test_attribute_filters_to_api_model( scenario: str, - attributes: Optional[list[Attribute]], - metrics: Optional[list[Metric]], - filters: Optional[list[Filter]], + attributes: list[Attribute] | None, + metrics: list[Metric] | None, + filters: list[Filter] | None, snapshot, ): # it is essential to define snapshot dir using absolute path, otherwise snapshots cannot be found when diff --git a/packages/tests-support/src/tests_support/vcrpy_utils.py b/packages/tests-support/src/tests_support/vcrpy_utils.py index d645cb433..73450d61f 100644 --- a/packages/tests-support/src/tests_support/vcrpy_utils.py +++ b/packages/tests-support/src/tests_support/vcrpy_utils.py @@ -5,7 +5,7 @@ import os import typing from json import JSONDecodeError -from typing import Any, Optional +from typing import Any import vcr import yaml @@ -88,8 +88,8 @@ def custom_before_request(request, headers_str: str = HEADERS_STR): def custom_before_response( response: dict[str, Any], headers_str: str = HEADERS_STR, - non_static_headers: Optional[list[str]] = None, - placeholder: Optional[list[str]] = None, + non_static_headers: list[str] | None = None, + placeholder: list[str] | None = None, ): if non_static_headers is None: non_static_headers = NON_STATIC_HEADERS