Skip to main content

Python toolkit for generating StratoScript files for Nightshade planetarium systems

Project description

pytshade

Python toolkit for generating StratoScript (.sts) files for Digitalis planetarium systems running Nightshade.

pytshade lets you write planetarium shows in Python! Constellations, eclipses, meteor showers, planet tours, etc. and compile them into the linear StratoScript format that Nightshade executes on the dome.

Features

  • Builder pattern - chain method calls, then build() or save() to emit a .sts file.
  • Shadow-state tracking - skips redundant flag/timerate/zoom commands automatically.
  • Version compatibility - targets Nightshade NG (OP3) or Nightshade Legacy (11.12.1) with a single version= switch.
  • Astronomy helpers - PyEphem wrapper for visibility checks, moon phases, eclipse lookups, and sun position calculations.
  • Deterministic resets - every script starts from a known state via init_block() / reset_to_default().
  • Long-pan waypoints - automatically splits camera pans > 170° on NG to work around SLERP shortest-path behavior.
  • Meteor radiant database - built-in RA/Dec for Perseids, Geminids, Leonids, Quadrantids, and Orionids.

Quick Start

# Clone and install with uv
git clone https://github.com/sidereumcorpus/pytshade.git
cd pytshade
uv sync --group dev

If you want the optional astronomy examples as well:

uv sync --group dev --extra examples
import datetime
from pytshade import StratoScriptBuilder

builder = StratoScriptBuilder("location.json")
builder.init_block()

builder.set_date(datetime.datetime.now().replace(hour=21))
builder.flag("atmosphere", False)
builder.constellations(show=True, art=True)
builder.wait(10)
builder.constellations(show=False)
builder.flag("atmosphere", True)

builder.save("my_show.sts")

Copy the .sts file to D:\Nightshade\data\scripts\ and run it from the Nightshade script menu.

uv Workflow

# Install dependencies
uv sync --group dev

# Run tests
uv run python -m unittest discover -s tests -v

# Run the demo generator
uv run python generate_demo_script.py

# Build distributions
uv build

Project Structure

pytshade/
  __init__.py          # Public API: StratoScriptBuilder, AstroHelper, NightshadeVersion
  builder.py           # Public builder import path
  astronomy.py         # Public astronomy import path
  version.py           # Public version import path
digitalis_scripts/
  ...                  # Backward-compatible internal implementation package
examples/
  quickstart.py        # Minimal 30-second constellation demo
  ephem_moon_phases.py # Moon-phase calendar using AstroHelper
  astropy_planet_tour.py  # Planet visibility tour using astropy
  legacy_mode.py       # Targeting Nightshade Legacy syntax
tests/
  test_builder.py      # Builder unit tests (63 tests)
  test_astronomy.py    # AstroHelper unit tests
  test_version.py      # Version profile tests
generate_demo_script.py  # Full 7-scene demo show generator
location.json            # Observer location config

Nightshade Version Targeting

pytshade defaults to Nightshade NG syntax. To generate scripts for Legacy 11.12.1:

from pytshade import StratoScriptBuilder, NightshadeVersion

builder = StratoScriptBuilder("location.json", version=NightshadeVersion.LEGACY)
Feature NG Legacy
Meteors meteors ra/dec + meteors zhr meteors rate
Video video action play external_viewer action play
Movement SLERP shortest path (auto-split > 170°) Linear interpolation

Using with Other Astronomy Libraries

PyEphem (built-in)

from pytshade import AstroHelper

astro = AstroHelper(lat="36.53", lon="-87.35", elevation=155)
moon_time = astro.find_good_moon_time(min_phase=0.5)
phase = astro.get_moon_phase(moon_time)

Astropy (optional)

See examples/astropy_planet_tour.py for a full working example that uses astropy.coordinates.get_body() to check planet altitudes and only visits those above the horizon.

uv sync --group dev --extra examples
uv run python examples/astropy_planet_tour.py

Skyfield / Other Libraries

pytshade's builder is library-agnostic. Compute positions with any library, then feed the results into the builder:

# Pseudocode - works with skyfield, poliastro, etc.
alt_deg, az_deg = my_library.get_planet_position("Mars", time)
if alt_deg > 0:
    builder.select_planet("Mars")
    builder.flag("track_object", True)
    builder.zoom(fov=10, duration=2)

Running Tests

uv run python -m unittest discover -s tests -v

Generating the Demo Show

uv run python generate_demo_script.py

This produces 7 individual .sts scripts plus a combined full show, copies them to the Nightshade scripts directory, and mirrors them in generated_scripts/ for version control.

Key Concepts

State Reset

Every standalone script should call builder.init_block() at the start. This runs clear + reset_to_default() which:

  1. Drops all media (images, video, audio)
  2. Deselects objects and stops tracking
  3. Returns to Earth at your location.json coordinates
  4. Resets all flags to sensible defaults
  5. Resets view direction, FOV, time, and timerate

Gotchas

  • track_object persists - always disable it when done tracking.
  • timerate persists - reset to timerate(1) at scene end.
  • Meteor showers need FOV 180 - meteors spawn at FOV edges; zooming in means they never enter view. Use ZHR 10000+ for visual density.
  • Solar System Observer - disable atmosphere and landscape before switching to "Solar System Observer".
  • Long pans on NG - pans > 170° are automatically split by pan_to(), but if you use set_view() directly you must handle this yourself.

Requirements

  • Python 3.10+
  • uv
  • PyEphem 4.x
  • Astropy (optional, for advanced ephemeris examples)

Publishing

Build locally with:

uv build

Check the artifacts before release:

uv run python -m twine check dist/*

The repo also includes GitHub Actions workflows for:

Before the first real publish, configure PyPI trusted publishing for your repository.

To publish a release, bump the package version, create a matching vX.Y.Z tag, push the tag, and then create a GitHub release for that tag.

Compatibility Note

The new public import path is pytshade:

from pytshade import StratoScriptBuilder

The older digitalis_scripts imports still work for now so existing scripts do not break immediately.

License

GNU General Public License v3.0 only (GPL-3.0-only). See 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

pytshade-0.1.2.tar.gz (34.8 kB view details)

Uploaded Source

Built Distribution

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

pytshade-0.1.2-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

Details for the file pytshade-0.1.2.tar.gz.

File metadata

  • Download URL: pytshade-0.1.2.tar.gz
  • Upload date:
  • Size: 34.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pytshade-0.1.2.tar.gz
Algorithm Hash digest
SHA256 fcfc31dc0a43040a3b74d3d0d914f279f942c4db98440918764c1763297b0993
MD5 587c0d22526ec706a79e8088fdb9b144
BLAKE2b-256 31b7d3ee66d968af410024e17a9c011a608f8a6f6a097fe76b0975a6afbcdc35

See more details on using hashes here.

File details

Details for the file pytshade-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: pytshade-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pytshade-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 13d9e1ecacc46e132b82e999db32fb9c686da4b0ffd765f35d73bb01695892bd
MD5 5a147a53fbe5a5fe12511f57318ea0ab
BLAKE2b-256 0d82b9af05fad70722aa2bba7da94f9d72168a8d925a136e846d982782cc47dd

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