senpai 2.9.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. senpai-2.9.1/.dockerignore +3 -0
  2. senpai-2.9.1/.gitattributes +7 -0
  3. senpai-2.9.1/.github/workflows/ci.yml +95 -0
  4. senpai-2.9.1/.github/workflows/python-publish.yml +163 -0
  5. senpai-2.9.1/.gitignore +155 -0
  6. senpai-2.9.1/.markdownlint.json +4 -0
  7. senpai-2.9.1/CHANGELOG.md +311 -0
  8. senpai-2.9.1/Dockerfile +99 -0
  9. senpai-2.9.1/LICENSE +661 -0
  10. senpai-2.9.1/Makefile +184 -0
  11. senpai-2.9.1/PKG-INFO +211 -0
  12. senpai-2.9.1/README.md +168 -0
  13. senpai-2.9.1/coverage.svg +1 -0
  14. senpai-2.9.1/docs/RELEASING.md +113 -0
  15. senpai-2.9.1/docs/senpai_logo.png +0 -0
  16. senpai-2.9.1/packaging/astro-senpai/README.md +27 -0
  17. senpai-2.9.1/packaging/astro-senpai/pyproject.toml +26 -0
  18. senpai-2.9.1/pyproject.toml +285 -0
  19. senpai-2.9.1/scripts/psf_vs_exposure.py +223 -0
  20. senpai-2.9.1/senpai/__init__.py +36 -0
  21. senpai-2.9.1/senpai/api/main.py +165 -0
  22. senpai-2.9.1/senpai/api/models/examples.py +51 -0
  23. senpai-2.9.1/senpai/api/models/returns.py +592 -0
  24. senpai-2.9.1/senpai/api/routes/astrometry.py +136 -0
  25. senpai-2.9.1/senpai/api/routes/senpai.py +159 -0
  26. senpai-2.9.1/senpai/api/tests/__init__.py +0 -0
  27. senpai-2.9.1/senpai/api/tests/conftest.py +73 -0
  28. senpai-2.9.1/senpai/api/tests/test_api.py +293 -0
  29. senpai-2.9.1/senpai/astrometry.py +256 -0
  30. senpai-2.9.1/senpai/catalog/README.md +142 -0
  31. senpai-2.9.1/senpai/catalog/__init__.py +0 -0
  32. senpai-2.9.1/senpai/catalog/constants.py +76 -0
  33. senpai-2.9.1/senpai/catalog/gaia.py +208 -0
  34. senpai-2.9.1/senpai/catalog/gaia_local.py +101 -0
  35. senpai-2.9.1/senpai/catalog/gaia_mirror.py +232 -0
  36. senpai-2.9.1/senpai/catalog/gaia_transforms.py +64 -0
  37. senpai-2.9.1/senpai/catalog/runner.py +1142 -0
  38. senpai-2.9.1/senpai/catalog/sdss.py +390 -0
  39. senpai-2.9.1/senpai/catalog/sstrc7_source.py +187 -0
  40. senpai-2.9.1/senpai/cli/batch.py +438 -0
  41. senpai-2.9.1/senpai/cli/burr.py +1203 -0
  42. senpai-2.9.1/senpai/cli/calibrate.py +77 -0
  43. senpai-2.9.1/senpai/cli/catalog_magnitude_analysis.py +337 -0
  44. senpai-2.9.1/senpai/cli/common.py +122 -0
  45. senpai-2.9.1/senpai/cli/coverage.py +3107 -0
  46. senpai-2.9.1/senpai/cli/detect.py +154 -0
  47. senpai-2.9.1/senpai/cli/measure_gain.py +165 -0
  48. senpai-2.9.1/senpai/cli/photometry.py +114 -0
  49. senpai-2.9.1/senpai/cli/plotting.py +81 -0
  50. senpai-2.9.1/senpai/cli/rate.py +117 -0
  51. senpai-2.9.1/senpai/cli/rate_sidereal.py +155 -0
  52. senpai-2.9.1/senpai/cli/sidereal.py +122 -0
  53. senpai-2.9.1/senpai/core/__init__.py +0 -0
  54. senpai-2.9.1/senpai/core/config.py +702 -0
  55. senpai-2.9.1/senpai/core/constants.py +54 -0
  56. senpai-2.9.1/senpai/core/logging.py +160 -0
  57. senpai-2.9.1/senpai/engine/__init__.py +24 -0
  58. senpai-2.9.1/senpai/engine/constants.py +3 -0
  59. senpai-2.9.1/senpai/engine/detection/jacobian.py +313 -0
  60. senpai-2.9.1/senpai/engine/detection/kernels.py +245 -0
  61. senpai-2.9.1/senpai/engine/detection/point/fwhm.py +339 -0
  62. senpai-2.9.1/senpai/engine/detection/point/satellite.py +980 -0
  63. senpai-2.9.1/senpai/engine/detection/point/sidereal.py +670 -0
  64. senpai-2.9.1/senpai/engine/detection/streak/extraction.py +2628 -0
  65. senpai-2.9.1/senpai/engine/detection/streak/frame_shift.py +165 -0
  66. senpai-2.9.1/senpai/engine/detection/streak/masking.py +776 -0
  67. senpai-2.9.1/senpai/engine/detection/streak/rate_extraction.py +222 -0
  68. senpai-2.9.1/senpai/engine/detection/streak/rate_rate.py +872 -0
  69. senpai-2.9.1/senpai/engine/detection/streak/rate_sidereal.py +525 -0
  70. senpai-2.9.1/senpai/engine/detection/streak/sidereal_sidereal.py +56 -0
  71. senpai-2.9.1/senpai/engine/detection/streak/sidereal_streak.py +1597 -0
  72. senpai-2.9.1/senpai/engine/detection/streak/validation.py +988 -0
  73. senpai-2.9.1/senpai/engine/detection/track_mode.py +315 -0
  74. senpai-2.9.1/senpai/engine/models/astrometry.py +517 -0
  75. senpai-2.9.1/senpai/engine/models/images.py +224 -0
  76. senpai-2.9.1/senpai/engine/models/metadata.py +234 -0
  77. senpai-2.9.1/senpai/engine/models/senpai.py +938 -0
  78. senpai-2.9.1/senpai/engine/models/starfield.py +246 -0
  79. senpai-2.9.1/senpai/engine/models/streak_measurement.py +307 -0
  80. senpai-2.9.1/senpai/engine/observability/__init__.py +27 -0
  81. senpai-2.9.1/senpai/engine/observability/calibration.py +3298 -0
  82. senpai-2.9.1/senpai/engine/observability/detector_gain.py +239 -0
  83. senpai-2.9.1/senpai/engine/photometry/color_terms.py +310 -0
  84. senpai-2.9.1/senpai/engine/photometry/photometry.md +210 -0
  85. senpai-2.9.1/senpai/engine/photometry/utils.py +2831 -0
  86. senpai-2.9.1/senpai/engine/plotting/axes.py +18 -0
  87. senpai-2.9.1/senpai/engine/plotting/images.py +1449 -0
  88. senpai-2.9.1/senpai/engine/plotting/normalization.py +66 -0
  89. senpai-2.9.1/senpai/engine/plotting/photometry.py +868 -0
  90. senpai-2.9.1/senpai/engine/plotting/psf.py +574 -0
  91. senpai-2.9.1/senpai/engine/plotting/replot.py +384 -0
  92. senpai-2.9.1/senpai/engine/plotting/wcs_diagnostics.py +143 -0
  93. senpai-2.9.1/senpai/engine/processing/__init__.py +0 -0
  94. senpai-2.9.1/senpai/engine/processing/collect.py +937 -0
  95. senpai-2.9.1/senpai/engine/processing/photometry_pipeline.py +254 -0
  96. senpai-2.9.1/senpai/engine/processing/rate.py +323 -0
  97. senpai-2.9.1/senpai/engine/processing/rate_scan_confirmation.py +851 -0
  98. senpai-2.9.1/senpai/engine/processing/sidereal.py +188 -0
  99. senpai-2.9.1/senpai/engine/processing/stamp_confirmation.py +1408 -0
  100. senpai-2.9.1/senpai/engine/processing/streak_correlation.py +743 -0
  101. senpai-2.9.1/senpai/engine/tests/__init__.py +0 -0
  102. senpai-2.9.1/senpai/engine/tests/test_aperture_sums.py +93 -0
  103. senpai-2.9.1/senpai/engine/tests/test_burr_adapter.py +610 -0
  104. senpai-2.9.1/senpai/engine/tests/test_burr_replot.py +158 -0
  105. senpai-2.9.1/senpai/engine/tests/test_calibration.py +452 -0
  106. senpai-2.9.1/senpai/engine/tests/test_calibration_frames.py +326 -0
  107. senpai-2.9.1/senpai/engine/tests/test_catalog_logic.py +391 -0
  108. senpai-2.9.1/senpai/engine/tests/test_color_terms.py +261 -0
  109. senpai-2.9.1/senpai/engine/tests/test_config.py +210 -0
  110. senpai-2.9.1/senpai/engine/tests/test_detection_only_mode.py +499 -0
  111. senpai-2.9.1/senpai/engine/tests/test_detector_gain.py +97 -0
  112. senpai-2.9.1/senpai/engine/tests/test_export_coco.py +473 -0
  113. senpai-2.9.1/senpai/engine/tests/test_fits_io.py +367 -0
  114. senpai-2.9.1/senpai/engine/tests/test_frame_organization.py +188 -0
  115. senpai-2.9.1/senpai/engine/tests/test_gaia_local.py +73 -0
  116. senpai-2.9.1/senpai/engine/tests/test_gaia_sky_cache.py +88 -0
  117. senpai-2.9.1/senpai/engine/tests/test_half_flux_radius.py +71 -0
  118. senpai-2.9.1/senpai/engine/tests/test_masking.py +69 -0
  119. senpai-2.9.1/senpai/engine/tests/test_models.py +361 -0
  120. senpai-2.9.1/senpai/engine/tests/test_photometry_synthetic.py +514 -0
  121. senpai-2.9.1/senpai/engine/tests/test_photometry_zp.py +92 -0
  122. senpai-2.9.1/senpai/engine/tests/test_point_detection.py +610 -0
  123. senpai-2.9.1/senpai/engine/tests/test_preprocessing.py +411 -0
  124. senpai-2.9.1/senpai/engine/tests/test_sstrc7_source.py +113 -0
  125. senpai-2.9.1/senpai/engine/tests/test_stats.py +57 -0
  126. senpai-2.9.1/senpai/engine/tests/test_streak_extraction.py +184 -0
  127. senpai-2.9.1/senpai/engine/tests/test_streak_geometry.py +320 -0
  128. senpai-2.9.1/senpai/engine/tests/test_streak_validation.py +256 -0
  129. senpai-2.9.1/senpai/engine/tests/test_track_rate_units.py +48 -0
  130. senpai-2.9.1/senpai/engine/tests/test_wcs_helpers.py +79 -0
  131. senpai-2.9.1/senpai/engine/utils/astrometry_diagnostics.py +98 -0
  132. senpai-2.9.1/senpai/engine/utils/darks.py +945 -0
  133. senpai-2.9.1/senpai/engine/utils/file_io.py +156 -0
  134. senpai-2.9.1/senpai/engine/utils/fits_io.py +515 -0
  135. senpai-2.9.1/senpai/engine/utils/flats.py +746 -0
  136. senpai-2.9.1/senpai/engine/utils/frame_organization.py +174 -0
  137. senpai-2.9.1/senpai/engine/utils/memory.py +25 -0
  138. senpai-2.9.1/senpai/engine/utils/preprocessing.py +1548 -0
  139. senpai-2.9.1/senpai/engine/utils/propagate_wcs.py +21 -0
  140. senpai-2.9.1/senpai/engine/utils/serialization.py +52 -0
  141. senpai-2.9.1/senpai/engine/utils/simulation.py +206 -0
  142. senpai-2.9.1/senpai/engine/utils/stats.py +43 -0
  143. senpai-2.9.1/senpai/engine/utils/streak_chain.py +161 -0
  144. senpai-2.9.1/senpai/engine/utils/wcs_helpers.py +736 -0
  145. senpai-2.9.1/senpai/engine/utils/wcs_ops.py +329 -0
  146. senpai-2.9.1/senpai/engine/utils/wcs_refinement.py +1091 -0
  147. senpai-2.9.1/senpai/engine/utils/wcs_validation.py +191 -0
  148. senpai-2.9.1/senpai/export/README.md +176 -0
  149. senpai-2.9.1/senpai/export/__init__.py +11 -0
  150. senpai-2.9.1/senpai/export/cli.py +447 -0
  151. senpai-2.9.1/senpai/export/coco.py +1162 -0
  152. senpai-2.9.1/senpai/export/dataset_split.py +424 -0
  153. senpai-2.9.1/senpai/export/example_folder.py +132 -0
  154. senpai-2.9.1/senpai/integrations/__init__.py +0 -0
  155. senpai-2.9.1/senpai/integrations/burr/__init__.py +26 -0
  156. senpai-2.9.1/senpai/integrations/burr/filenames.py +96 -0
  157. senpai-2.9.1/senpai/integrations/burr/night.py +679 -0
  158. senpai-2.9.1/senpai/integrations/burr/replot.py +12 -0
  159. senpai-2.9.1/senpai/integrations/burr/run_state.py +134 -0
  160. senpai-2.9.1/senpai/resources/config/burr.yaml +115 -0
  161. senpai-2.9.1/senpai/resources/config/containerized.yaml +28 -0
  162. senpai-2.9.1/senpai/resources/config/dao.yaml +156 -0
  163. senpai-2.9.1/senpai/resources/config/local-localastrometry.yaml +27 -0
  164. senpai-2.9.1/senpai/resources/config/local.yaml +109 -0
  165. senpai-2.9.1/senpai/resources/config/local2.yaml +105 -0
  166. senpai-2.9.1/senpai.code-workspace +33 -0
  167. senpai-2.9.1/tests/astrometry/test_astrometric_fit.py +45 -0
  168. senpai-2.9.1/tests/astrometry/test_solver_mode.py +177 -0
  169. senpai-2.9.1/tests/conftest.py +17 -0
  170. senpai-2.9.1/tests/data/output_starlistinimage.json +511 -0
  171. senpai-2.9.1/tests/data/x_y_counts_1024_1024.txt +100 -0
  172. senpai-2.9.1/tests/engine/test_prod_stability_guards.py +637 -0
  173. senpai-2.9.1/tests/test_packaging.py +113 -0
  174. senpai-2.9.1/tests.svg +1 -0
