diff --git a/Scripts/NASA_APOD_Downloader/README.md b/Scripts/NASA_APOD_Downloader/README.md new file mode 100644 index 0000000..b41a37e --- /dev/null +++ b/Scripts/NASA_APOD_Downloader/README.md @@ -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 +================================================== +``` diff --git a/Scripts/NASA_APOD_Downloader/main.py b/Scripts/NASA_APOD_Downloader/main.py new file mode 100644 index 0000000..a4e821a --- /dev/null +++ b/Scripts/NASA_APOD_Downloader/main.py @@ -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}") diff --git a/Scripts/NASA_APOD_Downloader/requirements.txt b/Scripts/NASA_APOD_Downloader/requirements.txt new file mode 100644 index 0000000..6ce3af9 --- /dev/null +++ b/Scripts/NASA_APOD_Downloader/requirements.txt @@ -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