Skip to main content

A tool for asteroid observation scheduling and analysis

Project description

AsteroidPy

GitHub Contributor Covenant contributions welcome

AsteroidPy is a command-line tool for astronomers to schedule and manage asteroid observations. It integrates with the Minor Planet Center and other astronomical data sources to provide ephemerides, NEO confirmation candidates, weather forecasts, and observing aids—all from an interactive terminal UI built with Textual.


Table of Contents


Features

Feature Description
Weather forecast Astronomical weather (cloud cover, seeing, transparency) up to 72 hours via 7Timer
Observation scheduling Plan sessions with target lists and visibility windows
NEOcp candidates List and filter Near-Earth Object candidates from the MPC Confirmation Page
Object ephemeris Retrieve detailed ephemeris data for any minor body
Twilight & Sun/Moon Civil, nautical, and astronomical twilight; rise/set times
Virtual horizon Simulate horizon obstructions for visibility calculations

Requirements

  • Python 3.9 or later
  • pip (or another Python package manager)

AsteroidPy runs on Linux, macOS, and Windows.

On Windows, use Windows Terminal (recommended) or another modern terminal for the Textual UI. The first pip install may take several minutes because scientific dependencies (astropy, lxml, and related packages) download platform-specific wheels. Python 3.10–3.12 from python.org is the most reliable choice on Windows.


Installation

From PyPI

With Python 3.9+ and a virtual environment activated (recommended):

pip install asteroidpy

See the package on PyPI.

On Windows, after installation the asteroidpy command is available in your virtual environment's Scripts folder (for example .venv\Scripts\asteroidpy.exe).

From source

  1. Clone the repository:

    git clone https://github.com/ziriuz84/asteroidpy.git
    cd asteroidpy
    
  2. (Recommended) Create and activate a virtual environment:

    python -m venv .venv
    source .venv/bin/activate   # On Windows: .venv\Scripts\activate
    
  3. Install in editable mode:

    pip install -e .
    

    Or in normal mode:

    pip install .
    

Quick Start

Run the application:

asteroidpy

On first launch, AsteroidPy creates a config file with default settings. Use the Configuration menu to set:

  • Observatory: coordinates, altitude, MPC code
  • Virtual horizon: minimum altitude per cardinal direction
  • General: interface language

Configuration

Configuration is stored in a single INI file named .asteroidpy, in the application config directory returned by platformdirs (for example ~/.config/asteroidpy/ on Linux, ~/Library/Application Support/asteroidpy/ on macOS, and %LOCALAPPDATA%\asteroidpy\ on Windows). Legacy installs may still have a copy at ~/.asteroidpy, which is migrated automatically on first run.

Use the in-app Configuration → General menu to change:

Option Description
Observatory Latitude, longitude, altitude, MPC observatory code
Virtual horizon Minimum altitude (in degrees) per cardinal direction for visibility
Language Interface language (English, Italiano, Deutsch, Français, Español, Português)

FAQ

Where do I find my MPC observatory code?
The Minor Planet Center publishes the list of observatory codes. If your site is not listed, use XXX or another temporary code until you register it with the MPC.

Why do ephemerides differ from Stellarium or other tools?
Small differences can arise from different orbital elements, epoch dates, or time handling. AsteroidPy uses MPC data directly; ensure your observatory coordinates and time (UTC vs local) match across tools.

The application fails to start or shows errors.
Check that all dependencies are installed (pip install asteroidpy from PyPI, or pip install . from a source checkout), that the config directory is writable (see Configuration for the platform-specific path), and that you have internet access (required for weather and ephemeris queries). If the config file is corrupted, remove .asteroidpy from that config directory and let the app recreate it on next run.

Which languages are supported?
English (default), Italiano, Deutsch, Français, Español, Português. Change the language in Configuration → GeneralLanguage. PyPI wheels ship with compiled .mo catalogs for all supported languages. When working from a source checkout, only locales with compiled .mo files are listed as selectable; if a folder under asteroidpy/locales/ has only a base.po, the UI may show a notice when opening the language screen—compile with msgfmt so the locale appears as a proper option.


Data Sources

AsteroidPy relies on:


For Contributors

Thank you for considering contributing to AsteroidPy. Please read the Code of Conduct before participating.

Types of contributions we welcome

  • Code: bug fixes, new features, refactoring
  • QA: bug reports with repro steps and environment details
  • Documentation: improvements to this README, docstrings, or Sphinx docs
  • Community: presenting the project, organizing local meetups

Development setup

  1. Clone the repository and install in editable mode (see Installation).

  2. Install development dependencies (optional, for tests and linting):

    pip install -e ".[dev]"
    

    Or install tools individually: pytest, ruff, mypy, black, isort.

  3. Run the test suite:

    pytest -q
    

    Run a single test:

    pytest tests/test_scheduling.py::test_name -q
    
  4. Lint and type-check:

    ruff check .
    mypy .
    
  5. Build the package:

    python -m build
    

    Before building a release wheel, compile locale catalogs if you changed .po files:

    msgfmt -o asteroidpy/locales/en/LC_MESSAGES/base.mo asteroidpy/locales/en/LC_MESSAGES/base.po
    # repeat for other locales, or use ./release.sh which compiles them automatically
    

Continuous integration (Jenkins)

CI runs on Jenkins via Jenkinsfile (triggered on every push to GitHub). The pipeline:

Stage When What it does
Setup always venv, pip install -e ".[dev]", installs gettext/msgfmt when missing
Lint always (including releases) ruff, mypy, isort, black --check
Test always pytest with coverage (coverage.xml archived)
Build always compiles .mo catalogs, then python -m build
Validate / install smoke test always twine check, install wheel, verify locale catalogs and asteroidpy entry point
Publish to PyPI release tags only (vX.Y.Z) uploads to PyPI when the tag matches asteroidpy/version.py