@@ -0,0 +1,3 @@
1
+ .venv/
2
+ **/.git*
3
+ **/.git*/*
@@ -0,0 +1,7 @@
1
+ tests/ export-ignore
2
+ .github/ export-ignore
3
+ docs/ export-ignore
4
+ *.ipynb export-ignore
5
+ coverage-*.xml export-ignore
6
+ junit-*.xml export-ignore
7
+ senpai/tests/data/** export-ignore
@@ -0,0 +1,95 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, dev]
6
+ pull_request:
7
+ branches: [main, dev]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v4
15
+ with:
16
+ version: "latest"
17
+ - name: Set up Python
18
+ run: uv python install 3.12
19
+ - name: Install dependencies
20
+ run: uv sync --all-extras
21
+ - name: Ruff (errors and unused code)
22
+ run: uv run ruff check senpai --select E9,F63,F7,F82,F401,F541,F811
23
+
24
+ test:
25
+ runs-on: ubuntu-latest
26
+ strategy:
27
+ matrix:
28
+ python-version: ["3.11", "3.12", "3.13"]
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ - uses: astral-sh/setup-uv@v4
32
+ with:
33
+ version: "latest"
34
+ - name: Set up Python ${{ matrix.python-version }}
35
+ run: uv python install ${{ matrix.python-version }}
36
+ - name: Install dependencies
37
+ run: uv sync --all-extras --python ${{ matrix.python-version }}
38
+ - name: Run tests with coverage
39
+ # Astrometry.net + index files and local star catalogs aren't available
40
+ # on CI runners; those tests are marker-skipped. Run `make coverage`
41
+ # locally to exercise the full suite and regenerate the README badges.
42
+ run: |
43
+ uv run pytest -v \
44
+ -m "not requires_astrometry and not requires_catalog" \
45
+ --junitxml=reports/junit/junit.xml \
46
+ --cov=senpai \
47
+ --cov-report=xml
48
+
49
+ build:
50
+ # Packaging check: catches a broken build or bad metadata on a PR rather
51
+ # than mid-release, when the GitHub Release is already public.
52
+ runs-on: ubuntu-latest
53
+ steps:
54
+ - uses: actions/checkout@v4
55
+ - uses: astral-sh/setup-uv@v4
56
+ with:
57
+ version: "latest"
58
+ - name: Set up Python
59
+ run: uv python install 3.12
60
+ - name: Build distributions
61
+ run: |
62
+ uv build
63
+ uv build --out-dir dist-shim packaging/astro-senpai
64
+ - name: Check distribution metadata
65
+ run: uvx twine check dist/* dist-shim/*
66
+
67
+ - name: Construct the app from the installed wheel
68
+ # Issue #6: create_app() worked in an editable checkout and raised on
69
+ # every real install, because shipped code read files that live outside
70
+ # the `senpai/` package a wheel ships. Only a non-editable install
71
+ # catches that. Run from /tmp so the checkout's senpai/ cannot shadow
72
+ # the installed package.
73
+ run: |
74
+ uv venv /tmp/wheel-check
75
+ uv pip install --python /tmp/wheel-check/bin/python dist/*.whl
76
+ cd /tmp
77
+ /tmp/wheel-check/bin/python -c "
78
+ from senpai.api.main import create_app
79
+ create_app().openapi()
80
+ print('installed wheel constructs the app and its OpenAPI schema')
81
+ "
82
+
83
+ - name: Install the astro-senpai shim over the built senpai
84
+ # The shim must pin exactly this senpai version (--find-links offers
85
+ # the local build; a wrong pin fails to resolve) and ship no code.
86
+ run: |
87
+ uv pip install --python /tmp/wheel-check/bin/python --find-links dist dist-shim/*.whl
88
+ cd /tmp
89
+ /tmp/wheel-check/bin/python -c "
90
+ from importlib.metadata import files, version
91
+ import senpai
92
+ assert version('astro-senpai') == version('senpai') == senpai.__version__, senpai.__version__
93
+ assert not [f for f in files('astro-senpai') if f.suffix == '.py'], 'shim ships code'
94
+ print('astro-senpai', version('astro-senpai'), '-> senpai', senpai.__version__)
95
+ "
@@ -0,0 +1,163 @@
1
+ # Build and publish senpai to PyPI when a GitHub Release is published, along
2
+ # with astro-senpai (its old PyPI name) as an empty package pinned to the same
3
+ # senpai version (packaging/astro-senpai/).
4
+ #
5
+ # Trigger: publishing a Release (not merges to main, not draft releases,
6
+ # not prereleases -- see the `if:` guard on release-build).
7
+ # Auth: PyPI Trusted Publishing (OIDC). No API token secret is used.
8
+ # Gate: the `pypi` environment. Add required reviewers there so a human
9
+ # must approve before anything reaches PyPI.
10
+ #
11
+ # One-time setup required before this can succeed -- see docs/RELEASING.md.
12
+
13
+ name: Upload Python Package
14
+
15
+ on:
16
+ release:
17
+ types: [published]
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ concurrency:
23
+ group: pypi-publish-${{ github.event.release.tag_name }}
24
+ cancel-in-progress: false
25
+
26
+ jobs:
27
+ release-build:
28
+ # Never publish from a draft or a prerelease. Publishing a draft flips
29
+ # `draft` to false before this fires, so the prerelease check is the one
30
+ # that does the real work; the draft check is belt-and-braces.
31
+ if: ${{ !github.event.release.draft && !github.event.release.prerelease }}
32
+ runs-on: ubuntu-latest
33
+
34
+ env:
35
+ # PyPI project names. The shim's built artifacts normalize `-` to `_`.
36
+ DIST_NAME: senpai
37
+ SHIM_NAME: astro-senpai
38
+ SHIM_FILE: astro_senpai
39
+ SHIM_DIR: packaging/astro-senpai
40
+
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+ with:
44
+ # Check out the exact commit the release tag points at, not the
45
+ # branch head, so we build what was actually tagged.
46
+ ref: ${{ github.event.release.tag_name }}
47
+
48
+ - uses: astral-sh/setup-uv@v5
49
+ with:
50
+ enable-cache: true
51
+ # Sets UV_PYTHON so `uv sync` and `uv run` agree on the interpreter.
52
+ python-version: "3.12"
53
+
54
+ - name: Verify release tag matches pyproject.toml version
55
+ env:
56
+ TAG: ${{ github.event.release.tag_name }}
57
+ run: |
58
+ PROJECT_VERSION="$(uv run --no-project python -c 'import tomllib,pathlib; print(tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"])')"
59
+ echo "pyproject.toml version: ${PROJECT_VERSION}"
60
+ echo "release tag: ${TAG}"
61
+ if [ "${TAG}" != "v${PROJECT_VERSION}" ]; then
62
+ echo "::error::Release tag '${TAG}' does not match pyproject.toml version '${PROJECT_VERSION}' (expected tag 'v${PROJECT_VERSION}'). Bump the version or retag."
63
+ exit 1
64
+ fi
65
+ echo "VERSION=${PROJECT_VERSION}" >> "$GITHUB_ENV"
66
+
67
+ - name: Verify astro-senpai shim is pinned to this version
68
+ run: |
69
+ uv run --no-project python - <<'EOF'
70
+ import os, pathlib, tomllib
71
+ version = os.environ["VERSION"]
72
+ shim = tomllib.loads(pathlib.Path(os.environ["SHIM_DIR"], "pyproject.toml").read_text())["project"]
73
+ want = f"senpai=={version}"
74
+ if shim["version"] != version or shim["dependencies"] != [want]:
75
+ raise SystemExit(f"::error::{os.environ['SHIM_DIR']}/pyproject.toml must have version = \"{version}\" and dependencies = [\"{want}\"], got version {shim['version']!r}, dependencies {shim['dependencies']!r}.")
76
+ print(f"shim OK: astro-senpai {version} -> {want}")
77
+ EOF
78
+
79
+ - name: Verify version is not already on PyPI
80
+ run: |
81
+ for name in "${DIST_NAME}" "${SHIM_NAME}"; do
82
+ if curl -sf "https://pypi.org/pypi/${name}/${VERSION}/json" > /dev/null; then
83
+ echo "::error::${name} ${VERSION} is already published on PyPI. Bump the version in pyproject.toml and ${SHIM_DIR}/pyproject.toml -- PyPI will not accept a re-upload."
84
+ exit 1
85
+ fi
86
+ done
87
+ echo "PyPI check OK: ${VERSION} is not yet published"
88
+
89
+ - name: Install dependencies
90
+ # No --frozen: uv.lock is gitignored in this repo, so there is nothing
91
+ # to freeze against.
92
+ run: uv sync --all-extras
93
+
94
+ - name: Lint
95
+ # Same narrow rule set as ci.yml. The full `make lint` config reports
96
+ # ~850 pre-existing findings, so gating releases on it would block
97
+ # every release until that backlog is cleared.
98
+ run: uv run ruff check senpai --select E9,F63,F7,F82,F401,F541,F811
99
+
100
+ - name: Run tests
101
+ # Same subset as `make test-ci`: astrometry.net, index files, and local
102
+ # star catalogs are not available on GitHub runners.
103
+ run: uv run pytest -v -m "not requires_astrometry and not requires_catalog"
104
+
105
+ - name: Build release distributions
106
+ run: |
107
+ uv build --out-dir dist/senpai
108
+ uv build --out-dir dist/astro-senpai "${SHIM_DIR}"
109
+
110
+ - name: Verify built artifacts carry the expected version
111
+ run: |
112
+ ls -lR dist/
113
+ for f in "senpai/${DIST_NAME}-${VERSION}-py3-none-any.whl" "senpai/${DIST_NAME}-${VERSION}.tar.gz" \
114
+ "astro-senpai/${SHIM_FILE}-${VERSION}-py3-none-any.whl" "astro-senpai/${SHIM_FILE}-${VERSION}.tar.gz"; do
115
+ test -f "dist/${f}" || { echo "::error::Expected dist/${f}, got: $(ls -R dist/)"; exit 1; }
116
+ done
117
+
118
+ - name: Check distribution metadata
119
+ run: uvx twine check dist/senpai/* dist/astro-senpai/*
120
+
121
+ - name: Upload distributions
122
+ uses: actions/upload-artifact@v4
123
+ with:
124
+ name: release-dists
125
+ path: dist/
126
+
127
+ pypi-publish:
128
+ runs-on: ubuntu-latest
129
+ needs:
130
+ - release-build
131
+
132
+ permissions:
133
+ # Mandatory for trusted publishing.
134
+ id-token: write
135
+
136
+ # Configure required reviewers on this environment in
137
+ # Settings -> Environments -> pypi. The build above runs unattended;
138
+ # this job waits for a human approval before uploading.
139
+ environment:
140
+ name: pypi
141
+ url: https://pypi.org/p/senpai
142
+
143
+ steps:
144
+ - name: Retrieve release distributions
145
+ uses: actions/download-artifact@v4
146
+ with:
147
+ name: release-dists
148
+ path: dist/
149
+
150
+ # senpai first: the astro-senpai shim depends on it. skip-existing lets
151
+ # a re-run of this job finish the shim upload if senpai already went up;
152
+ # the build job has already refused versions that were on PyPI before.
153
+ - name: Publish senpai to PyPI
154
+ uses: pypa/gh-action-pypi-publish@release/v1
155
+ with:
156
+ packages-dir: dist/senpai/
157
+ skip-existing: true
158
+
159
+ - name: Publish astro-senpai shim to PyPI
160
+ uses: pypa/gh-action-pypi-publish@release/v1
161
+ with:
162
+ packages-dir: dist/astro-senpai/
163
+ skip-existing: true
@@ -0,0 +1,155 @@
1
+ coverage-app.xml
2
+ junit-app.xml
3
+ reports/
4
+ uv.lock
5
+
6
+
7
+ senpai/api/logs/
8
+ docs/api
9
+
10
+ *-env
11
+
12
+ .process
13
+ .test/
14
+
15
+ *.DS_Store
16
+ *.vscode
17
+ .claude/
18
+ *.SP3
19
+ *.all
20
+ example_master*yaml
21
+ .config*
22
+
23
+ *.pem
24
+
25
+ *.udl
26
+ *.openapi
27
+
28
+ *.avi
29
+ *.mp4
30
+
31
+ .example
32
+ .test
33
+
34
+ packages/
35
+
36
+ examples/*json
37
+
38
+ # Byte-compiled / optimized / DLL files
39
+ __pycache__/
40
+ *.py[cod]
41
+ *$py.class
42
+
43
+ # C extensions
44
+ *.so
45
+
46
+ # Distribution / packaging
47
+ .Python
48
+ build/
49
+ develop-eggs/
50
+ dist/
51
+ downloads/
52
+ eggs/
53
+ .eggs/
54
+ lib/
55
+ lib64/
56
+ parts/
57
+ sdist/
58
+ var/
59
+ wheels/
60
+ *.egg-info/
61
+ .installed.cfg
62
+ *.egg
63
+ MANIFEST
64
+
65
+ # PyInstaller
66
+ # Usually these files are written by a python script from a template
67
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
68
+ *.manifest
69
+ *.spec
70
+
71
+ # Installer logs
72
+ pip-log.txt
73
+ pip-delete-this-directory.txt
74
+
75
+ # Unit test / coverage reports
76
+ htmlcov/
77
+ .tox/
78
+ .coverage
79
+ .coverage.*
80
+ .cache
81
+ nosetests.xml
82
+ coverage.xml
83
+ *.cover
84
+ .hypothesis/
85
+ .pytest_cache/
86
+
87
+ # Translations
88
+ *.mo
89
+ *.pot
90
+
91
+ # Django stuff:
92
+ *.log
93
+ local_settings.py
94
+ db.sqlite3
95
+
96
+ # Flask stuff:
97
+ instance/
98
+ .webassets-cache
99
+
100
+ # Scrapy stuff:
101
+ .scrapy
102
+
103
+ # Sphinx documentation
104
+ docs/_build/
105
+
106
+ # PyBuilder
107
+ target/
108
+
109
+ # Jupyter Notebook
110
+ .ipynb_checkpoints
111
+
112
+ # pyenv
113
+ .python-version
114
+
115
+ # celery beat schedule file
116
+ celerybeat-schedule
117
+
118
+ # SageMath parsed files
119
+ *.sage.py
120
+
121
+ # Environments
122
+ .env
123
+ .venv
124
+ env/
125
+ venv/
126
+ ENV/
127
+ env.bak/
128
+ venv.bak/
129
+
130
+ # Spyder project settings
131
+ .spyderproject
132
+ .spyproject
133
+
134
+ # Rope project settings
135
+ .ropeproject
136
+
137
+ # mkdocs documentation
138
+ /site
139
+
140
+ # mypy
141
+ .mypy_cache/
142
+
143
+ # ruff
144
+ .ruff_cache/
145
+
146
+ stars-with-metadata-fc46157d-13b9-461b-ac71-7a528f419e43.json
147
+ tests/data/geodss*/
148
+ tests/imageset/
149
+ hello.png
150
+ remote-test-paths.txt
151
+
152
+ # local scratch / simulation fixtures (not source)
153
+ tmp.go
154
+ sidereal_streak_data/
155
+ score_streaks.py
@@ -0,0 +1,4 @@
1
+ {
2
+ "MD013": false,
3
+ "MD024": false
4
+ }