NextAstro logo NextAstroDocumentation Open Hub

Python scripting

Getting started

Run OBS in its normal visible console. Run student Python in another terminal or notebook on the same computer. The existing local console must be enabled; its default port is 8221. Equipment access uses the existing local operator privilege. No Hub account login or Hub connection is used for student communication. OBS's existing startup, weather/enclosure, and other online dependencies still apply.

The control client requires Python 3.10 or later and uses the standard library. The optional image measurement methods use NumPy and astropy.io.fits in the student's Python environment. Reading compressed pipeline source catalogues also uses zstandard. These imports occur only when the corresponding method is called; OBS's interpreter or Nuitka executable remains independent.

From the source repository root:

python -m nextastro_obs_client.examples.inspect_observatory
python -m nextastro_obs_client.examples.single_exposure --ra 12.5 --dec -30 --target "Student field" --filter V --seconds 5

For a script stored elsewhere, use the source runner directly:

python C:\path\to\codexobs\nextastro_obs_client\run_script.py C:\students\my_script.py

For a compiled distribution, use its isolated student_python directory:

python C:\path\to\obs.dist\student_python\nextastro_obs_client\run_script.py C:\students\my_script.py

Keep actively developed code in its owning checkout; the build stages this directory for distribution with the actual executable.

In a notebook, add the parent of the client directory to the notebook kernel's import path once:

import sys
sys.path.insert(0, r"C:\path\to\codexobs")  # compiled: C:\path\to\obs.dist\student_python
from nextastro_obs_client import Observatory

obs = Observatory()  # use port=... if the local console has a different port
print(obs.site)
print(obs.status())

with obs.session(name="Notebook experiment", userid="student01"):
    images = obs.camera.expose(seconds=5, filter="V", count=1)
    print(images.paths)

Observatory() reads capabilities. Entering obs.session(...) performs the controlling connection: it blocks until handover is complete. Reading status does not acquire equipment. Keep a context open across the notebook work that needs coherent control; exiting it relinquishes script ownership.

The supplied rotator-flat example performs real acquisitions when run against a real OBS. Edit temperatures, exposure times, and filter names for that camera. Mechanical rotation is the controller's mechanical frame. Do not transfer old MaxIm/ASCOM sky-angle zero offsets into this frame without interpreting them.

See the example library for experiments, command lines, scientific assumptions, and suggested extensions. Every example also accepts --help without connecting to OBS.