windborne 1.1.3__py3-none-any.whl → 1.1.4__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.
windborne/__init__.py CHANGED
@@ -14,6 +14,7 @@ from .data_api import (
14
14
  get_flying_missions,
15
15
  get_mission_launch_site,
16
16
  get_predicted_path,
17
+ get_current_location,
17
18
  get_flight_path
18
19
  )
19
20
 
@@ -22,6 +23,7 @@ from .forecasts_api import (
22
23
  get_point_forecasts,
23
24
  get_initialization_times,
24
25
 
26
+ get_full_gridded_forecast,
25
27
  get_temperature_2m,
26
28
  # get_dewpoint_2m,
27
29
  get_wind_u_10m, get_wind_v_10m,
@@ -51,11 +53,13 @@ __all__ = [
51
53
  "get_flying_missions",
52
54
  "get_mission_launch_site",
53
55
  "get_predicted_path",
56
+ "get_current_location",
54
57
  "get_flight_path",
55
58
 
56
59
  "get_point_forecasts",
57
60
  "get_initialization_times",
58
61
 
62
+ "get_full_gridded_forecast",
59
63
  "get_temperature_2m",
60
64
  # "get_dewpoint_2m",
61
65
  "get_wind_u_10m",
windborne/cli.py CHANGED
@@ -14,10 +14,12 @@ from . import (
14
14
  get_flying_missions,
15
15
  get_mission_launch_site,
16
16
  get_predicted_path,
17
+ get_current_location,
17
18
  get_flight_path,
18
19
 
19
20
  get_point_forecasts,
20
21
  get_initialization_times,
22
+ get_full_gridded_forecast,
21
23
  get_temperature_2m,
22
24
  # get_dewpoint_2m,
23
25
  get_wind_u_10m, get_wind_v_10m,
@@ -121,6 +123,11 @@ def main():
121
123
  launch_site_parser.add_argument('mission_id', help='Mission ID')
122
124
  launch_site_parser.add_argument('output', nargs='?', help='Output file')
123
125
 
126
+ # Get Current Location Command
127
+ current_location_parser = subparsers.add_parser('current-location', help='Get current location')
128
+ current_location_parser.add_argument('mission_id', help='Mission ID')
129
+ current_location_parser.add_argument('output', nargs='?', help='Output file')
130
+
124
131
  # Get Predicted Path Command
125
132
  prediction_parser = subparsers.add_parser('predict-path', help='Get predicted flight path')
126
133
  prediction_parser.add_argument('mission_id', help='Mission ID')
@@ -149,6 +156,9 @@ def main():
149
156
 
150
157
  # GRIDDED FORECASTS
151
158
  ####################################################################################################################
159
+ full_gridded_parser = subparsers.add_parser('grid_full', help='Get full gridded forecast')
160
+ full_gridded_parser.add_argument('args', nargs='*', help='time output_file')
161
+
152
162
  # Gridded 2m temperature Command
153
163
  gridded_temperature_2m_parser = subparsers.add_parser('grid_temp_2m', help='Get gridded output of global 2m temperature forecasts')
154
164
  gridded_temperature_2m_parser.add_argument('args', nargs='*', help='time output_file')
@@ -379,7 +389,12 @@ def main():
379
389
  output_file=args.output,
380
390
  print_result=(not args.output)
381
391
  )
382
-
392
+ elif args.command == 'current-location':
393
+ get_current_location(
394
+ mission_id=args.mission_id,
395
+ output_file=args.output,
396
+ print_result=(not args.output)
397
+ )
383
398
  elif args.command == 'predict-path':
384
399
  get_predicted_path(
385
400
  mission_id=args.mission_id,
@@ -419,6 +434,17 @@ def main():
419
434
  elif args.command == 'init_times':
420
435
  get_initialization_times(print_response=True)
421
436
 
437
+ if args.command == 'grid_full':
438
+ # Parse get_full_gridded_forecast arguments
439
+ if len(args.args) in [0,1]:
440
+ print("To get the full gridded forecast you need to provide the time for which to get the forecast and an output file.")
441
+ print("\nUsage: windborne get_full_gridded_forecast time output_file")
442
+ elif len(args.args) == 2:
443
+ get_full_gridded_forecast(time=args.args[0], output_file=args.args[1])
444
+ else:
445
+ print("Too many arguments")
446
+ print("\nUsage: windborne get_full_gridded_forecast time output_file")
447
+
422
448
  elif args.command == 'grid_temp_2m':
423
449
  # Parse grid_temp_2m arguments
424
450
  if len(args.args) in [0,1]:
windborne/data_api.py CHANGED
@@ -622,22 +622,22 @@ def get_mission_launch_site(mission_id=None, output_file=None, print_result=Fals
622
622
  return response.get('launch_site')
623
623
 
624
624
 
625
- def get_predicted_path(mission_id=None, output_file=None, print_result=False):
625
+ def get_flying_mission(mission_id, verify_flying=True):
626
626
  """
627
- Fetches the predicted flight path for a given mission.
628
- Displays currently flying missions if the provided mission ID is invalid.
627
+ Fetches a flying mission by ID.
628
+ If the mission is not flying, displays a list of currently flying missions.
629
629
 
630
- Args:
631
- mission_id (str): The ID of the mission to fetch the prediction for.
632
- output_file (str): Optional path to save the response data.
633
- print_result (bool): Whether to print the results in the CLI.
630
+ Args:
631
+ mission_id (str): The ID of the mission to fetch.
632
+ verify_flying (bool): Whether to always check if the mission is flying.
634
633
 
635
- Returns:
636
- list: The API response containing the predicted flight path data.
634
+ Returns:
635
+ dict: The API response containing the mission data, or None if the mission is not flying.
637
636
  """
638
- if not mission_id:
639
- print("To get the predicted flight path for a given mission you must provide a mission ID.")
640
- return
637
+ if not verify_flying and not mission_id.startswith('W-'):
638
+ return {
639
+ 'id': mission_id,
640
+ }
641
641
 
642
642
  # Check if provided mission ID belong to a flying mission
643
643
  flying_missions = get_flying_missions()
@@ -658,8 +658,30 @@ def get_predicted_path(mission_id=None, output_file=None, print_result=False):
658
658
  print_table(flying_missions, keys=['id', 'name'], headers=['Mission ID', 'Mission Name'])
659
659
  else:
660
660
  print("No missions are currently flying.")
661
+ return None
662
+
663
+ return mission
664
+
665
+
666
+ def get_predicted_path(mission_id=None, output_file=None, print_result=False):
667
+ """
668
+ Fetches the predicted flight path for a given mission.
669
+ Displays currently flying missions if the provided mission ID is invalid.
670
+
671
+ Args:
672
+ mission_id (str): The ID of the mission to fetch the prediction for.
673
+ output_file (str): Optional path to save the response data.
674
+ print_result (bool): Whether to print the results in the CLI.
675
+
676
+ Returns:
677
+ list: The API response containing the predicted flight path data.
678
+ """
679
+ if not mission_id:
680
+ print("To get the predicted flight path for a given mission you must provide a mission ID.")
661
681
  return
662
682
 
683
+ mission = get_flying_mission(mission_id)
684
+
663
685
  url = f"{DATA_API_BASE_URL}/missions/{mission.get('id')}/prediction.json"
664
686
  response = make_api_request(url)
665
687
 
@@ -677,6 +699,42 @@ def get_predicted_path(mission_id=None, output_file=None, print_result=False):
677
699
  return response.get('prediction')
678
700
 
679
701
 
702
+ def get_current_location(mission_id=None, output_file=None, print_result=False, verify_flying=True):
703
+ """
704
+ Fetches the current location for a given mission.
705
+
706
+ Args:
707
+ mission_id (str): The ID of the mission to fetch the current location for.
708
+ output_file (str): Optional path to save the response data.
709
+ print_result (bool): Whether to print the results in the CLI.
710
+ verify_flying (bool): Whether to verify the mission is flying before trying to fetch the current location
711
+
712
+ Returns:
713
+ dict: Current location with latitude, longitude, and altitude, or None if not found
714
+ """
715
+ if not mission_id:
716
+ print("To get the current location for a given mission you must provide a mission ID.")
717
+ return
718
+
719
+ mission = get_flying_mission(mission_id, verify_flying=verify_flying)
720
+
721
+ url = f"{DATA_API_BASE_URL}/missions/{mission.get('id')}/current_location.json"
722
+ response = make_api_request(url)
723
+
724
+ if response is None:
725
+ return
726
+
727
+ if output_file:
728
+ save_arbitrary_response(output_file, response, csv_data_key=None)
729
+
730
+ if print_result:
731
+ print("Current location\n")
732
+ print_table([response], keys=['latitude', 'longitude', 'altitude'],
733
+ headers=['Latitude', 'Longitude', 'Altitude'])
734
+
735
+ return response
736
+
737
+
680
738
  def get_flight_path(mission_id=None, output_file=None, print_result=False):
681
739
  """
682
740
  Fetches the flight path for a given mission.
@@ -141,6 +141,9 @@ def get_gridded_forecast(time, variable, output_file=None):
141
141
 
142
142
  return response
143
143
 
144
+ def get_full_gridded_forecast(time, output_file=None):
145
+ return get_gridded_forecast(time, "FULL", output_file)
146
+
144
147
  def get_temperature_2m(time, output_file=None):
145
148
  return get_gridded_forecast(time, "temperature_2m", output_file)
146
149
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: windborne
3
- Version: 1.1.3
3
+ Version: 1.1.4
4
4
  Summary: A Python library for interacting with WindBorne Data and Forecasts API
5
5
  Author-email: WindBorne Systems <data@windbornesystems.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -0,0 +1,13 @@
1
+ windborne/__init__.py,sha256=jPqxHTqOEcAnPU-7VCJionGToE2tqY7Q3SuSdQrdl9Q,1944
2
+ windborne/api_request.py,sha256=zh1TaaZAaRfAXp2NYMja75fKeduWLfao02JRRFVpQCA,11108
3
+ windborne/cli.py,sha256=fJ4cLcBpc7YasfMu3pNrqCX9idGCWA-2j2necNpDfck,36696
4
+ windborne/data_api.py,sha256=f2TdMpSxQLiWKcUJxbG_9SqAp4DU-sZ3rBvqTcBHbuk,33343
5
+ windborne/forecasts_api.py,sha256=Jea1hGd2CQHbyRXnJXLamF1GdgBsoqX7oGyg8S6YoRo,14102
6
+ windborne/observation_formatting.py,sha256=c739aaun6aaYhXl5VI-SRGR-TDS355_0Bfu1t6McoiM,14993
7
+ windborne/track_formatting.py,sha256=LaLfTyjpWoOtHmReJPLViY0MKm_iPL_5I2OB_lNvGGA,10054
8
+ windborne/utils.py,sha256=H8gvZ4Lrr0UmLl25iMZs6NsZliCY_73Ved_rBIqxJg4,7240
9
+ windborne-1.1.4.dist-info/METADATA,sha256=PqFm1t3RoKqj0K1UtUtJYMfIwl1gauKIAinS1Elyir4,1235
10
+ windborne-1.1.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
11
+ windborne-1.1.4.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
12
+ windborne-1.1.4.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
13
+ windborne-1.1.4.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- windborne/__init__.py,sha256=DcxmiLq4UnjoRjZd4UeuYt29FBsi9paMXGtI91Itn04,1826
2
- windborne/api_request.py,sha256=zh1TaaZAaRfAXp2NYMja75fKeduWLfao02JRRFVpQCA,11108
3
- windborne/cli.py,sha256=xRPRLh50iC4Uu0AYEHL-LHRxUnpxqB_Mn-easp5VSK4,35370
4
- windborne/data_api.py,sha256=QsG1NJyOCzTrTLRaoz5Z4nGRI0HCMEJvbDyRUlY3Usg,31388
5
- windborne/forecasts_api.py,sha256=E0X9FyUW2yz3pQZKkFBYDMeg6PhFJ1bp4z1Cg1g0uGs,13987
6
- windborne/observation_formatting.py,sha256=c739aaun6aaYhXl5VI-SRGR-TDS355_0Bfu1t6McoiM,14993
7
- windborne/track_formatting.py,sha256=LaLfTyjpWoOtHmReJPLViY0MKm_iPL_5I2OB_lNvGGA,10054
8
- windborne/utils.py,sha256=H8gvZ4Lrr0UmLl25iMZs6NsZliCY_73Ved_rBIqxJg4,7240
9
- windborne-1.1.3.dist-info/METADATA,sha256=unPmA3uPzt8obgqSmJSrsSzSLat4yH7o3uJtb-i3wy0,1235
10
- windborne-1.1.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
11
- windborne-1.1.3.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
12
- windborne-1.1.3.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
13
- windborne-1.1.3.dist-info/RECORD,,