buildstock-fetch 1.1.0__py3-none-any.whl → 1.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.

Potentially problematic release.


This version of buildstock-fetch might be problematic. Click here for more details.

@@ -28,6 +28,9 @@ app = typer.Typer(
28
28
  # File configuration
29
29
  BUILDSTOCK_RELEASES_FILE = str(files("buildstock_fetch").joinpath("data").joinpath("buildstock_releases.json"))
30
30
 
31
+ # File types that haven't been implemented yet
32
+ UNAVAILABLE_FILE_TYPES = ["load_curve_daily"]
33
+
31
34
 
32
35
  class InvalidProductError(Exception):
33
36
  """Exception raised when an invalid product is provided."""
@@ -122,6 +125,14 @@ def _get_release_versions_options(
122
125
  )
123
126
  available_release_versions = list({parsed_releases[release]["release_version"] for release in available_releases})
124
127
 
128
+ if (
129
+ product_type == "resstock"
130
+ and weather_file == "tmy3"
131
+ and release_year == "2024"
132
+ and "1" in available_release_versions
133
+ ):
134
+ available_release_versions.remove("1")
135
+
125
136
  # Define the desired order: "2", "1.1", "1"
126
137
  display_order = ["2", "1.1", "1"]
127
138
 
@@ -222,6 +233,7 @@ def _get_file_type_options_grouped(release_name: str) -> list[dict]:
222
233
  "load_curve_annual",
223
234
  ],
224
235
  "Metadata": ["metadata"],
236
+ "Weather": ["weather"],
225
237
  }
226
238
 
227
239
  choices = []
@@ -431,18 +443,80 @@ def _print_data_processing_info(inputs: Mapping[str, Union[str, list[str]]]) ->
431
443
  print(f"Output directory: {inputs['output_directory']}")
432
444
 
433
445
 
434
- def _check_unavailable_file_types(inputs: Mapping[str, Union[str, list[str]]]) -> None:
435
- """Check and print warning for unavailable file types."""
436
- unavailable_file_types = ["load_curve_hourly", "load_curve_daily"]
437
- selected_file_types = inputs["file_type"].split() if isinstance(inputs["file_type"], str) else inputs["file_type"]
438
- selected_unavailable = [ft for ft in selected_file_types if ft in unavailable_file_types]
439
- if selected_unavailable:
446
+ def _check_weather_map_available_states(inputs: Mapping[str, Union[str, list[str]]]) -> tuple[list[str], list[str]]:
447
+ """Check if the weather map is available for the given release and state."""
448
+ available_states: list[str] = []
449
+ unavailable_states: list[str] = []
450
+ product_short_name = "res" if inputs["product"] == "resstock" else "com"
451
+ release_name = f"{product_short_name}_{inputs['release_year']}_{inputs['weather_file']}_{inputs['release_version']}"
452
+ selected_release = _get_all_available_releases()[release_name]
453
+ if "weather_map_available_states" not in selected_release:
454
+ unavailable_states = inputs["states"] if isinstance(inputs["states"], list) else [inputs["states"]]
455
+ else:
456
+ unavailable_states = [
457
+ state for state in inputs["states"] if state not in selected_release["weather_map_available_states"]
458
+ ]
459
+ available_states = [
460
+ state for state in inputs["states"] if state in selected_release["weather_map_available_states"]
461
+ ]
462
+ return available_states, unavailable_states
463
+
464
+
465
+ def _check_weather_file_availability(
466
+ inputs: Mapping[str, Union[str, list[str]]],
467
+ available_file_types: list[str],
468
+ selected_unavailable_file_types: list[str],
469
+ ) -> None:
470
+ """Check weather file availability and update file type lists."""
471
+ available_states, unavailable_states = _check_weather_map_available_states(inputs)
472
+
473
+ if len(unavailable_states) > 0:
474
+ selected_unavailable_file_types.append("weather")
475
+ if len(unavailable_states) == len(inputs["states"]) and "weather" in available_file_types:
476
+ available_file_types.remove("weather")
477
+
478
+ if len(unavailable_states) > 0:
479
+ console.print(
480
+ f"\n[yellow]The weather map is not available for the following states: {unavailable_states}[/yellow]"
481
+ )
482
+ console.print(
483
+ "\n[yellow]Please first build the weather station mapping for this state using the weather station mapping CLI tool (just build-weather-station-map)[/yellow]"
484
+ )
485
+ for state in unavailable_states:
486
+ selected_unavailable_file_types.append(f"weather: {state}")
487
+
488
+
489
+ def _print_unavailable_file_types_warning(selected_unavailable_file_types: list[str]) -> None:
490
+ """Print warning for unavailable file types."""
491
+ if selected_unavailable_file_types:
440
492
  console.print("\n[yellow]The following file types are not available yet:[/yellow]")
