Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions Scripts/NASA_APOD_Downloader/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 🪐 Cosmic Log: NASA APOD Viewer

A unique Python script that connects to the official NASA API to retrieve the Astronomy Picture of the Day (APOD) for any specified date, displaying its title, explanation, and media link directly in the command line.

This project showcases professional skills in API integration, dependency management, and robust error handling.

## 💻 Requirements

This script requires the `requests` library for making HTTP calls.

```bash
pip install -r requirements.txt
```

## 🚀 How to Run

API Key: The script is set to use the `DEMO_KEY` which has rate limits. For heavy use, you can obtain a free API key from the NASA Open APIs website.

Run the script from your terminal:

```bash
python apod_viewer.py
```

The script will prompt you to enter a date in `YYYY-MM-DD` format (e.g., `1995-06-16` for the very first APOD). Leave the input blank to fetch today's APOD.

## Example Output

```text
Welcome to the Cosmic Log (NASA APOD Viewer)!
This script uses NASA's open API to fetch astronomical data.
Enter a date (YYYY-MM-DD) or leave blank for today: 2024-03-20

Fetching APOD data for 2024-03-20...

==================================================
TITLE: Spring Equinox Over the Northern Hemisphere
DATE: 2024-03-20
COPYRIGHT: Public Domain
--------------------------------------------------

EXPLANATION:
Today is the equinox, the day when day and night have about the same duration.
In the northern hemisphere of planet Earth, this equinox marks the beginning of
spring. In the south, it marks the beginning of autumn. To celebrate, a favorite
satellite view of the Earth from the fourth day of spring in 2020 is featured.
--------------------------------------------------

MEDIA TYPE: IMAGE
VIEW URL: [https://apod.nasa.gov/apod/image/2403/EarthEquinox_Himawari_3000.jpg](https://apod.nasa.gov/apod/image/2403/EarthEquinox_Himawari_3000.jpg)

To save the image, please visit the URL above.
Note: Image data is too large for simple console saving
==================================================
```
127 changes: 127 additions & 0 deletions Scripts/NASA_APOD_Downloader/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from dotenv import load_dotenv
import requests
import json
import datetime
import os

load_dotenv()

# Users should get their own key for production use.
NASA_API_KEY = os.getenv("NASA_API_KEY")
API_URL = os.getenv("API_URL")
OUTPUT_DIR = os.getenv("OUTPUT_DIR")

RED = "\033[31m"
GREEN = "\033[32m"
BLUE = "\033[34m"
MAGENTA = "\033[35m"
RESET = "\033[0m"

def fetch_apod_data(date_str):
"""
Fetches the Astronomy Picture of the Day (APOD) data for a given date.
"""
print(f"Fetching APOD data for {date_str}...")

# Define parameters for the API call
params = {
'api_key': NASA_API_KEY,
'date': date_str
}

try:
# Make the API request
response = requests.get(API_URL, params=params)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)

# Parse and return JSON data
return response.json()

except requests.exceptions.HTTPError as errh:
print(f"\n{RED}--- ERROR ---{RESET}")
if response.status_code == 404:
print(f"{RED}Error 404:{RESET} No data found for {date_str}. APOD service might not have an entry for this specific date.")
else:
print(f"{RED}HTTP Error occurred: {errh}{RESET}")
return None

except requests.exceptions.RequestException as err:
print(f"\n{RED}--- ERROR ---{RESET}")
print(f"{RED}Network error or DNS failure:{RESET} {err}")
print("Check your internet connection.")
return None

except json.JSONDecodeError:
print(f"{RED}Failed{RESET} to decode JSON response from NASA API.")
return None


def display_and_save_apod(data):
"""
Displays the APOD information and advises on image saving.
"""
if not data:
return

print("\n" + "="*50)
print(f"{MAGENTA}TITLE: {data.get('title', 'N/A')}{RESET}")
print(f"{MAGENTA}DATE:{RESET} {data.get('date', 'N/A')}")
print(f"{MAGENTA}COPYRIGHT:{RESET} {data.get('copyright', 'Public Domain').strip()}")
print("-" * 50)
print(f"{MAGENTA}EXPLANATION:{RESET}")
# Wrap text to keep the output clean
explanation = data.get('explanation', 'No explanation provided.')
for i in range(0, len(explanation), 80):
print(explanation[i:i+80])

print("-" * 50)

media_type = data.get('media_type', 'image')
url = data.get('hdurl') or data.get('url') # Prioritize HD URL

print(f"MEDIA TYPE: {media_type.upper()}")
print(f"VIEW URL: {url}")

# Note: To keep the script simple and avoid complex file system operations and dependency on PIL for displaying images, we only provide the link.
if media_type == 'image' and url:
print(f"\n{GREEN}To save the image, please visit the URL above.{RESET}")
print(f"{BLUE}Note:{RESET} Image data is too large for simple console saving.")

print("="*50 + "\n")


def get_user_date():
"""
Prompts the user for a date and validates the format.
"""
while True:
try:
input_date = input("Enter a date (YYYY-MM-DD) or leave blank for today: ")

if not input_date:
# Return today's date if blank
return datetime.date.today().strftime('%Y-%m-%d')

# Validate format and ensure date is not in the future
date_obj = datetime.datetime.strptime(input_date, '%Y-%m-%d').date()
if date_obj > datetime.date.today():
print("Cannot look into the future! Please enter a valid past or current date.")
continue

return input_date

except ValueError:
print(f"{RED}Invalid date format.{RESET} Please use YYYY-MM-DD (e.g., 2023-10-25).")


if __name__ == "__main__":
print(f"{MAGENTA}Welcome to the Cosmic Log (NASA APOD Viewer)!{RESET}")
print(f"{GREEN}This script uses {BLUE}NASA's open API{RESET} to fetch astronomical data.")

selected_date = get_user_date()

if selected_date:
apod_data = fetch_apod_data(selected_date)
display_and_save_apod(apod_data)
else:
print(f"{RED}Operation cancelled.{RESET}")
6 changes: 6 additions & 0 deletions Scripts/NASA_APOD_Downloader/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
certifi==2025.8.3
charset-normalizer==3.4.3
idna==3.10
python-dotenv==1.1.1
requests==2.32.5
urllib3==2.5.0