Skip to main content

A modern vedic astrology calculation engine

Project description

ndastro-engine

PyPI version Python 3.10+ License: MIT

A modern Python library for Vedic and Western astronomical calculations, built on top of 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
  • 🔄 16 Ayanamsa Systems - Comprehensive support for Vedic and Western sidereal systems:
    • Lahiri, Raman, Krishnamurti (KP New & Old), Fagan-Bradley
    • Traditional: Kali, Janma, Yukteshwar, Suryasiddhanta, Aryabhatta
    • Star-based: True Citra, True Revati, True Pusya, Ushashasi
    • Additional: Madhava, Vishnu, True ayanamsa
  • 🌍 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)
  • Verified Accuracy - All ayanamsa values verified against astro-seek.com reference
  • 🔧 Easy Configuration - Automatic ephemeris data management
  • 📦 Modern Python - Full type hints, clean API, and comprehensive test coverage

Installation

Install using pip:

pip install ndastro-engine

For development:

pip install ndastro-engine[dev]

Quick Start

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

Ayanamsa Calculation

from datetime import datetime
from ndastro_engine.ayanamsa import (
    get_lahiri_ayanamsa,
    get_raman_ayanamsa,
    get_krishnamurti_new_ayanamsa,
    get_fagan_bradley_ayanamsa
)

# Calculate ayanamsa for a specific date
date = datetime(2026, 1, 15, 12, 0, 0)

lahiri = get_lahiri_ayanamsa(date)
raman = get_raman_ayanamsa(date)
kp = get_krishnamurti_new_ayanamsa(date)
fagan = get_fagan_bradley_ayanamsa(date)

print(f"Lahiri Ayanamsa: {lahiri:.4f}°")
print(f"Raman Ayanamsa: {raman:.4f}°")
print(f"KP New Ayanamsa: {kp:.4f}°")
print(f"Fagan-Bradley Ayanamsa: {fagan:.4f}°")

Planetary Position Calculation

from datetime import datetime
import pytz
from ndastro_engine.core import get_planet_position
from ndastro_engine.enums.planet_enum import Planets
from ndastro_engine.ayanamsa import get_lahiri_ayanamsa

# 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 = get_lahiri_ayanamsa(time)
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

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

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

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:

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:

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:

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

# 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:

# 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:

# 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.

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
# 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 by Brandon Rhodes
  • Uses JPL ephemeris data (DE440t) for high-precision calculations
  • Inspired by the need for a simple, modern astronomical calculation library

Support

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 for a list of changes.


Made with ❤️ by Jaganathan B

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ndastro_engine-0.4.2.tar.gz (17.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ndastro_engine-0.4.2-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

Details for the file ndastro_engine-0.4.2.tar.gz.

File metadata

  • Download URL: ndastro_engine-0.4.2.tar.gz
  • Upload date:
  • Size: 17.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.12.6 Windows/11

File hashes

Hashes for ndastro_engine-0.4.2.tar.gz
Algorithm Hash digest
SHA256 c884e58bce998c13b1b962dc5adbff3316573ee725be977d800fdfc975c01d59
MD5 1db8c61861f66878e664d74fe2f3aefc
BLAKE2b-256 549990ff004ddc94868763e9a4516bd6ceed222763a2cc48fc55bd630a22c1c3

See more details on using hashes here.

File details

Details for the file ndastro_engine-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: ndastro_engine-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.12.6 Windows/11

File hashes

Hashes for ndastro_engine-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b87269ec0e04ab39f3c88b1fc421045af4d23cb84c4b5aff612b3d36352114db
MD5 e9731712fe8682a70eef5d3d1d1236f9
BLAKE2b-256 ed80e34f6983f505b7e5edfd35c06b2fb67a2315b3f8570121524d3e8d147e1c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page