441
- for file_type in selected_unavailable:
493
+ for file_type in selected_unavailable_file_types:
442
494
  console.print(f" • {file_type}")
443
495
  console.print("")
444
496
 
445
497
 
498
+ def _check_unavailable_file_types(inputs: Mapping[str, Union[str, list[str]]]) -> tuple[list[str], list[str]]:
499
+ """Check and print warning for unavailable file types."""
500
+ selected_file_types = inputs["file_type"].split() if isinstance(inputs["file_type"], str) else inputs["file_type"]
501
+ # Create a copy to avoid modifying the original list
502
+ available_file_types = selected_file_types.copy()
503
+ selected_unavailable_file_types = []
504
+
505
+ for ft in selected_file_types:
506
+ if ft in UNAVAILABLE_FILE_TYPES:
507
+ selected_unavailable_file_types.append(ft)
508
+ # Only remove if it exists in available_file_types
509
+ if ft in available_file_types:
510
+ available_file_types.remove(ft)
511
+
512
+ if "weather" in selected_file_types:
513
+ _check_weather_file_availability(inputs, available_file_types, selected_unavailable_file_types)
514
+
515
+ _print_unavailable_file_types_warning(selected_unavailable_file_types)
516
+
517
+ return available_file_types, selected_unavailable_file_types
518
+
519
+
446
520
  def _fetch_all_building_ids(inputs: Mapping[str, Union[str, list[str]]]) -> list:
447
521
  """Fetch building IDs for all states and upgrade IDs."""
448
522
  bldg_ids = []
