Как создать Python-приложение, которое предупредит о приближении астероида

от автора

Привет, Хабр! В статье я постарался показать, как объединить космос и технологии в одном приложении, которое через API оповестит пользователей по SMS о приближающемся к Земле астероиде. Подробности, как всегда, под катом.

NASA OpenAPI

NASA каждый день собирает более 15 терабайт различных данных! Вся эта информация доступна широкой аудитории бесплатно. С помощью API агентства разработчики могут использовать её для создания приложений.

Вот некоторые из доступных API, которые потенциально полезны для вашего проекта:

  • камера полихроматической визуализации Земли (EPIC) — полные изображения диска Земли:

  • отслеживание природных явлений обсерваторией EONET — прототип веб-службы, предоставляющий постоянно обновляемые метаданные природных явлений, такие как изображения штормов, собранные с поверхности Земли;

  • библиотека изображений и видео NASA — доступ к библиотеке изображений и видео;

  • звуки (бета-версия) — доступ к космическим звукам через SoundCloud с устранением некоторых шумов;

  • веб-служба объектов, сближающихся с Землёй (NeoWs) — предоставляет доступ к информации об астероидах, которые держат курс на нашу планету. Этот сервис нам и нужен.

Как подключить NASA API

Механику мы подглядели в этой статье на HackerNoon. И попробовали адаптировать шаги для аудитории Хабра.

Нужно получить доступ к необходимому нам программному интерфейсу. На официальном сайте NASA кликните по ссылке для подачи заявки на получение личного API-ключа. После отправки заявки NASA пришлёт вам ключ по электронной почте.

Экран с формой регистрации API НАСА.

Экран с формой регистрации API НАСА.

Обратите внимание, что большинство протоколов имеет ограничение API в 1 000 запросов в час. Они подходят для тестов и личного использования, но не для коммерческих целей.

Изучение данных от NASA API

Посмотрим на данные, возвращаемые API, для построения нашего варианта использования.

Запрос (GET):

  • start_date (ГГГГ-ММ-ДД) — дата начала поиска астероидов

  • end_date (ГГГГ-ММ-ДД) — дата окончания поиска астероидов

  • api_key — ключ, который вы получили по электронной почте на предыдущем шаге

Ответ:

Возвращает объект JSON с ценными данными, с которыми нужно работать для получения результата.

