Metadata-Version: 2.3
Name: ndastro-engine
Version: 0.3.1
Summary: A modern vedic astrology calculation engine
License: MIT
Keywords: astronomy,vedic astrology,south indian astrology,north indian astrology,astro,skyfield,astronomical-calculations,birth-chart,horoscope
Author: Jaganathan, B
Author-email: jaganathan.eswaran@gmail.com
Maintainer: Jaganathan, B
Maintainer-email: jaganathan.eswaran@gmail.com
Requires-Python: >=3.10
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Provides-Extra: dev
Requires-Dist: mypy (>=1.19.1) ; extra == "dev"
Requires-Dist: pytest (>=9.0.2) ; extra == "dev"
Requires-Dist: pytest-cov (>=6.0.0) ; extra == "dev"
Requires-Dist: pytest-xdist (>=3.6.1) ; extra == "dev"
Requires-Dist: pytz (>=2025.2,<2026.0)
Requires-Dist: ruff (>=0.14.10) ; extra == "dev"
Requires-Dist: skyfield (>=1.53,<2.0)
Project-URL: Bug Tracker, https://github.com/jaganathanb/ndastro-core/issues
Project-URL: Changelog, https://github.com/jaganathanb/ndastro-core/releases
Project-URL: Documentation, https://github.com/jaganathanb/ndastro-core#readme
Project-URL: Homepage, https://github.com/jaganathanb/ndastro-core
Project-URL: Repository, https://github.com/jaganathanb/ndastro-core
Description-Content-Type: text/markdown

# ndastro-engine

