From 82d7298d59e31c8684ba21e6ba8a8f402732422f Mon Sep 17 00:00:00 2001 From: Nicholas Long <1907354+nllong@users.noreply.github.com> Date: Wed, 15 Nov 2023 10:55:57 -0700 Subject: [PATCH] add analysis retrieve methods (#34) --- pyseed/seed_client.py | 55 +++++++++++++++++++++++++++++++++----- pyseed/seed_client_base.py | 6 ++++- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/pyseed/seed_client.py b/pyseed/seed_client.py index e16e8e8..c60335b 100644 --- a/pyseed/seed_client.py +++ b/pyseed/seed_client.py @@ -216,8 +216,8 @@ def get_property_view(self, property_view_id: int) -> dict: property_view_id, endpoint="property_views", data_name="property_views" ) - def get_property(self, property_id: int) -> dict: - """Return a single property by the property id. + def get_property(self, property_view_id: int) -> dict: + """Return a single property by the property view id. Args: property__id (int): ID of the property to return. This is the ID that is in the URL http://SEED_URL/app/#/properties/{property_view_id} @@ -236,7 +236,7 @@ def get_property(self, property_id: int) -> dict: """ # NOTE: this seems to be the call that OEP uses (returns property and labels dictionaries) return self.client.get( - property_id, endpoint="properties", data_name="properties" + property_view_id, endpoint="properties", data_name="properties" ) def search_buildings( @@ -379,18 +379,23 @@ def delete_label(self, label_name: str) -> dict: return self.client.delete(id, endpoint="labels") - def get_view_ids_with_label(self, label_names: list = []) -> list: - """Get the view IDs of the properties with a given label name. + def get_view_ids_with_label(self, label_names: Union[str, list] = []) -> list: + """Get the view IDs of the properties with a given label name(s). Can be a single + label or a list of labels. Note that with labels, the data.selected field is for property view ids! SEED was updated in June 2022 to add in the label_names to filter on. Args: - label_names (list, optional): list of the labels to filter on. Defaults to []. + label_names (str, list, optional): list of the labels to filter on. Defaults to []. Returns: list: list of labels and the views they are associated with """ + # if the label_names is not a list, then make it one + if not isinstance(label_names, list): + label_names = [label_names] + properties = self.client.post( endpoint="properties_labels", cycle=self.cycle_id, @@ -1472,3 +1477,41 @@ def import_portfolio_manager_property(self, seed_id: int, cycle_id: int, mapping ) return response + + def retrieve_analyses_for_property(self, property_id: int) -> dict: + """Retrieve a list of all the analyses for a single property id. Since this + is a property ID, then it is all the analyses for the all cycles. Note that this endpoint + requires the passing of the organization id as a query parameter, otherwise it fails. + + Args: + property_id (int): Property view id to return the list of analyses + + Returns: + dict: list of all the analyses that have run (or failed) for the property view + """ + return self.client.get( + None, + required_pk=False, + endpoint="properties_analyses", + url_args={"PK": property_id}, + include_org_id_query_param=True, + ) + + def retrieve_analysis_result(self, analysis_id: int, analysis_view_id: int) -> dict: + """Return the detailed JSON of a single analysis view. The endpoint in SEED is + typically: https://dev1.seed-platform.org/app/#/analyses/274/runs/14693. + + Args: + analysis_id (int): ID of the analysis + analysis_view_id (int): ID of the analysis view + + Returns: + dict: Return the detailed results of a single analysis view + """ + return self.client.get( + None, + required_pk=False, + endpoint="analyses_views", + url_args={"PK": analysis_id, "ANALYSIS_VIEW_PK": analysis_view_id}, + include_org_id_query_param=True, + ) diff --git a/pyseed/seed_client_base.py b/pyseed/seed_client_base.py index bffbbb0..5528fcb 100644 --- a/pyseed/seed_client_base.py +++ b/pyseed/seed_client_base.py @@ -51,7 +51,6 @@ 'properties': '/api/v3/properties/', 'properties_labels': '/api/v3/properties/labels/', 'properties_search': '/api/v3/properties/search/', - 'property_states': '/api/v3/property_states/', 'property_views': '/api/v3/property_views/', 'taxlots': '/api/v3/taxlots/', 'upload': '/api/v3/upload/', @@ -69,10 +68,12 @@ 'properties_update_with_buildingsync': 'api/v3/properties/PK/update_with_building_sync/', 'property_update_with_espm': 'api/v3/properties/PK/update_with_espm/', # GETs with replaceable keys + 'analyses_views': '/api/v3/analyses/PK/views/ANALYSIS_VIEW_PK/', 'import_files_matching_results': '/api/v3/import_files/PK/matching_and_geocoding_results/', 'progress': '/api/v3/progress/PROGRESS_KEY/', 'properties_meters': '/api/v3/properties/PK/meters/', 'properties_meter_usage': '/api/v3/properties/PK/meter_usage/', + 'properties_analyses': '/api/v3/properties/PK/analyses/', 'audit_template_building_xml': '/api/v3/audit_template/PK/get_building_xml', # GET & POST with replaceable keys 'properties_meters_reading': '/api/v3/properties/PK/meters/METER_PK/readings/', @@ -425,11 +426,14 @@ def get(self, pk, endpoint=None, data_name=None, **kwargs): """ url_args = kwargs.pop('url_args', None) + org_id_qp = kwargs.pop('include_org_id_query_param', False) kwargs = self._set_params(kwargs) endpoint = _set_default(self, 'endpoint', endpoint) data_name = _set_default(self, 'data_name', data_name, required=False) url = add_pk(self.urls[endpoint], pk, required=kwargs.pop('required_pk', True), slash=True) url = _replace_url_args(url, url_args) + if org_id_qp: + url += f"?organization_id={self.org_id}" response = super(ReadMixin, self)._get(url=url, **kwargs) self._check_response(response, **kwargs) return self._get_result(response, data_name=data_name, **kwargs)