Pyplan Functions
This page provides detailed technical information about the functions available in the Pyplan API. Each function is crafted to perform specific operations essential for managing and interacting with Pyplan services.
To access and utilize these functions, prefix them with pp. in your code. For example, to initiate a file upload, use pp.upload().
The documentation below outlines the purpose of each function, describes the parameters and return types, and provides usage examples. This will help you integrate and leverage Pyplan functionalities efficiently in your workflows.
Pyplan node types
This section outlines the functions related to different node types in Pyplan. These functions help in creating and configuring various types of nodes, such as selectors, forms, and input cubes.
selector
selector(options, selected, multiselect = False, save_selected_labels = False, node_identifier = None)
Creates a UI Pyplan selector for decision nodes.
Parameters
- options (
Union[List[Any], pd.Index]): List or pandas Index with values that can be selected. - selected (
Union[int, List[int], List[Union[str, int, float]]]): Current selected value or values. - multiselect (
bool, optional): Whether to allow multiple selection. Defaults toFalse. - save_selected_labels (
bool, optional): IfFalse(default), saves selected indexes inselectedparameter. Otherwise, saves the actual selected value (string, integer, float). - node_identifier (
str, optional): ID of node that holds the definition for the selector. Mandatory ifsave_selected_labelsisTrue. Best option is addingself.identifierfor this param (without quotes). - persistence_type (
PersistenceType, optional): One of the following options: 'in_definition', 'in_memory' or 'on_disk'. Defaults toin_definition. - persistence_params (
Dict[str, Any], optional): Additional params for the different persistence_type values. Ifpersistence_typeison_disk, thepath(str) param must be supplied.
Returns
- Selector: Pyplan Selector object.
Examples
>>> options = ["option1", "option2", "option3"]
>>> selected = 1
>>> selector = pp.selector(options, selected)
>>> options = ["option1", "option2", "option3"]
>>> selected = ["option2", "option3"]
>>> selector = pp.selector(
options,
selected,
multiselect=True,
save_selected_labels=True,
node_identifier=self.identifier
)
>>> selector = pp.selector(
["Brand A", "Brand B"],
[],
multiselect=True,
persistence_type="on_disk",
persistence_params={"path": "selectors_data/brands.json"}
)
form
form(table_name, columns, settings)
Creates a UI Pyplan form with the given table name, columns, and settings.
Args
- table_name (str): The name of the table to be displayed in the form.
- columns (List[FormColumn]): A list of FormColumn objects that define the columns to be displayed in the form.
- settings (FormSettings, optional): An object containing settings for the form, such as default values and validation rules. Defaults to None.
Returns
- Form: An instance of the Form class.
Example
>>> pp.form(
table_name='node1',
columns=[
FormColumn(field='column1', title='column1', column_type=ColumnType.input, data_type=DataType.string, nested_headers=['header1', 'header2']),
FormColumn(field='column2', title='column2', column_type=ColumnType.input, data_type=DataType.string),
FormColumn(field='column3', title='column3', column_type=ColumnType.input, data_type=DataType.string)
],
settings=FormSettings(database_engine=DatabaseConnectionString.sqlite, database_connection=SQLiteConnection(database_path='forms_data/forms.db'))
)
FormColumn:
Dataclass with all accepted parameters for a form column.
- field (str): name of the field in the database table.
- title (str): label that will be displayed in the form.
- data_type (DataType): data type of the column in the database table.
- column_type (ColumnType): column variant for the form.
- default_value (Any): value to insert when adding new rows.
- hidden (bool): hides the column when editing the form.
- read_only (bool): prevents editing the column in the form.
- change_validation_function (Callable[[Any, str, Union[int, str], pd.DataFrame], tuple[bool, str]]): Optional validation function that runs upon applying a change to a cell in the column. It receives a 'value', 'column_name', 'row_id' and a pandas DataFrame ('df') as parameters and must return a tuple (bool, str), where the boolean indicates whether the validation was successful (True) or failed (False), and the string contains a message to display after applying the change. Example:
>>> from typing import Any, Union
QUANTITIES_THRESHOLD = 300
def _quantities_change_validation_fn(
value: Any, column_name: str, row_id: Union[int, str], df: pd.DataFrame
) -> tuple[bool, str]:
"""Validates the given value against a predefined maximum threshold.
Args:
value (Any): The value to be validated.
column_name (str): The name of the column where the value is located.
row_id (Union[int, str]): The identifier of the row containing the value.
df (pd.DataFrame): The DataFrame with the current state of the form.
Returns:
tuple[bool, str]: A tuple where the first element is a boolean indicating
whether the value is valid, and the second element is a message to display after the validation.
"""
if value > QUANTITIES_THRESHOLD:
return (
False,
f'Invalid value {value}. The maximum value is {QUANTITIES_THRESHOLD}',
)
return True, ''
- formula (str or function): for
ColumnType.calconly.- When
formulais a string, it evaluates a string describing operations on form columns. See: pandas.DataFrame.eval. - When
formulais a function, it passes the form DataFrame to the function as an argument.
- When
- values (List): for
ColumnType.selectoronly. List of values to display in the selector for the entire column. - filter_rows_by_domain (bool): for
ColumnType.selectoronly. WhenTrue, displayed rows of the form will be filtered by the available elements in thevalueslist parameter. - related_map (pd.DataFrame or pp.Form): for
ColumnType.related_selectoronly. DataFrame with related columns allocation. - related_map_column_values (str): for
ColumnType.related_selectoronly. Name of the column inrelated_mapthat has the values to be displayed in the selector. - related_columns (str or List[str]): Name or list of names of columns in
related_mapthat will filter the results of therelated_map_column_valuescolumn. These columns should be present in the form as field names and inrelated_mapas columns. - nested_headers (List[str]): List of headers to display in nested columns. For example,
['header1', 'header2']will display a column withheader1as a child andheader2as a parent. It's important to note that this is a nested structure, so children cannot be wider than parents. If so, headers andnested_headerswill not be rendered. - strict (bool): for
ColumnType.selectorandColumnType.related_selectoronly. WhenTrue, it only allows values that are defined as options in the selector. - multiselect (bool): for
ColumnType.selectorandColumnType.related_selectoronly. WhenTrue, it allows selecting multiple values in the selector. - count_values_to_render (int): for
ColumnType.selectorandColumnType.related_selectoronly. WhenmultiselectisTrue, this integer will be used to limit the number of values rendered in the selector. Defaults to1.
FormSettings
Dataclass with all accepted parameters for form settings.
- database_engine (DatabaseConnectionString): one of
'sqlite','postgresql', or'custom'. - database_connection (Union[SQLiteConnection, EncryptedSQLiteConnection, PostgreSQLConnection]): connection parameters for the given database engine.
- confirm_validation_function (Callable[[pd.DataFrame], tuple[bool, str]]): Optional validation function that runs upon confirmation. It receives a pandas DataFrame ('df') as a parameter and must return a tuple (bool, str), where the boolean indicates whether the validation was successful (True) or failed (False), and the string contains a message to display after confirmation. Example:
>>> QUANTITY_TOTAL_SUM_THRESHOLD = 1200
PRICE_MEAN_THRESHOLD = 15.0
def _confirm_validation_fn(df: pd.DataFrame) -> tuple[bool, str]:
"""Validates whether the total sum of the 'quantity' column and the average of
the 'price' column meet the defined constraints.
Args:
df (pd.DataFrame): The DataFrame with the current state of the form.
Returns:
tuple[bool, str]: A tuple where the first element is a boolean indicating
whether the DataFrame meets the validation criteria, and the second element
is an error message if the validation fails.
"""
quantity_total_sum = df['quantity'].sum().item(0)
if not quantity_total_sum <= QUANTITY_TOTAL_SUM_THRESHOLD:
return (
False,
f'The total sum of Quantity must be {QUANTITY_TOTAL_SUM_THRESHOLD} or less. Current total: {quantity_total_sum}',
)
price_mean = df['price'].mean().item(0)
if not price_mean <= PRICE_MEAN_THRESHOLD:
return (
False,
f'The average Price must be {PRICE_MEAN_THRESHOLD} or less. Current average: {price_mean}',
)
return True, ''
- database_custom_url (str): database connection URL for a custom database engine.
- initial_empty_rows (int): number of rows to display when the form is created.
- allow_add_rows (bool): allows inserting new rows.
- allow_remove_rows (bool): allows removing existing rows.
- allow_add_new_columns (bool): if set to
True, creates new columns in the table if a new column is found after the form was created. Otherwise, raises aValueError. - fixed_columns (int): number of columns to fix when scrolling the form horizontally.
- from_dataframe (bool): if set to
True, every row in the form is originated in a given pandas DataFrame object. - source_dataframe_node (pd.DataFrame): used when
from_dataframeisTrueonly. Pandas DataFrame object that will be the source of every row in the form. - source_dataframe_id_column (str): used when
from_dataframeisTrueonly. Column name insource_dataframe_nodeDataFrame that will be used to uniquely identify rows in the form. - remove_old_rows (str): used when
from_dataframeisTrueonly. When set toTrue, it deletes rows where its ID column value was previously stored in the database but is not currently present in the source pandas DataFrame.
input_cube
input_cube(table_name, dimensions, settings)
Creates a UI Pyplan InputCube with the given table name, dimensions, and settings.
Args
- table_name (str): The name of the table to be displayed in the InputCube.
- dimensions (List[InputCubeDimension]): A list of InputCubeDimension objects defining the dimensions to be displayed in the InputCube.
- settings (InputCubeSettings, optional): An object containing settings for the InputCube, such as default values and validation rules. Defaults to None.
Returns
- InputCube: An instance of the InputCube class.
Example
>>> pp.input_cube(
table_name='sales',
dimensions=[
InputCubeDimension(field='regions', name=regions.node.identifier),
InputCubeDimension(field='item_types', name=item_types.node.identifier)
],
settings=InputCubeSettings(
data_type=DataType.float,
default_value_type=DefaultValueType.scalar,
default_value=0.0,
database_engine=DatabaseConnectionString.sqlite,
database_connection=SQLiteConnection(database_path='inputs_data/input_cubes.db')
)
)
InputCubeDimension
Dataclass with all accepted parameters for an InputCube dimension.
- field (str): name of the field that will be saved in the database.
- name (str): name of the dimension. Must be a node identifier corresponding to a pandas Index.
InputCubeSettings
Dataclass with all accepted parameters for InputCube settings.
- database_engine (DatabaseConnectionString): one of
'sqlite','postgresql', or'custom'. - database_connection (Union[SQLiteConnection, EncryptedSQLiteConnection, PostgreSQLConnection]): connection parameters for the given database engine.
- database_custom_url (str): database connection URL for a custom database engine.
- confirm_validation_function (Callable[[pd.DataFrame], tuple[bool, str]]): Optional validation function that runs upon confirmation. It receives a pandas DataFrame ('df') as a parameter and must return a tuple (bool, str), where the boolean indicates whether the validation was successful (True) or failed (False), and the string contains a message to display after confirmation.
- data_type (DataType): data type of every value in the table.
- default_value_type (DefaultValueType): one of
'scalar','app_node'. - default_value (Union[float, int, str]): value to be set by default. If
default_value_typeis'scalar', it can befloat,int, orstr. If it is'app_node', it must be astrwith the node identifier from which its result will be taken as a default value. - remove_non_existing_combinations (bool): if
True, removes any combination of dimensions that is not present in the actual set of combinations from given dimensions. - allow_dimension_changes (bool): if
False, raises an error when a new dimension is added or removed.
Process
Functions related to process management within Pyplan allow you to retrieve and manage processes, including their statuses and updates.
get_all_processes
get_all_processes(in_progress_only = True)
Returns a list of all processes available in the current application.
Parameters
- in_progress_only (
bool, optional): Whether to include In progress processes only (True) or all process statuses (Stopped,In Progress, andCompleted). Defaults toTrue.
Returns
- List[Dict]: A list of dictionaries with the following structure:
[
{
"id": 1,
"name": "Process A",
"description": "",
"status": {
"id": 2,
"name": "In progress",
"color": "#ff7f0e",
"status_type": "in_progress"
},
"start_date": "2023-08-01T14:10:50+0000",
"end_date": None,
"subscribers": [
{
"id": "1b23133b-a005-4a28-9768-7eb3a0ec2555",
"username": "app_administrator",
"first_name": "App",
"last_name": "Administrator"
}
],
"groups": [
{
"id": 2,
"name": "Demand Planning",
"position": 1,
"tasks": [
{
"id": 2,
"name": "Historical Analysis",
"description": "",
"action_type": "open_interface",
"action_data": "d64d9487-83bb-46ce-9dfb-d7e48144fb07",
"responsible": {
"id": "dbc28680-0a42-4aeb-a2cc-ddf5829f3b2c",
"username": "viewer_user",
"first_name": "Viewer",
"last_name": "User"
},
"status": {
"id": 2,
"name": "In progress",
"color": "#ff7f0e",
"status_type": "in_progress"
},
"due_days": 2,
"due_hours": 0,
"due_minutes": 0,
"due_type": {
"id": "2",
"name": "since_blocking_task_completed"
},
"is_delayed": False,
"subscribers": [],
"is_blocked_by": [1],
"reviewers": [
{
"id": "1b23133b-a005-4a28-9768-7eb3a0ec2555",
"username": "app_administrator",
"first_name": "App",
"last_name": "Administrator"
}
],
"comments": [],
"finished": None,
"reviewer_interface": "d64d9487-83bb-46ce-9dfb-d7e48144fb07"
},
{
"id": 4,
"name": "Baseline Forecast",
"description": "",
"action_type": "open_interface",
"action_data": "99721db0-b967-4f99-a39c-40a78e3ed19a",
"responsible": {
"id": "dbc28680-0a42-4aeb-a2cc-ddf5829f3b2c",
"username": "viewer_user",
"first_name": "Viewer",
"last_name": "User"
},
"status": {
"id": 5,
"name": "Not ready to start",
"color": "#e6e6fa",
"status_type": "not_ready_to_start"
},
"due_days": 2,
"due_hours": 0,
"due_minutes": 0,
"due_type": {
"id": "2",
"name": "since_blocking_task_completed"
},
"is_delayed": False,
"subscribers": [],
"is_blocked_by": [2],
"reviewers": [
{
"id": "1b23133b-a005-4a28-9768-7eb3a0ec2555",
"username": "app_administrator",
"first_name": "App",
"last_name": "Administrator"
}
],
"comments": [],
"finished": None,
"reviewer_interface": "5a61034d-98f2-4716-84cb-1ce6eb110982"
},
]
}
],
"is_delayed": False
},
{
"id": 2,
"name": "Process B",
"description": "",
"status": {
"id": 2,
"name": "In progress",
"color": "#ff7f0e",
"status_type": "in_progress"
},
"start_date": "2023-08-16T14:53:07+0000",
"end_date": None,
"subscribers": [
{
"id": "4107a468-ba9a-4843-b3bb-1961ce665313",
"username": "app_administrator2",
"first_name": "App",
"last_name": "Administrator 2"
}
],
"groups": [
{
"id": 3,
"name": "Supply Planning",
"position": 0,
"tasks": [
{
"id": 7,
"name": "Production Plan",
"description": "",
"action_type": "open_interface",
"action_data": "3abf4d4a-ab24-4b29-8e92-2add9bdef422",
"responsible": {
"id": "dbc28680-0a42-4aeb-a2cc-ddf5829f3b2c",
"username": "viewer_user",
"first_name": "Viewer",
"last_name": "User"
},
"status": {
"id": 4,
"name": "Completed",
"color": "#127517",
"status_type": "completed"
},
"due_days": 2,
"due_hours": 0,
"due_minutes": 0,
"due_type": {
"id": "1",
"name": "since_process_starts"
},
"is_delayed": False,
"subscribers": [],
"is_blocked_by": [],
"reviewers": [],
"comments": [],
"finished": "2023-08-23T15:10:50+0000",
"reviewer_interface": ""
},
],
}
],
"is_delayed": False
}
]
Example
result = pp.get_all_processes()
get_my_processes
get_my_processes(in_progress_only = True)
Returns a list of all processes in which the current user is involved. A user is considered involved in a process if any of the following conditions are met: a) The user is a subscriber to the process. b) The user is responsible for a task within the process. c) The user is a subscriber or reviewer for a task within the process.
If condition a) is met, the function will return all tasks associated with the process. If either condition b) or c) is met, the function will only return tasks for which the user is responsible, a subscriber, or a reviewer.
Parameters
- in_progress_only (
bool, optional): Whether to include In progress processes only (True) or all process statuses (Stopped,In Progress, andCompleted). Defaults toTrue.
Returns
- List[Dict]: A list of dictionaries with the following structure:
[
{
"id": 1,
"name": "Process A",
"description": "",
"status": {
"id": 2,
"name": "In progress",
"color": "#ff7f0e",
"status_type": "in_progress"
},
"start_date": "2023-08-01T14:10:50+0000",
"end_date": None,
"subscribers": [
{
"id": "1b23133b-a005-4a28-9768-7eb3a0ec2555",
"username": "app_administrator",
"first_name": "App",
"last_name": "Administrator"
}
],
"groups": [
{
"id": 2,
"name": "Demand Planning",
"position": 1,
"tasks": [
{
"id": 2,
"name": "Historical Analysis",
"description": "",
"action_type": "open_interface",
"action_data": "d64d9487-83bb-46ce-9dfb-d7e48144fb07",
"responsible": {
"id": "dbc28680-0a42-4aeb-a2cc-ddf5829f3b2c",
"username": "viewer_user",
"first_name": "Viewer",
"last_name": "User"
},
"status": {
"id": 2,
"name": "In progress",
"color": "#ff7f0e",
"status_type": "in_progress"
},
"due_days": 2,
"due_hours": 0,
"due_minutes": 0,
"due_type": {
"id": "2",
"name": "since_blocking_task_completed"
},
"is_delayed": False,
"subscribers": [],
"is_blocked_by": [1],
"reviewers": [
{
"id": "1b23133b-a005-4a28-9768-7eb3a0ec2555",
"username": "app_administrator",
"first_name": "App",
"last_name": "Administrator"
}
],
"comments": [],
"finished": None,
"reviewer_interface": "d64d9487-83bb-46ce-9dfb-d7e48144fb07"
},
{
"id": 4,
"name": "Baseline Forecast",
"description": "",
"action_type": "open_interface",
"action_data": "99721db0-b967-4f99-a39c-40a78e3ed19a",
"responsible": {
"id": "dbc28680-0a42-4aeb-a2cc-ddf5829f3b2c",
"username": "viewer_user",
"first_name": "Viewer",
"last_name": "User"
},
"status": {
"id": 5,
"name": "Not ready to start",
"color": "#e6e6fa",
"status_type": "not_ready_to_start"
},
"due_days": 2,
"due_hours": 0,
"due_minutes": 0,
"due_type": {
"id": "2",
"name": "since_blocking_task_completed"
},
"is_delayed": False,
"subscribers": [],
"is_blocked_by": [2],
"reviewers": [
{
"id": "1b23133b-a005-4a28-9768-7eb3a0ec2555",
"username": "app_administrator",
"first_name": "App",
"last_name": "Administrator"
}
],
"comments": [],
"finished": None,
"reviewer_interface": "5a61034d-98f2-4716-84cb-1ce6eb110982"
},
]
}
],
"is_delayed": False
},
{
"id": 2,
"name": "Process B",
"description": "",
"status": {
"id": 2,
"name": "In progress",
"color": "#ff7f0e",
"status_type": "in_progress"
},
"start_date": "2023-08-16T14:53:07+0000",
"end_date": None,
"subscribers": [
{
"id": "4107a468-ba9a-4843-b3bb-1961ce665313",
"username": "app_administrator2",
"first_name": "App",
"last_name": "Administrator 2"
}
],
"groups": [
{
"id": 3,
"name": "Supply Planning",
"position": 0,
"tasks": [
{
"id": 7,
"name": "Production Plan",
"description": "",
"action_type": "open_interface",
"action_data": "3abf4d4a-ab24-4b29-8e92-2add9bdef422",
"responsible": {
"id": "dbc28680-0a42-4aeb-a2cc-ddf5829f3b2c",
"username": "viewer_user",
"first_name": "Viewer",
"last_name": "User"
},
"status": {
"id": 4,
"name": "Completed",
"color": "#127517",
"status_type": "completed"
},
"due_days": 2,
"due_hours": 0,
"due_minutes": 0,
"due_type": {
"id": "1",
"name": "since_process_starts"
},
"is_delayed": False,
"subscribers": [],
"is_blocked_by": [],
"reviewers": [],
"comments": [],
"finished": "2023-08-23T15:10:50+0000",
"reviewer_interface": ""
},
],
}
],
"is_delayed": False
}
]
Example
result = pp.get_my_processes()
get_task_statuses
get_task_statuses()
Summary
Returns a list of dictionaries containing all available statuses.
Returns
- list of dicts: Returns a list of dictionaries with the following structure:
[
{'id': 1, 'name': 'Not started', 'color': '#a7a7a7', 'status_type': 'not_started'},
{'id': 2, 'name': 'In progress', 'color': '#ff7f0e', 'status_type': 'in_progress'},
{'id': 3, 'name': 'Pending review', 'color': '#FFC400', 'status_type': 'pending_review'},
{'id': 4, 'name': 'Completed', 'color': '#127517', 'status_type': 'completed'},
{'id': 5, 'name': 'Not ready to start', 'color': '#e6e6fa', 'status_type': 'not_ready_to_start'},
]
Example
Copy code
result = pp.get_task_statuses()
change_task_status
change_task_status(task_id, new_task_status_id)
Summary
Updates the status of a given task.
Args
- task_id: (int) ID of the task to update.
- new_task_status_id: (int) ID of the desired status type to set. Reference values (use
pp.get_task_statuses()for more statuses):- 1: Not started
- 2: In progress
- 3: Pending review
- 4: Completed
- 5: Not ready to start
Returns
- bool
Example
result = pp.change_task_status(task_id=3, new_task_status_id=2)
update_process
update_process(process_id, data)
Summary
Updates the properties of a given process.
Args
- process_id: (int) ID of the process to update.
- data: (dict) Dictionary with the properties to update as keys and the new values as values. Available properties:
- name (str): name of the process.
- description (str): Description of the process.
- start_date (date): Start date of the process.
- end_date (date): End date of the process.
- status (dict): Status of the process. Get a list of the available statuses with 'pp.get_process_statuses()'.
- groups (list[dict]): List of groups to update or create, where each group can include:
- id (int, optional): ID of the group to update.
- name (str): Name of the group.
- position (int, optional): Position of the group (for new groups).
- tasks (list[dict]): List of tasks within the group, where each task can include:
- id (int, optional): ID of the task to update.
- name (str): Name of the task.
- description (str): Description of the task.
- action_type (str): Type of action associated with the task.
- action_data (str): Data related to the action.
- responsible (int): ID of the user responsible for the task.
- due_days (int): Number of due days for the task.
- due_type (str): Type of due date.
- status (dict): Status of the task. Requires a key 'id' with the status ID.
- reviewer_interface (str): Reviewer interface configuration.
- is_blocked_by (list[int]): List of task IDs that block this task.
- reviewers (list[int]): List of user IDs as reviewers for the task.
- subscribers (list[int]): List of user IDs subscribed to the task.
- tasks_to_delete (list[int]): List of task IDs to delete.
- subscribers (list[int]): List of user IDs subscribed to the process.
Returns
- bool
Example
import datetime
new_data = {
'end_date': datetime.datetime.now(),
'status': {
'id': 3,
'name': 'Completed',
'color': '#127517',
'status_type': 'completed'
}
}
result = pp.update_process(process_id=2, data=new_data)
Scheduled tasks
This subsection contains functions related to the management and monitoring of scheduled tasks within Pyplan. These functions allow you to log task activity, initiate the execution of scheduled tasks, and retrieve logs to monitor task progress and outcomes.
log_task
log_task(task_state, task_description, task_activity, task_info)
Generates a log entry. Used for scheduled tasks.
Parameters
- task_state (
str): State of the task. It can be one of the following: 'PROGRESS', 'INFO', 'WARNING', 'FAILURE', 'RETRY', 'SUCCESS', 'REVOKED', 'STARTED', 'PENDING', 'RECEIVED'. - task_description (
str): Short description of the task. Example: 'start process'. - task_activity (
str): Additional short description. - task_info (
dict): JSON containing more information about the task. Keys should be strings and values can be strings or integers.
Returns
- requests.Response: The response of the API call.
Example
>>> import requests
>>> pp.log_task(task_state='SUCCESS', task_description='Process finished', task_activity='Data import',
task_info={'imported_rows': 100})
run_scheduled_task
run_scheduled_task(task_id, version, notification_emails=None)
Summary
Initiates the execution of a scheduled task.
Args
- task_id: (int) ID of the task to initiate.
- version: (str) Version of the application to run. If not provided, it will run the version that was set for the task.
- notification_emails: (List[str]): Optional list of recipient emails. If None or an empty list, task default notification users will be used.
Returns
- str: "OK" if the task started executing successfully.
Raises
- ValueError: If
task_idis not a positive integer. - Exception: If there's an issue initiating the task execution.
Examples
>>> result = pp.run_scheduled_task(task_id=3)
>>> result = pp.run_scheduled_task(task_id=2, version='7+5')
>>> result = pp.run_scheduled_task(task_id=2, notification_emails=['user@company.com'])
get_scheduled_task_logs
get_scheduled_task_logs(task_id, result_size=50, task_details=True)
Summary
Retrieves the logs/messages of a scheduled task.
Args
- task_id: (int) ID of the task to retrieve logs for.
- result_size: (int) Number of log messages to retrieve (default is 50).
- task_details: (bool) Whether to include detailed information about the task (default is True).
Returns
- List[dict]: List of dictionaries containing the latest 'result_size' log messages.
Structure with task_details=True:
[
{
"id": "32ed40e6-d98b-43f7-a192-581107892f3b",
"state": "INFO",
"params": null,
"task_logs": [
{
"id": "b704722b-77d8-4bf6-8687-46074a201225",
"state": "RECEIVED",
"is_running": false,
"description": "Start Job",
"activity": null,
"created_at": "2024-03-26T17:41:45+0000",
"updated_at": "2024-03-26T17:41:45+0000",
"info": {
"params": {
"param1": "0"
},
"node_id": "a1millonfilas",
"version": null,
"app_path": "pyplan/admin/Analisis de datos 1"
},
"periodic_task_log": "c3d70913-d6a9-4d12-9327-a8a0e2c191cd"
},
{
"id": "06c27e3c-a850-4954-bf88-e6fe26a2eeae",
"state": "PROGRESS",
"is_running": false,
"description": "Application successfully opened",
"activity": null,
"created_at": "2024-03-26T17:41:47+0000",
"updated_at": "2024-03-26T17:41:47+0000",
"info": {},
"periodic_task_log": "c3d70913-d6a9-4d12-9327-a8a0e2c191cd"
},
{
"id": "021d79b5-fb69-43b5-bee7-3b1f56a52caf",
"state": "INFO",
"is_running": false,
"description": "Checking Existence",
"activity": null,
"created_at": "2024-03-26T17:41:47+0000",
"updated_at": "2024-03-26T17:41:47+0000",
"info": {
"Existence": "Node a1millonfilas does exists"
},
"periodic_task_log": "c3d70913-d6a9-4d12-9327-a8a0e2c191cd"
},
{
"id": "060fc7e7-d90b-48aa-af5a-3b9c710e945b",
"state": "INFO",
"is_running": false,
"description": "Node run started",
"activity": null,
"created_at": "2024-03-26T17:41:47+0000",
"updated_at": "2024-03-26T17:41:47+0000",
"info": {},
"periodic_task_log": "c3d70913-d6a9-4d12-9327-a8a0e2c191cd"
}
],
"created_at": "2024-03-26T12:58:42+0000",
"task_id": "0ecea047-bc4b-4129-adf7-802091b5a969",
"periodic_task": 11
},
{
"id": "8e8b5287-057b-4041-a8fe-4ba6a69bfcf0",
"state": "INFO",
"params": {
"param1": "12"
},
"created_at": "2024-03-26T13:06:16+0000",
"task_id": "b8274630-f4fd-41bb-b59e-2c75e579dc8a",
"periodic_task": 11
},
]
Structure with task_details=False:
[
{
"id": "8e8b5287-057b-4041-a8fe-4ba6a69bfcf0",
"state": "INFO",
"params": {
"param1": "12"
},
"created_at": "2024-03-26T13:06:16+0000",
"task_id": "b8274630-f4fd-41bb-b59e-2c75e579dc8a",
"periodic_task": 11
},
]
Raises
- ValueError: If task_id is not a positive integer.
- Exception: If there's an issue retrieving the task logs.
Example
logs = pp.get_scheduled_task_logs(task_id=3, result_size=20, task_details=True)
Agents
The Agents functions allow you to interact with and configure an AI agent within your application.
agent_chat
agent_chat(agent_code, chat_message, chat_session_id, metadata=None, context=None)
Summary
Chat with an AI agent.
Args
- agent_code: (str) Agent code.
- chat_message: (str) Message to be sent to the agent.
- chat_session_id: (str) ID of the chat session.
- metadata: (Optional[Dict]) Metadata to be used by the agent.
- context: (Optional[Dict]) Context to be used by the agent.
Returns
- Any: What the agent is configured to reply.
Example
result = pp.agent_chat(
agent_code=agent_node.code,
chat_message='Hello',
chat_session_id='ab12345'
)
Assistant bots
The Assistant Bot functions allow you to interact with and configure a virtual assistant within your application. You can update the assistant's parameters, such as its name, description, and behavior, or initiate conversations by sending messages to it. This functionality is designed to enhance the user experience by providing customizable AI-driven assistance within your applications.
update_application_assistant
update_application_assistant(assistant_id, engine_type, name=None, description=None, instructions=None, model=None, advanced_settings=None, reindex_documents=True, add_nodes_info_file=True, add_interfaces_info_file=True, active=None)
Summary
Updates the parameters of the currently selected assistant bot for the application.
Args
- assistant_id: (str) ID of the assistant to update.
- engine_type: (str) One of the following options: 'openai_assistant' or 'haystack'.
- name: (str) Name of the assistant.
- description: (str) Description of the assistant.
- instructions: (str) The system instructions that the assistant uses.
- model: (str) ID of the model to use.
- advanced_settings: (Dict) Dictionary with additional parameters (not mentioned before) to be used when updating the assistant.
- reindex_documents: (bool) If True, it updates the indexed information about the uploaded documents.
- add_nodes_info_file: (bool) If true, it updates the information about nodes of the current application.
- add_interfaces_info_file: (bool) If true, it updates the information about interfaces of the current application.
- active: (bool) If true, this assistant is displayed as an option when launching the Assistant bot widget in Pyplan.
Returns
- Union[str, None]: ID of the updated assistant bot.
Example
result = pp.update_application_assistant(
assistant_id='asst_i4....',
engine_type='openai_assistant',
reindex_documents=True
)
assistant_chat
assistant_chat(assistant_id, engine_type, chat_message, chat_history=None)
Summary
Chat with an assistant.
Args
- assistant_id: (str) ID of the assistant to update.
- engine_type: (str) One of the following options: 'openai_assistant' or 'haystack'.
- chat_message: Union[dict, str] Message to be sent to the assistant.
- chat_history: [List[dict]] Chat message history.
- Example:
[
{'role': 'user', 'content': 'Hello'},
{'role': 'assistant', 'content': 'Hello, how can I help you?'},
{'role': 'user', 'content': 'I need help with...'}
]
- Example:
Returns
- Union[str, None]: Message returned by the assistant.
Example
result = pp.assistant_chat(
assistant_id='asst_i4...',
engine_type='openai_assistant',
message='Analyze the following data and...'
)
Automated tests
Functions related to application tests created in the Automation tests section.
execute_tests
execute_tests(test_ids=None, detached_run=False)
Executes tests by their IDs.
Parameters
- test_ids (
List[str], optional): List of test IDs to execute. If not provided, all tests are executed. - detached_run (
bool, optional): If True, the tests are executed in detached mode. This can be useful for a periodic task that runs tests. Otherwise, tests are run using the current instance. Defaults to False.
Returns
- Dict[str, Any]: A dictionary with test IDs as keys and their execution results as values.
Example
result = pp.execute_tests(test_ids=['test1', 'test2', 'test3'])
Encription
The Encryption functions provide secure methods for managing sensitive data within your application. These functions enable you to retrieve encrypted secrets, manage your secret keys, and decrypt encrypted SQLite databases. This ensures that your data remains protected while allowing you to access and manage it as needed.
get_secret
get_secret(secret_key, department_code=None)
Summary
Returns the value of a secret key.
Args
- secret_key: (str) The key of the secret to get.
- department_code: (str, optional) The code of the department to which the secret belongs.
Returns
- Union[str, None]: Returns the value of the secret key if it exists, otherwise
None.
Example
result = pp.get_secret(secret_key='my_secret_key', department_code='my_department_code')
get_my_secret_keys
get_my_secret_keys()
Summary
Returns a list of all the secret keys the user has access to.
Returns
- List[str]: List of secret keys.
Example
result = pp.get_my_secret_keys()
decrypt_sqlite_database
decrypt_sqlite_database(encrypted_db_path, decrypted_db_path, password, remove_encrypted_db_when_done=False, sqlite_cipher_mode=ENCRYPTED_SQLITE_CIPHER_MODE, sqlite_kdf_iter=ENCRYPTED_SQLITE_KDF_ITER)
Summary
Decrypts an existing cyphered SQLite database and creates a new SQLite database without encryption with its original data.
Args
- encrypted_db_path: (str) Path to the encrypted SQLite database.
- decrypted_db_path: (str) Path to the new decrypted SQLite database.
- password: (str) Password used to encrypt the original SQLite database.
- remove_encrypted_db_when_done: (bool) If true, if the process finishes successfully, deletes the original encrypted SQLite database file.
- sqlite_cipher_mode: (Union[str, None]) If provided, it is used to unlock the encrypted SQLite database. Pass None to bypass it.
- sqlite_kdf_iter: (Union[str, None]) If provided, it is used to unlock the encrypted SQLite database. Pass None to bypass it.
Returns
- None
Example
import os
result = pp.decrypt_sqlite_database(
encrypted_db_path=os.path.join(current_forms_data_path, 'encrypted_forms.db'),
decrypted_db_path=os.path.join(current_forms_data_path, 'decrypted_forms.db'),
password=pp.get_secret('MY_FORMS_DB_PASSWORD'),
remove_encrypted_db_when_done=True
)
File Operations and Messaging
This section covers functions related to handling files and managing messages within the Pyplan environment.
download
download(file_path)
Download file from Pyplan UI.
Parameters
- file_path (
str): The path of the file to download. It can be absolute, relative, or from temp.
Example
# absolute
pp.download('/company/Public/data/sample.csv')
# relative to current application
pp.download('output.csv')
# from temp directory
pp.download('/temp/uuid.csv')
# download folder as .zip file
pp.download('folder1')
upload
upload(target_path, target_filename=None, allowed_extensions=None, validation_node_id=None, callback_node_id=None, list_of_node_ids_to_invalidate=None, upload_text=None, multiple=False)
Display upload wizard in Pyplan UI.
Parameters
- target_path (
str): Upload target folder. - target_filename (
Union[str, None], optional): Always assign this name to the uploaded file. Generate a copy if the file already exists. - allowed_extensions (
List[str], optional): File extensions allowed for upload. - validation_node_id (
str, optional): Identifier of the node that will execute the validation. The node must return a function (see in the examples). - callback_node_id (
str, optional): Identifier of the node to invoke once the file has been uploaded. The node must return a function (see in the examples). - list_of_node_ids_to_invalidate (
List[str], optional): List of node identifiers to be invalidated after file uploading. - upload_text (
str, optional): Text to be displayed in the upload dialog box. - multiple (
bool, optional): If true, allows uploading more than one file at a single time. 'target_filename' parameter is not used when multiple is True.
Example
# absolute
pp.upload(target_path='/company/Public/data')
# relative to current application
pp.upload(target_path='data')
# fixed file name
pp.upload(target_path='data', target_filename='input_template.xlsx')
# filter file extensions
pp.upload(target_path='data', allowed_extensions=['.xls','.xlsx','.xlsm'])
# with validation node
pp.upload(target_path='data', validation_node_id='validation_upload')
# example definition of validation_upload node:
def _fn(filename: str) -> bool:
# your validation code here
...
pp.send_message('your message here')
return True
result = _fn
# using callback
pp.upload(target_path='data', callback_node_id='upload_callback')
# example definition of upload_callback node:
def _fn(filename: str):
# your code here
result = _fn
# using invalidate nodes:
pp.upload(target_path='data', list_of_node_ids_to_invalidate=['connection_node_1', 'connection_node_2'])
# upload multiple files
pp.upload(target_path='/company/Public/data', allowed_extensions=['.xls','.xlsx','.xlsm'], multiple=True)
send_message
send_message(message_text, message_title = None, not_level_reverse = "info", auto_hide_duration = None, extra_params = None)
Sends a message to the UI. Only used with Pyplan UI.
Parameters
- message_text (
str): The message text to be displayed. - message_title (
Optional[str], optional): The message title to be displayed. Defaults toNone. - not_level_reverse (
str, optional): The level of the message. Can be "info", "success", "warning", or "error". Defaults to "info". - auto_hide_duration (
int, optional): The time in milliseconds to automatically hide the message. - extra_params (
dict, optional): Dictionary with additional parameters to be supplied:- When providing an "interface_id", the notification will redirect the user to the specified interface.
- When providing a "section", the notification will navigate the user to the given section.
Returns
- None
Examples
>>> pp.send_message("The process has been completed", "Process complete!", "success", 3000)
>>> pp.send_message("The process has been completed", "Process complete!", "success", 3000, extra_params={'interface_id': '444ef11c-fec3-4ec8-9297-2a7034ec48b2'})
>>> pp.send_message("The process has been completed", "Files updated!", "info", 2000, extra_params={'section': 'files'})
send_notification
send_notification(target_usernames, message, notification_type='general', application_id=None, extra_params=None, notify_live_users=False)
Summary
Creates a new app notification for a given user.
Args
- target_usernames: (Union[str, List[str]]) Usernames that will receive the notification. It can be a string (single user) or a list of strings.
- message: (str) String with the desired message. It can contain HTML tags for custom formatting.
- notification_type: (Optional[str]) Application section to which the link will redirect the user. Must be one of the following types:
- 'workflow'
- 'scheduler'
- 'interface'
- 'code'
- 'file_manager'
- 'version_manager'
- 'scenario_manager'
- 'app_consolidation'
- 'interface_links'
- 'external_link_endpoints'
- 'general' (default): in this case, the notification will not redirect anywhere.
- application_id: (Optional[str]) ID of the application. It will use the current application ID if it is not supplied.
- extra_params: (Optional[dict]) Dictionary with additional parameters to be supplied:
- When notification_type is 'scheduler', you may provide a 'task_id' parameter if you want the link to redirect the user to the given task logs.
- When notification_type is 'interface', you must provide an 'interface_id' parameter.
- notify_live_users: (Optional[bool]) If True, users that have the application open will be notified immediately. Default is False.
Returns
- bool
Example
message = 'The process ended <span style="color: green">SUCCESSFULLY</span>. Click to see the results...'
pp.send_notification(
target_usernames=['analyst_user_1', 'analyst_user_2'],
message=message,
notification_type='interface',
extra_params={'interface_id': '444ef11c-fec3-4ec8-9297-2a7034ec48b2'},
notify_live_users=True
)
progressbar
progressbar(progress, message_text = "", not_level_reverse = "info", close_when_finished = False)
Creates and updates a progress bar. Only used with Pyplan UI.
Parameters
- progress (
int): A value between 0 and 100 representing the current progress of the task. - message_text (
str, optional): A message to display along with the progress bar. Defaults to an empty string. - not_level_reverse (
str, optional): The level of the notification. Can be one of "info", "success", "warning", or "error". Defaults to "info". - close_when_finished (
bool, optional): Whether to close the progress bar when the task is finished. Defaults toFalse.
Returns
- None
Example
>>> pp.progressbar(20, "Step 1", "info")
>>> pp.progressbar(100, "Complete!", "success")
DataArray and Dataframe Functions
This collection of functions provides tools for manipulating and managing DataArray and DataFrame objects. They include methods for setting domains, creating new arrays, subscript and index management, data slicing, and filling missing values. Additionally, functions for concatenating rows and converting between various data formats and structures are included. These utilities facilitate effective data handling and transformation within Pyplan.
set_domain
set_domain(dataArray, domainDic, defaultValue=None)
Reindexes the dataArray by applying the indices of the domainDic parameter. This function takes an xarray DataArray and a dictionary as inputs. The dictionary should have keys as the dimension names and values as indices from Pandas. The function then reindexes the dataArray along the dimensions specified in the dictionary using the values provided in the dictionary. The reindexed dataArray is then renamed to the names provided in the dictionary. If a defaultValue is provided, the function will fill any missing values in the reindexed DataArray with the provided value. The function then returns the reindexed and renamed DataArray with the new domain set.
Parameters
- dataArray (
xr.DataArray): TheDataArrayfor which the domain is to be set. - domainDic (
Dict[str, pd.Index]): A dictionary with keys as the dimensions of theDataArrayand values as Pandas indexes representing the new domain. The Pandas indexes must have a name. - defaultValue (
Optional[Union[float, int]], optional): A default value to fill in any missing values in theDataArrayafter reindexing. If not provided, missing values will not be filled.
Returns
- xr.DataArray: The
DataArraywith the new domain set.
Example
pp.set_domain(da, {"time": time_index, "products": product_index})
create_dataarray
create_dataarray(value, coords, dtype=None)
Creates a DataArray using an atomic value distributed along all dimensions.
Parameters
- value (
Union[float, int]): The value to fill theDataArraywith. - coords (
List[List[Any]]): A list of lists representing the coordinates of theDataArray. Each list within the outer list should contain the values for a single dimension. - dtype (
Optional[np.dtype], optional): The data type of theDataArray. If not provided, the data type will be inferred from the value. Default isNone.
Returns
- xr.DataArray: The created
DataArray.
Example
>>> data_array = create_dataarray(5, [[1, 2, 3], [4, 5, 6]], np.int64)
>>> print(data_array)
<xarray.DataArray (dim_0: 3, dim_1: 3)>
array([[5, 5, 5],
[5, 5, 5],
[5, 5, 5]], dtype=int64)
Coordinates:
* dim_0 (dim_0) int64 1 2 3
* dim_1 (dim_1) int64 4 5 6
subscript
subscript(dataArray, indexes, values)
Filters a DataArray using the specified indexes and values.
Parameters
- dataArray (
xr.DataArray): The DataArray to be filtered. - indexes (
Union[Index, List[Index]]): The index or list of indexes to filter by. The indexes must be an index node or have a name. - values (
Union[List[str], str]): The value or list of values to filter by.
Returns
- xr.DataArray: The filtered DataArray.
Example
>>> data = xr.DataArray(np.random.rand(3,3), coords=[("x",[1,2,3]),("y",[4,5,6])])
>>> data
<xarray.DataArray (x: 3, y: 3)>
array([[0.90468629, 0.83137329, 0.16108201],
[0.41570222, 0.52236005, 0.83363554],
[0.70427948, 0.49809961, 0.06619599]])
Coordinates:
* x (x) int64 1 2 3
* y (y) int64 4 5 6
>>> indexes = pd.Index(["x"],name='x')
>>> values = [2]
>>> pp.subscript(data, indexes, values)
<xarray.DataArray (y: 3)>
array([0.41570222, 0.52236005, 0.83363554])
Coordinates:
* y (y) int64 4 5 6
subset
subset(cube)
Returns a Pandas index with the elements of the index for which the condition cube is true. The function is used to create a new index that is a subset of an existing index.
Parameters
- cube (
xr.DataArray): The data array which is used as a condition to select elements of the index. The condition should be in the form of a booleanDataArray.
Returns
- pd.Index: The resulting index that is a subset of the existing index based on the given condition.
Example
>>> cube = xr.DataArray([1, 2, 3, 4, 5]) > 2
>>> pp.subset(cube)
Int64Index([2, 3, 4], dtype='int64')
change_index
change_index(dataArray, oldIndex, newIndex, compareMode=1, defaultValue=None)
Changes the index of a DataArray object.
Parameters
- dataArray (
xr.DataArray): The DataArray to change the index of. - oldIndex (
pd.Index): The old index to be replaced. - newIndex (
pd.Index): The new index to replace the old one. - compareMode (
int, optional): 1: by Value (default), 2: by pos. - defaultValue (
float, optional): The default value to fill NaN values with. Defaults toNone.
Returns
- xr.DataArray: The DataArray with the new index.
Example
>>> pp.change_index(dataArray, oldIndex, newIndex)
slice_dataarray
slice_dataarray(dataArray, index, position)
Filters a DataArray by integer position along the specified index.
Parameters
- dataArray (
xr.DataArray): The DataArray to be filtered. - index (
pd.Index): The index used to filter the DataArray. Must have a name. - position (
int): Integer position along the specified index.
Returns
- xr.DataArray: The filtered DataArray.
fill_inf
fill_inf(dataArray, value=0)
Summary
Fills np.inf values in an xarray.DataArray with a specified value.
Args
- dataArray: (xr.DataArray) The array which needs to be processed.
- value: (Union[int, float], optional) The value which will be used to replace
np.inf. Defaults to 0.
Returns
- xr.DataArray: The processed array with replaced
infvalues.
Example
>>> pp.fill_inf(dataArray, 0)
fill_all
fill_all(dataArray, value = 0)
Fills np.inf and np.nan values in a DataArray with the specified value.
Parameters
- dataArray (
xr.DataArray): The DataArray to fill. - value (
Union[float, int]): Value to replacenp.infandnp.nanwith. Default is0.
Returns
- xr.DataArray: DataArray with
np.infandnp.nanreplaced by the specified value.
concat_rows
concat_rows(array_param, index_param)
Flattens array_param by creating a new index that includes all combinations of values from
index_param. The new index will have the same name as the original index.
Parameters
- array_param (
xr.DataArray): The data array to flatten. - index_param (
str): The name of the index dimension ofarray_paramto use to create the new index.
Returns
- pd.Index: The new flattened index.
Example
>>> import xarray as xr
>>> dataArray = xr.DataArray([[1, 2], [3, 4]], coords=[('x', ['A', 'B']), ('y', [1, 2])])
>>> new_index = pp.concat_rows(dataArray, 'x')
>>> new_index
Index(['A', 'B'], dtype='object')
pandas_from_excel
pandas_from_excel(excel, sheetName=None, namedRange=None, cellRange=None, indexes=None, driver="")
Returns a pandas DataFrame from an Excel spreadsheet (.xlsx).
This function automatically generates pickles from every named range in the Excel file
when the excel parameter is a string.
If excel is a string, the function tries to read from automatically generated pickles for each named range if they are newer than the Excel file (based on modification date).
If the pickles do not exist or are outdated, the function attempts to generate one pickle for every named range.
Requirements (for pickle generation):
- The file must have writing permissions.
- The file must contain named ranges.
If the above conditions are not met, the function loads the spreadsheet using the openpyxl library and reads from the specified sheet, named range, or cell range.
Parameters
- excel (
Union[str, Workbook]): Path to the Excel file or anopenpyxl.Workbookobject. - sheetName (
Optional[str], default:None): Name of the sheet to read from. - namedRange (
Optional[str], default:None): Named range to read from the Excel file. - cellRange (
Optional[str], default:None): Specific cell range (e.g.,"A1:D10") to read within the sheet. - indexes (
Optional[List[str]], default:None): List of column names to set as index in the resulting DataFrame. - driver (
str, default:""): Reserved for future use. Not currently used.
Returns
- pd.DataFrame: A pandas DataFrame containing the requested data from the Excel spreadsheet.
Example
>>> df = pp.pandas_from_excel("report.xlsx", sheetName="Sheet1")
>>> df = pp.pandas_from_excel("report.xlsx", namedRange="SummaryData")
>>> df = pp.pandas_from_excel("report.xlsx", sheetName="Sheet1", cellRange="B2:F20")
pandas_from_xlsb_file
pandas_from_xlsb_file(filepath)
Returns a pandas DataFrame from an xlsb file.
Parameters
- filepath (
str): The path of the xlsb file to be opened.
Returns
- Optional[pd.DataFrame]: A pandas DataFrame containing the contents of the xlsb file. Returns
Noneif the file cannot be read.
Example
>>> _df = pp.pandas_from_xlsb_file('path/to/xlsb/file')
pandas_from_dataarray
pandas_from_dataarray(dataarray)
Create a pandas DataFrame from an xarray DataArray with n dimensions.
Parameters
- dataarray (
xr.DataArray): The DataArray to convert to a DataFrame.
Returns
- pd.DataFrame: The resulting DataFrame.
Example
>>> import xarray as xr
>>> data = xr.DataArray([1, 2, 3], dims=["x"], coords={"x": [1, 2, 3]})
>>> pp.pandas_from_dataarray(data)
x value
0 1 1
1 2 2
2 3 3
pandas_from_access
pandas_from_access()
Class to manage access databases.
index_from_pandas
index_from_pandas(dataframe, columnName, removeEmpty)
Returns a Pandas Index from a column of a Pandas DataFrame.
Parameters
- dataframe (
pd.DataFrame): Pandas DataFrame. - columnName (
Optional[str], optional): DataFrame column name used to create thepd.Index. By default, it is created using the first column. - removeEmpty (
bool, optional): True to remove empty rows.
Returns
- pd.Index: A pandas index created from the DataFrame.
Example
>>> import pandas as pd
>>> df = pd.DataFrame({'A':[1,2,3], 'B':[4,5,6]})
>>> pp.index_from_pandas(df)
Int64Index([1, 2, 3], dtype='int64')
>>> pp.index_from_pandas(df, "B")
Int64Index([4, 5, 6], dtype='int64')
index_from_excel
index_from_excel(excel, sheetName, namedRange, cellRange, columnName, removeEmpty)
Returns a pandas.Index from an Excel file.
Parameters
- excel (
Union[str, Workbook]): Excel object. - sheetName (
Optional[str], optional): Sheet name to be read. - namedRange (
Optional[str], optional): Name of the range to be read. - cellRange (
Optional[str], optional): Used withsheetName, for reading from a simple range. - columnName (
Optional[str], optional): DataFrame column name used to create the index. By default, it is created using the first column. - removeEmpty (
bool, optional): True to remove empty rows.
Returns
- pandas.Index: The index created from the Excel file.
Example
>>> pp.index_from_excel(excelNode, "Sheet 1")
>>> pp.index_from_excel(excelNode, namedRange="name_range")
>>> pp.index_from_excel(excelNode, "Sheet 1", cellRange="A1:H10", columnName="column10")
dataarray_from_pandas
dataarray_from_pandas(dataframe, domainDic, valueColumns, defaultValue, valueColumnsAsDim, sumDuplicateRecords)
Converts a Pandas DataFrame into an xr.DataArray or xr.Dataset by applying the set_domain function.
Parameters
- dataframe (
pd.DataFrame): Pandas DataFrame with no index columns. - domainDic (
Dict[str, pd.Index]): A dictionary where keys are the dimensions of the resulting DataArray and values are Pandas indices representing the new domain. Example:{'Column Name': index_name}. - valueColumns (
Union[str, List[str], pd.Index]): DataFrame's value columns. - defaultValue (
Optional[Any]): Default value when applying theset_domainfunction. - valueColumnsAsDim (
bool): If True,valueColumnsbecomes a dimension of the resulting DataArray. If False, each value column becomes a variable of the resulting Dataset. - sumDuplicateRecords (
bool): If True, sums identical rows. Otherwise, removes duplicates (except the first one).
Returns
- Union[xr.DataArray, xr.Dataset]: A DataArray or Dataset depending on the input of
valueColumnsandvalueColumnsAsDim.
Example
>>> pp.dataarray_from_pandas(sales_dataframe, {'Sales Channel': sales_channels, 'Month': time}, 'Sales', 0.0)
dataarray_from_excel
dataarray_from_excel(excel, sheetName, namedRange, cellRange, indexes, valueColumns, indexColumnHeaders, replaceByIndex, defaultValue)
Creates an xr.DataArray from an Excel file by reading the specified sheet, named range, or cell range.
Parameters
- excel (
Union[str, Workbook]):excel_connectionobject. - sheetName (
Optional[str], optional): Sheet name to be read. - namedRange (
Optional[str], optional): Name of the range to be read. - cellRange (
Optional[str], optional): Used withsheetNameto read from a simple range. - indexes (
Optional[List[pd.Index]], optional): List ofpd.Indexobjects to perform achange_indexoperation. - valueColumns (
Optional[Union[str, pd.Index]], optional): String with the column name of the DataFrame that contains the values.pd.Indexwith column names to convert columns to an index. - indexColumnHeaders (
Optional[List[str]], optional): Column names in Pandas to parse with indexes. Used if the header on the DataFrame is not equal to index identifiers. - replaceByIndex (
Optional[pd.Index], optional): Replace the index used invalueColumnswith this index (usingchange_index). - defaultValue (
float, optional): Default value for the created DataArray. Defaults to 0.
Returns
- xr.DataArray: DataArray created from the Excel file.
Examples
>>> pp.dataarray_from_excel(excelNode, "Sheet 1", indexes=[indicadores], valueColumns="descuentos")
>>> pp.dataarray_from_excel(excelNode, namedRange="nombre_rango", indexes=[indicadores], valueColumns=time)
to_dataarray
to_dataarray(index)
Converts an index into a DataArray indexed by the input index and with its values.
Parameters
- index (
pd.Index): Index to be used as the DataArray's index.
Returns
- xr.DataArray: DataArray indexed by the input index with its values.
Example
>>> pp.to_dataarray(time_index)
aggregate
aggregate(dataArray, mapInfo, sourceIndex, targetIndex, aggregationFunction='sum', numericOnly=None)
Converts dataArray, originally indexed by sourceIndex, to a dataArray indexed by targetIndex, aggregating according to the mapInfo's allocation of targetIndex: sourceIndex.
Parameters
- dataArray (
xr.DataArray): The DataArray to be aggregated. - mapInfo (
Union[xr.DataArray, List[xr.DataArray]]): DataArray or list of DataArrays that gives the value oftargetIndexfor each element ofsourceIndex. If the map does not match, then the element will not be set into the target index, and information will be lost. - sourceIndex (
pd.Index): The original index ofdataArray. - targetIndex (
Union[pd.Index, List[pd.Index]]): Index or list of pd.Index objects that will be used as the new index ofdataArray. - aggregationFunction (
str, optional): Specifies the function to be used when grouping data (sum,mean,min,max,median). Default is'sum'. - numericOnly (
Optional[bool], optional):numeric_onlyparameter for the aggregation function.
Returns
- xr.DataArray: A new DataArray indexed by
targetIndex, aggregated according to themapInfo.
Example
# Example: Aggregating time information into an annual index
pp.aggregate(dataArray, timeToYearsMap, time, years)
dynamic
dynamic(dataArray, index, shift, initialValues=None, sliceInputs=True)
Performs cyclic calculations between nodes.
Parameters
- dataArray (
xr.DataArray): The DataArray to perform the cyclic dependency calculation on. - index (
pd.Index): Index fromdataArrayto shift. Must have a name. - shift (
int): Number of elements to shift. Can be positive or negative. - initialValues (
Union[xr.DataArray, float, int], optional): Initial values to apply to the first "shift" elements. Defaults toNone. - sliceInputs (
bool, optional): Boolean to apply subscript to every input in the dynamic loop. If one of the nodes in the dynamic loop is set toTrue, it applies it to every other node in the loop. Defaults toTrue.
Returns
- xr.DataArray: DataArray shifted by the specified amount.
lookup
lookup(dataArray, dataMap, sharedIndex, defaultValue=0)
Returns the value of dataArray indexed by the index of dataMap.
Parameters
- dataArray (
xr.DataArray): DataArray indexed bysharedIndexwhose values correspond to elements ofsharedIndex. - dataMap (
xr.DataArray): DataArray containing the index to lookup indataArray. - sharedIndex (
pd.Index): The shared index betweendataArrayanddataMap. - defaultValue (
Union[int, float], optional): The value to fill when the index lookup fails. Defaults to0.
Returns
- xr.DataArray: DataArray with the values of
dataArrayindexed bydataMap.
Example
# Example: Let's say you have a dataArray with an estimated inflation rate by Country ("inflation_rate"
# is the name of the dataArray; "country" is the name of the index) and you want to assign it to the
# corresponding Company depending on its location. On the other hand, there's a many-to-one map where
# each Company is allocated to a single Country ("country_to_company_allocation"). The sharedIndex,
# in this case, is Country ("country").
pp.lookup(inflation_rate, country_to_company_allocation, country)
# This will return the estimated inflation rate by Company.
where
where(obj, condition, condition_values, x, y, **kwargs)
Summary
Returns elements chosen from x or y depending on the condition. This function is a wrapper for xarray's where function that provides extended condition options and passes additional positional and keyword arguments.
Args
- obj: (Union[xr.DataArray, pd.Index]) The input object, which can be either a Pandas Index or an xarray DataArray.
- condition: (str) The condition to apply, e.g.,
=,!=,>,>=,<,<=. - condition_values: (Union[str, List[str]]) The values to compare with the object based on the condition. Can be a single string or a list of strings for conditions like '!='.
- x: (Union[xr.DataArray, int, float]) The values to use where the condition is True.
- y: (Union[xr.DataArray, int, float]) The values to use where the condition is False.
- kwargs: Additional keyword arguments to pass to xarray's
wherefunction.
Returns
- xr.DataArray: A new DataArray with values selected based on the condition and additional options.
Examples
# Example with Pandas Index
countries = pd.Index(["Latvia", "Argentina", "Chile"])
result1 = pp.where(countries, '!=', ['Latvia', 'Argentina'], 1, 0, some_arg)
result2 = pp.where(countries, '!=', 'Latvia', 1, 0, another_arg, yet_another_arg)
# Example with xarray DataArray
time = xr.DataArray(['2023', '2024', '2025'])
result3 = pp.where(time, '>', '2024', '2023', '2022', some_kwarg=some_value)
result4 = pp.where(time, '=', '2024', '2023', '2022')
maximum
maximum(x, y, **kwargs)
Summary
Calculates the maximum between two xarray DataArrays, pandas DataFrames, or pandas Index objects.
Args
- x: (Union[xr.DataArray, pd.DataFrame, pd.Index]) The first input data structure.
- y: (Union[xr.DataArray, pd.DataFrame, pd.Index]) The second input data structure.
- kwargs: Additional keyword arguments to pass to
np.maximum.
Returns
- Union[xr.DataArray, pd.DataFrame, pd.Index]: A data structure of the same type as
xandycontaining the maximum values.
Example
data_array_1 = xr.DataArray([1, 2, 3, 4], dims=['x'])
data_array_2 = xr.DataArray([3, 4, 2, 5], dims=['x'])
max_value = pp.maximum(data_array_1, data_array_2)
print(max_value)
# Output: [3 4 3 5]
minimum
minimum(x, y, **kwargs)
Summary
Calculates the minimum between two xarray DataArrays, pandas DataFrames, or pandas Index objects.
Args
- x: (Union[xr.DataArray, pd.DataFrame, pd.Index]) The first input data structure.
- y: (Union[xr.DataArray, pd.DataFrame, pd.Index]) The second input data structure.
- kwargs: Additional keyword arguments to pass to
np.minimum.
Returns
- Union[xr.DataArray, pd.DataFrame, pd.Index]: A data structure of the same type as
xandycontaining the minimum values.
Example
data_array_1 = xr.DataArray([1, 2, 3, 4], dims=['x'])
data_array_2 = xr.DataArray([3, 4, 2, 5], dims=['x'])
min_value = pp.minimum(data_array_1, data_array_2)
print(min_value)
# Output: [1 2 2 4]
copy_index
copy_index(dataArray, sortValues = True)
Generates a pd.Index with the unique values of the dataArray.
Parameters
- dataArray (
xr.DataArray): The DataArray from which the index will be copied. - sortValues (
bool, optional): Whether to sort the unique values in ascending order. Defaults toTrue.
Returns
- pd.Index: The unique values of the
dataArray.
Example
>>> data_array = xr.DataArray([1, 2, 2, 3, 4], dims=['x'])
>>> pp.copy_index(data_array, sortValues=True)
Index([1, 2, 3, 4], dtype='int64')
sequence_index
sequence_index(_start, _end, _step = 1)
Returns a pd.Index with the sequence between _start and _end parameters. Both limits are inclusive. Values are
converted to string.
Parameters
- _start (
int): The start of the sequence. - _end (
int): The end of the sequence. - _step (
int, optional): The step between each element of the sequence. Defaults to1.
Returns
- pd.Index: A pandas index with the sequence of numbers between
_startand_end.
Raises
- ValueError: Only numbers are allowed as _start, _end, and _step parameters.
Examples
>>> pp.sequence_index(0, 10)
Index(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], dtype='object')
subindex
subindex(dataArray, targetValue, targetIndex, method = 'Last')
Returns a dataArray containing the value of targetIndex for which dataArray (indexed by targetIndex) is equal
to targetValue.
Parameters
- dataArray (
xr.DataArray): XarrayDataArray. - targetValue (
Union[int, float, str]): Target value to search indataArray. - targetIndex (
pd.Index): PandasIndex. - method (
str, optional): Method to select the index."Last"returns the last occurrence oftargetIndexfor whichdataArrayis equal totargetValue."First"returns the first occurrence. Defaults to"Last".
Returns
- xr.DataArray:
DataArraycontaining the value oftargetIndexfor whichdataArrayis equal totargetValue.
Example
>>> import xarray as xr
>>> import pandas as pd
>>> dataArray = xr.DataArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]], coords=[['A', 'B', 'C'], [1, 2, 3]], dims=['x', 'y'])
>>> targetIndex = pd.Index([1, 2, 3])
>>> pp.subindex(dataArray, 8, targetIndex)
<DataArray (y: 1)>
array([2])
Coordinates:
* y (y) int64 2
create_report
create_report(reportItems, reportIndexName = "Report index", reportIndex = None)
Concatenates the reportItems data arrays along the reportIndex dimension.
Parameters
- reportItems (
Union[Dict[str, xr.DataArray], List[xr.DataArray]]): A dictionary or list of data arrays to concatenate. All data arrays must have the same structure. - reportIndexName (
Optional[str]): The name of the newReportIndexdimension that will be created. Defaults to "Report index". - reportIndex (
Optional[pd.Index]): The index to overwrite thereportIndexdimension. Defaults toNone.
Returns
- xr.DataArray: The concatenated data array with the new
reportIndexdimension.
Example
>>> reportItems = {"Demand": demand, "Product Stock": stock}
>>> pp.create_report(reportItems, reportIndexName="New Report")
concat_dataarrays
concat_dataarrays(valuesList, dim)
Concatenates Xarray DataArrays along one or two new dimensions, broadcasting by all possible dimensions.
Args
- valuesList (Union[List[Union[xr.DataArray, int, str, float]], List[List[Union[xr.DataArray, int, str, float]]]]): List or list of lists of DataArrays, integers, strings, or floats. At least one element must be a DataArray object.
- dim (Union[pd.Index, List[pd.Index]]): Pandas Index or list of Pandas Indexes with the same shape as
valuesList.
Returns
- xr.DataArray: A concatenated DataArray.
Example
>>> pp.concat_dataarrays(valuesList=[node1, node2, node3], dim=three_items_index)
<xarray.DataArray (dim: 3, ...)>
array([...])
Coordinates:
* dim (dim) object ...
>>> pp.concat_dataarrays(valuesList=['String Example', node2, 0], dim=three_items_index)
<xarray.DataArray (dim: 3, ...)>
array([...])
Coordinates:
* dim (dim) object ...
>>> pp.concat_dataarrays(valuesList=[[node1, node2, node3], [node4, node5, node6]], dim=[two_items_index, three_items_index])
<xarray.DataArray (dim1: 2, dim2: 3, ...)>
array([...])
Coordinates:
* dim1 (dim1) object ...
* dim2 (dim2) object ...
Data Manipulation Functions
This section includes specialized functions designed for operations on DataFrames, DataArrays, and indexes, along with a selection of mathematical operations. These functions are optimized for handling and manipulating data structures efficiently, providing essential tools for data analysis and transformation.
find
find(param1, param2, compareType=1, caseSensitive=True)
Finds the occurrences of param1 in param2 using the specified comparison type.
Parameters
- param1 (
Union[str, int, pd.Index]): The value or index to compare. - param2 (
Union[str, int, pd.Index]): The value or index to compare against. - compareType (
int, optional): The type of comparison to use. The options are:- 1: Exact match (default)
- 2: Starts with
- 3: Ends with
- 4: Contains
- caseSensitive (
bool, optional): Whether the comparison should be case-sensitive. Default isTrue.
Returns
- xr.DataArray: The resulting
DataArraywith the comparison results.
Example
# If param1 is a scalar (numeric or str) and param2 is an index:
# return a DataArray indexed by param2 with True on occurrences of param2.
>>> pp.find("te", region, cp.end_with)
# If param1 is an index and param2 is an index too:
# return a DataArray indexed by param1 and param2 with True on occurrences of param1 on param2.
>>> pp.find(subregion, region, cp.contain)
apply_fn
apply_fn(obj, applyFn, *args)
Applies a function to a DataArray or Index.
Parameters
- obj (
Union[xr.DataArray, pd.Index]): TheDataArrayorIndexto which the function should be applied. - applyFn (
Callable): The function to be applied. - args: Additional arguments to be passed to the function.
Returns
- xr.DataArray or pd.Index: The resulting
DataArrayorIndexafter the function has been applied. - None: If the
objis not of typexr.DataArrayorpd.Index.
Example
>>> data_array = xr.DataArray(np.random.rand(3, 3), dims=('x', 'y'))
>>> new_array = apply_fn(data_array, np.square)
>>> print(new_array)
<xarray.DataArray (x: 3, y: 3)>
array([[0.19290767, 0.10126844, 0.09544723],
[0.17547571, 0.01341797, 0.1707827 ],
[0.15894374, 0.07128388, 0.16331167]])
Coordinates:
* x (x) int64 0 1 2
* y (y) int64 0 1 2
split_text
split_text(param1, separator, part=None)
Returns a DataArray object with text values formed by splitting the elements of param1 text values at each occurrence of the separator separator. The DataArray will have the original dimension plus a new dimension 'Parts' of length (number of separators + 1). All text values must have the same number of separators separator.
Parameters
- param1 (
xr.DataArray): TheDataArraycontaining the text values to be split. - separator (
str): The separator used to split the text values. - part (
int, optional): The part of the split text to return. If not provided, all parts will be returned.
Returns
- xr.DataArray: The resulting
DataArraywith the split text values, with a new dimension 'Parts' of length (number of separators + 1).
Example
>>> data_array = xr.DataArray(["hello,world", "hi,world", "hey,world"], dims=('x'))
>>> new_array = split_text(data_array, ",")
>>> print(new_array)
<xarray.DataArray (x: 3, Parts: 2)>
array([['hello', 'world'],
['hi', 'world'],
['hey', 'world']], dtype=object)
Coordinates:
* x (x) int64 0 1 2
* Parts (Parts) object 'Part 1' 'Part 2'
get_pos
get_pos(index)
Returns a DataArray with the positions of an index as values and indexed by the given index.
Parameters
- index (
pd.Index): The index for which the positions are to be returned.
Returns
- xr.DataArray: The resulting
DataArraywith the positions of the index as values and indexed by the given index.
Example
>>> index = pd.Index(['a', 'b', 'c'])
>>> pos_array = get_pos(index)
>>> print(pos_array)
<xarray.DataArray (index: 3)>
array([0, 1, 2])
Coordinates:
* index (index) object 'a' 'b' 'c'
concat_index
concat_index(*args)
Concatenates two or more indexes and/or atomic values and returns a single new index.
Parameters
- *args (
pd.Indexor atomic value): Two or more indexes and/or atomic values to be concatenated.
Returns
- pd.Index: The resulting index that is a concatenation of the given indexes and/or atomic values.
Example
>>> index1 = pd.Index(['a', 'b', 'c'])
>>> index2 = pd.Index(['d', 'e', 'f'])
>>> pp.concat_index(index1, index2, 'g', 'h')
Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], dtype='object')
linear_depreciation
linear_depreciation(investments, usefulLife, timeIndex, includeInCurrentMonth=False, timeIndexFormat='%Y.%m')
Returns the straight-line depreciation of the given investments DataArray over its useful life.
Parameters
- investments (
xr.DataArray): ADataArraycontaining the investments. - usefulLife (
xr.DataArrayorint): ADataArrayor integer with the number of years of life expectancy. - timeIndex (
pd.Index): The time dimension of theDataArray. Must be a PandasIndexfrom an Index node. - includeInCurrentMonth (
bool, optional): Whether to start depreciating in the current month (t) or the next month (t+1). Default isFalse. - timeIndexFormat (
str, optional): Format of the time index. e.g., for '2016.01' use '%Y.%m'. Default is'%Y.%m'.
Returns
- xr.DataArray: The resulting
DataArraywith the straight-line depreciation of the investments over its useful life.
Example
>>> product = pd.Index(['prod1','prod2'])
>>> time_list = pp.Index(pp.create_time('2021.01', '2021.06', freq='M', format='%Y.%m').values)
>>> data = xr.DataArray(np.random.rand(2, 2, len(time_list)),
dims=('fabrica', 'product', 'time_list'),
coords={'fabrica': ['fab1', 'fab2'], 'product': ['prod1', 'prod2'], 'time_list': time_list})
>>> vida_util = xr.DataArray([4, 10],
dims=('product'),
coords={'product': product})
>>> pp.linear_depreciation(investments=data, usefulLife=vida_util, timeIndex=time_list, includeInCurrentMonth=False)
<xarray.DataArray (fabrica: 2, product: 2, time_list: 6)>
array([[[0. , 0.00729475, 0.00947053, 0.01165097, 0.03016374,
0.0456418 ],
[0. , 0.00751886, 0.01090068, 0.01772 , 0.01858931,
0.01974675]],
[[0. , 0.01736181, 0.02019148, 0.02518252, 0.0285973 ,
0.04491098],
[0. , 0.00784025, 0.01253238, 0.02069702, 0.02174192,
0.02660816]]])
Coordinates:
* fabrica (fabrica) <U4 'fab1' 'fab2'
* product (product) <U5 'prod1' 'prod2'
* time_list (time_list) object '2021.01' '2021.02' ... '2021.05' '2021.06'
irr
irr(flow, time_index)
Returns the Internal Rate of Return (IRR) of a series of periodic payments (negative values) and inflows (positive values). The IRR is the discount rate at which the Net Present Value (NPV) of the flows equals zero. The variable flow must be indexed by time_index.
If the cash flow never changes sign, pp.irr() has no solution and returns NAN (Not A Number).
Parameters
- flow (
xr.DataArray): ADataArraycontaining the cash flows. - time_index (
pd.Index): The index that corresponds to the time dimension of the cash flows. Thetime_indexmust be defined in another node.
Returns
- Union[float, xr.DataArray]: A
DataArraywith the IRR value.
Example
>>> # The Index time must be defined in another node.
>>> time = pd.date_range(start='1/1/2020', end='12/31/2020', freq='M')
>>> flow = xr.DataArray([-1000, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200], [('time', time)])
>>> pp.irr(flow, time)
0.4089653663721178
copy_as_values
copy_as_values(source, targetId)
Copy values of an object source into a new object with id targetId. This function alters the definition of the object with the targetId identifier.
Parameters
- source (
xr.DataArray,pd.DataFrame,pd.Series,pd.Index,float,int,str): DataArray/DataFrame/Index to copy values from. Can also be a string with the id of a node. - targetId (
str): Identifier of the target node.
Returns
- bool:
Trueif successful.
Example
>>> source = xr.DataArray([1, 2, 3], dims=['x'])
>>> targetId = 'node1'
>>> pp.copy_as_values(source, targetId)
True
excel_connection
excel_connection(filepath, useOpenpyxl=False, dataOnly=True, readOnly=True)
Creates an Excel object from the given filepath.
Parameters
- filepath (
str): Path to the Excel file. - useOpenpyxl (
bool, optional): Whether to use openpyxl to open the file. Defaults toFalse. - dataOnly (
bool, optional): Whether to only get values, not the formulas. Defaults toTrue. - readOnly (
bool, optional): Whether to open the Excel file in read-only mode. Defaults toTrue.
Returns
- Union[Workbook, str]: The resulting Excel object.
Example
>>> excel_obj = pp.excel_connection("/path/to/the/excelfile.xlsx")
kind_to_string
kind_to_string(kind)
Convert a Numpy dtype "kind" to a human-readable string representation.
Parameters
- kind (
str): A single character code indicating the general kind of data.
Returns
- str: The data type in human-readable string format.
Example
>>> pp.kind_to_string('U')
'string'
goal_seek
goal_seek(nodeIdX, nodeIdObjective, goal=0, startValue=1, matrixIndex=None, maxIter=50, tol=1.48e-08, fullOutput=False)
Finds the value of nodeIdX that makes nodeIdObjective equal to goal. This function implements scipy.optimize.newton function. Returns a dictionary if matrixIndex is not None; otherwise, returns the root of the problem.
Parameters
- nodeIdX (
str): Identifier of node X. - nodeIdObjective (
str): Identifier of node Objective. - goal (
Union[int, float]): Goal value to be reached. Defaults to 0. - startValue (
Union[int, float]): An initial estimate of the zero that should be somewhere near the actual zero. Defaults to 1. - matrixIndex (
Union[pd.Index, List[pd.Index]], optional): For multidimensional goal seek. Defaults toNone. - maxIter (
int): Maximum number of iterations. Defaults to 50. - tol (
float): The allowable error of the zero value. Defaults to1.48e-08. - fullOutput (
bool): IfFalse(default), the root is returned. IfTrueandstartValueis scalar, the return value is(x, r), wherexis the root andris aRootResultsobject. IfTrueandstartValueis non-scalar, the return value is(x, converged, zero_der). Defaults toFalse.
Returns
- res (
Union[float, dict]): IfmatrixIndexisNone, returns the root of the problem. Otherwise, returns a dictionary containing the results of each combination ofmatrixIndexvalues.
Example
# To find the value of node1 that makes node2 equal to 2, we can use the goal_seek function as follows:
>>> node1 = 0
>>> node2 = node1 ** 2
>>> goal = 2
>>> pp.goal_seek('node18', 'node21', goal)
1.414213562373095
create_time
create_time(date_start, date_end, freq='M', format='%Y.%m')
Creates a time index using start and end dates and a specified frequency. The resulting index is formatted with the provided format.
Parameters
- date_start (
str): The starting date of the index. - date_end (
str): The end date of the index. - freq (
str, optional): The frequency of the index. Defaults to 'M' (monthly). - format (
str, optional): The format to use for the resulting index. Defaults to '%Y.%m'.
Returns
- pd.Index: The time index.
Example
pp.create_time('2021.01', '2021.06')
# Output: Index(['2021.01', '2021.02', '2021.03', '2021.04', '2021.05', '2021.06'], dtype='object')
pp.create_time('2021.01.01', '2021.01.10', freq='D', format='%d/%m/%Y')
# Output: Index(['01/01/2021', '02/01/2021', '03/01/2021', '04/01/2021', '05/01/2021',
# '06/01/2021', '07/01/2021', '08/01/2021', '09/01/2021', '10/01/2021'], dtype='object')
add_periods
add_periods(start, periods, freq = 'M', format = '%Y.%m')
Add a given number of periods to a starting date. Allows setting the frequency and output format of the resulting date.
Parameters
- start (
str): Starting date in the format of 'yyyy.mm' or 'yyyy-mm'. - periods (
int): Number of periods to add. Can be positive or negative. - freq (
str, optional): Frequency of the periods. Defaults to 'M' for months. - format (
str, optional): Output format for the resulting date. Defaults to '%Y.%m'.
Returns
- str: The resulting date in the specified format.
Examples
>>> pp.add_periods('2016.01', 6)
'2016.07'
>>> pp.add_periods('2016.01', -6)
'2015.07'
>>> pp.add_periods('2016.01', 6, freq='D', format='%d/%m/%Y')
'07/01/2016'
npv
npv(rate, flow, time_index, offset = 1)
Returns the Net Present Value (NPV) of a cash flow with equally spaced periods. The flow parameter must contain a series of periodic payments (negative values) and inflows (positive values), indexed by time_index. The optional offset parameter specifies the offset of the first value relative to the current time period. By default, offset is set to 1, indicating that the first value is discounted as if it is one step in the future.
Parameters
- rate (
float): The rate used to discount the cash flows. - flow (
xr.DataArray): The cash flows. - time_index (
pd.Index): The time index used to calculate the NPV. Must have a name. - offset (
int, optional): The offset of the first value relative to the current time period. Defaults to 1.
Returns
- xr.DataArray: The calculated NPV.
Example
>>> rate = 0.03
>>> cash_flows = xr.DataArray([-1000, 200, 300, 400], coords=[('time', ['2020','2021','2022','2023'])], dims=['time'])
>>> time_index = pd.Index(['2020', '2021', '2022', '2023'], name='time') # Example time index
>>> pp.npv(rate, cash_flows, time_index)
<xarray.DataArray ()>
array(-156.98980623705643)
xnpv
xnpv(rate, flow, time_index, initial_dates, calendar)
Compute the net present value (NPV) of a non-periodic cash flow with a constant discount rate.
Parameters
- rate (
Union[float, int, xr.DataArray]): The annual discount rate for a 365-day year. - flow (
xr.DataArray): Cash flow withtime_indexas the dimension. - time_index (
pd.Index): The time index of the cash flow. - initial_dates (
Union[str, xr.DataArray]): The initial date of the cash flow. - calendar (
xr.DataArray): Number of days for each period oftime_index.
Returns
- Union[float, int]: The net present value of the cash flow.
Example
>>> rate = 0.05
>>> cash_flows = xr.DataArray([-1000, 200, 300, 400], coords=[('time', ['2020-01-01', '2020-06-01', '2021-01-01', '2021-06-01'])], dims=['time'])
>>> time_index = pd.Index(['2020-01-01', '2020-06-01', '2021-01-01', '2021-06-01'], name='time')
>>> initial_dates = '2020-01-01'
>>> calendar = xr.DataArray([182, 183, 182, 182], coords=[('time', time_index)], dims=['time'])
>>> pp.xnpv(rate, cash_flows, time_index, initial_dates, calendar)
-132.99
get_nested_lists_shape
get_nested_lists_shape(lst, shape=())
Returns a tuple with the shape of nested lists similarly to numpy's shape.
Args
- lst (list): The nested list.
- shape (tuple, optional): The shape up to the current recursion depth. Defaults to an empty tuple.
Returns
- tuple: The shape of the nested list.
Example
>>> nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> pp.get_nested_lists_shape(nested_list)
(3, 3)
report
report(items_allocation, settings)
Creates a UI Pyplan Report with the given parameters.
Args
- items_allocation (List[ReportItem]): A list of ReportItem objects where each item assigns a node result or scalar to a given concept. The list should contain concepts as keys and ReportItem as values.
- settings (ReportSettings): An instance of the ReportSettings class that defines various settings for the report.
Returns
- Report: An instance of the Report class.
Example
>>> pp.report(
items_allocation=[
ReportItem(name='Sales', item_source=ReportItemSource.app_node_id, value=fin_sales.node.identifier),
ReportItem(name='Gross Margin', item_source=ReportItemSource.app_node_id, value=fin_gross_margin.node.identifier),
ReportItem(name='Depreciation', item_source=ReportItemSource.input, value=-100.)
],
settings=ReportSettings(
output_type=ReportOutputType.dataarray,
items_node_id=report_concepts.node.identifier,
default_value=0
)
)
>>> pp.report(
items_allocation=[
ReportItem(name='Sales', item_source=ReportItemSource.app_node_id, value=fin_sales.node.identifier),
ReportItem(name='Costs', item_source=ReportItemSource.app_node_id, value=fin_costs.node.identifier, as_negative=True),
ReportItem(name='Gross Margin', item_source=ReportItemSource.app_node_id, value=fin_gross_margin.node.identifier),
ReportItem(name='Depreciation', item_source=ReportItemSource.input, value=-100.)
],
settings=ReportSettings(
output_type=ReportOutputType.dataframe,
dimension_name='report_concepts',
default_value=0
)
)
get_specific_range
get_specific_range(specific_range, file_path)
Get the specific range from an Excel file with defined name ranges.
Args
- specific_range (str): The name of the range to get.
- file_path (str): The path of the Excel file.
Returns
- Dict: Dictionary with
usecols,skiprows, andnrowskeys.usecolsis a string with the range of columns to use.skiprowsis an int with the number of rows to skip before reading.nrowsis an int with the number of rows to read.
Example
>>> pp.get_specific_range(specific_range='MyRange', file_path='my_file.xlsx')
{'usecols': 'A:C', 'skiprows': 1, 'nrows': 10}
get_new_range
get_new_range(range_value)
Set range_to_read_excel with range_value given.
Parameters
- range_value (
str): The range value of the cells to be read.
Returns
- dict: A dictionary with the keys
usecols,skiprows, andnrowscontaining the information for the range of cells to be read.
Example
>>> range_value = 'A2:C11'
>>> pp.get_new_range(range_value)
{'usecols': 'A:C', 'skiprows': 1, 'nrows': 10}
remove_duplicates_words
remove_duplicates_words(text_to_clean)
Summary
Removes duplicate words from a string.
Args
- text_to_clean: (str) The string to process.
Returns
- str: The string with duplicate words removed.
Example
result = pp.remove_duplicates_words("hello hello world world")
print(result)
# "hello world"
General Functions
This section includes general-purpose functions that support various operations within the application. These functions provide useful information about Pyplan users, help navigate different sections of the interface, and handle system dependencies, providing essential utilities for seamless interaction with the platform.
get_user_list
get_user_list()
Gets the list of all users in the company.
Returns
- List[Dict]: A list of dictionaries, each containing user details with the following structure:
[
{
'id': 'abc',
'username': 'user_name',
'first_name': 'User',
'last_name': 'Lastname',
'email': 'user@company.com',
'departments': [
{
'id': 1,
'code': 'pyplan-default',
'name': 'Default'
}
],
'is_active': True,
'last_login': '2023-07-11T21:27:52+0000'
},
{
'id': 'xyz',
'username': 'user_name',
'first_name': 'User firstname',
'last_name': 'User lastname',
'email': 'user@company.com',
'departments': [
{
'id': 1,
'code': 'pyplan-default',
'name': 'Default'
}
],
'is_active': True,
'last_login': '2023-07-10T20:12:31+0000'
}
]
Example
result = pp.get_user_list()
open_app
open_app(folder, version, read_only, resources, open_on_new_instance, show_versions_on_open,interface_id_to_open_on_start)
Summary
Sends message to command UI to open an application.
Args
- folder: (str) Path to the folder containing the application.
- version: (Optional[str]) Name of the version to open.
- read_only: (Optional[bool]) If True, the application will be opened in read-only mode.
- resources: (Optional[Dict]) Dictionary with the desired resources to be used when opening the application.
- open_on_new_instance: (Optional[bool]) If True, the application will be opened in a new instance.
- show_versions_on_open: (Optional[bool]) If True, the application will show the list of available versions on open.
- interface_id_to_open_on_start: (Optional[str]) ID of the interface to open when the application is launched. If not provided, the default interface for that version will be opened.
Returns
- None
Examples
pp.open_app(
folder='my_company/Public/Demand Forecast',
version='v2.3',
)
pp.open_app(
folder='my_company/Public/Demand Forecast',
read_only=True,
show_versions_on_open=True
)
pp.open_app(
folder='my_company/Public/Demand Forecast',
open_on_new_instance=True,
resources={
'metadata': {'cpu_architecture': 'x86'},
'pod_definition': {'spec': {'nodeSelector': {'env': 'PyplanEngines'}}},
'container_params': {'resources': {'limits': {'cpu': '0.95', 'memory': '7.4Gi'}, 'requests': {'cpu': '0.95', 'memory': '7.4Gi'}}}
}
)
pp.open_app(
folder='my_company/Public/Demand Forecast',
version='v2.3',
interface_id_to_open_on_start='u026f30b-b167-4da4-b19c-48b0ba9a37fa'
)
navigate_to_pyplan_section
navigate_to_pyplan_section(section, params)
Summary
Sends message to command UI to go to the selected section.
Args
- section: (NavigationSection) The section of the app to navigate to. Available options:
- 'home'
- 'code'
- 'interfaces'
- 'files'
- 'apps'
- 'scenarios/scenario-manager'
- 'scenarios/scenario-template'
- 'process'
- 'versions'
- 'app-consolidation'
- 'interface-links'
- 'api-endpoints'
- 'instances'
- 'logs'
- 'general-settings'
- 'users'
- 'teams'
- 'departments'
- 'roles'
- 'permissions-by-role'
- 'companies'
- 'assistant-bots'
- params: (Optional[dict]) Dictionary with additional parameters for the following sections:
- If section is 'code':
- 'node_id': (str) ID of the node to navigate to.
- 'code_layout_id' (Optional[int]) One of the following layout codes:
- 1: Result
- 2: Result+Code
- 'run_node': (Optional[bool]) Boolean to indicate if the node must be run when selected.
- If section is 'interface':
- 'interface_id': (Optional[str]) ID of the interface to navigate to.
- If section is 'files':
- 'folder_path': (Optional[str]) Folder path to navigate to.
- If section is 'code':
Returns
- None
Examples
pp.navigate_to_pyplan_section(
section='code',
params={
'node_id': 'cdm_demand',
'code_layout_id': 1,
'run_node': True
}
)
pp.navigate_to_pyplan_section(
section='interfaces',
params={
'interface_id': '0026f30b-b167-4da4-b19c-48b0ba9a37ff'
}
)
pp.navigate_to_pyplan_section(
section='files',
params={
'folder_path': 'pyplan/Public/My app/data'
}
)
pp.navigate_to_pyplan_section(
section='versions'
)
send_email
send_email(html_content, emails_to, names_to, subject, cc, bcc, reply_to, name_from, attachment_paths, email_from, email_type, context)
Summary
Sends an email with the given parameters.
Args
- html_content: (str) HTML content of the email body.
- emails_to: (List[str]) List of recipient email addresses.
- names_to: (Optional[List[str]]) List of recipient names corresponding to
emails_to. - subject: (Optional[str]) Email subject.
- cc: (Optional[List[str]]) List of CC recipient email addresses.
- bcc: (Optional[List[str]]) List of BCC recipient email addresses.
- reply_to: (Optional[List[str]]) List of Reply-To email addresses.
- attachment_paths: (Optional[List[str]]) List of absolute file paths for attachments.
- name_from: (Optional[str]) Display name of the sender.
- email_from: (Optional[str]) Sender email address.
- email_type: (Optional[int]) Email type identifier (mapped to the
EmailTypeenum). - context: (Optional[Dict]) Dictionary containing additional template context for the email.
Returns
- None
Examples
pp.send_email(
html_content='<p>Forecast report is ready.</p>',
emails_to=['jdoe@example.com', 'jbloggs@example.com'],
subject='Sales Forecast Summary',
)
pp.send_email(
html_content='<p>Dear team, please check the attached sales forecast report.</p>',
emails_to=['jdoe@example.com'],
names_to=['John Doe'],
subject='Sales Forecast Summary',
cc=['jbloggs@example.com'],
reply_to=['michael.smith@my-company.com'],
name_from='Sales Team',
attachment_paths=['/data/models/my_company/Public/My app/outputs/report.pdf'],
)
install_library
install_library(pypi_name, import_name=None)
DEPRECATED. Use the Lib manager instead.
Parameters
- pypi_name (
str): The name of the package to be installed from PyPI. - import_name (
Optional[str]): The name used to import the package. Defaults topypi_name.
Returns
- bool:
Trueif the installation is successful.
Example
# Example usage is not recommended as this function is deprecated.
_exists_module
_exists_module(import_name)
Checks if a module is installed.
Parameters
- import_name (
str): The name of the module to check for.
Returns
- bool:
Trueif the module is installed,Falseotherwise.
Example
>>> pp._exists_module('scipy')
True