{     "links": {         "next": "http://api.nasa.gov/neo/rest/v1/feed?start_date=2023-10-17&end_date=2023-10-17&detailed=false&api_key=8DaCUyeKqnNbupBJvDO42iUMS6tqfLFK4JjM263G",         "prev": "http://api.nasa.gov/neo/rest/v1/feed?start_date=2023-10-15&end_date=2023-10-15&detailed=false&api_key=8DaCUyeKqnNbupBJvDO42iUMS6tqfLFK4JjM263G",         "self": "http://api.nasa.gov/neo/rest/v1/feed?start_date=2023-10-16&end_date=2023-10-16&detailed=false&api_key=8DaCUyeKqnNbupBJvDO42iUMS6tqfLFK4JjM263G"     },     "element_count": 10,     "near_earth_objects": {         "2023-10-16": [             {                 "links": {                     "self": "http://api.nasa.gov/neo/rest/v1/neo/2337558?api_key=8DaCUyeKqnNbupBJvDO42iUMS6tqfLFK4JjM263G"                 },                 "id": "2337558",                 "neo_reference_id": "2337558",                 "name": "337558 (2001 SG262)",                 "nasa_jpl_url": "http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=2337558",                 "absolute_magnitude_h": 19.33,                 "estimated_diameter": {                     "kilometers": {                         "estimated_diameter_min": 0.3618719966,                         "estimated_diameter_max": 0.8091703835                     },                     "meters": {                         "estimated_diameter_min": 361.8719965994,                         "estimated_diameter_max": 809.1703835499                     },                     "miles": {                         "estimated_diameter_min": 0.2248567644,                         "estimated_diameter_max": 0.5027950104                     },                     "feet": {                         "estimated_diameter_min": 1187.2441213233,                         "estimated_diameter_max": 2654.758561166                     }                 },                 "is_potentially_hazardous_asteroid": true,                 "close_approach_data": [                     {                         "close_approach_date": "2023-10-16",                         "close_approach_date_full": "2023-Oct-16 16:00",                         "epoch_date_close_approach": 1697472000000,                         "relative_velocity": {                             "kilometers_per_second": "20.8203253059",                             "kilometers_per_hour": "74953.171101087",                             "miles_per_hour": "46572.9856766726"                         },                         "miss_distance": {                             "astronomical": "0.2519750156",                             "lunar": "98.0182810684",                             "kilometers": "37694925.626976772",                             "miles": "23422540.6669605736"                         },                         "orbiting_body": "Earth"                     }                 ],                 "is_sentry_object": false             },             [...]

Обратите внимание на структуру near_earth_objects с необходимыми деталями:

  • estimated_diameter — диаметр астероида в метрах, километрах, милях и футах

  • relative_velocity — относительная скорость объекта

  • miss_distance — расстояние от орбитального тела

  • orbiting_body — в большинстве случаев это Земля, но при желании вы можете изучить и другие варианты

Поиск данных ближайшего астероида с помощью Python-приложения

NASA API даёт сведения об объектах, проходящих рядом. Мы найдём ближайший из них, чтобы ежедневно отправлять предупреждение в SMS. Используем для этого Python и библиотеку requests. Если у вас ещё не установлен Python, скачайте его с официального сайта.

Чтобы установить библиотеку requests, введите следующую команду: 

$ python -m pip install requests

Создайте новый файл, например alert.py. Импортируйте установленную библиотеку requests, чтобы отправлять запросы в API. Также добавьте объект date из стандартного модуля datetime, чтобы получить сегодняшнюю дату:

import requests from datetime import date

Получите сегодняшнюю дату с помощью импортированного модуля в формате, нужном для отправки HTTP-запроса в NASA:

# Сегодняшняя дата todays_date = date.today().strftime("%Y-%m-%d")

Пропишите API-ключ и URL-адрес для подключения к NASA API. Получить бесплатный API-ключ нужно здесь:

nasa_api_key = "NASA_API_KEY" nasa_url = "https://api.nasa.gov/neo/rest/v1/feed?start_date=" + todays_date +"&end_date="+ todays_date + "&api_key="+nasa_api_key

Отправьте GET-запрос в NASA API и конвертируйте ответ в JSON-формат:

# Отправляем запрос в NASA API и получаем ответ в JSON nasa_response = requests.get(nasa_url) json_nasa_response = nasa_response.json()

В полученном от NASA ответе нужно найти ближайший к Земле астероид в массиве near_earth_objects. Напишите функцию для поиска индекса ближайшего астероида в массиве всех близких к Земле астероидов:

# Функция для нахождения индекса ближайшего к Земле астероида в массиве всех близких астероидов def find_closest_asteroid_index(near_asteroids):     # пустой массив для учёта дальности астероидов от Земли     asteroids = []     # перебираем астероиды в массиве near_earth_objects     for i in range(0, len(near_asteroids)):         # добавляем расстояние до Земли в массив         asteroids.insert(i, near_asteroids[i]['close_approach_data'][0]['miss_distance']['kilometers'])     # находим минимальное расстояние в массиве и возвращаем его индекс     # индекс будет совпадать с индексом ближайшего астероида в near_earth_objects         return asteroids.index(min(asteroids))

Отправка SMS-уведомления с данными о ближайшем астероиде

Далее нужно отправить SMS-уведомление, если NASA API сообщает о том, что вблизи Земли есть астероиды. Проверьте, есть ли массив near_earth_objects в ответе от NASA API. Если есть, получите список всех ближайших астероидов и найдите индекс ближайшего с помощью функции, которую написали ранее:

# Если около Земли есть астероиды if "near_earth_objects" in json_nasa_response:     # Получаем список близких астероидов     near_asteroids = json_nasa_response['near_earth_objects'][todays_date]     # Индекс ближайшего астероида     closest_asteroid_index = find_closest_asteroid_index(near_asteroids)

Получите данные ближайшего астероида, которые отправим в SMS-уведомлении:

    # Получаем данные астероида, которые отправим в SMS-уведомлении     name = near_asteroids[closest_asteroid_index]['name'] #название астероида     how_close = near_asteroids[closest_asteroid_index]['close_approach_data'][0]['miss_distance']['kilometers'] #расстояние от Земли     diameter =  near_asteroids[closest_asteroid_index]['estimated_diameter']['meters']['estimated_diameter_max'] #диаметр астероида

Переведите полученные данные в строку и сформируйте текст сообщения:

    # Форматируем данные в строку     how_close_str = str(round(float(how_close)))     diameter_str = str(round(diameter))         # Формируем сообщение     alert ="Ближайший астероид сегодня - " + name + ". Он находится в " + how_close_str + " км от Земли. Его диаметр составляет " + diameter_str + " метров."

Теперь можно перейти к отправке SMS-уведомления с помощью Exolve SMS API. Для этого нам понадобятся:

Добавьте в код номер Exolve, URL-адрес, API-ключ и номер получателя:

    # Настройки подключения к Exolve     exolve_number = "7999XXXXXXX"     exolve_url = "https://api.exolve.ru/messaging/v1/SendSMS"     recipient_number = "7924XXXXXXX"     exolve_api_key = "EXOLVE_API_KEY"

Сделайте запрос к Exolve API с помощью библиотеки requests, чтобы отправить SMS-уведомление на указанный номер со сформированным ранее текстом сообщения с данными о ближайшем астероиде:

    # Отправляем запрос в EXOLVE SMS API и получаем ответ в JSON     exolve_response = requests.post(exolve_url,     headers = {"Authorization": "Bearer " + exolve_api_key},     json = {         "number": exolve_number,         "destination": recipient_number,         "text": alert     })     json_exolve_response = exolve_response.json()     print(json_exolve_response) # message_id или ошибка отправки

Запустите код. Вы должны получить похожее SMS-уведомление:

SMS-уведомление

SMS-уведомление

Резюме

Подытожим, что мы сделали:

  1. Получили ключ API для портала NASA OpenAPI.

  2. Изучили API NeoWs, который даёт доступ к информации об астероидах, направляющихся к Земле.

  3. Нашли ближайший к нашей планете объект из всех тех, что могли пройти поблизости.

  4. Отправили SMS-уведомление, чтобы предупредить себя об этой встрече.

Теперь можно спать спокойно, учитывая, что вы знаете о каждом большом объекте, летящем к Земле.

Исходный код приложения можно найти на GitHub.


ссылка на оригинал статьи https://habr.com/ru/articles/824772/