Successful builds archive dist/* (and coverage.xml) as Jenkins artifacts. GitHub Actions workflows are not used; Jenkins is the single CI/CD path for builds and PyPI publishing.

Code style

  • Imports: standard library → third-party → local; explicit imports only
  • Formatting: Black for style; isort for import order
  • Types: type hints on public APIs; snake_case for functions/variables; CamelCase for classes
  • Errors: avoid bare except; raise or propagate clear exceptions; validate inputs early
  • Tests: small, isolated tests; prefer parameterized tests where sensible

Getting involved

  • Browse open issues and comment or pick one to work on
  • Open issues for bugs or feature ideas—the more detail, the better
  • Pull requests are welcome; please ensure tests pass and style is consistent

Project architecture

asteroidpy/
├── __init__.py       # Entry point; loads config, launches interface
├── interface/        # Textual TUI, gettext setup (legacy menu helpers retained)
├── scheduling.py     # Ephemerides, weather, NEOcp, twilight
├── configuration.py  # Observatory config, horizon, language
└── locales/          # gettext translations (en, it, de, fr, es, pt), shipped in PyPI wheels
  • interface — Main entry for the interactive UI (Textual screens). Loads config, sets up gettext, and delegates to scheduling for ephemeris/weather/NEOcp and to configuration for settings.
  • scheduling — Astronomy logic: MPC queries, 7Timer weather, twilight, Sun/Moon ephemeris. Uses configuration.load_config() to read observatory data.
  • configuration — Persists and loads settings via platformdirs; handles observatory coordinates, virtual horizon, and language. Used by both interface and scheduling.

How to add a translation

AsteroidPy uses GNU gettext with a single catalog base. Translations live under asteroidpy/locales/<lang>/LC_MESSAGES/.

  1. Create a new locale directory:

    mkdir -p asteroidpy/locales/nl/LC_MESSAGES
    
  2. Copy and adapt an existing .po file, or create one from the template:

    cp asteroidpy/locales/it/LC_MESSAGES/base.po asteroidpy/locales/nl/LC_MESSAGES/base.po
    

    Edit asteroidpy/locales/nl/LC_MESSAGES/base.po, set Language: nl, and translate all msgstr entries.

  3. Compile the .po file into a .mo file (required for the language to appear in the menu when running from source):

    msgfmt -o asteroidpy/locales/nl/LC_MESSAGES/base.mo asteroidpy/locales/nl/LC_MESSAGES/base.po
    

    The msgfmt command comes with the gettext package (gettext on most Linux distros; on Windows, install via MSYS2 or Chocolatey). Until the .mo exists, text from that .po is not used by gettext; the interactive UI may notify you once per incomplete locale under GeneralLanguage.

  4. The new language will appear in Configuration → General after restart.

To add or update translatable strings for all locales, update asteroidpy/locales/base.pot (e.g. with xgettext or pybabel), then merge into each .po with msgmerge, translate, and recompile with msgfmt.

Release process

Releases are automated with helper scripts and published by Jenkins when a version tag is pushed.

  1. Prepare the release (bumps asteroidpy/version.py, compiles locale catalogs, prepends CHANGELOG.md, commits, tags, and pushes):

    ./release.sh --patch    # or --minor, --major, or an explicit X.Y.Z
    

    Preview without changes: ./release.sh --dry-run --patch

  2. Jenkins detects the new vX.Y.Z tag, runs tests, builds the wheel/sdist, validates the package, and publishes to PyPI.

  3. Create the GitHub release (release notes taken from the top CHANGELOG.md entry):

    ./ghrelease.sh
    

Manual alternative (without the scripts): update asteroidpy/version.py and CHANGELOG.md, compile .mo files under asteroidpy/locales/, commit, tag (git tag vX.Y.Z), push the branch and tag, then run ./ghrelease.sh after Jenkins finishes the PyPI upload.


Release History

See CHANGELOG.md.


TODO

  • NEOcp alert integration
  • Observation registration

License

AsteroidPy is licensed under the GPL-3.0 license.

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

asteroidpy-1.3.2.tar.gz (75.7 kB view details)

Uploaded Source

Built Distribution

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

asteroidpy-1.3.2-py3-none-any.whl (77.5 kB view details)

Uploaded Python 3

File details

Details for the file asteroidpy-1.3.2.tar.gz.

File metadata

  • Download URL: asteroidpy-1.3.2.tar.gz
  • Upload date:
  • Size: 75.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for asteroidpy-1.3.2.tar.gz
Algorithm Hash digest
SHA256 699974c51deed1bc093903a582228fef9764e2219d9d526c73b197c1d697a667
MD5 2acf5fa6520718f03d367445d7369441
BLAKE2b-256 364c57b00b1293d70fa3f75b7b5c48f47aeb97e52e087ad080fe855d4787a657

See more details on using hashes here.

File details

Details for the file asteroidpy-1.3.2-py3-none-any.whl.

File metadata

  • Download URL: asteroidpy-1.3.2-py3-none-any.whl
  • Upload date:
  • Size: 77.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for asteroidpy-1.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 721250d2c474cb9c3d59b4337a6cb39e18ab72f976245babdc9ecd8b9415731c
MD5 37fbd91f7a5101643affbecdad6fb83c
BLAKE2b-256 cc2e37bd7d25a5bedcb78cc848a87355f616dcbfdc452afbd2a7b7ee5bf9bae4

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