[![PyPI version](https://badge.fury.io/py/ndastro-engine.svg)](https://badge.fury.io/py/ndastro-engine)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A modern Python library for Vedic and Western astronomical calculations, built on top of [Skyfield](https://rhodesmill.org/skyfield/). ndastro-engine provides a clean, intuitive API for computing planetary positions, sunrise/sunset times, lunar nodes (Rahu/Kethu), ascendant, and other astronomical events for any location on Earth.

## Features

- 🪐 **Planetary Positions** - Calculate positions for Sun, Moon, Mars, Mercury, Jupiter, Venus, and Saturn
- 🌅 **Sunrise & Sunset** - Accurate sunrise and sunset times for any location
- 🌙 **Lunar Nodes** - Rahu (North Node) and Kethu (South Node) calculations
- ⬆️ **Ascendant Calculation** - Compute rising sign (Lagna) for any time and location
- 🔄 **Ayanamsa Support** - Convert between tropical and sidereal (Vedic) zodiac systems
- 🌍 **WGS84 Coordinates** - Support for standard latitude/longitude coordinates
- 📅 **Date-based Queries** - Calculate astronomical events for any date and time
- 🎯 **High Precision** - Powered by Skyfield using JPL ephemeris data (DE440t)
- 🔧 **Easy Configuration** - Automatic ephemeris data management
- 📦 **Modern Python** - Full type hints, clean API, and comprehensive test coverage

## Installation

Install using pip:

```bash
pip install ndastro-engine
```

For development:

```bash
pip install ndastro-engine[dev]
```

## Quick Start

```python
from datetime import datetime
import pytz
from ndastro_engine.core import get_planet_position, get_all_planet_positions, get_sunrise_sunset
from ndastro_engine.enums.planet_enum import Planets

# Define location (New York City)
latitude = 40.7128
longitude = -74.0060
time = datetime(2026, 1, 6, 12, 0, 0, tzinfo=pytz.UTC)

# Get Sun's position
lat, lon, dist = get_planet_position(Planets.SUN, latitude, longitude, time)
print(f"Sun: Longitude {lon:.2f}°, Latitude {lat:.4f}°, Distance {dist:.4f} AU")

# Get all planetary positions
positions = get_all_planet_positions(latitude, longitude, time)
for planet, (lat, lon, dist) in positions.items():
    print(f"{planet.name}: {lon:.2f}°")

# Get sunrise and sunset
sunrise, sunset = get_sunrise_sunset(latitude, longitude, time)
print(f"Sunrise: {sunrise}")
print(f"Sunset: {sunset}")
```

## Usage Examples

### Planetary Position Calculation

```python
from datetime import datetime
import pytz
from ndastro_engine.core import get_planet_position
from ndastro_engine.enums.planet_enum import Planets

# Location: Mumbai, India
lat = 19.0760
lon = 72.8777
time = datetime(2026, 1, 15, 12, 0, 0, tzinfo=pytz.UTC)

# Get Jupiter's position (tropical)
lat_jupiter, lon_jupiter, dist_jupiter = get_planet_position(
    Planets.JUPITER, lat, lon, time
)
print(f"Jupiter (Tropical): {lon_jupiter:.2f}°")

# Get Jupiter's position (sidereal/Vedic with Lahiri ayanamsa)
ayanamsa = 24.19  # Lahiri ayanamsa for 2026
lat_jupiter, lon_jupiter, dist_jupiter = get_planet_position(
    Planets.JUPITER, lat, lon, time, ayanamsa=ayanamsa
)
print(f"Jupiter (Sidereal): {lon_jupiter:.2f}°")
```

### Get All Planetary Positions at Once

```python
from datetime import datetime
import pytz
from ndastro_engine.core import get_all_planet_positions
from ndastro_engine.enums.planet_enum import Planets

lat = 51.5074  # London
lon = -0.1278
time = datetime(2026, 3, 20, 0, 0, 0, tzinfo=pytz.UTC)

# Get positions for all planets including Rahu, Kethu, and Ascendant
positions = get_all_planet_positions(lat, lon, time)

for planet, (latitude, longitude, distance) in positions.items():
    if planet in [Planets.RAHU, Planets.KETHU, Planets.ASCENDANT]:
        print(f"{planet.name}: {longitude:.2f}°")
    else:
        print(f"{planet.name}: {longitude:.2f}° (Distance: {distance:.4f} AU)")
```

### Basic Sunrise/Sunset Calculation

```python
from datetime import datetime
from ndastro_engine.astro_engine import get_sunrise_sunset

# Location: London, UK
lat = 51.5074
lon = -0.1278

# Calculate for a specific date
date = datetime(2026, 1, 15)
sunrise, sunset = get_sunrise_sunset(lat, lon, date)

print(f"On {date.date()}, sunrise is at {sunrise.strftime('%H:%M:%S')} UTC")
print(f"On {date.date()}, sunset is at {sunset.strftime('%H:%M:%S')} UTC")
```

### Working with Different Time Zones

```python
from datetime import datetime
import pytz
from ndastro_engine.astro_engine import get_sunrise_sunset

# Location: Tokyo, Japan
lat = 35.6762
lon = 139.6503

# Get times in local timezone
date = datetime(2026, 6, 21)
sunrise_utc, sunset_utc = get_sunrise_sunset(lat, lon, date)

# Convert to Tokyo time
tokyo_tz = pytz.timezone('Asia/Tokyo')
sunrise_local = sunrise_utc.replace(tzinfo=pytz.UTC).astimezone(tokyo_tz)
sunset_local = sunset_utc.replace(tzinfo=pytz.UTC).astimezone(tokyo_tz)

print(f"Sunrise (Tokyo): {sunrise_local.strftime('%H:%M:%S %Z')}")
print(f"Sunset (Tokyo): {sunset_local.strftime('%H:%M:%S %Z')}")
```

## Configuration

The library automatically downloads and caches the required JPL ephemeris data (DE441) on first use. The data is stored in your system's application data directory:

- **Windows**: `%APPDATA%\ndastro`
- **macOS**: `~/Library/Application Support/ndastro`
- **Linux**: `~/.local/share/ndastro`

This data is approximately 150 MB and only needs to be downloaded once.

## API Reference

### `get_planet_position(planet, lat, lon, given_time, ayanamsa=None)`

Calculate the position of a specific planet.

**Parameters:**
- `planet` (Planets): The planet enum (e.g., Planets.SUN, Planets.MOON)
- `lat` (float): Latitude of the observer in decimal degrees
- `lon` (float): Longitude of the observer in decimal degrees
- `given_time` (datetime): The datetime of observation in UTC
- `ayanamsa` (float, optional): Ayanamsa value for sidereal calculations

**Returns:**
- `tuple[float, float, float]`: (latitude, longitude, distance) - Planet's ecliptic latitude in degrees, ecliptic longitude in degrees, distance in AU

**Example:**
```python
from datetime import datetime
import pytz
from ndastro_engine.core import get_planet_position
from ndastro_engine.enums.planet_enum import Planets

lat, lon, dist = get_planet_position(
    Planets.MARS, 
    34.0522, -118.2437,  # Los Angeles
    datetime(2026, 3, 20, tzinfo=pytz.UTC),
    ayanamsa=24.19  # Optional: for sidereal zodiac
)
```

### `get_all_planet_positions(lat, lon, given_time, ayanamsa=None)`

Calculate positions for all planets, including Rahu, Kethu, and Ascendant.

**Parameters:**
- `lat` (float): Latitude of the observer in decimal degrees
- `lon` (float): Longitude of the observer in decimal degrees
- `given_time` (datetime): The datetime of observation in UTC
- `ayanamsa` (float, optional): Ayanamsa value for sidereal calculations

**Returns:**
- `dict[Planets, tuple[float, float, float]]`: Dictionary mapping each planet to its (latitude, longitude, distance)

**Example:**
```python
from datetime import datetime
import pytz
from ndastro_engine.core import get_all_planet_positions

positions = get_all_planet_positions(
    12.97, 77.59,  # Bangalore, India
    datetime(2026, 1, 15, tzinfo=pytz.UTC)
)
```

### `get_sunrise_sunset(lat, lon, given_time, elevation=914)`

Calculate sunrise and sunset times for a specific location and date.

**Parameters:**
- `lat` (float): Latitude of the location in decimal degrees
- `lon` (float): Longitude of the location in decimal degrees
- `given_time` (datetime): The date for which to calculate sunrise/sunset
- `elevation` (float, optional): Elevation in meters (default: 914m)

**Returns:**
- `tuple[datetime, datetime]`: (sunrise, sunset) as UTC datetime objects

**Example:**
```python
from datetime import datetime
import pytz
from ndastro_engine.core import get_sunrise_sunset

sunrise, sunset = get_sunrise_sunset(
    34.0522, -118.2437,  # Los Angeles
    datetime(2026, 3, 20, tzinfo=pytz.UTC)
)
```

## Requirements

- Python 3.10 or higher
- skyfield >= 1.53
- pytz >= 2025.2

## Development

### Setting Up Development Environment

```bash
# Clone the repository
git clone https://github.com/jaganathanb/ndastro-core.git
cd ndastro-core

# Install with development dependencies
pip install -e .[dev]

# Verify installation by running tests
pytest tests/ -v
```

**Development Dependencies Include:**
- pytest>=9.0.2 - Testing framework
- pytest-cov>=6.0.0 - Coverage reporting
- pytest-xdist>=3.6.1 - Parallel test execution
- ruff>=0.14.10 - Linting and formatting
- mypy>=1.19.1 - Type checking

### Running Tests

The project includes comprehensive test coverage with multiple ways to run tests:

```bash
# Run all tests with coverage (recommended)
pytest tests/

# Or using the test runner scripts:
# PowerShell (Windows)
.\run_tests.ps1

# Batch (Windows)
run_tests.bat coverage

# Make (cross-platform)
make test
```

**Test Modes:**

```bash
# Run only unit tests
pytest -m unit tests/

# Run fast tests (exclude slow tests)
pytest -m "not slow" tests/

# Run with verbose output
pytest tests/ -v

# Run in parallel (faster for large test suites)
pytest -n 4 tests/

# Generate HTML coverage report
pytest tests/ --cov=ndastro_engine --cov-report=html
# Then open htmlcov/index.html in your browser
```

**Test Coverage:**
- 69 total unit tests covering all core functionality
- Parametrized tests for comprehensive edge case coverage
- Test markers for easy filtering (unit, integration, slow)
- Automated coverage reporting

For detailed testing documentation, see [TESTING.md](TESTING.md).

### Code Quality

The project uses:
- **pytest** for testing with coverage reporting
- **pytest-cov** for coverage analysis
- **pytest-xdist** for parallel test execution
- **ruff** for linting and formatting
- **mypy** for type checking

```bash
# Run linter
ruff check ndastro_engine/ tests/

# Run type checker
mypy ndastro_engine/

# Format code
ruff format ndastro_engine/ tests/

# Run all quality checks
make lint && make type-check && make test
```

## 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 file for details.

## Acknowledgments

- Built on [Skyfield](https://rhodesmill.org/skyfield/) by Brandon Rhodes
- Uses JPL ephemeris data (DE440t) for high-precision calculations
- Inspired by the need for a simple, modern astronomical calculation library

## Support

- 📫 **Email**: jaganathan.eswaran at gmail.com
- 🐛 **Issues**: [GitHub Issues](https://github.com/jaganathanb/ndastro-core/issues)
- 📖 **Documentation**: [GitHub Repository](https://github.com/jaganathanb/ndastro-core)

## Roadmap

### Coming Soon: Vedic Astrology Features 🕉️

The library will soon include comprehensive Vedic (Hindu/Indian) astrology functionalities:

**Panchanga Calculations:**
- Tithi (Lunar day) - All 30 tithis with precise timing
- Nakshatra (Lunar mansion) - 27 nakshatras with pada divisions
- Yoga - 27 yogas based on Sun-Moon positions
- Karana - Half-tithi divisions
- Vara (Weekday) - Traditional Hindu weekday system

**Astrological Timings:**
- Rahu Kala (Inauspicious period)
- Gulika Kala
- Yamaganda Kala
- Abhijit Muhurta (Auspicious time)
- Brahma Muhurta (Pre-dawn period)
- Dur Muhurtam (Inauspicious periods)

**Planetary Calculations:**
- Graha Sphuta (Planetary positions in sidereal zodiac)
- Ayanamsa corrections (Lahiri, Raman, Krishnamurti systems)
- Bhava (House) calculations
- Dasha periods (Vimshottari, Ashtottari, Yogini)
- Planetary strengths (Shadbala, Ashtakavarga)

**Hora & Choghadiya:**
- Hourly lord calculations
- Choghadiya divisions for day/night
- Auspicious/inauspicious period identification

**Festival & Event Calculations:**
- Hindu festival dates (Diwali, Holi, Navratri, etc.)
- Ekadashi dates
- Purnima (Full moon) and Amavasya (New moon)
- Sankranti (Solar transitions)
- Vyatipata and Vaidhriti yogas

**Birth Chart Features:**
- Rashi (Moon sign) calculations
- Lagna (Ascendant) determination
- Navamsa and other divisional charts
- Compatibility matching (Guna Milan)

### Other Planned Features

- Moon phase calculations
- Solar and lunar eclipse predictions
- Planetary positions (Western tropical system)
- Twilight times (civil, nautical, astronomical)
- Constellation identification
- Custom observer elevation support

## Changelog

See [CHANGELOG.md](https://github.com/jaganathanb/ndastro-core/releases) for a list of changes.

---

Made with ❤️ by Jaganathan B