@@ -643,6 +717,91 @@ UPGRADE_ID_OPTION = typer.Option(
643
717
  OUTPUT_DIRECTORY_OPTION = typer.Option(None, "--output_directory", "-o", help='e.g., "data" or "../output"')
644
718
 
645
719
 
720
+ def _run_interactive_mode_wrapper() -> dict[str, Union[str, list[str]]]:
721
+ """Run interactive mode with error handling."""
722
+ try:
723
+ while True:
724
+ inputs = _run_interactive_mode()
725
+ if _verify_interactive_inputs(inputs):
726
+ return inputs
727
+ console.print("[yellow]Let's try again...[/yellow]")
728
+ except KeyboardInterrupt:
729
+ console.print("\n[red]Operation cancelled by user.[/red]")
730
+ raise typer.Exit(0) from None
731
+
732
+
733
+ def _process_direct_inputs(
734
+ product: str,
735
+ release_year: str,
736
+ weather_file: str,
737
+ release_version: float,
738
+ states: str,
739
+ file_type: str,
740
+ upgrade_id: str,
741
+ output_directory: str,
742
+ ) -> dict[str, Union[str, list[str]]]:
743
+ """Process direct command line inputs."""
744
+ states_list = states.split() if states else []
745
+ upgrade_ids_list = upgrade_id.split() if upgrade_id else ["0"]
746
+ file_type_list = file_type.split() if file_type else []
747
+
748
+ direct_inputs: dict[str, Union[str, list[str]]] = {
749
+ "product": product,
750
+ "release_year": release_year,
751
+ "weather_file": weather_file,
752
+ "release_version": _normalize_release_version(release_version),
753
+ "states": states_list,
754
+ "file_type": file_type_list,
755
+ "upgrade_ids": upgrade_ids_list,
756
+ "output_directory": output_directory,
757
+ }
758
+
759
+ try:
760
+ validation_result = _validate_direct_inputs(direct_inputs)
761
+ if validation_result is not True:
762
+ console.print(f"\n[red]{validation_result}[/red]")
763
+ raise typer.Exit(1) from None
764
+ except InvalidProductError:
765
+ console.print(f"\n[red]Invalid product: {direct_inputs['product']}[/red]")
766
+ raise typer.Exit(1) from None
767
+
768
+ return direct_inputs
769
+
770
+
771
+ def _process_data_download(inputs: dict[str, Union[str, list[str]]]) -> None:
772
+ """Process data download based on available file types."""
773
+ available_file_types, unavailable_file_types = _check_unavailable_file_types(inputs)
774
+ if "weather" in inputs["file_type"]:
775
+ available_weather_states, unavailable_weather_states = _check_weather_map_available_states(inputs)
776
+ else:
777
+ available_weather_states = None
778
+
779
+ if len(available_file_types) > 0:
780
+ # Fetch the building ids and download data
781
+ bldg_ids = _fetch_all_building_ids(inputs)
782
+
783
+ # Ask user about download choice
784
+ selected_bldg_ids = _get_user_download_choice(bldg_ids)
785
+
786
+ if selected_bldg_ids:
787
+ file_type_tuple = (
788
+ tuple(inputs["file_type"].split())
789
+ if isinstance(inputs["file_type"], str)
790
+ else tuple(inputs["file_type"])
791
+ )
792
+ output_dir = inputs["output_directory"]
793
+ if isinstance(output_dir, list):
794
+ output_dir = output_dir[0] if output_dir else "."
795
+
796
+ fetch_bldg_data(
797
+ selected_bldg_ids, file_type_tuple, Path(output_dir), weather_states=available_weather_states
798
+ )
799
+ else:
800
+ console.print("[yellow]No files selected for download.[/yellow]")
801
+ else:
802
+ console.print("[yellow]None of the selected file types are available for download.[/yellow]")
803
+
804
+
646
805
  def main_callback(
647
806
  product: str = PRODUCT_OPTION,
648
807
  release_year: str = RELEASE_YEAR_OPTION,
@@ -659,61 +818,15 @@ def main_callback(
659
818
 
660
819
  # If no arguments provided, run interactive mode
661
820
  if not any([product, release_year, weather_file, release_version, states, file_type]):
662
- try:
663
- while True:
664
- inputs = _run_interactive_mode()
665
- if _verify_interactive_inputs(inputs):
666
- break
667
- console.print("[yellow]Let's try again...[/yellow]")
668
- except KeyboardInterrupt:
669
- console.print("\n[red]Operation cancelled by user.[/red]")
670
- raise typer.Exit(0) from None
821
+ inputs = _run_interactive_mode_wrapper()
671
822
  else:
672
- states_list = states.split() if states else []
673
- upgrade_ids_list = upgrade_id.split() if upgrade_id else ["0"]
674
- file_type_list = file_type.split() if file_type else []
675
-
676
- direct_inputs: dict[str, Union[str, list[str]]] = {
677
- "product": product,
678
- "release_year": release_year,
679
- "weather_file": weather_file,
680
- "release_version": _normalize_release_version(release_version),
681
- "states": states_list,
682
- "file_type": file_type_list,
683
- "upgrade_ids": upgrade_ids_list,
684
- "output_directory": output_directory,
685
- }
686
- try:
687
- validation_result = _validate_direct_inputs(direct_inputs)
688
- if validation_result is not True:
689
- console.print(f"\n[red]{validation_result}[/red]")
690
- raise typer.Exit(1) from None
691
- except InvalidProductError:
692
- console.print(f"\n[red]Invalid product: {direct_inputs['product']}[/red]")
693
- raise typer.Exit(1) from None
694
-
695
- inputs = direct_inputs
823
+ inputs = _process_direct_inputs(
824
+ product, release_year, weather_file, release_version, states, file_type, upgrade_id, output_directory
825
+ )
696
826
 
697
827
  # Process the data
698
828
  _print_data_processing_info(inputs)
699
- _check_unavailable_file_types(inputs)
700
-
701
- # Fetch the building ids and download data
702
- bldg_ids = _fetch_all_building_ids(inputs)
703
-
704
- # Ask user about download choice
705
- selected_bldg_ids = _get_user_download_choice(bldg_ids)
706
-
707
- if selected_bldg_ids:
708
- file_type_tuple = (
709
- tuple(inputs["file_type"].split()) if isinstance(inputs["file_type"], str) else tuple(inputs["file_type"])
710
- )
711
- output_dir = inputs["output_directory"]
712
- if isinstance(output_dir, list):
713
- output_dir = output_dir[0] if output_dir else "."
714
- fetch_bldg_data(selected_bldg_ids, file_type_tuple, Path(output_dir))
715
- else:
716
- console.print("[yellow]No files selected for download.[/yellow]")
829
+ _process_data_download(inputs)
717
830
 
718
831
 
719
832
  app.command()(main_callback)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: buildstock-fetch
3
- Version: 1.1.0
3
+ Version: 1.3.0
4
4
  Summary: This library simplifies downloading building characteristics and load curve data from NREL's ResStock and ComStock projects.
5
5
  Author-email: Switchbox <hello@switch.box>
6
6
  Project-URL: Homepage, https://switchbox-data.github.io/buildstock-fetch/
@@ -1,8 +1,8 @@
1
1
  buildstock_fetch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  buildstock_fetch/__main__.py,sha256=wEPNJ-s7F6KcRQ_4B5Xh08uqvYZHno5F2R8DU0BMBtk,80
3
- buildstock_fetch/main.py,sha256=r37TmyQo-RPZktnJvWRkpUr2uuuoDynht-wJf_NhrGQ,57071
4
- buildstock_fetch/main_cli.py,sha256=EslGmRfjhj4k7vjtKTrBrlOJDFShma5Ut8hl0q79DKw,27394
5
- buildstock_fetch/data/buildstock_releases.json,sha256=E1Uexf2jcLtrmJ-B9btIBSi0n8biF_O4x7vlLMPRK6E,9648
3
+ buildstock_fetch/main.py,sha256=6NAYxs_5yW0PpNgPdCgmaJJUqgSF-InrMO8xZJe4npQ,73839
4
+ buildstock_fetch/main_cli.py,sha256=3zKJ5sXG2QGmAs--kZPQy1qhLEnaw5gvi4RoH_q65dI,31891
5
+ buildstock_fetch/data/buildstock_releases.json,sha256=rHbNkWtTi6VXFim7xtvhwFWQUvtqvcbCfjtvRjkWV-4,10853
6
6
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=comstock/release_year=2021/weather_file=amy2018/release_version=1/state=AK/d1454abff0d94c8090af7b3e923c473b-0.parquet,sha256=nG6H3oGyDzPk1B15YmFd_U81PsA14uABqqwK7P30nKE,7059
7
7
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=comstock/release_year=2021/weather_file=amy2018/release_version=1/state=AK/dcd864cc169b4695be2b9775b1a054ae-0.parquet,sha256=fsREWV9g4fsA3cIWqyPnXVwd7FsJxED2btYpmyOvnbQ,7163
8
8
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=comstock/release_year=2021/weather_file=amy2018/release_version=1/state=AL/d1454abff0d94c8090af7b3e923c473b-0.parquet,sha256=jiTG48ly-LZwfwAL3THdfRzHDG1qEogoxO7P78U4WOU,41201
@@ -1599,10 +1599,10 @@ buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/r
1599
1599
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/release_year=2024/weather_file=tmy3/release_version=2/state=WV/dcd864cc169b4695be2b9775b1a054ae-0.parquet,sha256=-taHsRgrCKXW_7QKoD8QwFBnavXSsSNc6ok3DHqZOXE,42818
1600
1600
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/release_year=2024/weather_file=tmy3/release_version=2/state=WY/d1454abff0d94c8090af7b3e923c473b-0.parquet,sha256=bWuUnd02XJXYXkHqiXQuIidtm1be5yHmrz1-iFZ14ao,22304
1601
1601
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/release_year=2024/weather_file=tmy3/release_version=2/state=WY/dcd864cc169b4695be2b9775b1a054ae-0.parquet,sha256=EC1DGLtXqwF1slnnbuTJyQZF0Ox5hoDRDxgaF_SpN8g,21727
1602
- buildstock_fetch/data/weather_station_map/weather_station_map.parquet,sha256=623W-fMLbpgKw5Rg-lM4blfi966f60govY1-IiAFprk,131839
1603
- buildstock_fetch-1.1.0.dist-info/licenses/LICENSE,sha256=TJeh2yvO8__8Rbamd8r48-zvlFCINAsu9nOo5QdMRX8,1066
1604
- buildstock_fetch-1.1.0.dist-info/METADATA,sha256=ZuU3FodFG0610biFzWf3QUml8piQ5lUbTYj2gkkiUZQ,7607
1605
- buildstock_fetch-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1606
- buildstock_fetch-1.1.0.dist-info/entry_points.txt,sha256=C7zPk3BSLcI47ymvYKI05nvfRJMEXz4BPIIDKsjePn8,54
1607
- buildstock_fetch-1.1.0.dist-info/top_level.txt,sha256=-PGb2C-Tb3O-wPqUHSOBrvJqRzNHgY_KTbTsXaHIo5M,17
1608
- buildstock_fetch-1.1.0.dist-info/RECORD,,
1602
+ buildstock_fetch/data/weather_station_map/weather_station_map.parquet,sha256=igNrx-UGH20CqPcjANTDrrMyj6Z4_JcXIg2aaCNhFRg,346990
1603
+ buildstock_fetch-1.3.0.dist-info/licenses/LICENSE,sha256=TJeh2yvO8__8Rbamd8r48-zvlFCINAsu9nOo5QdMRX8,1066
1604
+ buildstock_fetch-1.3.0.dist-info/METADATA,sha256=Ifx3dv3sp1coZB7-umz3kdpk3NEILXnZSjTdrIRYFOg,7607
1605
+ buildstock_fetch-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1606
+ buildstock_fetch-1.3.0.dist-info/entry_points.txt,sha256=C7zPk3BSLcI47ymvYKI05nvfRJMEXz4BPIIDKsjePn8,54
1607
+ buildstock_fetch-1.3.0.dist-info/top_level.txt,sha256=-PGb2C-Tb3O-wPqUHSOBrvJqRzNHgY_KTbTsXaHIo5M,17
1608
+ buildstock_fetch-1.3.0.dist-info/RECORD,,