-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Merge main into develop after release (#21) * Release 0.3.0 (#20) * precommit * Fix delete cycle progress key and race condition (#24) * Release 0.3.0 (#20) * precommit * add progress key to delete cycles * Remove deprecated APIs, fix typos (#23) * Update README.rst * update license (#26) * Updates to support 179d, includes creating property, downloading property reports from ESPM, and updating building search(#22) * adding create_building and update_building methods * modify search_buildings to provide appropriate cycle id * adding client methods for creating extra data columns * add pass throughs for file downloads * updates for audit template workflow * method to download property xlsx --------- Co-authored-by: Alex Swindler <[email protected]> Co-authored-by: Nicholas Long <[email protected]> Co-authored-by: Nicholas Long <[email protected]> * prep release * increase timeout for server start * increase timeout for server start (#31) * cleanup before release (#32) * configure seed to load small EEEJ dataset for integration test (#33) * add analysis retrieve methods (#34) * Added multiple cycle upload argument (#27) * Added multiple cycle upload argument * Responded to comments and fixed failing tests * Converted to using kwargs * Pre-commit * Cleanup README.rst (#35) * cleanup readme * populate description in pypi * precommit fix * Endpoint to download an Audit Template Report Submission and store in SEED (#36) * start of AT report download method * adding endpoint to download AT report submission and store in SEED * add analysis retrieve methods (#34) * Added multiple cycle upload argument (#27) * Added multiple cycle upload argument * Responded to comments and fixed failing tests * Converted to using kwargs * Pre-commit * Cleanup README.rst (#35) * cleanup readme * populate description in pypi * precommit fix * Endpoint to download an Audit Template Report Submission and store in SEED (#36) * start of AT report download method * adding endpoint to download AT report submission and store in SEED * prep 0.4.1 (#37) * Update CHANGELOG.rst * update release instruction * Update README.rst * Update README.rst * add new method to get AT submission metadata (#39) * Update CHANGELOG.rst * Update setup.cfg * Added ESPM functions to py-seed client (#28) * Added ESPM functions to py-seed client * Cleaned up the code and put the downloads into its own folder called "reports" * Added openpyxl to requirements * Fixing tests * First pass at adding test * First draft of finishing the test * Finished get report template names test * Started troubleshooting mypy errors * Fixed remaining conflict * Fixed integration test errors * Fix mypy errors * Fixed mypy for Python 3.10 * Precommit * Fix unnecessary typing * Fixed integration tests --------- Co-authored-by: Nicholas Long <[email protected]> Co-authored-by: Alex Swindler <[email protected]> * prep version 0.4.3 (#41) * Add PyPi release action (#42) * add python 3.12 * update test versions * add release connection and update instructions * update precommit versions (#44) * Add create organization and retrieve property cross cycle data (#45) * add methods to support cross cycle property api * cleanup * cleanup * remove prints * fix mypy * comment cleanup * Add is_omitted column to column mapping profiles (#46) * add code to enable client to read the isOmitted field in the CSV file, if present, and to pass it to the backend * isOmitted -> is_omitted * linter * prep version 0.5.0 and added compatibility matrix to readme (#47) * prep version 0.4.4 and added compatibility matrix to readme * fix compatibility table * fix title * Update README.rst * Update setup.cfg --------- Co-authored-by: Nicholas Long <[email protected]> * Update CHANGELOG.rst --------- Co-authored-by: Alex Swindler <[email protected]> Co-authored-by: Katherine Fleming <[email protected]> Co-authored-by: Alex Chapin <[email protected]> Co-authored-by: Caleb Rutan <[email protected]>
- Loading branch information
1 parent
9f6b851
commit 8daebec
Showing
11 changed files
with
244 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,6 +153,18 @@ def instance_information(self) -> dict: | |
info["username"] = self.client.username | ||
return info | ||
|
||
def get_users(self) -> dict: | ||
"""Get a list of users visible to the current user | ||
Returns: | ||
dict: { "users": [{ | ||
"email": "[email protected]", | ||
"user_id": 1 | ||
}]} | ||
""" | ||
users = self.client.list(endpoint="users") | ||
return users | ||
|
||
def get_organizations(self, brief: bool = True) -> dict: | ||
"""Get a list organizations (that one is allowed to view) | ||
|
@@ -179,6 +191,67 @@ def get_organizations(self, brief: bool = True) -> dict: | |
) | ||
return orgs | ||
|
||
def get_user_id(self, username: str) -> Union[None, int]: | ||
"""Get the user ID for the given username | ||
Args: | ||
username (str): username to get the ID for | ||
Returns: | ||
int: user ID | ||
""" | ||
for user in self.get_users()['users']: | ||
# compare string case insensitive | ||
if user["email"].lower() == username.lower(): | ||
return user["user_id"] | ||
|
||
return None | ||
|
||
def create_organization(self, org_name: str) -> dict: | ||
"""Create an organization with the given name | ||
Args: | ||
org_name (str): name of the organization to create | ||
Returns: | ||
dict: { | ||
'status': 'success', | ||
'message': 'Organization created', | ||
'organization': { | ||
'name': 'NEW ORG', | ||
'org_id': 17, | ||
'id': 17, | ||
'number_of_users': 1, | ||
'user_is_owner': True, | ||
'user_role': 'owner', | ||
'owners': [...], | ||
'sub_orgs': [...], | ||
'is_parent': True, | ||
'parent_id': 17, | ||
... | ||
'display_units_eui': 'kBtu/ft**2/year', | ||
'cycles': [...], | ||
'created': '2024-06-13', | ||
'mapquest_api_key': '', | ||
} | ||
} | ||
""" | ||
# see if the organization already exists | ||
orgs = self.get_organizations() | ||
for org in orgs: | ||
if org["name"].lower() == org_name.lower(): | ||
raise Exception(f"Organization '{org_name}' already exists") | ||
|
||
user_id = self.get_user_id(self.client.username) | ||
|
||
payload = { | ||
"user_id": user_id, | ||
"organization_name": org_name, | ||
} | ||
org = self.client.post(endpoint="organizations", json=payload) | ||
return org | ||
|
||
def get_buildings(self) -> list[dict]: | ||
total_qry = self.client.list(endpoint="properties", data_name="pagination", per_page=100) | ||
|
||
|
@@ -584,13 +657,14 @@ def get_or_create_cycle( | |
end_date: date, | ||
set_cycle_id: bool = False, | ||
) -> dict: | ||
"""Get or create a new cycle. If the cycle_name already exists, then it simply returns the existing cycle. However, if the cycle_name does not exist, then it will create a new cycle. | ||
"""Get or create a new cycle. If the cycle_name already exists, then it simply returns | ||
the existing cycle. However, if the cycle_name does not exist, then it will create a new cycle. | ||
Args: | ||
cycle_name (str): name of the cycle to get or create | ||
start_date (date): MM/DD/YYYY of start date cycle | ||
end_date (date): MM/DD/YYYY of end data for cycle | ||
set_cycle_id (str): Set the object's cycle_id to the resulting cycle that is returned (either existing or newly created) | ||
set_cycle_id (str): Set the object's cycle_id to the resulting cycle that is returned (either existing or newly created) | ||
Returns: | ||
dict: { | ||
|
@@ -850,6 +924,7 @@ def create_or_update_column_mapping_profile( | |
"from_units": null, | ||
"to_table_name": "PropertyState" | ||
"to_field": "address_line_1", | ||
"is_omitted": False | ||
}, | ||
{ | ||
"from_field": "address1", | ||
|
@@ -860,6 +935,7 @@ def create_or_update_column_mapping_profile( | |
... | ||
] | ||
The is_omitted mapping may be absent - it is treated as False if it is not present. | ||
Returns: | ||
dict: { | ||
'id': 1 | ||
|
@@ -898,9 +974,9 @@ def create_or_update_column_mapping_profile_from_file( | |
) -> dict: | ||
"""creates or updates a mapping profile. The format of the mapping file is a CSV with the following format: | ||
Raw Columns, units, SEED Table, SEED Columns\n | ||
PM Property ID, , PropertyState, pm_property_id\n | ||
Building ID, , PropertyState, custom_id_1\n | ||
Raw Columns, units, SEED Table, SEED Columns, Omit\n | ||
PM Property ID, , PropertyState, pm_property_id, False\n | ||
Building ID, , PropertyState, custom_id_1, False\n | ||
...\n | ||
This only works for 'Normal' column mapping profiles, that is, it does not work for | ||
|
@@ -949,7 +1025,7 @@ def set_import_file_column_mappings( | |
) | ||
|
||
def get_columns(self) -> dict: | ||
"""get the list of columns. | ||
"""Get the list of columns | ||
Returns: | ||
dict: { | ||
|
@@ -961,7 +1037,8 @@ def get_columns(self) -> dict: | |
return result | ||
|
||
def create_extra_data_column(self, column_name: str, display_name: str, inventory_type: str, column_description: str, data_type: str) -> dict: | ||
""" create an extra data column. If column exists, skip | ||
"""Create an extra data column. If column exists, skip | ||
Args: | ||
'column_name': 'project_type', | ||
'display_name': 'Project Type', | ||
|
@@ -979,7 +1056,6 @@ def create_extra_data_column(self, column_name: str, display_name: str, inventor | |
} | ||
} | ||
""" | ||
|
||
# get extra data columns (only) | ||
result = self.client.list(endpoint="columns") | ||
columns = result['columns'] | ||
|
@@ -1005,7 +1081,8 @@ def create_extra_data_column(self, column_name: str, display_name: str, inventor | |
return result | ||
|
||
def create_extra_data_columns_from_file(self, columns_csv_filepath: str) -> list: | ||
""" create extra data columns from a csv file. if column exist, skip. | ||
"""Create extra data columns from a csv file. if column exist, skip. | ||
Args: | ||
'columns_csv_filepath': 'path/to/file' | ||
file is expected to have headers: column_name, display_name, column_description, | ||
|
@@ -1156,11 +1233,13 @@ def get_meter_data(self, property_id, interval: str = 'Exact', excluded_meter_id | |
|
||
def start_save_data(self, import_file_id: int, multiple_cycle_upload: bool = False) -> dict: | ||
"""start the background process to save the data file to the database. | ||
This is the state before the mapping. | ||
This is the state before the mapping. If multiple_cycle_upload is set to True, then the | ||
importing file's year_ending column will be used to determine the cycle. Note that the | ||
cycles must be created in SEED for the multiple cycle upload to work correctly | ||
Args: | ||
import_file_id (int): id of the import file to save | ||
multiple_cycle_upload (bool): whether to use multiple cycle upload | ||
multiple_cycle_upload (bool): whether to use multiple cycle upload. | ||
Returns: | ||
dict: progress key | ||
|
@@ -1435,8 +1514,12 @@ def upload_and_match_datafile( | |
column_mapping_profile_name (str): Name of the column mapping profile to use | ||
column_mappings_file (str): Mapping that will be uploaded to the column_mapping_profile_name | ||
import_meters_if_exist (bool): If true, will import meters from the meter tab if they exist in the datafile. Defaults to False. | ||
Kwargs: | ||
datafile_type (str): Type of datafile | ||
multiple_cycle_upload (bool): Whether to use multiple cycle upload. Defaults to False. | ||
Returns: | ||
dict: { | ||
matching summary | ||
|
@@ -1707,3 +1790,22 @@ def retrieve_analysis_result(self, analysis_id: int, analysis_view_id: int) -> d | |
url_args={"PK": analysis_id, "ANALYSIS_VIEW_PK": analysis_view_id}, | ||
include_org_id_query_param=True, | ||
) | ||
|
||
def get_cross_cycle_data(self, property_view_id: int) -> dict: | ||
"""Retrieve the cross cycle data for a property. This is the data that | ||
is shared across all the cycles used to populate a property's cross | ||
cycle view. | ||
Args: | ||
property_view_id (int): Property view id | ||
Returns: | ||
dict: Cross cycle data for the property view | ||
""" | ||
return self.client.get( | ||
None, | ||
required_pk=False, | ||
endpoint="properties_cross_cycle_data", | ||
url_args={"PK": property_view_id}, | ||
include_org_id_query_param=True, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[metadata] | ||
name=py-seed | ||
version=0.4.3 | ||
version=0.5.0 | ||
description=A Python API client for the SEED Platform | ||
author=Nicholas Long, Katherine Fleming, Fable Turas, Paul Munday | ||
author_email[email protected], [email protected], [email protected] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Oops, something went wrong.