-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add
TM1
source and Prefect tasks (#1105)
* 🚀 Added tm1 source * ⚡️ Updated tm1 source * ✨ Added tm1 task * ✨ Added tm1 prefect flow * ♻️ Refactor structure * ✅ Add unit tests * 📝 Update docs * ♻️ Refactor code * ♻️ Refactor code * ⚡️ Improved logic * ➕ Added tm1py
- Loading branch information
Showing
10 changed files
with
482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
"""Flow for downloading data from TM1 to a Parquet file.""" | ||
|
||
from typing import Literal | ||
|
||
from prefect import flow | ||
|
||
from viadot.orchestration.prefect.tasks.task_utils import df_to_parquet | ||
from viadot.orchestration.prefect.tasks.tm1 import tm1_to_df | ||
|
||
|
||
@flow( | ||
name="extract--tm1--parquet", | ||
description="Extract data from TM1 and load it into Parquet file", | ||
retries=1, | ||
retry_delay_seconds=60, | ||
) | ||
def tm1_to_parquet( # noqa: PLR0913 | ||
path: str | None = None, | ||
mdx_query: str | None = None, | ||
cube: str | None = None, | ||
view: str | None = None, | ||
limit: int | None = None, | ||
private: bool = False, | ||
credentials_secret: str | None = None, | ||
config_key: str | None = None, | ||
if_empty: str = "skip", | ||
if_exists: Literal["append", "replace", "skip"] = "replace", | ||
verify: bool = True, | ||
) -> None: | ||
"""Download data from TM1 to a Parquet file. | ||
Args: | ||
mdx_query (str, optional): MDX select query needed to download the data. | ||
Defaults to None. | ||
cube (str, optional): Cube name from which data will be downloaded. | ||
Defaults to None. | ||
view (str, optional): View name from which data will be downloaded. | ||
Defaults to None. | ||
limit (str, optional): How many rows should be extracted. | ||
If None all the available rows will be downloaded. Defaults to None. | ||
private (bool, optional): Whether or not data download should be private. | ||
Defaults to False. | ||
credentials_secret (dict[str, Any], optional): The name of the secret that | ||
stores TM1 credentials. | ||
More info on: https://docs.prefect.io/concepts/blocks/. Defaults to None. | ||
config_key (str, optional): The key in the viadot config holding relevant | ||
credentials. Defaults to "TM1". | ||
if_empty (str, optional): What to do if output DataFrame is empty. | ||
Defaults to "skip". | ||
if_exists (Literal["append", "replace", "skip"], optional): | ||
What to do if the table exists. Defaults to "replace". | ||
verify (bool, optional): Whether or not verify SSL certificate. | ||
Defaults to False. | ||
""" | ||
df = tm1_to_df( | ||
mdx_query=mdx_query, | ||
cube=cube, | ||
view=view, | ||
limit=limit, | ||
private=private, | ||
credentials_secret=credentials_secret, | ||
config_key=config_key, | ||
verify=verify, | ||
if_empty=if_empty, | ||
) | ||
return df_to_parquet( | ||
df=df, | ||
path=path, | ||
if_exists=if_exists, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
"""Task for downloading data from TM1 to a pandas DataFrame.""" | ||
|
||
from pandas import DataFrame | ||
from prefect import task | ||
from prefect.logging import get_run_logger | ||
|
||
from viadot.config import get_source_credentials | ||
from viadot.orchestration.prefect.exceptions import MissingSourceCredentialsError | ||
from viadot.orchestration.prefect.utils import get_credentials | ||
from viadot.sources.tm1 import TM1 | ||
|
||
|
||
@task(retries=3, retry_delay_seconds=10, timeout_seconds=60 * 60 * 3) | ||
def tm1_to_df( | ||
mdx_query: str | None = None, | ||
cube: str | None = None, | ||
view: str | None = None, | ||
limit: int | None = None, | ||
private: bool = False, | ||
credentials_secret: str | None = None, | ||
config_key: str | None = None, | ||
verify: bool = False, | ||
if_empty: str = "skip", | ||
) -> DataFrame: | ||
"""Download data from TM1 to pandas DataFrame. | ||
Args: | ||
mdx_query (str, optional): MDX select query needed to download the data. | ||
Defaults to None. | ||
cube (str, optional): Cube name from which data will be downloaded. | ||
Defaults to None. | ||
view (str, optional): View name from which data will be downloaded. | ||
Defaults to None. | ||
limit (str, optional): How many rows should be extracted. | ||
If None all the available rows will be downloaded. Defaults to None. | ||
private (bool, optional): Whether or not data download should be private. | ||
Defaults to False. | ||
credentials_secret (dict[str, Any], optional): The name of the secret that | ||
stores TM1 credentials. | ||
More info on: https://docs.prefect.io/concepts/blocks/. Defaults to None. | ||
config_key (str, optional): The key in the viadot config holding relevant | ||
credentials. Defaults to "TM1". | ||
verify (bool, optional): Whether or not verify SSL certificate. | ||
Defaults to False. | ||
if_empty (str, optional): What to do if output DataFrame is empty. | ||
Defaults to "skip". | ||
""" | ||
if not (credentials_secret or config_key): | ||
raise MissingSourceCredentialsError | ||
|
||
logger = get_run_logger() | ||
|
||
credentials = get_source_credentials(config_key) or get_credentials( | ||
credentials_secret | ||
) | ||
|
||
bc = TM1( | ||
credentials=credentials, | ||
config_key=config_key, | ||
limit=limit, | ||
private=private, | ||
verify=verify, | ||
) | ||
|
||
df = bc.to_df( | ||
if_empty=if_empty, | ||
mdx_query=mdx_query, | ||
cube=cube, | ||
view=view, | ||
) | ||
|
||
nrows = df.shape[0] | ||
ncols = df.shape[1] | ||
|
||
logger.info( | ||
f"Successfully downloaded {nrows} rows and {ncols} columns of data to a DataFrame." | ||
) | ||
|
||
return df |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.