Skip to content

Reference

translate

Source code in metric_transpi/translate.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def to_pulse(m: Metric)-> MetricDefinition:

    definition = MetricDefinition(
        metadata=MetricDefinitionMetadata(
            name=m.name,
            description=m.description,
        ),
        specification=def_spec(
            datasource=datasource(
                id=m.datasource_id
            ),
            basic_specification=basic_spec(
                measure=measure(
                    var_field=m.expression,
                    aggregation=TableauAggregation[m.calculation_method.name].value
                ),
                time_dimension=time_dim(
                    field=m.timestamp,
                )
            ),
            is_running_total=True
        ),
        extension_options=extension(
            allowed_dimensions=m.dimensions,
            allowed_granularities=[TableauGranularity[grain.name].value for grain in m.time_grains]
        ),
        representation_options=representation_opt(),
        insights_options=insights_opt(),
        comparisons=TableauMetricqueryserviceTypesV1Comparisons(
            comparisons=[
                TableauMetricqueryserviceTypesV1ComparisonsComparison(
                    compare_config=TableauMetricqueryserviceTypesV1CompareConfig(
                        comparison='TIME_COMPARISON_PREVIOUS_PERIOD'
                    )
            )]
        )
    ) 
    return definition
Source code in metric_transpi/translate.py
59
60
61
62
63
64
65
66
67
68
69
70
71
def to_dbt(mdf: MetricDefinition)->Metric:
    return Metric(
        name=mdf.metadata.name,
        description=mdf.metadata.description,
        label='',
        model='',
        datasource_id=mdf.specification.datasource.id,
        timestamp=mdf.specification.basic_specification.time_dimension.var_field,
        expression=mdf.specification.basic_specification.measure.var_field,
        time_grains=[TimeGrains[TableauGranularity(grain).name].value for grain in mdf.extension_options.allowed_granularities],
        calculation_method=CalculationMethod[TableauAggregation(mdf.specification.basic_specification.measure.aggregation).name].value,
        dimensions=mdf.extension_options.allowed_dimensions
    )

dbt metrics

Bases: BaseModel

Source code in metric_transpi/dbt.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Metric(BaseModel):
    name: str
    model: str
    label: Optional[str] = None
    description: Optional[str] = None
    datasource_id: Optional[str] = None
    calculation_method: CalculationMethod
    expression: str
    timestamp: str
    time_grains: List[TimeGrains]
    dimensions: List[str]

    def to_dict(self) -> Dict[str, Any]:
        _dict = self.model_dump(
            by_alias=True,
            exclude_none=True,
        )

        return _dict

Tableau metric defintion

Bases: BaseModel

TableauMetricqueryserviceTypesV1Definition

Source code in openapi_client/models/tableau_metricqueryservice_types_v1_definition.py
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
class MetricDefinition(BaseModel):
    """
    TableauMetricqueryserviceTypesV1Definition
    """ # noqa: E501
    metadata: Optional[MetricDefinitionMetadata] = None
    specification: Optional[TableauMetricqueryserviceTypesV1DefinitionSpecification] = None
    extension_options: Optional[TableauMetricqueryserviceTypesV1ExtensionOptions] = None
    metrics: Optional[List[TableauMetricqueryserviceTypesV1Metric]] = None
    total_metrics: Optional[int] = None
    representation_options: Optional[TableauMetricqueryserviceTypesV1RepresentationOptions] = None
    insights_options: Optional[TableauMetricqueryserviceTypesV1InsightsOptions] = None
    comparisons: Optional[TableauMetricqueryserviceTypesV1Comparisons] = None
    __properties: ClassVar[List[str]] = ["metadata", "specification", "extension_options", "metrics", "total_metrics", "representation_options", "insights_options", "comparisons"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of TableauMetricqueryserviceTypesV1Definition from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of metadata
        if self.metadata:
            _dict['metadata'] = self.metadata.to_dict()
        # override the default output from pydantic by calling `to_dict()` of specification
        if self.specification:
            _dict['specification'] = self.specification.to_dict()
        # override the default output from pydantic by calling `to_dict()` of extension_options
        if self.extension_options:
            _dict['extension_options'] = self.extension_options.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in metrics (list)
        _items = []
        if self.metrics:
            for _item_metrics in self.metrics:
                if _item_metrics:
                    _items.append(_item_metrics.to_dict())
            _dict['metrics'] = _items
        # override the default output from pydantic by calling `to_dict()` of representation_options
        if self.representation_options:
            _dict['representation_options'] = self.representation_options.to_dict()
        # override the default output from pydantic by calling `to_dict()` of insights_options
        if self.insights_options:
            _dict['insights_options'] = self.insights_options.to_dict()
        # override the default output from pydantic by calling `to_dict()` of comparisons
        if self.comparisons:
            _dict['comparisons'] = self.comparisons.to_dict()
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of TableauMetricqueryserviceTypesV1Definition from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "metadata": MetricDefinitionMetadata.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None,
            "specification": TableauMetricqueryserviceTypesV1DefinitionSpecification.from_dict(obj["specification"]) if obj.get("specification") is not None else None,
            "extension_options": TableauMetricqueryserviceTypesV1ExtensionOptions.from_dict(obj["extension_options"]) if obj.get("extension_options") is not None else None,
            "metrics": [TableauMetricqueryserviceTypesV1Metric.from_dict(_item) for _item in obj["metrics"]] if obj.get("metrics") is not None else None,
            "total_metrics": obj.get("total_metrics"),
            "representation_options": TableauMetricqueryserviceTypesV1RepresentationOptions.from_dict(obj["representation_options"]) if obj.get("representation_options") is not None else None,
            "insights_options": TableauMetricqueryserviceTypesV1InsightsOptions.from_dict(obj["insights_options"]) if obj.get("insights_options") is not None else None,
            "comparisons": TableauMetricqueryserviceTypesV1Comparisons.from_dict(obj["comparisons"]) if obj.get("comparisons") is not None else None
        })
        return _obj

