EPA-PM-API-Wrapper 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (654) hide show
  1. epa_pm_api_wrapper/__init__.py +30 -0
  2. epa_pm_api_wrapper/__main__.py +4 -0
  3. epa_pm_api_wrapper/cli.py +413 -0
  4. epa_pm_api_wrapper/client.py +507 -0
  5. epa_pm_api_wrapper/exceptions.py +67 -0
  6. epa_pm_api_wrapper/models/__init__.py +1451 -0
  7. epa_pm_api_wrapper/models/accept_reject_type.py +12 -0
  8. epa_pm_api_wrapper/models/account.py +15 -0
  9. epa_pm_api_wrapper/models/account_info.py +58 -0
  10. epa_pm_api_wrapper/models/account_type.py +122 -0
  11. epa_pm_api_wrapper/models/account_type_language_preference.py +9 -0
  12. epa_pm_api_wrapper/models/additional_identifier.py +58 -0
  13. epa_pm_api_wrapper/models/additional_identifier_type.py +60 -0
  14. epa_pm_api_wrapper/models/additional_identifier_type_group.py +10 -0
  15. epa_pm_api_wrapper/models/additional_identifier_types.py +19 -0
  16. epa_pm_api_wrapper/models/additional_identifiers.py +19 -0
  17. epa_pm_api_wrapper/models/address_type.py +84 -0
  18. epa_pm_api_wrapper/models/address_type_state.py +159 -0
  19. epa_pm_api_wrapper/models/adult_education.py +17 -0
  20. epa_pm_api_wrapper/models/agency_type.py +41 -0
  21. epa_pm_api_wrapper/models/agency_type_country.py +242 -0
  22. epa_pm_api_wrapper/models/alerts.py +16 -0
  23. epa_pm_api_wrapper/models/alerts_type.py +47 -0
  24. epa_pm_api_wrapper/models/alerts_type_alert.py +29 -0
  25. epa_pm_api_wrapper/models/all_energy_meters_type.py +32 -0
  26. epa_pm_api_wrapper/models/all_meter_types.py +130 -0
  27. epa_pm_api_wrapper/models/ambulatory_surgical_center.py +16 -0
  28. epa_pm_api_wrapper/models/amount_of_laundry_processed_annually.py +17 -0
  29. epa_pm_api_wrapper/models/amount_of_laundry_processed_annually_type.py +28 -0
  30. epa_pm_api_wrapper/models/amount_of_laundry_processed_annually_units_type.py +9 -0
  31. epa_pm_api_wrapper/models/annual_research_expenditure.py +16 -0
  32. epa_pm_api_wrapper/models/annual_research_expenditure_type.py +22 -0
  33. epa_pm_api_wrapper/models/annual_research_expenditure_type_value.py +10 -0
  34. epa_pm_api_wrapper/models/aquarium.py +17 -0
  35. epa_pm_api_wrapper/models/area_of_all_walk_in_refrigeration_units.py +19 -0
  36. epa_pm_api_wrapper/models/average_effluent_biological_oxygen_demand.py +16 -0
  37. epa_pm_api_wrapper/models/average_influent_biological_oxygen_demand.py +16 -0
  38. epa_pm_api_wrapper/models/average_number_of_residents.py +15 -0
  39. epa_pm_api_wrapper/models/average_number_of_vehicles_in_inventory.py +16 -0
  40. epa_pm_api_wrapper/models/bank_branch.py +16 -0
  41. epa_pm_api_wrapper/models/bank_branch_type.py +35 -0
  42. epa_pm_api_wrapper/models/bank_branch_type_use_details.py +58 -0
  43. epa_pm_api_wrapper/models/bar_nightclub.py +17 -0
  44. epa_pm_api_wrapper/models/barracks.py +17 -0
  45. epa_pm_api_wrapper/models/barracks_type.py +35 -0
  46. epa_pm_api_wrapper/models/barracks_type_use_details.py +58 -0
  47. epa_pm_api_wrapper/models/baseline_and_target.py +16 -0
  48. epa_pm_api_wrapper/models/baseline_and_target_type.py +27 -0
  49. epa_pm_api_wrapper/models/baseline_type.py +41 -0
  50. epa_pm_api_wrapper/models/billboard_metric_setting.py +21 -0
  51. epa_pm_api_wrapper/models/billboard_metric_type.py +33 -0
  52. epa_pm_api_wrapper/models/billboard_metrics.py +11 -0
  53. epa_pm_api_wrapper/models/billboard_metrics_type.py +26 -0
  54. epa_pm_api_wrapper/models/bowling_alley.py +40 -0
  55. epa_pm_api_wrapper/models/bowling_alley_use_details.py +58 -0
  56. epa_pm_api_wrapper/models/building.py +11 -0
  57. epa_pm_api_wrapper/models/casino.py +16 -0
  58. epa_pm_api_wrapper/models/category_type.py +17 -0
  59. epa_pm_api_wrapper/models/cegep.py +15 -0
  60. epa_pm_api_wrapper/models/cegep_type.py +35 -0
  61. epa_pm_api_wrapper/models/cegep_type_use_details.py +131 -0
  62. epa_pm_api_wrapper/models/ceiling_height.py +15 -0
  63. epa_pm_api_wrapper/models/ceiling_height_units_type.py +27 -0
  64. epa_pm_api_wrapper/models/clear_height.py +16 -0
  65. epa_pm_api_wrapper/models/clear_height_units_type.py +26 -0
  66. epa_pm_api_wrapper/models/college_university.py +15 -0
  67. epa_pm_api_wrapper/models/college_university_type.py +37 -0
  68. epa_pm_api_wrapper/models/college_university_type_use_details.py +131 -0
  69. epa_pm_api_wrapper/models/common_entrance.py +16 -0
  70. epa_pm_api_wrapper/models/community_center_and_social_meeting_hall.py +46 -0
  71. epa_pm_api_wrapper/models/community_center_and_social_meeting_hall_use_details.py +58 -0
  72. epa_pm_api_wrapper/models/completely_enclosed_footage.py +15 -0
  73. epa_pm_api_wrapper/models/construction_status_type.py +9 -0
  74. epa_pm_api_wrapper/models/contact_type.py +70 -0
  75. epa_pm_api_wrapper/models/convenience_store_with_gas_station.py +19 -0
  76. epa_pm_api_wrapper/models/convenience_store_with_gas_station_type.py +37 -0
  77. epa_pm_api_wrapper/models/convenience_store_with_gas_station_type_use_details.py +140 -0
  78. epa_pm_api_wrapper/models/convenience_store_without_gas_station.py +19 -0
  79. epa_pm_api_wrapper/models/convenience_store_without_gas_station_type.py +37 -0
  80. epa_pm_api_wrapper/models/convenience_store_without_gas_station_type_use_details.py +140 -0
  81. epa_pm_api_wrapper/models/convention_center.py +16 -0
  82. epa_pm_api_wrapper/models/cooking_facilities.py +15 -0
  83. epa_pm_api_wrapper/models/cooking_located_onsite.py +16 -0
  84. epa_pm_api_wrapper/models/cooling_equipment_redundancy.py +15 -0
  85. epa_pm_api_wrapper/models/cooling_equipment_redundancy_type.py +22 -0
  86. epa_pm_api_wrapper/models/cooling_equipment_redundancy_type_value.py +12 -0
  87. epa_pm_api_wrapper/models/country_code.py +16 -0
  88. epa_pm_api_wrapper/models/country_list.py +493 -0
  89. epa_pm_api_wrapper/models/courthouse.py +16 -0
  90. epa_pm_api_wrapper/models/courthouse_type.py +35 -0
  91. epa_pm_api_wrapper/models/courthouse_type_use_details.py +58 -0
  92. epa_pm_api_wrapper/models/custom_field.py +109 -0
  93. epa_pm_api_wrapper/models/custom_field_list.py +20 -0
  94. epa_pm_api_wrapper/models/custom_field_list_custom_field.py +17 -0
  95. epa_pm_api_wrapper/models/custom_field_valid_characters.py +15 -0
  96. epa_pm_api_wrapper/models/custom_field_when_to_prompt.py +15 -0
  97. epa_pm_api_wrapper/models/custom_metric.py +49 -0
  98. epa_pm_api_wrapper/models/custom_units_type.py +19 -0
  99. epa_pm_api_wrapper/models/custom_use.py +15 -0
  100. epa_pm_api_wrapper/models/custom_use_detail1.py +15 -0
  101. epa_pm_api_wrapper/models/custom_use_detail2.py +15 -0
  102. epa_pm_api_wrapper/models/custom_use_details_type.py +50 -0
  103. epa_pm_api_wrapper/models/custom_use_details_type_data_type.py +8 -0
  104. epa_pm_api_wrapper/models/custom_use_type.py +35 -0
  105. epa_pm_api_wrapper/models/custom_use_type_use_details.py +27 -0
  106. epa_pm_api_wrapper/models/customer.py +77 -0
  107. epa_pm_api_wrapper/models/customer_language_preference.py +9 -0
  108. epa_pm_api_wrapper/models/data_center.py +17 -0
  109. epa_pm_api_wrapper/models/data_center_type.py +35 -0
  110. epa_pm_api_wrapper/models/data_center_type_use_details.py +50 -0
  111. epa_pm_api_wrapper/models/data_exchange_settings.py +37 -0
  112. epa_pm_api_wrapper/models/data_exchange_settings_supported_meter_types.py +20 -0
  113. epa_pm_api_wrapper/models/data_exchange_settings_terms_of_use.py +40 -0
  114. epa_pm_api_wrapper/models/data_request.py +88 -0
  115. epa_pm_api_wrapper/models/data_request_locations.py +19 -0
  116. epa_pm_api_wrapper/models/data_request_locations_location.py +22 -0
  117. epa_pm_api_wrapper/models/data_request_requester_details.py +32 -0
  118. epa_pm_api_wrapper/models/data_request_status_type.py +13 -0
  119. epa_pm_api_wrapper/models/data_response.py +47 -0
  120. epa_pm_api_wrapper/models/data_response_properties.py +20 -0
  121. epa_pm_api_wrapper/models/data_type.py +9 -0
  122. epa_pm_api_wrapper/models/delivery_facility.py +16 -0
  123. epa_pm_api_wrapper/models/demand_tracking_type.py +35 -0
  124. epa_pm_api_wrapper/models/design.py +15 -0
  125. epa_pm_api_wrapper/models/design_base_type.py +83 -0
  126. epa_pm_api_wrapper/models/design_base_type_estimated_energy_list.py +17 -0
  127. epa_pm_api_wrapper/models/design_base_type_property_uses.py +709 -0
  128. epa_pm_api_wrapper/models/design_base_type_target.py +34 -0
  129. epa_pm_api_wrapper/models/design_unit_of_measure.py +37 -0
  130. epa_pm_api_wrapper/models/detail_type.py +22 -0
  131. epa_pm_api_wrapper/models/details_types.py +20 -0
  132. epa_pm_api_wrapper/models/disposal_destination_type.py +60 -0
  133. epa_pm_api_wrapper/models/distribution_center.py +17 -0
  134. epa_pm_api_wrapper/models/distribution_center_type.py +37 -0
  135. epa_pm_api_wrapper/models/distribution_center_type_use_details.py +76 -0
  136. epa_pm_api_wrapper/models/drinking_water_treatment_and_distribution.py +18 -0
  137. epa_pm_api_wrapper/models/drinking_water_treatment_and_distribution_type.py +37 -0
  138. epa_pm_api_wrapper/models/drinking_water_treatment_and_distribution_type_use_details.py +18 -0
  139. epa_pm_api_wrapper/models/e_grid_subregion.py +38 -0
  140. epa_pm_api_wrapper/models/e_grid_subregion_country.py +242 -0
  141. epa_pm_api_wrapper/models/e_grid_subregion_list.py +19 -0
  142. epa_pm_api_wrapper/models/edu.py +64 -0
  143. epa_pm_api_wrapper/models/edu_list.py +18 -0
  144. epa_pm_api_wrapper/models/electric_vehicle_charging_station.py +15 -0
  145. epa_pm_api_wrapper/models/empty_string.py +7 -0
  146. epa_pm_api_wrapper/models/empty_type.py +7 -0
  147. epa_pm_api_wrapper/models/enclosed_floor_area.py +15 -0
  148. epa_pm_api_wrapper/models/enclosed_mall.py +16 -0
  149. epa_pm_api_wrapper/models/energy_meter_assoc_and_config_type.py +25 -0
  150. epa_pm_api_wrapper/models/energy_performance_project.py +11 -0
  151. epa_pm_api_wrapper/models/energy_performance_project_type.py +136 -0
  152. epa_pm_api_wrapper/models/energy_power_station.py +20 -0
  153. epa_pm_api_wrapper/models/energy_uom_type.py +11 -0
  154. epa_pm_api_wrapper/models/enrollment.py +11 -0
  155. epa_pm_api_wrapper/models/error_type.py +29 -0
  156. epa_pm_api_wrapper/models/errors_type.py +25 -0
  157. epa_pm_api_wrapper/models/estimated_energy_list_type.py +19 -0
  158. epa_pm_api_wrapper/models/estimated_energy_type.py +58 -0
  159. epa_pm_api_wrapper/models/estimates_applied.py +15 -0
  160. epa_pm_api_wrapper/models/ev_charging_station_type.py +37 -0
  161. epa_pm_api_wrapper/models/ev_charging_station_type_use_details.py +41 -0
  162. epa_pm_api_wrapper/models/evaluation_period_type.py +35 -0
  163. epa_pm_api_wrapper/models/exterior_entrance_to_the_public.py +15 -0
  164. epa_pm_api_wrapper/models/fast_food_restaurant.py +17 -0
  165. epa_pm_api_wrapper/models/fast_food_restaurant_type.py +37 -0
  166. epa_pm_api_wrapper/models/fast_food_restaurant_type_use_details.py +84 -0
  167. epa_pm_api_wrapper/models/federal_agencies.py +19 -0
  168. epa_pm_api_wrapper/models/financial_office.py +16 -0
  169. epa_pm_api_wrapper/models/financial_office_type.py +35 -0
  170. epa_pm_api_wrapper/models/financial_office_type_use_details.py +58 -0
  171. epa_pm_api_wrapper/models/fire_station.py +16 -0
  172. epa_pm_api_wrapper/models/fire_station_type.py +35 -0
  173. epa_pm_api_wrapper/models/fire_station_type_use_details.py +92 -0
  174. epa_pm_api_wrapper/models/fitness_center_health_club_gym.py +42 -0
  175. epa_pm_api_wrapper/models/fitness_center_health_club_gym_use_details.py +58 -0
  176. epa_pm_api_wrapper/models/fixed_film_trickle_filtration_process.py +15 -0
  177. epa_pm_api_wrapper/models/floor_area_type_base.py +23 -0
  178. epa_pm_api_wrapper/models/food_sales.py +17 -0
  179. epa_pm_api_wrapper/models/food_sales_type.py +35 -0
  180. epa_pm_api_wrapper/models/food_sales_type_use_details.py +114 -0
  181. epa_pm_api_wrapper/models/food_service.py +17 -0
  182. epa_pm_api_wrapper/models/full_service_spa_floor_area.py +15 -0
  183. epa_pm_api_wrapper/models/generation_location_type.py +41 -0
  184. epa_pm_api_wrapper/models/government_subsidized_housing.py +16 -0
  185. epa_pm_api_wrapper/models/grant_dollars.py +11 -0
  186. epa_pm_api_wrapper/models/green_power_fuel_source_enum.py +13 -0
  187. epa_pm_api_wrapper/models/green_power_type_enum.py +15 -0
  188. epa_pm_api_wrapper/models/gross_floor_area_hotel_conference_space.py +18 -0
  189. epa_pm_api_wrapper/models/gross_floor_area_that_is_exhibit_space.py +19 -0
  190. epa_pm_api_wrapper/models/gross_floor_area_type.py +24 -0
  191. epa_pm_api_wrapper/models/gross_floor_area_units_type.py +8 -0
  192. epa_pm_api_wrapper/models/gross_floor_area_used_for_food_preparation.py +19 -0
  193. epa_pm_api_wrapper/models/gym_center_floor_area.py +15 -0
  194. epa_pm_api_wrapper/models/gymnasium_floor_area.py +15 -0
  195. epa_pm_api_wrapper/models/has_computer_lab.py +15 -0
  196. epa_pm_api_wrapper/models/has_dining_hall.py +15 -0
  197. epa_pm_api_wrapper/models/has_laboratory.py +15 -0
  198. epa_pm_api_wrapper/models/hey.py +11 -0
  199. epa_pm_api_wrapper/models/hey_type.py +29 -0
  200. epa_pm_api_wrapper/models/hey_type_meter.py +35 -0
  201. epa_pm_api_wrapper/models/hey_type_meter_meter_data.py +22 -0
  202. epa_pm_api_wrapper/models/hey_type_property_info.py +35 -0
  203. epa_pm_api_wrapper/models/hierarchy.py +16 -0
  204. epa_pm_api_wrapper/models/hierarchy_type.py +84 -0
  205. epa_pm_api_wrapper/models/highest_award_level.py +17 -0
  206. epa_pm_api_wrapper/models/highest_award_level_type.py +20 -0
  207. epa_pm_api_wrapper/models/highest_award_level_type_value.py +11 -0
  208. epa_pm_api_wrapper/models/hospital.py +22 -0
  209. epa_pm_api_wrapper/models/hospital_type.py +35 -0
  210. epa_pm_api_wrapper/models/hospital_type_use_details.py +132 -0
  211. epa_pm_api_wrapper/models/hotel.py +17 -0
  212. epa_pm_api_wrapper/models/hotel_type.py +41 -0
  213. epa_pm_api_wrapper/models/hotel_type_use_details.py +140 -0
  214. epa_pm_api_wrapper/models/hours_per_day_guests_onsite.py +16 -0
  215. epa_pm_api_wrapper/models/hours_per_day_guests_onsite_type.py +22 -0
  216. epa_pm_api_wrapper/models/hours_per_day_guests_onsite_type_value.py +9 -0
  217. epa_pm_api_wrapper/models/ice_curling_rink.py +27 -0
  218. epa_pm_api_wrapper/models/ice_curling_rink_type.py +35 -0
  219. epa_pm_api_wrapper/models/ice_curling_rink_type_use_details.py +78 -0
  220. epa_pm_api_wrapper/models/ice_events.py +15 -0
  221. epa_pm_api_wrapper/models/individual_meter.py +86 -0
  222. epa_pm_api_wrapper/models/indoor_arena.py +17 -0
  223. epa_pm_api_wrapper/models/indoor_arena_type.py +35 -0
  224. epa_pm_api_wrapper/models/indoor_arena_type_use_details.py +104 -0
  225. epa_pm_api_wrapper/models/international_weather_station_list.py +26 -0
  226. epa_pm_api_wrapper/models/irrigation_area_type.py +28 -0
  227. epa_pm_api_wrapper/models/irrigation_area_type_base.py +30 -0
  228. epa_pm_api_wrapper/models/irrigation_area_units_type.py +10 -0
  229. epa_pm_api_wrapper/models/is_high_school.py +16 -0
  230. epa_pm_api_wrapper/models/is_tertiary_care.py +17 -0
  231. epa_pm_api_wrapper/models/it_energy_configuration_type.py +20 -0
  232. epa_pm_api_wrapper/models/it_energy_configuration_type_value.py +14 -0
  233. epa_pm_api_wrapper/models/it_energy_meter_configuration.py +16 -0
  234. epa_pm_api_wrapper/models/k12_school.py +16 -0
  235. epa_pm_api_wrapper/models/k12_school_type.py +35 -0
  236. epa_pm_api_wrapper/models/k12_school_type_use_details.py +126 -0
  237. epa_pm_api_wrapper/models/laboratory.py +17 -0
  238. epa_pm_api_wrapper/models/laundry_facility.py +16 -0
  239. epa_pm_api_wrapper/models/length_of_all_commercial_kitchen_hoods.py +19 -0
  240. epa_pm_api_wrapper/models/length_of_all_open_closed_refrigeration_units.py +21 -0
  241. epa_pm_api_wrapper/models/length_of_use_detail_type.py +26 -0
  242. epa_pm_api_wrapper/models/length_units_type.py +8 -0
  243. epa_pm_api_wrapper/models/library.py +17 -0
  244. epa_pm_api_wrapper/models/library_type.py +35 -0
  245. epa_pm_api_wrapper/models/library_type_use_details.py +58 -0
  246. epa_pm_api_wrapper/models/license.py +60 -0
  247. epa_pm_api_wrapper/models/license_list.py +19 -0
  248. epa_pm_api_wrapper/models/licensed_bed_capacity.py +19 -0
  249. epa_pm_api_wrapper/models/lifestyle_center.py +18 -0
  250. epa_pm_api_wrapper/models/link_type.py +52 -0
  251. epa_pm_api_wrapper/models/links_type.py +19 -0
  252. epa_pm_api_wrapper/models/log.py +11 -0
  253. epa_pm_api_wrapper/models/log_type.py +79 -0
  254. epa_pm_api_wrapper/models/mailing_center_post_office.py +16 -0
  255. epa_pm_api_wrapper/models/mailing_center_post_office_type.py +37 -0
  256. epa_pm_api_wrapper/models/mailing_center_post_office_type_use_details.py +74 -0
  257. epa_pm_api_wrapper/models/manufacturing_industrial_plant.py +17 -0
  258. epa_pm_api_wrapper/models/manufacturing_industrial_plant_type.py +37 -0
  259. epa_pm_api_wrapper/models/manufacturing_industrial_plant_type_use_details.py +49 -0
  260. epa_pm_api_wrapper/models/mapping.py +11 -0
  261. epa_pm_api_wrapper/models/mapping_type.py +23 -0
  262. epa_pm_api_wrapper/models/maximum_number_of_floors.py +15 -0
  263. epa_pm_api_wrapper/models/maximum_resident_capacity.py +15 -0
  264. epa_pm_api_wrapper/models/medical_office.py +16 -0
  265. epa_pm_api_wrapper/models/medical_office_type.py +35 -0
  266. epa_pm_api_wrapper/models/medical_office_type_use_details.py +82 -0
  267. epa_pm_api_wrapper/models/meter.py +11 -0
  268. epa_pm_api_wrapper/models/meter_category_type.py +9 -0
  269. epa_pm_api_wrapper/models/meter_consumption.py +15 -0
  270. epa_pm_api_wrapper/models/meter_consumption_type.py +110 -0
  271. epa_pm_api_wrapper/models/meter_data.py +11 -0
  272. epa_pm_api_wrapper/models/meter_data_type.py +41 -0
  273. epa_pm_api_wrapper/models/meter_delivery.py +11 -0
  274. epa_pm_api_wrapper/models/meter_delivery_type.py +68 -0
  275. epa_pm_api_wrapper/models/meter_list_type.py +23 -0
  276. epa_pm_api_wrapper/models/meter_property_association_list.py +18 -0
  277. epa_pm_api_wrapper/models/meter_property_association_list_type.py +38 -0
  278. epa_pm_api_wrapper/models/meter_property_use_association_list.py +16 -0
  279. epa_pm_api_wrapper/models/meter_type.py +131 -0
  280. epa_pm_api_wrapper/models/meter_type_unit_of_measure.py +40 -0
  281. epa_pm_api_wrapper/models/metric.py +71 -0
  282. epa_pm_api_wrapper/models/months_in_use.py +15 -0
  283. epa_pm_api_wrapper/models/months_in_use_type.py +21 -0
  284. epa_pm_api_wrapper/models/months_main_indoor_ice_rink_in_use.py +15 -0
  285. epa_pm_api_wrapper/models/months_school_in_use_type.py +21 -0
  286. epa_pm_api_wrapper/models/movie_theater.py +15 -0
  287. epa_pm_api_wrapper/models/multifamily_housing.py +16 -0
  288. epa_pm_api_wrapper/models/multifamily_housing_type.py +37 -0
  289. epa_pm_api_wrapper/models/multifamily_housing_type_use_details.py +124 -0
  290. epa_pm_api_wrapper/models/museum.py +26 -0
  291. epa_pm_api_wrapper/models/museum_type.py +35 -0
  292. epa_pm_api_wrapper/models/museum_type_use_details.py +78 -0
  293. epa_pm_api_wrapper/models/non_refrigerated_warehouse.py +16 -0
  294. epa_pm_api_wrapper/models/non_refrigerated_warehouse_type.py +37 -0
  295. epa_pm_api_wrapper/models/non_refrigerated_warehouse_type_use_details.py +76 -0
  296. epa_pm_api_wrapper/models/notification_list.py +16 -0
  297. epa_pm_api_wrapper/models/notification_list_type.py +19 -0
  298. epa_pm_api_wrapper/models/notification_type.py +106 -0
  299. epa_pm_api_wrapper/models/number_of_annual_emergency_incidents.py +17 -0
  300. epa_pm_api_wrapper/models/number_of_bedrooms.py +15 -0
  301. epa_pm_api_wrapper/models/number_of_cash_registers.py +15 -0
  302. epa_pm_api_wrapper/models/number_of_commercial_refrigeration_units.py +16 -0
  303. epa_pm_api_wrapper/models/number_of_commercial_washing_machines.py +16 -0
  304. epa_pm_api_wrapper/models/number_of_computers.py +15 -0
  305. epa_pm_api_wrapper/models/number_of_concert_show_events_per_year.py +15 -0
  306. epa_pm_api_wrapper/models/number_of_cooking_equipment_units.py +15 -0
  307. epa_pm_api_wrapper/models/number_of_curling_sheets.py +16 -0
  308. epa_pm_api_wrapper/models/number_of_dc_fast_ev_charging_stations.py +15 -0
  309. epa_pm_api_wrapper/models/number_of_emergency_vehicles.py +16 -0
  310. epa_pm_api_wrapper/models/number_of_fteworkers.py +16 -0
  311. epa_pm_api_wrapper/models/number_of_full_time_students_enrolled_january_to_april.py +16 -0
  312. epa_pm_api_wrapper/models/number_of_full_time_students_enrolled_may_to_august.py +16 -0
  313. epa_pm_api_wrapper/models/number_of_full_time_students_enrolled_september_to_december.py +16 -0
  314. epa_pm_api_wrapper/models/number_of_guest_meals_served_per_year.py +15 -0
  315. epa_pm_api_wrapper/models/number_of_hotel_rooms.py +15 -0
  316. epa_pm_api_wrapper/models/number_of_indoor_ice_rinks.py +18 -0
  317. epa_pm_api_wrapper/models/number_of_laundry_hookups_in_all_units.py +16 -0
  318. epa_pm_api_wrapper/models/number_of_laundry_hookups_in_common_area.py +16 -0
  319. epa_pm_api_wrapper/models/number_of_letters_packages_per_year.py +17 -0
  320. epa_pm_api_wrapper/models/number_of_level_one_ev_charging_stations.py +15 -0
  321. epa_pm_api_wrapper/models/number_of_level_two_ev_charging_stations.py +15 -0
  322. epa_pm_api_wrapper/models/number_of_mri_machines.py +15 -0
  323. epa_pm_api_wrapper/models/number_of_open_closed_refrigeration_units.py +27 -0
  324. epa_pm_api_wrapper/models/number_of_paint_bays.py +16 -0
  325. epa_pm_api_wrapper/models/number_of_people.py +15 -0
  326. epa_pm_api_wrapper/models/number_of_repair_bays.py +16 -0
  327. epa_pm_api_wrapper/models/number_of_residential_lift_systems.py +15 -0
  328. epa_pm_api_wrapper/models/number_of_residential_living_units.py +20 -0
  329. epa_pm_api_wrapper/models/number_of_residential_living_units_high_rise_setting.py +18 -0
  330. epa_pm_api_wrapper/models/number_of_residential_living_units_low_rise_setting.py +18 -0
  331. epa_pm_api_wrapper/models/number_of_residential_living_units_mid_rise_setting.py +18 -0
  332. epa_pm_api_wrapper/models/number_of_residential_washing_machines.py +15 -0
  333. epa_pm_api_wrapper/models/number_of_rooms.py +16 -0
  334. epa_pm_api_wrapper/models/number_of_special_other_events_per_year.py +16 -0
  335. epa_pm_api_wrapper/models/number_of_sporting_events_per_year.py +15 -0
  336. epa_pm_api_wrapper/models/number_of_staffed_beds.py +15 -0
  337. epa_pm_api_wrapper/models/number_of_sterilization_units.py +15 -0
  338. epa_pm_api_wrapper/models/number_of_surgical_operating_beds.py +16 -0
  339. epa_pm_api_wrapper/models/number_of_walk_in_refrigeration_units.py +16 -0
  340. epa_pm_api_wrapper/models/number_of_warming_heating_equipment_units.py +15 -0
  341. epa_pm_api_wrapper/models/number_of_weekdays_open.py +17 -0
  342. epa_pm_api_wrapper/models/number_of_weekdays_type.py +21 -0
  343. epa_pm_api_wrapper/models/number_of_weekly_ice_resurfacing_for_all_rinks.py +23 -0
  344. epa_pm_api_wrapper/models/number_of_weekly_ice_resurfacing_type.py +20 -0
  345. epa_pm_api_wrapper/models/number_of_workers.py +16 -0
  346. epa_pm_api_wrapper/models/nutrient_removal.py +16 -0
  347. epa_pm_api_wrapper/models/occupancy_type.py +27 -0
  348. epa_pm_api_wrapper/models/office.py +16 -0
  349. epa_pm_api_wrapper/models/office_type.py +35 -0
  350. epa_pm_api_wrapper/models/office_type_use_details.py +58 -0
  351. epa_pm_api_wrapper/models/offsite_green_power_purchase.py +11 -0
  352. epa_pm_api_wrapper/models/offsite_green_power_purchase_type.py +224 -0
  353. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_amount_purchased.py +31 -0
  354. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_amount_purchased_percentage.py +46 -0
  355. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_amount_purchased_percentage_meters.py +21 -0
  356. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_amount_purchased_quantity.py +31 -0
  357. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_cost.py +31 -0
  358. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_fuel_sources.py +22 -0
  359. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_fuel_sources_fuel_source.py +35 -0
  360. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_rated_capacity.py +31 -0
  361. epa_pm_api_wrapper/models/offsite_green_power_purchase_type_renewable_generation_technologies.py +21 -0
  362. epa_pm_api_wrapper/models/on_site_laundry_facility.py +15 -0
  363. epa_pm_api_wrapper/models/onsite_laundry_type.py +20 -0
  364. epa_pm_api_wrapper/models/onsite_laundry_type_value.py +10 -0
  365. epa_pm_api_wrapper/models/onsite_renewable_detail.py +11 -0
  366. epa_pm_api_wrapper/models/onsite_renewable_detail_type.py +60 -0
  367. epa_pm_api_wrapper/models/onsite_renewable_details.py +28 -0
  368. epa_pm_api_wrapper/models/onsite_renewable_optional_info.py +13 -0
  369. epa_pm_api_wrapper/models/onsite_renewable_optional_info_type.py +134 -0
  370. epa_pm_api_wrapper/models/onsite_renewable_optional_info_type_rated_capacity.py +31 -0
  371. epa_pm_api_wrapper/models/onsite_renewable_optional_info_type_renewable_generation_technologies.py +21 -0
  372. epa_pm_api_wrapper/models/onsite_usage_detail_type.py +70 -0
  373. epa_pm_api_wrapper/models/open_footage.py +15 -0
  374. epa_pm_api_wrapper/models/open_on_weekends.py +16 -0
  375. epa_pm_api_wrapper/models/optional_floor_area_type.py +19 -0
  376. epa_pm_api_wrapper/models/organization_type.py +77 -0
  377. epa_pm_api_wrapper/models/other.py +16 -0
  378. epa_pm_api_wrapper/models/other_education.py +18 -0
  379. epa_pm_api_wrapper/models/other_entertainment_public_assembly.py +17 -0
  380. epa_pm_api_wrapper/models/other_lodging_residential.py +19 -0
  381. epa_pm_api_wrapper/models/other_mall.py +17 -0
  382. epa_pm_api_wrapper/models/other_public_services.py +21 -0
  383. epa_pm_api_wrapper/models/other_recreation.py +16 -0
  384. epa_pm_api_wrapper/models/other_restaurant_bar.py +17 -0
  385. epa_pm_api_wrapper/models/other_services.py +16 -0
  386. epa_pm_api_wrapper/models/other_speciality_hospital.py +17 -0
  387. epa_pm_api_wrapper/models/other_stadium.py +16 -0
  388. epa_pm_api_wrapper/models/other_stadium_type.py +35 -0
  389. epa_pm_api_wrapper/models/other_stadium_type_use_details.py +104 -0
  390. epa_pm_api_wrapper/models/other_technology_science.py +16 -0
  391. epa_pm_api_wrapper/models/other_type.py +35 -0
  392. epa_pm_api_wrapper/models/other_type_use_details.py +42 -0
  393. epa_pm_api_wrapper/models/other_utility.py +16 -0
  394. epa_pm_api_wrapper/models/outpatient_rehabilitation_physical_therapy.py +16 -0
  395. epa_pm_api_wrapper/models/owned_by.py +16 -0
  396. epa_pm_api_wrapper/models/owned_by_type.py +20 -0
  397. epa_pm_api_wrapper/models/owned_by_type_value.py +9 -0
  398. epa_pm_api_wrapper/models/parking.py +15 -0
  399. epa_pm_api_wrapper/models/parking_type.py +35 -0
  400. epa_pm_api_wrapper/models/parking_type_use_details.py +40 -0
  401. epa_pm_api_wrapper/models/partially_enclosed_footage.py +16 -0
  402. epa_pm_api_wrapper/models/ped.py +26 -0
  403. epa_pm_api_wrapper/models/pending_accounts_type.py +58 -0
  404. epa_pm_api_wrapper/models/pending_list.py +15 -0
  405. epa_pm_api_wrapper/models/pending_list_type.py +53 -0
  406. epa_pm_api_wrapper/models/pending_meters_type.py +104 -0
  407. epa_pm_api_wrapper/models/pending_properties_type.py +77 -0
  408. epa_pm_api_wrapper/models/percent_cooled.py +16 -0
  409. epa_pm_api_wrapper/models/percent_cooled_type.py +20 -0
  410. epa_pm_api_wrapper/models/percent_cooled_type_value.py +17 -0
  411. epa_pm_api_wrapper/models/percent_heated.py +16 -0
  412. epa_pm_api_wrapper/models/percent_heated_type.py +20 -0
  413. epa_pm_api_wrapper/models/percent_heated_type_value.py +17 -0
  414. epa_pm_api_wrapper/models/percent_of_gross_floor_area_that_is_common_space_only.py +16 -0
  415. epa_pm_api_wrapper/models/percent_of_lab_floor_area.py +16 -0
  416. epa_pm_api_wrapper/models/percent_office_cooled.py +11 -0
  417. epa_pm_api_wrapper/models/percent_office_cooled_type.py +20 -0
  418. epa_pm_api_wrapper/models/percent_office_cooled_type_value.py +9 -0
  419. epa_pm_api_wrapper/models/percent_office_heated.py +11 -0
  420. epa_pm_api_wrapper/models/percent_office_heated_type.py +20 -0
  421. epa_pm_api_wrapper/models/percent_office_heated_type_value.py +9 -0
  422. epa_pm_api_wrapper/models/percent_used_for_cold_storage.py +18 -0
  423. epa_pm_api_wrapper/models/performance_target_type.py +42 -0
  424. epa_pm_api_wrapper/models/performance_target_type_target_metric.py +10 -0
  425. epa_pm_api_wrapper/models/performance_target_type_target_value.py +107 -0
  426. epa_pm_api_wrapper/models/performing_arts.py +15 -0
  427. epa_pm_api_wrapper/models/period_type.py +8 -0
  428. epa_pm_api_wrapper/models/personal_services.py +17 -0
  429. epa_pm_api_wrapper/models/pgp.py +56 -0
  430. epa_pm_api_wrapper/models/pgp_list.py +18 -0
  431. epa_pm_api_wrapper/models/plant_data_type.py +28 -0
  432. epa_pm_api_wrapper/models/plant_data_type_value.py +71 -0
  433. epa_pm_api_wrapper/models/plant_design_flow_rate.py +16 -0
  434. epa_pm_api_wrapper/models/plant_design_flow_rate_type.py +22 -0
  435. epa_pm_api_wrapper/models/plant_design_flow_rate_units_type.py +8 -0
  436. epa_pm_api_wrapper/models/plant_type.py +17 -0
  437. epa_pm_api_wrapper/models/police_station.py +16 -0
  438. epa_pm_api_wrapper/models/pool_location.py +15 -0
  439. epa_pm_api_wrapper/models/pool_size.py +16 -0
  440. epa_pm_api_wrapper/models/pool_size_type.py +20 -0
  441. epa_pm_api_wrapper/models/pool_size_type_value.py +9 -0
  442. epa_pm_api_wrapper/models/pool_type.py +20 -0
  443. epa_pm_api_wrapper/models/pool_type_value.py +8 -0
  444. epa_pm_api_wrapper/models/precision_controls_for_temperature_and_humidity.py +16 -0
  445. epa_pm_api_wrapper/models/preschool_daycare.py +17 -0
  446. epa_pm_api_wrapper/models/preschool_daycare_type.py +35 -0
  447. epa_pm_api_wrapper/models/preschool_daycare_type_use_details.py +68 -0
  448. epa_pm_api_wrapper/models/primary_business_type.py +33 -0
  449. epa_pm_api_wrapper/models/primary_function_type.py +95 -0
  450. epa_pm_api_wrapper/models/prison.py +17 -0
  451. epa_pm_api_wrapper/models/professional_designation_list.py +23 -0
  452. epa_pm_api_wrapper/models/professional_designation_list_professional_designation.py +41 -0
  453. epa_pm_api_wrapper/models/property.py +11 -0
  454. epa_pm_api_wrapper/models/property_design_type.py +66 -0
  455. epa_pm_api_wrapper/models/property_metrics.py +15 -0
  456. epa_pm_api_wrapper/models/property_metrics_list.py +19 -0
  457. epa_pm_api_wrapper/models/property_metrics_type.py +58 -0
  458. epa_pm_api_wrapper/models/property_representation.py +59 -0
  459. epa_pm_api_wrapper/models/property_representation_property_representation_type.py +27 -0
  460. epa_pm_api_wrapper/models/property_type.py +192 -0
  461. epa_pm_api_wrapper/models/property_use.py +22 -0
  462. epa_pm_api_wrapper/models/race_track.py +16 -0
  463. epa_pm_api_wrapper/models/rated_capacity_uom_type.py +8 -0
  464. epa_pm_api_wrapper/models/rec_ownership_enum.py +10 -0
  465. epa_pm_api_wrapper/models/refrigerated_warehouse.py +17 -0
  466. epa_pm_api_wrapper/models/refrigerated_warehouse_type.py +37 -0
  467. epa_pm_api_wrapper/models/refrigerated_warehouse_type_use_details.py +66 -0
  468. epa_pm_api_wrapper/models/renewable_generation_technology_enum.py +11 -0
  469. epa_pm_api_wrapper/models/report.py +72 -0
  470. epa_pm_api_wrapper/models/report_error.py +53 -0
  471. epa_pm_api_wrapper/models/report_error_missing_metrics.py +21 -0
  472. epa_pm_api_wrapper/models/report_error_missing_metrics_property_missing_metric.py +43 -0
  473. epa_pm_api_wrapper/models/report_error_missing_metrics_property_missing_metric_metric.py +33 -0
  474. epa_pm_api_wrapper/models/report_metric_values_ws.py +57 -0
  475. epa_pm_api_wrapper/models/report_metrics.py +26 -0
  476. epa_pm_api_wrapper/models/report_metrics_group.py +36 -0
  477. epa_pm_api_wrapper/models/report_metrics_group_metrics.py +24 -0
  478. epa_pm_api_wrapper/models/report_metrics_group_metrics_metric.py +62 -0
  479. epa_pm_api_wrapper/models/report_properties.py +20 -0
  480. epa_pm_api_wrapper/models/report_status.py +11 -0
  481. epa_pm_api_wrapper/models/report_status_def.py +62 -0
  482. epa_pm_api_wrapper/models/report_status_type.py +33 -0
  483. epa_pm_api_wrapper/models/report_template.py +11 -0
  484. epa_pm_api_wrapper/models/report_template_type.py +63 -0
  485. epa_pm_api_wrapper/models/report_template_type_metrics.py +21 -0
  486. epa_pm_api_wrapper/models/report_type.py +17 -0
  487. epa_pm_api_wrapper/models/reporting_interval_type.py +15 -0
  488. epa_pm_api_wrapper/models/residence_hall_dormitory.py +16 -0
  489. epa_pm_api_wrapper/models/residence_hall_dormitory_type.py +37 -0
  490. epa_pm_api_wrapper/models/residence_hall_dormitory_type_use_details.py +58 -0
  491. epa_pm_api_wrapper/models/resident_population.py +16 -0
  492. epa_pm_api_wrapper/models/resident_population_type.py +20 -0
  493. epa_pm_api_wrapper/models/resident_population_type_value.py +12 -0
  494. epa_pm_api_wrapper/models/residential_care_facility.py +16 -0
  495. epa_pm_api_wrapper/models/residential_care_facility_type.py +37 -0
  496. epa_pm_api_wrapper/models/residential_care_facility_type_use_details.py +120 -0
  497. epa_pm_api_wrapper/models/response.py +11 -0
  498. epa_pm_api_wrapper/models/response_status.py +36 -0
  499. epa_pm_api_wrapper/models/response_status_errors.py +19 -0
  500. epa_pm_api_wrapper/models/response_type.py +59 -0
  501. epa_pm_api_wrapper/models/restaurant.py +20 -0
  502. epa_pm_api_wrapper/models/restaurant_type.py +35 -0
  503. epa_pm_api_wrapper/models/restaurant_type_use_details.py +84 -0
  504. epa_pm_api_wrapper/models/retail.py +17 -0
  505. epa_pm_api_wrapper/models/retail_type.py +35 -0
  506. epa_pm_api_wrapper/models/retail_type_use_details.py +130 -0
  507. epa_pm_api_wrapper/models/roller_rink.py +16 -0
  508. epa_pm_api_wrapper/models/school_district.py +15 -0
  509. epa_pm_api_wrapper/models/search_result_type.py +23 -0
  510. epa_pm_api_wrapper/models/search_results.py +15 -0
  511. epa_pm_api_wrapper/models/seating_capacity.py +16 -0
  512. epa_pm_api_wrapper/models/self_storage_facility.py +15 -0
  513. epa_pm_api_wrapper/models/self_storage_facility_type.py +37 -0
  514. epa_pm_api_wrapper/models/self_storage_facility_type_use_details.py +84 -0
  515. epa_pm_api_wrapper/models/send_data_response.py +43 -0
  516. epa_pm_api_wrapper/models/send_data_response_additional_email_addresses.py +17 -0
  517. epa_pm_api_wrapper/models/send_data_response_file_format.py +8 -0
  518. epa_pm_api_wrapper/models/senior_living_community.py +16 -0
  519. epa_pm_api_wrapper/models/senior_living_community_type.py +37 -0
  520. epa_pm_api_wrapper/models/senior_living_community_type_use_details.py +120 -0
  521. epa_pm_api_wrapper/models/share_level_type.py +12 -0
  522. epa_pm_api_wrapper/models/sharing_response.py +16 -0
  523. epa_pm_api_wrapper/models/sharing_response_type.py +34 -0
  524. epa_pm_api_wrapper/models/single_family_home.py +16 -0
  525. epa_pm_api_wrapper/models/single_family_home_type.py +35 -0
  526. epa_pm_api_wrapper/models/single_family_home_type_use_details.py +34 -0
  527. epa_pm_api_wrapper/models/single_store.py +15 -0
  528. epa_pm_api_wrapper/models/size_of_electronic_score_boards.py +15 -0
  529. epa_pm_api_wrapper/models/spectator_seating_capacity.py +16 -0
  530. epa_pm_api_wrapper/models/stadium_closed.py +17 -0
  531. epa_pm_api_wrapper/models/stadium_closed_type.py +35 -0
  532. epa_pm_api_wrapper/models/stadium_closed_type_use_details.py +104 -0
  533. epa_pm_api_wrapper/models/stadium_open.py +17 -0
  534. epa_pm_api_wrapper/models/stadium_open_type.py +35 -0
  535. epa_pm_api_wrapper/models/stadium_open_type_use_details.py +104 -0
  536. epa_pm_api_wrapper/models/state_code.py +159 -0
  537. epa_pm_api_wrapper/models/station.py +45 -0
  538. epa_pm_api_wrapper/models/status_type.py +8 -0
  539. epa_pm_api_wrapper/models/strip_mall.py +17 -0
  540. epa_pm_api_wrapper/models/student_seating_capacity.py +16 -0
  541. epa_pm_api_wrapper/models/supermarket.py +17 -0
  542. epa_pm_api_wrapper/models/supermarket_type.py +35 -0
  543. epa_pm_api_wrapper/models/supermarket_type_use_details.py +114 -0
  544. epa_pm_api_wrapper/models/supplemental_heating.py +15 -0
  545. epa_pm_api_wrapper/models/surgery_center_floor_area.py +16 -0
  546. epa_pm_api_wrapper/models/swimming_pool.py +15 -0
  547. epa_pm_api_wrapper/models/swimming_pool_type.py +35 -0
  548. epa_pm_api_wrapper/models/swimming_pool_type_use_details.py +34 -0
  549. epa_pm_api_wrapper/models/system_determined_string.py +7 -0
  550. epa_pm_api_wrapper/models/target_finder.py +11 -0
  551. epa_pm_api_wrapper/models/target_type_percentage_type.py +17 -0
  552. epa_pm_api_wrapper/models/target_type_percentage_values_type.py +107 -0
  553. epa_pm_api_wrapper/models/target_type_score_type.py +17 -0
  554. epa_pm_api_wrapper/models/target_type_score_values_type.py +106 -0
  555. epa_pm_api_wrapper/models/template_type.py +19 -0
  556. epa_pm_api_wrapper/models/template_type_value.py +15 -0
  557. epa_pm_api_wrapper/models/tenant_common_area_energy_type.py +21 -0
  558. epa_pm_api_wrapper/models/tenant_common_area_energy_use_information_type.py +31 -0
  559. epa_pm_api_wrapper/models/terminate_share_response_type.py +24 -0
  560. epa_pm_api_wrapper/models/terminate_sharing_response.py +16 -0
  561. epa_pm_api_wrapper/models/timeframe_type.py +103 -0
  562. epa_pm_api_wrapper/models/timeframe_type_baseline_period.py +18 -0
  563. epa_pm_api_wrapper/models/timeframe_type_compare_baseline_period.py +25 -0
  564. epa_pm_api_wrapper/models/timeframe_type_compare_current_period.py +25 -0
  565. epa_pm_api_wrapper/models/timeframe_type_current_period.py +18 -0
  566. epa_pm_api_wrapper/models/timeframe_type_current_vs_baseline.py +18 -0
  567. epa_pm_api_wrapper/models/timeframe_type_date_range.py +30 -0
  568. epa_pm_api_wrapper/models/timeframe_type_single_period.py +18 -0
  569. epa_pm_api_wrapper/models/timeframe_type_two_periods.py +24 -0
  570. epa_pm_api_wrapper/models/total_gross_floor_area.py +11 -0
  571. epa_pm_api_wrapper/models/total_ice_rink_surface_area_for_all_rinks.py +21 -0
  572. epa_pm_api_wrapper/models/transportation_terminal_station.py +16 -0
  573. epa_pm_api_wrapper/models/type_of_energy_star_partner.py +14 -0
  574. epa_pm_api_wrapper/models/type_of_meter.py +55 -0
  575. epa_pm_api_wrapper/models/type_of_waste_meter.py +122 -0
  576. epa_pm_api_wrapper/models/type_of_waste_meter_data_entry_method.py +18 -0
  577. epa_pm_api_wrapper/models/type_of_waste_meter_unit_of_measure.py +15 -0
  578. epa_pm_api_wrapper/models/un_auth_design_type.py +100 -0
  579. epa_pm_api_wrapper/models/un_auth_design_type_estimated_energy_list.py +17 -0
  580. epa_pm_api_wrapper/models/un_auth_design_type_property_uses.py +709 -0
  581. epa_pm_api_wrapper/models/un_auth_design_type_target.py +34 -0
  582. epa_pm_api_wrapper/models/ups_system_redundancy.py +16 -0
  583. epa_pm_api_wrapper/models/ups_system_redundancy_type.py +20 -0
  584. epa_pm_api_wrapper/models/ups_system_redundancy_type_value.py +12 -0
  585. epa_pm_api_wrapper/models/urgent_care_clinic_other_outpatient.py +17 -0
  586. epa_pm_api_wrapper/models/use_attribute_base.py +65 -0
  587. epa_pm_api_wrapper/models/use_attribute_base_default.py +9 -0
  588. epa_pm_api_wrapper/models/use_decimal_type.py +21 -0
  589. epa_pm_api_wrapper/models/use_details.py +1086 -0
  590. epa_pm_api_wrapper/models/use_integer_type.py +20 -0
  591. epa_pm_api_wrapper/models/use_string_type.py +19 -0
  592. epa_pm_api_wrapper/models/use_yes_no_type.py +20 -0
  593. epa_pm_api_wrapper/models/vehicle_dealership.py +16 -0
  594. epa_pm_api_wrapper/models/vehicle_dealership_type.py +37 -0
  595. epa_pm_api_wrapper/models/vehicle_dealership_type_use_details.py +84 -0
  596. epa_pm_api_wrapper/models/vehicle_repair_services.py +19 -0
  597. epa_pm_api_wrapper/models/vehicle_repair_services_type.py +37 -0
  598. epa_pm_api_wrapper/models/vehicle_repair_services_type_use_details.py +74 -0
  599. epa_pm_api_wrapper/models/verification.py +96 -0
  600. epa_pm_api_wrapper/models/veterinary_office.py +15 -0
  601. epa_pm_api_wrapper/models/vocational_school.py +16 -0
  602. epa_pm_api_wrapper/models/warning_type.py +29 -0
  603. epa_pm_api_wrapper/models/warnings_type.py +25 -0
  604. epa_pm_api_wrapper/models/waste_data.py +15 -0
  605. epa_pm_api_wrapper/models/waste_data_list.py +11 -0
  606. epa_pm_api_wrapper/models/waste_meter.py +11 -0
  607. epa_pm_api_wrapper/models/waste_meter_assoc_and_config_type.py +18 -0
  608. epa_pm_api_wrapper/models/waste_meter_data_type.py +32 -0
  609. epa_pm_api_wrapper/models/waste_meter_entry_type.py +113 -0
  610. epa_pm_api_wrapper/models/waste_meter_entry_type_average_percent_full.py +11 -0
  611. epa_pm_api_wrapper/models/waste_meter_type.py +81 -0
  612. epa_pm_api_wrapper/models/wastewater_treatment_plant.py +15 -0
  613. epa_pm_api_wrapper/models/wastewater_treatment_plant_type.py +37 -0
  614. epa_pm_api_wrapper/models/wastewater_treatment_plant_type_use_details.py +63 -0
  615. epa_pm_api_wrapper/models/water_meter_assoc_and_config_type.py +25 -0
  616. epa_pm_api_wrapper/models/weekly_building_occupied_hours.py +16 -0
  617. epa_pm_api_wrapper/models/weekly_operating_hours.py +19 -0
  618. epa_pm_api_wrapper/models/wholesale_club_supercenter.py +16 -0
  619. epa_pm_api_wrapper/models/wholesale_club_supercenter_type.py +37 -0
  620. epa_pm_api_wrapper/models/wholesale_club_supercenter_type_use_details.py +130 -0
  621. epa_pm_api_wrapper/models/worship_facility.py +19 -0
  622. epa_pm_api_wrapper/models/worship_facility_type.py +35 -0
  623. epa_pm_api_wrapper/models/worship_facility_type_use_details.py +102 -0
  624. epa_pm_api_wrapper/models/yes_no.py +8 -0
  625. epa_pm_api_wrapper/models/zoo.py +16 -0
  626. epa_pm_api_wrapper/py.typed +1 -0
  627. epa_pm_api_wrapper/resources/__init__.py +172 -0
  628. epa_pm_api_wrapper/resources/_base.py +22 -0
  629. epa_pm_api_wrapper/resources/account.py +37 -0
  630. epa_pm_api_wrapper/resources/association.py +145 -0
  631. epa_pm_api_wrapper/resources/building.py +89 -0
  632. epa_pm_api_wrapper/resources/consumption_data.py +142 -0
  633. epa_pm_api_wrapper/resources/custom_metric.py +91 -0
  634. epa_pm_api_wrapper/resources/customer.py +45 -0
  635. epa_pm_api_wrapper/resources/data_exchange.py +111 -0
  636. epa_pm_api_wrapper/resources/green_power.py +237 -0
  637. epa_pm_api_wrapper/resources/hey.py +22 -0
  638. epa_pm_api_wrapper/resources/hierarchy.py +59 -0
  639. epa_pm_api_wrapper/resources/identifier.py +92 -0
  640. epa_pm_api_wrapper/resources/meter.py +277 -0
  641. epa_pm_api_wrapper/resources/metrics.py +185 -0
  642. epa_pm_api_wrapper/resources/property.py +450 -0
  643. epa_pm_api_wrapper/resources/property_use.py +277 -0
  644. epa_pm_api_wrapper/resources/report.py +169 -0
  645. epa_pm_api_wrapper/resources/share.py +139 -0
  646. epa_pm_api_wrapper/resources/target_finder.py +34 -0
  647. epa_pm_api_wrapper/resources/verification.py +201 -0
  648. epa_pm_api_wrapper/resources/waste_data.py +124 -0
  649. epa_pm_api_wrapper/retry.py +219 -0
  650. epa_pm_api_wrapper-0.3.0.dist-info/METADATA +137 -0
  651. epa_pm_api_wrapper-0.3.0.dist-info/RECORD +654 -0
  652. epa_pm_api_wrapper-0.3.0.dist-info/WHEEL +4 -0
  653. epa_pm_api_wrapper-0.3.0.dist-info/entry_points.txt +2 -0
  654. epa_pm_api_wrapper-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,201 @@
