# PyASAN ๐
A Python wrapper and command-line interface for NASA's REST APIs, starting with the Astronomy Picture of the Day (APOD) API.
[](https://www.python.org/downloads/)
[](LICENSE)
## Features
- ๐ **Easy-to-use Python API** for NASA's APOD service
- ๐ฅ๏ธ **Beautiful command-line interface** with rich formatting
- ๐ **Flexible authentication** (API key or environment variables)
- ๐ **Comprehensive data models** with validation
- ๐ก๏ธ **Robust error handling** and retry logic
- ๐งช **Well-tested** with comprehensive unit tests
- ๐ **Extensible design** for future NASA APIs
## Installation
### From PyPI (when published)
```bash
pip install pyasan
```
### From Source
```bash
git clone https://github.com/yourusername/pyasan.git
cd pyasan
pip install -e .
```
### Development Installation
```bash
git clone https://github.com/yourusername/pyasan.git
cd pyasan
pip install -e ".[dev]"
```
## Quick Start
### Get Your NASA API Key
1. Visit [https://api.nasa.gov/](https://api.nasa.gov/)
2. Fill out the form to get your free API key
3. Set it as an environment variable:
```bash
export NASA_API_KEY=your_api_key_here
```
### Python API
```python
from pyasan import APODClient
# Initialize client (uses NASA_API_KEY env var by default)
client = APODClient()
# Or provide API key directly
client = APODClient(api_key="your_api_key_here")
# Get today's APOD
apod = client.get_apod()
print(f"Title: {apod.title}")
print(f"Date: {apod.date}")
print(f"URL: {apod.url}")
print(f"Explanation: {apod.explanation}")
# Get APOD for a specific date
apod = client.get_apod(date="2023-01-01", hd=True)
# Get random APOD
random_apod = client.get_random_apod()
# Get multiple random APODs
random_apods = client.get_random_apod(count=5)
for apod in random_apods:
print(apod.title)
# Get APOD for a date range
apods = client.get_apod_range(
start_date="2023-01-01",
end_date="2023-01-07"
)
# Get recent APODs
recent = client.get_recent_apods(days=7)
```
### Command Line Interface
The CLI provides a beautiful, user-friendly interface to NASA's APOD API:
```bash
# Get today's APOD
pyasan apod get
# Get APOD for a specific date
pyasan apod get --date 2023-01-01
# Get HD version
pyasan apod get --date 2023-01-01 --hd
# Get random APOD
pyasan apod random
# Get 5 random APODs
pyasan apod random --count 5
# Get APODs for a date range
pyasan apod range --start-date 2023-01-01 --end-date 2023-01-07
# Get recent APODs
pyasan apod recent --days 7
# Hide explanation text for cleaner output
pyasan apod get --no-explanation
# Use specific API key
pyasan apod get --api-key your_api_key_here
```
## API Reference
### APODClient
The main client for interacting with NASA's APOD API.
#### Methods
##### `get_apod(date=None, hd=False, thumbs=False)`
Get Astronomy Picture of the Day for a specific date.
**Parameters:**
- `date` (str|date, optional): Date in YYYY-MM-DD format or date object. Defaults to today.
- `hd` (bool): Return HD image URL if available
- `thumbs` (bool): Return thumbnail URL for videos
**Returns:** `APODResponse`
##### `get_random_apod(count=1, hd=False, thumbs=False)`
Get random Astronomy Picture(s) of the Day.
**Parameters:**
- `count` (int): Number of random images to retrieve (1-100)
- `hd` (bool): Return HD image URLs if available
- `thumbs` (bool): Return thumbnail URLs for videos
**Returns:** `APODResponse` if count=1, `APODBatch` if count>1
##### `get_apod_range(start_date, end_date, hd=False, thumbs=False)`
Get Astronomy Pictures of the Day for a date range.
**Parameters:**
- `start_date` (str|date): Start date in YYYY-MM-DD format or date object
- `end_date` (str|date): End date in YYYY-MM-DD format or date object
- `hd` (bool): Return HD image URLs if available
- `thumbs` (bool): Return thumbnail URLs for videos
**Returns:** `APODBatch`
##### `get_recent_apods(days=7, hd=False, thumbs=False)`
Get recent Astronomy Pictures of the Day.
**Parameters:**
- `days` (int): Number of recent days to retrieve (1-100)
- `hd` (bool): Return HD image URLs if available
- `thumbs` (bool): Return thumbnail URLs for videos
**Returns:** `APODBatch`
### Data Models
#### APODResponse
Represents a single APOD entry.
**Attributes:**
- `title` (str): The title of the image
- `date` (date): The date of the image
- `explanation` (str): The explanation of the image
- `url` (str): The URL of the image
- `media_type` (str): The type of media (image or video)
- `hdurl` (str, optional): The URL of the HD image
- `thumbnail_url` (str, optional): The URL of the thumbnail
- `copyright` (str, optional): The copyright information
**Properties:**
- `is_video` (bool): Check if the media is a video
- `is_image` (bool): Check if the media is an image
#### APODBatch
Represents multiple APOD entries.
**Attributes:**
- `items` (List[APODResponse]): List of APOD responses
**Methods:**
- `__len__()`: Get the number of items
- `__iter__()`: Iterate over items
- `__getitem__(index)`: Get item by index
## Configuration
### Environment Variables
- `NASA_API_KEY`: Your NASA API key
- `NASA_API_TOKEN`: Alternative name for the API key
### API Key Sources (in order of precedence)
1. Direct parameter: `APODClient(api_key="your_key")`
2. Environment variable: `NASA_API_KEY`
3. Environment variable: `NASA_API_TOKEN`
4. Default: `DEMO_KEY` (limited requests)
## Error Handling
PyASAN provides comprehensive error handling:
```python
from pyasan import APODClient
from pyasan.exceptions import (
ValidationError,
APIError,
AuthenticationError,
RateLimitError
)
client = APODClient()
try:
apod = client.get_apod(date="invalid-date")
except ValidationError as e:
print(f"Invalid input: {e}")
except AuthenticationError as e:
print(f"API key issue: {e}")
except RateLimitError as e:
print(f"Rate limit exceeded: {e}")
except APIError as e:
print(f"API error: {e}")
```
## Development
### Setup Development Environment
```bash
git clone https://github.com/yourusername/pyasan.git
cd pyasan
python -m venv venv
source venv/bin/activate # On Windows: venv\\Scripts\\activate
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=pyasan
# Run specific test file
pytest tests/test_apod.py
```
### Code Formatting
```bash
# Format code with black
black pyasan tests
# Check with flake8
flake8 pyasan tests
# Type checking with mypy
mypy pyasan
```
## Roadmap
- [x] APOD API support
- [ ] Mars Rover Photos API
- [ ] Earth Polychromatic Imaging Camera (EPIC) API
- [ ] Near Earth Object Web Service (NeoWs)
- [ ] Exoplanet Archive API
- [ ] Image and Video Library API
- [ ] Async support
- [ ] Caching support
- [ ] Image download utilities
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- NASA for providing free access to their amazing APIs
- The astronomy community for inspiring space exploration
- All contributors who help improve this project
## Links
- [NASA API Portal](https://api.nasa.gov/)
- [APOD API Documentation](https://api.nasa.gov/planetary/apod)
- [PyPI Package](https://pypi.org/project/pyasan/) (when published)
- [GitHub Repository](https://github.com/yourusername/pyasan)
---
Made with โค๏ธ for the astronomy and Python communities.
Raw data
{
"_id": null,
"home_page": null,
"name": "pyasan",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "nasa, api, astronomy, apod, cli",
"author": null,
"author_email": "Jeorry Balasabas <jeorry@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/16/36/518eadab1f1aeb8aeaf61c2268f94abaecbdbadea964dedb55d1a440a61c/pyasan-0.2.0.tar.gz",
"platform": null,
"description": "# PyASAN \ud83d\ude80\n\nA Python wrapper and command-line interface for NASA's REST APIs, starting with the Astronomy Picture of the Day (APOD) API.\n\n[](https://www.python.org/downloads/)\n[](LICENSE)\n\n## Features\n\n- \ud83c\udf1f **Easy-to-use Python API** for NASA's APOD service\n- \ud83d\udda5\ufe0f **Beautiful command-line interface** with rich formatting\n- \ud83d\udd11 **Flexible authentication** (API key or environment variables)\n- \ud83d\udcca **Comprehensive data models** with validation\n- \ud83d\udee1\ufe0f **Robust error handling** and retry logic\n- \ud83e\uddea **Well-tested** with comprehensive unit tests\n- \ud83d\udcda **Extensible design** for future NASA APIs\n\n## Installation\n\n### From PyPI (when published)\n```bash\npip install pyasan\n```\n\n### From Source\n```bash\ngit clone https://github.com/yourusername/pyasan.git\ncd pyasan\npip install -e .\n```\n\n### Development Installation\n```bash\ngit clone https://github.com/yourusername/pyasan.git\ncd pyasan\npip install -e \".[dev]\"\n```\n\n## Quick Start\n\n### Get Your NASA API Key\n\n1. Visit [https://api.nasa.gov/](https://api.nasa.gov/)\n2. Fill out the form to get your free API key\n3. Set it as an environment variable:\n ```bash\n export NASA_API_KEY=your_api_key_here\n ```\n\n### Python API\n\n```python\nfrom pyasan import APODClient\n\n# Initialize client (uses NASA_API_KEY env var by default)\nclient = APODClient()\n\n# Or provide API key directly\nclient = APODClient(api_key=\"your_api_key_here\")\n\n# Get today's APOD\napod = client.get_apod()\nprint(f\"Title: {apod.title}\")\nprint(f\"Date: {apod.date}\")\nprint(f\"URL: {apod.url}\")\nprint(f\"Explanation: {apod.explanation}\")\n\n# Get APOD for a specific date\napod = client.get_apod(date=\"2023-01-01\", hd=True)\n\n# Get random APOD\nrandom_apod = client.get_random_apod()\n\n# Get multiple random APODs\nrandom_apods = client.get_random_apod(count=5)\nfor apod in random_apods:\n print(apod.title)\n\n# Get APOD for a date range\napods = client.get_apod_range(\n start_date=\"2023-01-01\", \n end_date=\"2023-01-07\"\n)\n\n# Get recent APODs\nrecent = client.get_recent_apods(days=7)\n```\n\n### Command Line Interface\n\nThe CLI provides a beautiful, user-friendly interface to NASA's APOD API:\n\n```bash\n# Get today's APOD\npyasan apod get\n\n# Get APOD for a specific date\npyasan apod get --date 2023-01-01\n\n# Get HD version\npyasan apod get --date 2023-01-01 --hd\n\n# Get random APOD\npyasan apod random\n\n# Get 5 random APODs\npyasan apod random --count 5\n\n# Get APODs for a date range\npyasan apod range --start-date 2023-01-01 --end-date 2023-01-07\n\n# Get recent APODs\npyasan apod recent --days 7\n\n# Hide explanation text for cleaner output\npyasan apod get --no-explanation\n\n# Use specific API key\npyasan apod get --api-key your_api_key_here\n```\n\n## API Reference\n\n### APODClient\n\nThe main client for interacting with NASA's APOD API.\n\n#### Methods\n\n##### `get_apod(date=None, hd=False, thumbs=False)`\n\nGet Astronomy Picture of the Day for a specific date.\n\n**Parameters:**\n- `date` (str|date, optional): Date in YYYY-MM-DD format or date object. Defaults to today.\n- `hd` (bool): Return HD image URL if available\n- `thumbs` (bool): Return thumbnail URL for videos\n\n**Returns:** `APODResponse`\n\n##### `get_random_apod(count=1, hd=False, thumbs=False)`\n\nGet random Astronomy Picture(s) of the Day.\n\n**Parameters:**\n- `count` (int): Number of random images to retrieve (1-100)\n- `hd` (bool): Return HD image URLs if available \n- `thumbs` (bool): Return thumbnail URLs for videos\n\n**Returns:** `APODResponse` if count=1, `APODBatch` if count>1\n\n##### `get_apod_range(start_date, end_date, hd=False, thumbs=False)`\n\nGet Astronomy Pictures of the Day for a date range.\n\n**Parameters:**\n- `start_date` (str|date): Start date in YYYY-MM-DD format or date object\n- `end_date` (str|date): End date in YYYY-MM-DD format or date object \n- `hd` (bool): Return HD image URLs if available\n- `thumbs` (bool): Return thumbnail URLs for videos\n\n**Returns:** `APODBatch`\n\n##### `get_recent_apods(days=7, hd=False, thumbs=False)`\n\nGet recent Astronomy Pictures of the Day.\n\n**Parameters:**\n- `days` (int): Number of recent days to retrieve (1-100)\n- `hd` (bool): Return HD image URLs if available\n- `thumbs` (bool): Return thumbnail URLs for videos\n\n**Returns:** `APODBatch`\n\n### Data Models\n\n#### APODResponse\n\nRepresents a single APOD entry.\n\n**Attributes:**\n- `title` (str): The title of the image\n- `date` (date): The date of the image \n- `explanation` (str): The explanation of the image\n- `url` (str): The URL of the image\n- `media_type` (str): The type of media (image or video)\n- `hdurl` (str, optional): The URL of the HD image\n- `thumbnail_url` (str, optional): The URL of the thumbnail\n- `copyright` (str, optional): The copyright information\n\n**Properties:**\n- `is_video` (bool): Check if the media is a video\n- `is_image` (bool): Check if the media is an image\n\n#### APODBatch\n\nRepresents multiple APOD entries.\n\n**Attributes:**\n- `items` (List[APODResponse]): List of APOD responses\n\n**Methods:**\n- `__len__()`: Get the number of items\n- `__iter__()`: Iterate over items \n- `__getitem__(index)`: Get item by index\n\n## Configuration\n\n### Environment Variables\n\n- `NASA_API_KEY`: Your NASA API key\n- `NASA_API_TOKEN`: Alternative name for the API key\n\n### API Key Sources (in order of precedence)\n\n1. Direct parameter: `APODClient(api_key=\"your_key\")`\n2. Environment variable: `NASA_API_KEY`\n3. Environment variable: `NASA_API_TOKEN` \n4. Default: `DEMO_KEY` (limited requests)\n\n## Error Handling\n\nPyASAN provides comprehensive error handling:\n\n```python\nfrom pyasan import APODClient\nfrom pyasan.exceptions import (\n ValidationError, \n APIError, \n AuthenticationError, \n RateLimitError\n)\n\nclient = APODClient()\n\ntry:\n apod = client.get_apod(date=\"invalid-date\")\nexcept ValidationError as e:\n print(f\"Invalid input: {e}\")\nexcept AuthenticationError as e:\n print(f\"API key issue: {e}\")\nexcept RateLimitError as e:\n print(f\"Rate limit exceeded: {e}\")\nexcept APIError as e:\n print(f\"API error: {e}\")\n```\n\n## Development\n\n### Setup Development Environment\n\n```bash\ngit clone https://github.com/yourusername/pyasan.git\ncd pyasan\npython -m venv venv\nsource venv/bin/activate # On Windows: venv\\\\Scripts\\\\activate\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=pyasan\n\n# Run specific test file\npytest tests/test_apod.py\n```\n\n### Code Formatting\n\n```bash\n# Format code with black\nblack pyasan tests\n\n# Check with flake8\nflake8 pyasan tests\n\n# Type checking with mypy\nmypy pyasan\n```\n\n## Roadmap\n\n- [x] APOD API support\n- [ ] Mars Rover Photos API\n- [ ] Earth Polychromatic Imaging Camera (EPIC) API \n- [ ] Near Earth Object Web Service (NeoWs)\n- [ ] Exoplanet Archive API\n- [ ] Image and Video Library API\n- [ ] Async support\n- [ ] Caching support\n- [ ] Image download utilities\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- NASA for providing free access to their amazing APIs\n- The astronomy community for inspiring space exploration\n- All contributors who help improve this project\n\n## Links\n\n- [NASA API Portal](https://api.nasa.gov/)\n- [APOD API Documentation](https://api.nasa.gov/planetary/apod)\n- [PyPI Package](https://pypi.org/project/pyasan/) (when published)\n- [GitHub Repository](https://github.com/yourusername/pyasan)\n\n---\n\nMade with \u2764\ufe0f for the astronomy and Python communities.\n",
"bugtrack_url": null,
"license": null,
"summary": "A Python wrapper and CLI for NASA's REST APIs",
"version": "0.2.0",
"project_urls": {
"Bug Tracker": "https://github.com/jeorryb/pyasan/issues",
"Documentation": "https://github.com/jeorryb/pyasan#readme",
"Homepage": "https://github.com/jeorryb/pyasan",
"Repository": "https://github.com/jeorryb/pyasan"
},
"split_keywords": [
"nasa",
" api",
" astronomy",
" apod",
" cli"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "af74c1de3e75fa8b5c1de63e93c6986d9d0b1ea15505a600d8602ec2456a0c69",
"md5": "0043590431109f9ada4de34c5df10b1e",
"sha256": "614c6d7f387b6b3c73117f938d8590a604040e649f80846c878465ff88c6b922"
},
"downloads": -1,
"filename": "pyasan-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0043590431109f9ada4de34c5df10b1e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 13297,
"upload_time": "2025-09-13T02:16:33",
"upload_time_iso_8601": "2025-09-13T02:16:33.516749Z",
"url": "https://files.pythonhosted.org/packages/af/74/c1de3e75fa8b5c1de63e93c6986d9d0b1ea15505a600d8602ec2456a0c69/pyasan-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1636518eadab1f1aeb8aeaf61c2268f94abaecbdbadea964dedb55d1a440a61c",
"md5": "7159b5133ca237f78c2c8ead687f019b",
"sha256": "89a88314733a516a29b68515a54c107e85a81a27d602bd5aa483c213616fe414"
},
"downloads": -1,
"filename": "pyasan-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "7159b5133ca237f78c2c8ead687f019b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 15240,
"upload_time": "2025-09-13T02:16:34",
"upload_time_iso_8601": "2025-09-13T02:16:34.789683Z",
"url": "https://files.pythonhosted.org/packages/16/36/518eadab1f1aeb8aeaf61c2268f94abaecbdbadea964dedb55d1a440a61c/pyasan-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-13 02:16:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jeorryb",
"github_project": "pyasan",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "requests",
"specs": [
[
">=",
"2.25.0"
]
]
},
{
"name": "click",
"specs": [
[
">=",
"8.0.0"
]
]
},
{
"name": "python-dotenv",
"specs": [
[
">=",
"0.19.0"
]
]
},
{
"name": "rich",
"specs": [
[
">=",
"12.0.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
">=",
"1.8.0"
]
]
}
],
"lcname": "pyasan"
}