diff --git a/smartpm/endpoints/models.py b/smartpm/endpoints/models.py new file mode 100644 index 0000000..cc05cf4 --- /dev/null +++ b/smartpm/endpoints/models.py @@ -0,0 +1,65 @@ +from smartpm.client import SmartPMClient +from smartpm.decorators import api_wrapper +from smartpm.logging_config import logger + +from datetime import datetime + +class Models: + def __init__(self, client: SmartPMClient): + self.client = client + + @api_wrapper + def get_models(self, project_id): + """ + Gets all models for a project: https://developers.smartpmtech.com/#operation/get-public-v1-projects-projectId-models + + Parameters + ---------- + project_id : str + The Project ID containing the scenario for which you would like to pull the delay table for + + Returns + ------- + response : list of dict + model for a schedule + """ + logger.debug(f"Fetching models for project_id: {project_id}") + + endpoint = f'v1/projects/{project_id}/models' + response = self.client._get(endpoint=endpoint) + + return response + + @api_wrapper + def find_baseline_model(self, project_id, find_original=True): + """ + Gets the baseline models from a project. + + Parameters + ---------- + project_id : int + The Project ID containing the scenario for which you would like to pull the delay table for. + find_original : bool, default True + If True, find the original baseline model. If False, find the latest baseline model. + + Returns + ------- + dict + The baseline model for a schedule. + """ + models = self.get_models(project_id=project_id) + baseline_models = [model for model in models if model['projectId'] == project_id and model['modelType'] == 'BASELINE'] + + if not baseline_models: + return None # Return None if no baseline models found + + if find_original: + # Find the original baseline model (assuming there is only one original baseline) + original_model = next((model for model in baseline_models if model['isOriginalModel']), None) + + return original_model + else: + # Find the latest baseline model without modifying the original data + latest_model = max(baseline_models, key=lambda model: datetime.strptime(model['initialDataDate'], "%Y-%m-%dT%H:%M:%SZ")) + + return latest_model \ No newline at end of file diff --git a/smartpm/endpoints/projects.py b/smartpm/endpoints/projects.py index 9f330b3..94ad2e2 100644 --- a/smartpm/endpoints/projects.py +++ b/smartpm/endpoints/projects.py @@ -34,6 +34,46 @@ def get_projects(self, as_of=None): response = self.client._get(endpoint=endpoint, params=params) return response + @api_wrapper + def get_active_projects(self, as_of=None): + """ + Access basic project data: https://developers.smartpmtech.com/#operation/get-projects + Note: the `filters` parameter is hard-coded since the provided filter options are needed. + + Parameters + ---------- + as_of : str + specify date since projects have changed in format `2023-07-19T12:00:00` + + Returns + ------- + : list of dict + projects data as a JSON object + """ + logger.debug(f"Fetching projects as of: {as_of}") + + # Hard-code project plan filters into the params + # Inactive: 0b657f37-e317-4d65-9ebd-b4f6f0aae4b1 + filters = [ + 'PROJECT_PLAN_ID:1164d4b6-9635-42ca-b004-37907055b285', + 'PROJECT_PLAN_ID:6698a06d-a690-4a8d-8bb9-07ebd96ba320', + 'PROJECT_PLAN_ID:9beb9b50-649b-48b1-a367-9b937c75cee3' + ] + + # Construct the params dict + params = { + 'filters': filters # Passing the filters as a list + } + + if as_of: + params['asOf'] = as_of + + endpoint = 'v1/projects' + response = self.client._get(endpoint=endpoint, params=params) + + return response + + @api_wrapper def get_project(self, project_id): """ diff --git a/snippets/explore_models.py b/snippets/explore_models.py new file mode 100644 index 0000000..424d401 --- /dev/null +++ b/snippets/explore_models.py @@ -0,0 +1,76 @@ +import os +import sys +import json + +# Add the package root directory to the sys.path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))) + +from dotenv import load_dotenv +load_dotenv() # Load environment variables from .env file + +from smartpm.client import SmartPMClient +from smartpm.endpoints.projects import Projects # import projects to get project IDs +from smartpm.endpoints.models import Models + +API_KEY = os.getenv("API_KEY") +COMPANY_ID = os.getenv("COMPANY_ID") + +def main(): + # Setup SDK + client = SmartPMClient(API_KEY, COMPANY_ID) + projects_api = Projects(client) + models_api = Models(client) + + # Get Models Data + # --------------- + # For all projects + projects = projects_api.get_projects() + ''' + for project in projects: + project_id = project["id"] + models = models_api.get_models( + project_id=project_id + ) + print(f"Models for project {project['name']}:") + print(json.dumps(models, indent=4)) + ''' + # --------------- + + # Get Models Data for Specific Project + # ------------------------------------ + # Find project by name + name_to_find = "212096 - 401 FIRST STREET (College Station)" # replace with your project name + project = projects_api.find_project_by_name(name=name_to_find) + project_id = project["id"] + + print(f"Get Models data for {name_to_find}") + models = models_api.get_models( + project_id=project_id + ) + print(json.dumps(models, indent=4)) + # ------------------------------------ + + # Get Baseline Model for Specific Project + # --------------------------------------- + # Find project by name + name_to_find = "231068 Databank DFW8 ACCEL RE-BL - CO PENDING" # replace with your project name + project = projects_api.find_project_by_name(name=name_to_find) + project_id = project["id"] + + print(f"Get Original Basline Model for {name_to_find}") + model_baseline_original = models_api.find_baseline_model( + project_id=project_id, + find_original=True + ) + print(json.dumps(model_baseline_original, indent=4)) + + print(f"Get Latest Basline Model for {name_to_find}") + model_baseline_latest = models_api.find_baseline_model( + project_id=project_id, + find_original=False + ) + print(json.dumps(model_baseline_latest, indent=4)) + # --------------------------------------- + +if __name__ == "__main__": + main() diff --git a/snippets/explore_projects.py b/snippets/explore_projects.py index 10c715a..f510cd9 100644 --- a/snippets/explore_projects.py +++ b/snippets/explore_projects.py @@ -49,6 +49,16 @@ def main(): output_projects(project_list=projects) # ---------------- + # Get Active Projects + # ---------------- + print("Get Active Projects") + active_projects = projects_api.get_active_projects() + + # Show projects + print("Number of Active Projects:", len(active_projects)) + output_projects(project_list=active_projects) + # ---------------- + # Get Recently Updated Projects # ----------------------------- print("\nGet Recently Updated Projects") @@ -62,7 +72,7 @@ def main(): # Get Specific Project # -------------------- print("\nGet Specific Project") - project_id = 47939 + project_id = 47808 project_details = projects_api.get_project(project_id=project_id) print(json.dumps(project_details, indent=4))