from_dict(obj) classmethod

Create an instance of TableauMetricqueryserviceTypesV1Definition from a dict

Source code in openapi_client/models/tableau_metricqueryservice_types_v1_definition.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
    """Create an instance of TableauMetricqueryserviceTypesV1Definition from a dict"""
    if obj is None:
        return None

    if not isinstance(obj, dict):
        return cls.model_validate(obj)

    _obj = cls.model_validate({
        "metadata": MetricDefinitionMetadata.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None,
        "specification": TableauMetricqueryserviceTypesV1DefinitionSpecification.from_dict(obj["specification"]) if obj.get("specification") is not None else None,
        "extension_options": TableauMetricqueryserviceTypesV1ExtensionOptions.from_dict(obj["extension_options"]) if obj.get("extension_options") is not None else None,
        "metrics": [TableauMetricqueryserviceTypesV1Metric.from_dict(_item) for _item in obj["metrics"]] if obj.get("metrics") is not None else None,
        "total_metrics": obj.get("total_metrics"),
        "representation_options": TableauMetricqueryserviceTypesV1RepresentationOptions.from_dict(obj["representation_options"]) if obj.get("representation_options") is not None else None,
        "insights_options": TableauMetricqueryserviceTypesV1InsightsOptions.from_dict(obj["insights_options"]) if obj.get("insights_options") is not None else None,
        "comparisons": TableauMetricqueryserviceTypesV1Comparisons.from_dict(obj["comparisons"]) if obj.get("comparisons") is not None else None
    })
    return _obj

from_json(json_str) classmethod

Create an instance of TableauMetricqueryserviceTypesV1Definition from a JSON string

Source code in openapi_client/models/tableau_metricqueryservice_types_v1_definition.py
62
63
64
65
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
    """Create an instance of TableauMetricqueryserviceTypesV1Definition from a JSON string"""
    return cls.from_dict(json.loads(json_str))

to_dict()

Return the dictionary representation of the model using alias.

This has the following differences from calling pydantic's self.model_dump(by_alias=True):

  • None is only added to the output dict for nullable fields that were set at model initialization. Other fields with value None are ignored.
