hardknee commited on
Commit
c3a9d5d
·
verified ·
1 Parent(s): 620024d

Switched to new neo tool code

Browse files
Files changed (1) hide show
  1. tools/nasa_neo_data_fetcher.py +87 -42
tools/nasa_neo_data_fetcher.py CHANGED
@@ -3,31 +3,42 @@ import requests
3
  import json
4
  from calendar import monthrange
5
  from smolagents.tools import Tool
 
 
6
 
7
- class NASANeoDataFetcher(Tool):
 
8
  name = "nasa_neo_data_fetcher"
9
  description = "Retrieves Neo data from the NASA API for the dates in your query then returns the available Neo data."
10
- inputs = {'query': {'type': 'string', 'description': 'The range of dates to query.'}}
 
 
 
 
 
 
 
 
 
11
  output_type = "string"
12
-
13
- def __init__(self, query):
 
14
  self.api_key = os.getenv("NASA_API_KEY")
15
  self.root_url = "https://api.nasa.gov/neo/rest/v1/feed?"
16
- try:
17
- get_data = self.get_nasa_neo_data(query)
18
- except Error:
19
- get_data = self.fetch_neo_data_in_chunks(query)
20
- data = get_data(query)
21
-
22
 
23
- def forward(self, query):
24
- results = self.data(query)
25
- return results
26
-
 
 
 
 
27
 
28
- def get_nasa_neo_data(self, start_date: str, end_date: str) -> dict:
29
- """A function to get Near Earth Object data from NASA API. Try this function first before
30
- calling the fetch_neo_data_in_chunks function.
31
  Args:
32
  start_date: A string representing the start date of the data to be fetched.
33
  end_date: A string representing the end date of the data to be fetched.
@@ -38,49 +49,83 @@ class NASANeoDataFetcher(Tool):
38
  response = requests.get(url)
39
  if repr(response.status_code) == "200":
40
  data = response.json()
 
41
  return data
42
  else:
43
- fetch_neo_data_in_chunks(start_date, end_date)
44
  print("Error: ", response.status_code)
45
 
46
- def split_month_into_chunks(self, year: int, month: int) -> list:
 
 
47
  days_in_month = monthrange(year, month)[1]
48
- first_day = 1
49
- last_day = 7
50
  week_dates = []
51
- while last_day <= days_in_month:
 
52
  start_date = f"{year}-{month}-{first_day}"
53
- end_date = f"{year}-{month}-{last_day}"
54
  week_dates.append((start_date, end_date))
55
  first_day += 7
56
- last_day += 7
57
  remaining_days = days_in_month - first_day + 1
58
  if remaining_days > 0:
59
  start_date = f"{year}-{month}-{first_day}"
60
- end_date = f"{year}-{month}-{days_in_month}"
61
  week_dates.append((start_date, end_date))
62
  return week_dates
63
 
64
- def fetch_neo_data_in_chunks(
65
- self, start_year: int, end_year: int
66
- ) -> list[tuple[str, list[dict]]]:
67
- """A function to fetch Near Earth Object data from NASA API in chunks. Call this function if the API
68
- returns an error when you try to pull data e.g. a 400 or 429.
 
 
 
 
 
 
69
  Args:
70
- start_year: An integer representing the start year of the data to be fetched.
71
- end_year: An integer representing the end year of the data to be fetched.
72
- Returns: A list of Near Earth Object data fetched from the API as a JSON-like dictionary.
 
 
 
 
 
 
 
 
 
 
 
 
73
  """
74
  neo_data = []
 
 
75
  for year in range(start_year, end_year + 1):
76
- for month in range(1, 13):
77
- for chunk in self.split_month_into_chunks(year, month):
78
- start_date, end_date = chunk
79
- print(f"Fetching data for {start_date} to {end_date}")
80
- data = self.get_nasa_neo_data(
81
- start_date=start_date, end_date=end_date
82
- )
83
- if data and "near_earth_objects" in data:
84
- neo_data.extend(data["near_earth_objects"].items())
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  neo_data_json = json.dumps(neo_data)
86
  return neo_data_json
 
3
  import json
4
  from calendar import monthrange
5
  from smolagents.tools import Tool
6
+ from typing import Generator
7
+ from dotenv import load_dotenv
8
 
9
+
10
+ class NasaNeoDataFetcher(Tool):
11
  name = "nasa_neo_data_fetcher"
12
  description = "Retrieves Neo data from the NASA API for the dates in your query then returns the available Neo data."
13
+ inputs = {
14
+ "start_date": {
15
+ "type": "string",
16
+ "description": "The start date of the range to query.",
17
+ },
18
+ "end_date": {
19
+ "type": "string",
20
+ "description": "The end date of the range to query.",
21
+ },
22
+ }
23
  output_type = "string"
24
+
25
+ def __init__(self):
26
+ load_dotenv()
27
  self.api_key = os.getenv("NASA_API_KEY")
28
  self.root_url = "https://api.nasa.gov/neo/rest/v1/feed?"
29
+ self.is_initialized = False
 
 
 
 
 
30
 
31
+ def forward(self, start_date: str, end_date: str) -> str:
32
+ """A function to fetch Near Earth Object data from NASA API for a given date range.
33
+ Args:
34
+ start_date: A string representing the start date of the data to be fetched.
35
+ end_date: A string representing the end date of the data to be fetched.
36
+ Returns: The data fetched from the API as a JSON-like dictionary.
37
+ """
38
+ return self._fetch_neo_data_in_chunks(start_date, end_date)
39
 
40
+ def _get_nasa_neo_data(self, start_date: str, end_date: str) -> dict:
41
+ """A function to get Near Earth Object data from NASA API for a given date range.
 