1
+ """Verification resource — `/property/{propertyId}/verification` endpoints
2
+ plus the nested `verification.designations` sub-namespace for professional
3
+ designation management.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import TYPE_CHECKING
9
+
10
+ from epa_pm_api_wrapper.models import (
11
+ ProfessionalDesignationList,
12
+ Response,
13
+ Verification,
14
+ )
15
+
16
+ from ._base import AsyncResource, Resource
17
+
18
+ if TYPE_CHECKING:
19
+ from epa_pm_api_wrapper.client import EpaPmAsyncClient, EpaPmClient
20
+
21
+
22
+ class VerificationDesignationsResource(Resource):
23
+ def list(self, property_id: int) -> Verification:
24
+ """Get the verification record (which carries the designation list)."""
25
+ return self._client._request(
26
+ "GET",
27
+ f"property/{property_id}/verification/professionalDesignation",
28
+ response_type=Verification,
29
+ )
30
+
31
+ def delete_all(self, property_id: int) -> Response:
32
+ """Remove all professional designations from a property's verification."""
33
+ return self._client._request(
34
+ "DELETE",
35
+ f"property/{property_id}/verification/professionalDesignation",
36
+ response_type=Response,
37
+ )
38
+
39
+ def add(self, property_id: int, designation_type_id: int, data: ProfessionalDesignationList) -> Response:
40
+ """Add a professional designation entry."""
41
+ return self._client._request(
42
+ "POST",
43
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}",
44
+ data=data,
45
+ response_type=Response,
46
+ )
47
+
48
+ def update(self, property_id: int, designation_type_id: int, data: ProfessionalDesignationList) -> Response:
49
+ """Update licenses for a designation type."""
50
+ return self._client._request(
51
+ "PUT",
52
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}",
53
+ data=data,
54
+ response_type=Response,
55
+ )
56
+
57
+ def delete_type(self, property_id: int, designation_type_id: int) -> Response:
58
+ """Remove all entries of a single designation type."""
59
+ return self._client._request(
60
+ "DELETE",
61
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}",
62
+ response_type=Response,
63
+ )
64
+
65
+ def update_license(
66
+ self,
67
+ property_id: int,
68
+ designation_type_id: int,
69
+ index: int,
70
+ data: ProfessionalDesignationList,
71
+ ) -> Response:
72
+ """Update a specific license entry within a designation type."""
73
+ return self._client._request(
74
+ "PUT",
75
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}/{index}",
76
+ data=data,
77
+ response_type=Response,
78
+ )
79
+
80
+ def delete_license(self, property_id: int, designation_type_id: int, index: int) -> Response:
81
+ """Remove a specific license entry within a designation type."""
82
+ return self._client._request(
83
+ "DELETE",
84
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}/{index}",
85
+ response_type=Response,
86
+ )
87
+
88
+ def types(self) -> ProfessionalDesignationList:
89
+ """List the EPA-defined professional designation types (catalog)."""
90
+ return self._client._request(
91
+ "GET", "property/professionalDesignation/list", response_type=ProfessionalDesignationList
92
+ )
93
+
94
+
95
+ class VerificationResource(Resource):
96
+ def __init__(self, client: EpaPmClient) -> None:
97
+ super().__init__(client)
98
+ self.designations = VerificationDesignationsResource(client)
99
+
100
+ def get(self, property_id: int) -> Verification:
101
+ """Get verification (verifier) information for a property."""
102
+ return self._client._request("GET", f"property/{property_id}/verification", response_type=Verification)
103
+
104
+ def create(self, property_id: int, data: Verification) -> Response:
105
+ """Create verification information for a property."""
106
+ return self._client._request("POST", f"property/{property_id}/verification", data=data, response_type=Response)
107
+
108
+ def update(self, property_id: int, data: Verification) -> Response:
109
+ """Update verification information for a property."""
110
+ return self._client._request("PUT", f"property/{property_id}/verification", data=data, response_type=Response)
111
+
112
+ def delete(self, property_id: int) -> Response:
113
+ """Remove verification information from a property."""
114
+ return self._client._request("DELETE", f"property/{property_id}/verification", response_type=Response)
115
+
116
+
117
+ class AsyncVerificationDesignationsResource(AsyncResource):
118
+ async def list(self, property_id: int) -> Verification:
119
+ return await self._client._arequest(
120
+ "GET",
121
+ f"property/{property_id}/verification/professionalDesignation",
122
+ response_type=Verification,
123
+ )
124
+
125
+ async def delete_all(self, property_id: int) -> Response:
126
+ return await self._client._arequest(
127
+ "DELETE",
128
+ f"property/{property_id}/verification/professionalDesignation",
129
+ response_type=Response,
130
+ )
131
+
132
+ async def add(self, property_id: int, designation_type_id: int, data: ProfessionalDesignationList) -> Response:
133
+ return await self._client._arequest(
134
+ "POST",
135
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}",
136
+ data=data,
137
+ response_type=Response,
138
+ )
139
+
140
+ async def update(self, property_id: int, designation_type_id: int, data: ProfessionalDesignationList) -> Response:
141
+ return await self._client._arequest(
142
+ "PUT",
143
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}",
144
+ data=data,
145
+ response_type=Response,
146
+ )
147
+
148
+ async def delete_type(self, property_id: int, designation_type_id: int) -> Response:
149
+ return await self._client._arequest(
150
+ "DELETE",
151
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}",
152
+ response_type=Response,
153
+ )
154
+
155
+ async def update_license(
156
+ self,
157
+ property_id: int,
158
+ designation_type_id: int,
159
+ index: int,
160
+ data: ProfessionalDesignationList,
161
+ ) -> Response:
162
+ return await self._client._arequest(
163
+ "PUT",
164
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}/{index}",
165
+ data=data,
166
+ response_type=Response,
167
+ )
168
+
169
+ async def delete_license(self, property_id: int, designation_type_id: int, index: int) -> Response:
170
+ return await self._client._arequest(
171
+ "DELETE",
172
+ f"property/{property_id}/verification/professionalDesignation/{designation_type_id}/{index}",
173
+ response_type=Response,
174
+ )
175
+
176
+ async def types(self) -> ProfessionalDesignationList:
177
+ return await self._client._arequest(
178
+ "GET", "property/professionalDesignation/list", response_type=ProfessionalDesignationList
179
+ )
180
+
181
+
182
+ class AsyncVerificationResource(AsyncResource):
183
+ def __init__(self, client: EpaPmAsyncClient) -> None:
184
+ super().__init__(client)
185
+ self.designations = AsyncVerificationDesignationsResource(client)
186
+
187
+ async def get(self, property_id: int) -> Verification:
188
+ return await self._client._arequest("GET", f"property/{property_id}/verification", response_type=Verification)
189
+
190
+ async def create(self, property_id: int, data: Verification) -> Response:
191
+ return await self._client._arequest(
192
+ "POST", f"property/{property_id}/verification", data=data, response_type=Response
193
+ )
194
+
195
+ async def update(self, property_id: int, data: Verification) -> Response:
196
+ return await self._client._arequest(
197
+ "PUT", f"property/{property_id}/verification", data=data, response_type=Response
198
+ )
199
+
200
+ async def delete(self, property_id: int) -> Response:
201
+ return await self._client._arequest("DELETE", f"property/{property_id}/verification", response_type=Response)
@@ -0,0 +1,124 @@
1
+ """Waste data resource — `/meter/{meterId}/wasteData` and `/wasteData/{id}` endpoints."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import AsyncIterator, Iterator
6
+
7
+ from epa_pm_api_wrapper.models import Response, WasteData, WasteDataList
8
+
9
+ from ._base import AsyncResource, Resource
10
+
11
+
12
+ class WasteDataResource(Resource):
13
+ def list(
14
+ self,
15
+ meter_id: int,
16
+ page: int | None = None,
17
+ start_date: str | None = None,
18
+ end_date: str | None = None,
19
+ ) -> WasteDataList:
20
+ """Get waste data for a meter (up to 120 records per page)."""
21
+ params = {"page": page, "startDate": start_date, "endDate": end_date}
22
+ return self._client._request("GET", f"meter/{meter_id}/wasteData", params=params, response_type=WasteDataList)
23
+
24
+ def add(self, meter_id: int, data: WasteData) -> Response:
25
+ """Add a waste data record to a meter."""
26
+ return self._client._request("POST", f"meter/{meter_id}/wasteData", data=data, response_type=Response)
27
+
28
+ def delete_range(self, meter_id: int, start_date: str, end_date: str) -> Response:
29
+ """Delete waste data records on a meter within a date range."""
30
+ return self._client._request(
31
+ "DELETE",
32
+ f"meter/{meter_id}/wasteData",
33
+ params={"startDate": start_date, "endDate": end_date},
34
+ response_type=Response,
35
+ )
36
+
37
+ def update(self, waste_data_id: int, data: WasteData) -> Response:
38
+ """Update a single waste data record."""
39
+ return self._client._request("PUT", f"wasteData/{waste_data_id}", data=data, response_type=Response)
40
+
41
+ def delete(self, waste_data_id: int) -> Response:
42
+ """Delete a single waste data record."""
43
+ return self._client._request("DELETE", f"wasteData/{waste_data_id}", response_type=Response)
44
+
45
+ def what_changed(self, customer_id: int, date: str) -> Response:
46
+ """List meters under a connected customer with waste data modified on/after ``date``."""
47
+ return self._client._request(
48
+ "GET",
49
+ f"customer/{customer_id}/meter/wasteData/whatChanged",
50
+ params={"date": date},
51
+ response_type=Response,
52
+ )
53
+
54
+ def iter(
55
+ self,
56
+ meter_id: int,
57
+ start_date: str | None = None,
58
+ end_date: str | None = None,
59
+ ) -> Iterator[WasteData]:
60
+ """Iterate over every waste record for a meter, paging internally (120/page)."""
61
+ page = 1
62
+ while True:
63
+ data = self.list(meter_id, page=page, start_date=start_date, end_date=end_date)
64
+ records = data.waste_data or []
65
+ if not records:
66
+ return
67
+ yield from records
68
+ page += 1
69
+
70
+
71
+ class AsyncWasteDataResource(AsyncResource):
72
+ async def list(
73
+ self,
74
+ meter_id: int,
75
+ page: int | None = None,
76
+ start_date: str | None = None,
77
+ end_date: str | None = None,
78
+ ) -> WasteDataList:
79
+ params = {"page": page, "startDate": start_date, "endDate": end_date}
80
+ return await self._client._arequest(
81
+ "GET", f"meter/{meter_id}/wasteData", params=params, response_type=WasteDataList
82
+ )
83
+
84
+ async def add(self, meter_id: int, data: WasteData) -> Response:
85
+ return await self._client._arequest("POST", f"meter/{meter_id}/wasteData", data=data, response_type=Response)
86
+
87
+ async def delete_range(self, meter_id: int, start_date: str, end_date: str) -> Response:
88
+ return await self._client._arequest(
89
+ "DELETE",
90
+ f"meter/{meter_id}/wasteData",
91
+ params={"startDate": start_date, "endDate": end_date},
92
+ response_type=Response,
93
+ )
94
+
95
+ async def update(self, waste_data_id: int, data: WasteData) -> Response:
96
+ return await self._client._arequest("PUT", f"wasteData/{waste_data_id}", data=data, response_type=Response)
97
+
98
+ async def delete(self, waste_data_id: int) -> Response:
99
+ return await self._client._arequest("DELETE", f"wasteData/{waste_data_id}", response_type=Response)
100
+
101
+ async def what_changed(self, customer_id: int, date: str) -> Response:
102
+ return await self._client._arequest(
103
+ "GET",
104
+ f"customer/{customer_id}/meter/wasteData/whatChanged",
105
+ params={"date": date},
106
+ response_type=Response,
107
+ )
108
+
109
+ async def iter(
110
+ self,
111
+ meter_id: int,
112
+ start_date: str | None = None,
113
+ end_date: str | None = None,
114
+ ) -> AsyncIterator[WasteData]:
115
+ """Async equivalent of :meth:`WasteDataResource.iter`."""
116
+ page = 1
117
+ while True:
118
+ data = await self.list(meter_id, page=page, start_date=start_date, end_date=end_date)
119
+ records = data.waste_data or []
120
+ if not records:
121
+ return
122
+ for record in records:
123
+ yield record
124
+ page += 1
@@ -0,0 +1,219 @@
1
+ """Retry transport for transient HTTP failures.
2
+
3
+ Wraps an underlying ``httpx`` transport with retry/backoff for the responses
4
+ EPA most commonly returns when the system is under stress: 429 (rate limited),
5
+ 502/503/504 (gateway/upstream errors), and connection-level failures
6
+ (``httpx.ConnectError`` / ``httpx.ReadTimeout``). Auth (401) and client-side
7
+ 4xx errors are *not* retried — they will not change on retry.
8
+
9
+ Two transports, sync and async, share the same :class:`RetryConfig` and the
10
+ same backoff math. The default schedule is exponential with full jitter:
11
+ ``delay = uniform(0, base * 2**attempt)`` clamped to ``max_delay``. The HTTP
12
+ ``Retry-After`` header (numeric seconds form) overrides the computed delay
13
+ when present.
14
+
15
+ Transports are stacked: the user-supplied ``transport`` (or the default
16
+ ``httpx.HTTPTransport`` httpx builds for us) sits inside the retry transport.
17
+ This means proxies and other transport-layer customizations still apply.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import asyncio
23
+ import logging
24
+ import random
25
+ import time
26
+ from dataclasses import dataclass, field
27
+
28
+ import httpx
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+ DEFAULT_RETRY_STATUS_CODES = frozenset({429, 502, 503, 504})
33
+
34
+
35
+ @dataclass(frozen=True)
36
+ class RetryConfig:
37
+ """Retry behavior for the client transport layer.
38
+
39
+ Pass to ``EpaPmClient(retry=...)`` / ``EpaPmAsyncClient(retry=...)`` to
40
+ override the defaults. Pass ``retries=0`` on the client to disable.
41
+
42
+ :ivar max_retries: How many times to retry after the initial attempt
43
+ (default 3 → up to 4 total requests).
44
+ :ivar base_delay: Base for the exponential backoff in seconds.
45
+ :ivar max_delay: Cap on a single backoff sleep, in seconds.
46
+ :ivar retry_status_codes: HTTP status codes treated as transient.
47
+ :ivar respect_retry_after: Honor ``Retry-After`` headers (numeric form)
48
+ when the server provides them, capped at ``max_delay``.
49
+ """
50
+
51
+ max_retries: int = 3
52
+ base_delay: float = 0.5
53
+ max_delay: float = 30.0
54
+ retry_status_codes: frozenset[int] = field(default_factory=lambda: DEFAULT_RETRY_STATUS_CODES)
55
+ respect_retry_after: bool = True
56
+
57
+
58
+ def _retryable_status(response: httpx.Response, cfg: RetryConfig) -> bool:
59
+ return response.status_code in cfg.retry_status_codes
60
+
61
+
62
+ def _retry_after_seconds(response: httpx.Response, cfg: RetryConfig) -> float | None:
63
+ """Return the server-suggested delay in seconds, or ``None``.
64
+
65
+ Only the numeric form of ``Retry-After`` is honored; HTTP-date form falls
66
+ back to client-side backoff (it requires clock-correlation we'd rather
67
+ not assume).
68
+ """
69
+ if not cfg.respect_retry_after:
70
+ return None
71
+ raw = response.headers.get("retry-after")
72
+ if not raw:
73
+ return None
74
+ try:
75
+ return min(float(raw), cfg.max_delay)
76
+ except ValueError:
77
+ return None
78
+
79
+
80
+ def _backoff_seconds(attempt: int, cfg: RetryConfig) -> float:
81
+ """Exponential backoff with full jitter, capped at ``max_delay``.
82
+
83
+ ``attempt`` is 0-indexed (first retry → attempt=0).
84
+ """
85
+ upper = min(cfg.max_delay, cfg.base_delay * (2**attempt))
86
+ return random.uniform(0, upper)
87
+
88
+
89
+ def _delay_for(response: httpx.Response | None, attempt: int, cfg: RetryConfig) -> float:
90
+ """Server-hint delay if available, else backoff."""
91
+ if response is not None:
92
+ hinted = _retry_after_seconds(response, cfg)
93
+ if hinted is not None:
94
+ return hinted
95
+ return _backoff_seconds(attempt, cfg)
96
+
97
+
98
+ _RETRYABLE_EXCEPTIONS: tuple[type[Exception], ...] = (
99
+ httpx.ConnectError,
100
+ httpx.ReadTimeout,
101
+ httpx.WriteTimeout,
102
+ httpx.PoolTimeout,
103
+ httpx.RemoteProtocolError,
104
+ )
105
+
106
+
107
+ class RetryTransport(httpx.BaseTransport):
108
+ """Sync retry transport. Wrap an existing transport (or omit for the default)."""
109
+
110
+ def __init__(self, wrapped: httpx.BaseTransport | None = None, config: RetryConfig | None = None):
111
+ self._wrapped = wrapped if wrapped is not None else httpx.HTTPTransport()
112
+ self._config = config or RetryConfig()
113
+
114
+ def handle_request(self, request: httpx.Request) -> httpx.Response:
115
+ cfg = self._config
116
+ last_exc: Exception | None = None
117
+ for attempt in range(cfg.max_retries + 1):
118
+ try:
119
+ response = self._wrapped.handle_request(request)
120
+ except _RETRYABLE_EXCEPTIONS as exc:
121
+ last_exc = exc
122
+ if attempt >= cfg.max_retries:
123
+ logger.warning("request to %s failed after %d attempts: %s", request.url, attempt + 1, exc)
124
+ raise
125
+ delay = _delay_for(None, attempt, cfg)
126
+ logger.info(
127
+ "retrying %s after %s (attempt %d/%d, sleep %.2fs)",
128
+ request.url,
129
+ type(exc).__name__,
130
+ attempt + 1,
131
+ cfg.max_retries,
132
+ delay,
133
+ )
134
+ time.sleep(delay)
135
+ continue
136
+
137
+ if attempt >= cfg.max_retries or not _retryable_status(response, cfg):
138
+ return response
139
+
140
+ # Drain the body so the connection can be released to the pool.
141
+ response.read()
142
+ response.close()
143
+ delay = _delay_for(response, attempt, cfg)
144
+ logger.info(
145
+ "retrying %s after HTTP %d (attempt %d/%d, sleep %.2fs)",
146
+ request.url,
147
+ response.status_code,
148
+ attempt + 1,
149
+ cfg.max_retries,
150
+ delay,
151
+ )
152
+ time.sleep(delay)
153
+
154
+ # Should not be reachable — the loop returns or raises — but mypy/ty
155
+ # want a definite outcome.
156
+ if last_exc is not None:
157
+ raise last_exc
158
+ raise RuntimeError("RetryTransport: unreachable") # pragma: no cover
159
+
160
+ def close(self) -> None:
161
+ self._wrapped.close()
162
+
163
+
164
+ class AsyncRetryTransport(httpx.AsyncBaseTransport):
165
+ """Async retry transport. Wrap an existing transport (or omit for the default)."""
166
+
167
+ def __init__(
168
+ self,
169
+ wrapped: httpx.AsyncBaseTransport | None = None,
170
+ config: RetryConfig | None = None,
171
+ ):
172
+ self._wrapped = wrapped if wrapped is not None else httpx.AsyncHTTPTransport()
173
+ self._config = config or RetryConfig()
174
+
175
+ async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
176
+ cfg = self._config
177
+ last_exc: Exception | None = None
178
+ for attempt in range(cfg.max_retries + 1):
179
+ try:
180
+ response = await self._wrapped.handle_async_request(request)
181
+ except _RETRYABLE_EXCEPTIONS as exc:
182
+ last_exc = exc
183
+ if attempt >= cfg.max_retries:
184
+ logger.warning("request to %s failed after %d attempts: %s", request.url, attempt + 1, exc)
185
+ raise
186
+ delay = _delay_for(None, attempt, cfg)
187
+ logger.info(
188
+ "retrying %s after %s (attempt %d/%d, sleep %.2fs)",
189
+ request.url,
190
+ type(exc).__name__,
191
+ attempt + 1,
192
+ cfg.max_retries,
193
+ delay,
194
+ )
195
+ await asyncio.sleep(delay)
196
+ continue
197
+
198
+ if attempt >= cfg.max_retries or not _retryable_status(response, cfg):
199
+ return response
200
+
201
+ await response.aread()
202
+ await response.aclose()
203
+ delay = _delay_for(response, attempt, cfg)
204
+ logger.info(
205
+ "retrying %s after HTTP %d (attempt %d/%d, sleep %.2fs)",
206
+ request.url,
207
+ response.status_code,
208
+ attempt + 1,
209
+ cfg.max_retries,
210
+ delay,
211
+ )
212
+ await asyncio.sleep(delay)
213
+
214
+ if last_exc is not None:
215
+ raise last_exc
216
+ raise RuntimeError("AsyncRetryTransport: unreachable") # pragma: no cover
217
+
218
+ async def aclose(self) -> None:
219
+ await self._wrapped.aclose()
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: EPA-PM-API-Wrapper
3
+ Version: 0.3.0
4
+ Summary: Client wrapper for the EPA Portfolio Manager API.
5
+ Project-URL: bugs, https://github.com/harryw1/EPA-PM-API-Wrapper/issues
6
+ Project-URL: changelog, https://github.com/harryw1/EPA-PM-API-Wrapper/releases
7
+ Project-URL: documentation, https://harryw1.github.io/EPA-PM-API-Wrapper/
8
+ Project-URL: homepage, https://github.com/harryw1/EPA-PM-API-Wrapper
9
+ Author-email: Harrison Weiss <haweiss@dcas.nyc.gov>
10
+ Maintainer-email: Harrison Weiss <haweiss@dcas.nyc.gov>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: httpx>=0.28.1
26
+ Requires-Dist: python-dotenv>=1.2.2
27
+ Requires-Dist: rich>=13.7
28
+ Requires-Dist: typer>=0.12
29
+ Requires-Dist: xsdata>=26.2
30
+ Description-Content-Type: text/markdown
31
+
32
+ # EPA PM API Wrapper
33
+
34
+ [![PyPI version](https://img.shields.io/pypi/v/EPA-PM-API-Wrapper.svg)](https://pypi.org/project/EPA-PM-API-Wrapper/)
35
+ [![CI](https://github.com/harryw1/EPA-PM-API-Wrapper/actions/workflows/ci.yml/badge.svg)](https://github.com/harryw1/EPA-PM-API-Wrapper/actions/workflows/ci.yml)
36
+ [![Python versions](https://img.shields.io/pypi/pyversions/EPA-PM-API-Wrapper.svg)](https://pypi.org/project/EPA-PM-API-Wrapper/)
37
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
38
+
39
+ Client wrapper for the EPA Portfolio Manager API.
40
+
41
+ * [GitHub](https://github.com/harryw1/EPA-PM-API-Wrapper/) | [PyPI](https://pypi.org/project/EPA-PM-API-Wrapper/) | [Documentation](https://harryw1.github.io/EPA-PM-API-Wrapper/)
42
+ * Created by [Harrison Weiss](https://publicpresence.org) | GitHub [@harryw1](https://github.com/harryw1) | PyPI [@harryw1](https://pypi.org/user/harryw1/)
43
+ * MIT License
44
+
45
+ ## Features
46
+
47
+ * **Full API coverage:** Every public endpoint in the ENERGY STAR Portfolio Manager web services API is bound — account, property, propertyUse, building, meter, consumption, waste, reporting, target finder, HEY, and the various catalogs (federal agencies, eGrid, weather stations, EDU/PGP).
48
+ * **Sync and async clients:** `EpaPmClient` and `EpaPmAsyncClient` share the same resource-namespaced surface; pick whichever fits your runtime.
49
+ * **Typed XML models:** Request and response payloads are dataclasses generated from the EPA XSDs (via `xsdata`), so IDE autocomplete and type checkers work out of the box.
50
+ * **Structured error handling:** `EpaPmApiError` carries `status_code`, a parsed `errors` list, and an `error_number` accessor for branching without regexing the message; `EpaPmAuthError` covers 401s.
51
+ * **Production-ready transport:** Configurable timeout/transport/`httpx.Client` injection, context-manager lifecycle, and built-in retry/backoff for 429 + 5xx + connection-level errors with `Retry-After` support.
52
+ * **Pagination iterators:** `client.consumption_data.iter(meter_id)` and `client.waste_data.iter(meter_id)` walk pages internally.
53
+ * **Live and test environments:** Switch between production and `wstest` with a single flag.
54
+ * **CLI included:** A `typer`-based CLI (`epa_pm_api_wrapper`) for ad-hoc lookups across the most common resources.
55
+
56
+ ## Usage
57
+
58
+ The CLI will prompt for credentials or read them from environment variables.
59
+
60
+ ### Environment Variables
61
+
62
+ You can set the following environment variables:
63
+
64
+ * `EPA_PM_USERNAME`
65
+ * `EPA_PM_PASSWORD`
66
+ * `EPA_PM_TEST`: Set to `true` to target the test environment instead of live.
67
+
68
+ ### Using a `.env` file
69
+
70
+ Copy the example file and fill in your credentials:
71
+
72
+ ```bash
73
+ cp .env.example .env
74
+ # Edit .env with your credentials
75
+ ```
76
+
77
+ The CLI will automatically detect and load this file.
78
+
79
+ ## Documentation
80
+
81
+ Documentation is built with [Zensical](https://zensical.org/) and deployed to GitHub Pages.
82
+
83
+ * **Live site:** https://harryw1.github.io/EPA-PM-API-Wrapper/
84
+ * **Preview locally:** `just docs-serve` (serves at http://localhost:8000)
85
+ * **Build:** `just docs-build`
86
+
87
+ API documentation is auto-generated from docstrings using [mkdocstrings](https://mkdocstrings.github.io/).
88
+
89
+ Docs deploy automatically on push to `main` via GitHub Actions. To enable this, go to your repo's Settings > Pages and set the source to **GitHub Actions**.
90
+
91
+ ## Development
92
+
93
+ To set up for local development:
94
+
95
+ ```bash
96
+ # Clone your fork
97
+ git clone git@github.com:your_username/EPA-PM-API-Wrapper.git
98
+ cd EPA-PM-API-Wrapper
99
+
100
+ # Install in editable mode with live updates
101
+ uv tool install --editable .
102
+ ```
103
+
104
+ This installs the CLI globally but with live updates - any changes you make to the source code are immediately available when you run `epa_pm_api_wrapper`.
105
+
106
+ Run tests:
107
+
108
+ ```bash
109
+ uv run pytest
110
+ ```
111
+
112
+ Run quality checks (format, lint, type check, test):
113
+
114
+ ```bash
115
+ just qa
116
+ ```
117
+
118
+ ## Versioning
119
+
120
+ This project follows [Semantic Versioning](https://semver.org/). The public
121
+ API is everything exported from `epa_pm_api_wrapper.__all__` plus the
122
+ attribute-namespaced resource methods on `EpaPmClient` / `EpaPmAsyncClient`.
123
+ Anything in a private module (leading underscore) or the internal
124
+ `_request` / `_arequest` plumbing is implementation detail and may change
125
+ in any release.
126
+
127
+ Pin to a compatible release range when depending on this library:
128
+
129
+ ```
130
+ EPA-PM-API-Wrapper>=0.3,<0.4
131
+ ```
132
+
133
+ ## Author
134
+
135
+ EPA PM API Wrapper was created in 2026 by Harrison Weiss.
136
+
137
+ Built with [Cookiecutter](https://github.com/cookiecutter/cookiecutter) and the [audreyfeldroy/cookiecutter-pypackage](https://github.com/audreyfeldroy/cookiecutter-pypackage) project template.