Source code in openapi_client/models/tableau_metricqueryservice_types_v1_definition.py
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def to_dict(self) -> Dict[str, Any]:
    """Return the dictionary representation of the model using alias.

    This has the following differences from calling pydantic's
    `self.model_dump(by_alias=True)`:

    * `None` is only added to the output dict for nullable fields that
      were set at model initialization. Other fields with value `None`
      are ignored.
    """
    excluded_fields: Set[str] = set([
    ])

    _dict = self.model_dump(
        by_alias=True,
        exclude=excluded_fields,
        exclude_none=True,
    )
    # override the default output from pydantic by calling `to_dict()` of metadata
    if self.metadata:
        _dict['metadata'] = self.metadata.to_dict()
    # override the default output from pydantic by calling `to_dict()` of specification
    if self.specification:
        _dict['specification'] = self.specification.to_dict()
    # override the default output from pydantic by calling `to_dict()` of extension_options
    if self.extension_options:
        _dict['extension_options'] = self.extension_options.to_dict()
    # override the default output from pydantic by calling `to_dict()` of each item in metrics (list)
    _items = []
    if self.metrics:
        for _item_metrics in self.metrics:
            if _item_metrics:
                _items.append(_item_metrics.to_dict())
        _dict['metrics'] = _items
    # override the default output from pydantic by calling `to_dict()` of representation_options
    if self.representation_options:
        _dict['representation_options'] = self.representation_options.to_dict()
    # override the default output from pydantic by calling `to_dict()` of insights_options
    if self.insights_options:
        _dict['insights_options'] = self.insights_options.to_dict()
    # override the default output from pydantic by calling `to_dict()` of comparisons
    if self.comparisons:
        _dict['comparisons'] = self.comparisons.to_dict()
    return _dict

to_json()

Returns the JSON representation of the model using alias

Source code in openapi_client/models/tableau_metricqueryservice_types_v1_definition.py
57
58
59
60
def to_json(self) -> str:
    """Returns the JSON representation of the model using alias"""
    # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
    return json.dumps(self.to_dict())

to_str()

Returns the string representation of the model using alias

Source code in openapi_client/models/tableau_metricqueryservice_types_v1_definition.py
53
54
55
def to_str(self) -> str:
    """Returns the string representation of the model using alias"""
    return pprint.pformat(self.model_dump(by_alias=True))

Tableau Cloud

Signin to Tableau Cloud

Parameters:

Name Type Description Default
host str

description

required
site_url_id str

description

required
pat_token_name str

description

required
pat_token_secret str

description

required

Returns:

Name Type Description
token tuple

the API token associated for a session of 1 hour long

site_id tuple

the uid corresponding to the site_url, usefull to query datasources

Source code in metric_transpi/tableau_cloud.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def signin(
        host: str, 
        site_url_id: str, 
        pat_token_name: str, 
        pat_token_secret: str
    )-> tuple:
    """Signin to Tableau Cloud

    Args:
        host (str): _description_
        site_url_id (str): _description_
        pat_token_name (str): _description_
        pat_token_secret (str): _description_

    Returns:
        token: the API token associated for a session of 1 hour long
        site_id: the uid corresponding to the site_url, usefull to query datasources

    """

    headers = {
        'accept': 'application/json',
        'content-type': 'application/json'
    }
    payload = { 
        "credentials": { 
            "personalAccessTokenName": pat_token_name, 
            "personalAccessTokenSecret": pat_token_secret, 
            "site": {"contentUrl": site_url_id }}}

    req = requests.api.post(f"https://{host}/api/3.24/auth/signin", headers=headers, json=payload)
    req.raise_for_status()
    response = json.loads(req.content)
    token = response["credentials"]["token"]
    site_id = response["credentials"]["site"]["id"]

    return (token, site_id)
Source code in metric_transpi/tableau_cloud.py
51
52
53
54
55
56
57
58
59
60
61
62
63
def list_metric(host: str, api_token: str)-> list[MetricDefinition]:
    configuration = openapi_client.Configuration(
        host = host
    )

    with openapi_client.ApiClient(configuration) as api_client:
        # Create an instance of the API class
        api_instance = openapi_client.MetricDefinitionsApi(api_client)
        enable_sorting = True 
        x_tableau_auth = api_token

        api_response = api_instance.metric_query_service_list_definitions(enable_sorting=enable_sorting, x_tableau_auth=x_tableau_auth)
        return api_response.definitions
Source code in metric_transpi/tableau_cloud.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def update_metric(host: str, api_token: str, definition: Metric, definition_id: str)-> MetricDefinition:

    configuration = openapi_client.Configuration(host = host)
    x_tableau_auth = api_token

    with openapi_client.ApiClient(configuration) as api_client:
        api_instance = openapi_client.MetricDefinitionsApi(api_client)
        api_response = api_instance.metric_query_service_update_definition(
            definition_id=definition_id,
            x_tableau_auth=x_tableau_auth, 
            tableau_metricqueryservice_v1_update_definition_request=update_request(
                definition_id=definition_id,
                name=definition.metadata.name,
                description=definition.metadata.description,
                specification=definition.specification,
                insights_options=definition.insights_options,
                extension_options=definition.extension_options,
                representation_options=definition.representation_options,
                comparisons=definition.comparisons,
            )
        )
        return api_response.definition