42
  Args:
43
  start_date: A string representing the start date of the data to be fetched.
44
  end_date: A string representing the end date of the data to be fetched.
 
49
  response = requests.get(url)
50
  if repr(response.status_code) == "200":
51
  data = response.json()
52
+ print(f"Successfully fetched data for {start_date} to {end_date}")
53
  return data
54
  else:
 
55
  print("Error: ", response.status_code)
56
 
57
+ def _split_date_range_into_chunks(
58
+ self, year: int, month: int, first_day: int, last_day: int
59
+ ) -> list:
60
  days_in_month = monthrange(year, month)[1]
 
 
61
  week_dates = []
62
+ last_day_in_chunk = first_day + 6
63
+ while last_day_in_chunk <= last_day:
64
  start_date = f"{year}-{month}-{first_day}"
65
+ end_date = f"{year}-{month}-{last_day_in_chunk}"
66
  week_dates.append((start_date, end_date))
67
  first_day += 7
68
+ last_day_in_chunk += 7
69
  remaining_days = days_in_month - first_day + 1
70
  if remaining_days > 0:
71
  start_date = f"{year}-{month}-{first_day}"
72
+ end_date = f"{year}-{month}-{last_day}"
73
  week_dates.append((start_date, end_date))
74
  return week_dates
75
 
76
+ def _split_date_into_ymd(self, date: str) -> tuple[int, int, int]:
77
+ split_date = date.split("-")
78
+ year = int(split_date[0])
79
+ month = int(split_date[1])
80
+ day = int(split_date[2])
81
+ return year, month, day
82
+
83
+ def _get_neo_data_chunks(
84
+ self, *args: tuple[str, str]
85
+ ) -> Generator[dict, None, None]:
86
+ """A function that splits a date range into chunks of 7 days.
87
  Args:
88
+ *args: A variable number of date ranges to split.
89
+ Returns: A generator yielding NASA NEO data dictionaries.
90
+ """
91
+ for chunk in self._split_date_range_into_chunks(*args):
92
+ start_date, end_date = chunk
93
+ data = self._get_nasa_neo_data(start_date=start_date, end_date=end_date)
94
+ yield data
95
+
96
+ def _fetch_neo_data_in_chunks(self, start_date: str, end_date: str) -> str:
97
+ """A function that fetches Near Earth Object data from NASA API in chunks of 7 days. NB: The API
98
+ returns an error when you try to pull data covering longer than 7 days.
99
+ Args:
100
+ start_date: A string representing the start date of the data to be fetched.
101
+ end_date: A string representing the end date of the data to be fetched.
102
+ Returns: A JSON-like dictionary of Near Earth Object data fetched from the API.
103
  """
104
  neo_data = []
105
+ start_year, start_month, start_day = self._split_date_into_ymd(start_date)
106
+ end_year, end_month, end_day = self._split_date_into_ymd(end_date)
107
  for year in range(start_year, end_year + 1):
108
+ for month in range(start_month, end_month + 1):
109
+ days_in_month = monthrange(year, month)[1]
110
+ if month == start_month and start_month != end_month:
111
+ args = (year, month, start_day, days_in_month)
112
+ data = list(self._get_neo_data_chunks(*args))
113
+
114
+ elif month == end_month and start_day != 1:
115
+ args = (year, month, start_day, end_day)
116
+ data = list(self._get_neo_data_chunks(*args))
117
+
118
+ elif month == end_month:
119
+ args = (year, month, 1, end_day)
120
+ data = list(self._get_neo_data_chunks(*args))
121
+
122
+ else:
123
+ args = (year, month, 1, days_in_month)
124
+ data = list(self._get_neo_data_chunks(*args))
125
+
126
+ if data:
127
+ for item in data:
128
+ if "near_earth_objects" in item:
129
+ neo_data.extend(item["near_earth_objects"].items())
130
  neo_data_json = json.dumps(neo_data)
131
  return neo_data_json