harp-astro 0.1.0__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 (32) hide show
  1. harp_astro-0.1.0/PKG-INFO +178 -0
  2. harp_astro-0.1.0/README.md +140 -0
  3. harp_astro-0.1.0/pyproject.toml +114 -0
  4. harp_astro-0.1.0/setup.cfg +4 -0
  5. harp_astro-0.1.0/src/harp/__init__.py +12 -0
  6. harp_astro-0.1.0/src/harp/__main__.py +8 -0
  7. harp_astro-0.1.0/src/harp/catalog.py +419 -0
  8. harp_astro-0.1.0/src/harp/cli.py +377 -0
  9. harp_astro-0.1.0/src/harp/config.py +144 -0
  10. harp_astro-0.1.0/src/harp/ephemeris.py +165 -0
  11. harp_astro-0.1.0/src/harp/errors.py +27 -0
  12. harp_astro-0.1.0/src/harp/horizon.py +238 -0
  13. harp_astro-0.1.0/src/harp/mosaic.py +75 -0
  14. harp_astro-0.1.0/src/harp/nina.py +106 -0
  15. harp_astro-0.1.0/src/harp/optics.py +130 -0
  16. harp_astro-0.1.0/src/harp/planner.py +343 -0
  17. harp_astro-0.1.0/src/harp/py.typed +0 -0
  18. harp_astro-0.1.0/src/harp/report.py +164 -0
  19. harp_astro-0.1.0/src/harp_astro.egg-info/PKG-INFO +178 -0
  20. harp_astro-0.1.0/src/harp_astro.egg-info/SOURCES.txt +30 -0
  21. harp_astro-0.1.0/src/harp_astro.egg-info/dependency_links.txt +1 -0
  22. harp_astro-0.1.0/src/harp_astro.egg-info/entry_points.txt +2 -0
  23. harp_astro-0.1.0/src/harp_astro.egg-info/requires.txt +14 -0
  24. harp_astro-0.1.0/src/harp_astro.egg-info/top_level.txt +1 -0
  25. harp_astro-0.1.0/tests/test_catalog.py +162 -0
  26. harp_astro-0.1.0/tests/test_cli.py +201 -0
  27. harp_astro-0.1.0/tests/test_config.py +68 -0
  28. harp_astro-0.1.0/tests/test_horizon.py +80 -0
  29. harp_astro-0.1.0/tests/test_mosaic.py +56 -0
  30. harp_astro-0.1.0/tests/test_nina.py +142 -0
  31. harp_astro-0.1.0/tests/test_optics.py +57 -0
  32. harp_astro-0.1.0/tests/test_planner.py +75 -0
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: harp-astro
3
+ Version: 0.1.0
4
+ Summary: HARP - Horizon-Aware Recommender and Planner for deep-sky astrophotography sessions
5
+ Author-email: Stefano Zaghi <stefano.zaghi@gmail.com>
6
+ License: GPL-3.0-or-later OR BSD-2-Clause OR BSD-3-Clause OR MIT
7
+ Project-URL: Homepage, https://szaghi.github.io/harp/
8
+ Project-URL: Documentation, https://szaghi.github.io/harp/
9
+ Project-URL: Repository, https://github.com/szaghi/harp
10
+ Project-URL: Bug Tracker, https://github.com/szaghi/harp/issues
11
+ Keywords: astronomy,astrophotography,deep-sky,planner,session,telescope
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
+ Classifier: License :: OSI Approved :: BSD License
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: typer>=0.12
26
+ Requires-Dist: rich>=13
27
+ Requires-Dist: numpy>=1.26
28
+ Requires-Dist: astropy>=6.0
29
+ Requires-Dist: astroplan>=0.9
30
+ Requires-Dist: pyongc>=1.1
31
+ Requires-Dist: matplotlib>=3.8
32
+ Requires-Dist: pyyaml>=6.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=8; extra == "dev"
35
+ Requires-Dist: pytest-cov>=5; extra == "dev"
36
+ Requires-Dist: build>=1.2; extra == "dev"
37
+ Requires-Dist: ruff>=0.8; extra == "dev"
38
+
39
+ <div align="center">
40
+
41
+ # HARP
42
+
43
+ #### *image the sky your balcony can actually see*
44
+
45
+ ### **H**orizon-**A**ware **R**ecommender and **P**lanner
46
+
47
+ > A CLI planner for deep-sky astrophotography sessions. Given a date, a site, your
48
+ > telescope + camera, the **real horizon of your spot** and the Moon, HARP ranks the
49
+ > targets you can actually image tonight — usable windows, Moon impact, and mosaic
50
+ > framing tailored to your rig.
51
+
52
+ [![Version](https://img.shields.io/pypi/v/harp-astro?label=version)](https://pypi.org/project/harp-astro/)
53
+ [![CI](https://github.com/szaghi/harp/actions/workflows/ci.yml/badge.svg)](https://github.com/szaghi/harp/actions/workflows/ci.yml)
54
+ [![Python](https://img.shields.io/badge/python-3.11%2B-blue?logo=python&logoColor=white)](https://www.python.org/)
55
+ [![GitHub issues](https://img.shields.io/github/issues/szaghi/harp.svg)](https://github.com/szaghi/harp/issues)
56
+
57
+ [![License: GPL v3](https://img.shields.io/badge/license-GPL%20v3-blue)](licensing/LICENSE.gpl3.md)
58
+ [![License: BSD-2](https://img.shields.io/badge/license-BSD--2--Clause-blue)](licensing/LICENSE.bsd-2.md)
59
+ [![License: BSD-3](https://img.shields.io/badge/license-BSD--3--Clause-blue)](licensing/LICENSE.bsd-3.md)
60
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](licensing/LICENSE.mit.md)
61
+
62
+ <div>
63
+ <table>
64
+ <tr>
65
+ <td><b>🧱 Horizon-aware visibility</b><br><sub>Measure your site's obstructions once as an azimuth-dependent mask (<code>.hrz</code>, N.I.N.A.-compatible). A target counts as observable only when its altitude clears the ridge/wall <em>in its own direction</em> — not against an idealized flat horizon. <a href="https://szaghi.github.io/harp/guide/usage#build-a-horizon-file">Horizon guide</a></sub></td>
66
+ <td><b>⏱️ Continuous imaging windows</b><br><sub>Per target: total usable hours during astronomical darkness plus the longest <em>continuous</em> run before it enters a blocked sector — the number you actually size exposures and mosaic panels on. <a href="https://szaghi.github.io/harp/guide/usage#reading-the-output">Reading the output</a></sub></td>
67
+ </tr>
68
+ <tr>
69
+ <td><b>🏆 Desirability ranking</b><br><sub>Every target gets a 0-100 score: a weighted geometric mean of continuous window, total hours, peak altitude (inverse-airmass), Moon verdict, and how well the object fills your field of view — so one hopeless factor sinks a target instead of averaging away. <code>--sort hours</code> restores the classic order.</sub></td>
70
+ <td><b>🌙 Moon impact model</b><br><sub>Phase and separation folded into a per-target verdict — <code>none</code>, <code>ok(NB)</code>, <code>low/med/high</code> — with narrowband auto-derived from the object type: planetaries, supernova remnants and HII regions shrug at a Moon that ruins broadband RGB.</sub></td>
71
+ </tr>
72
+ <tr>
73
+ <td><b>🖼️ Mosaic framing &amp; panel coordinates</b><br><sub>Your focal length + sensor decide <code>1 frame</code> or <code>mosaic NxM</code>; <code>harp mosaic</code> then emits the actual per-panel RA/Dec centers (overlap-aware, position-angle rotated, correct at any declination) — plus single-frame crop suggestions for the monsters. <a href="https://szaghi.github.io/harp/guide/usage#mosaic-panel-coordinates">Mosaic guide</a></sub></td>
74
+ <td><b>🎯 N.I.N.A. integration</b><br><sub>The same <code>.hrz</code> horizon drives both tools, and <code>--nina</code> exports ranked targets or mosaic panels as CSVs N.I.N.A.'s sequencer imports directly — verified against N.I.N.A.'s actual parser source. Plan in HARP, shoot in N.I.N.A., retype nothing. <a href="https://szaghi.github.io/harp/guide/usage#nina-integration">N.I.N.A. guide</a></sub></td>
75
+ </tr>
76
+ <tr>
77
+ <td><b>🔭 Offline catalogues + your own</b><br><sub>Curated large emission nebulae (deliberately <em>not</em> magnitude-filtered), full Messier/NGC/IC via <a href="https://github.com/mattiaverga/PyOngc">pyongc</a> (<code>--catalogs M,NGC,IC</code>), and a user targets file that overrides everything (<code>--targets</code>). Cross-identification dedup: M42 and NGC1976 are one object, M43 stays its own. No network at run time.</sub></td>
78
+ <td><b>📈 Table, CSV, charts</b><br><sub>A ranked terminal table, a CSV for your session log, and altitude charts with the horizon obstruction band and the usable window overlaid — one command, all artifacts, all greppable and scriptable.</sub></td>
79
+ </tr>
80
+ </table>
81
+ </div>
82
+
83
+ **[Full documentation](https://szaghi.github.io/harp/)** — installation, usage, horizon measuring, configuration
84
+
85
+ </div>
86
+
87
+ ---
88
+
89
+ ## What HARP does
90
+
91
+ ```bash
92
+ harp plan # tonight, default site/optics from config
93
+ harp plan 2026-08-15 --site balcony --optics newton800
94
+ harp plan --catalogs M,NGC,IC --targets my_targets.yaml # full catalog + your objects
95
+ harp plan --nina tonight.csv # export ranked targets for N.I.N.A.
96
+ harp mosaic IC1396 --pa 30 --nina panels.csv # per-panel coords -> N.I.N.A. sequencer
97
+ harp list # sites and optics defined in the config
98
+ harp horizon points.yaml -o balcony.hrz # measured vertices -> .hrz horizon file
99
+ ```
100
+
101
+ ```
102
+ === Night 2026-08-15 | Castelli Balcony 41.7380,12.8899 ===
103
+ Astronomical darkness: 21:53 -> 04:32 local
104
+ Moon: ~12% illuminated | above horizon: below horizon all night
105
+ Setup: 800 mm + custom 23.5x15.7
106
+ Field of view: 101' x 67' | horizon: balcony.hrz
107
+
108
+ # object score kind const hrs cont window altMx az moonSep Moon frame
109
+ --------------------------------------------------------------------------------------------------------
110
+ 1 NGC281 Pacman 99 Nebula Cas 6.7 6.7 21:53-04:28 75 0 127 none 1 frame
111
+ 2 NGC7380 Wizard 99 Nebula Cep 5.2 5.2 21:53-03:03 73 0 124 none 1 frame
112
+ 3 NGC1039 99 Open Clus Per 6.7 6.7 21:53-04:28 71 78 128 none 1 frame
113
+ 4 IC59/63 Ghost of Cas 99 Nebula Cas 6.7 6.7 21:53-04:28 71 360 122 none 1 frame
114
+ 5 Sh2-155 Cave 98 Nebula Cep 5.8 5.8 21:53-03:38 69 0 121 none 1 frame
115
+ ```
116
+
117
+ ![Altitude charts](examples/altitude_charts.example.png)
118
+
119
+ The typical flow: **measure the horizon once → generate the `.hrz` → load it
120
+ in N.I.N.A. and in HARP → plan the night → export the ranked targets (or the
121
+ mosaic panels) straight into N.I.N.A.'s sequencer.** See
122
+ [`examples/`](examples/) for a working config, horizon file, and sample outputs.
123
+
124
+ ## The name
125
+
126
+ A *harp* is the celestial Lyre — the constellation **Lyra**, home of Vega and the
127
+ Ring Nebula. And the acronym leads with the input most planners ignore: your
128
+ horizon.
129
+
130
+ ## Installation
131
+
132
+ ```bash
133
+ pip install harp-astro
134
+ ```
135
+
136
+ The distribution is `harp-astro` (the bare PyPI name is squatted by an empty
137
+ project; a PEP 541 request is pending) — the installed package and the CLI
138
+ command are plain `harp`.
139
+
140
+ From source:
141
+
142
+ ```bash
143
+ git clone https://github.com/szaghi/harp
144
+ cd harp
145
+ make dev
146
+ ```
147
+
148
+ ## Configuration
149
+
150
+ Sites (position + `.hrz` + timezone) and optical setups (focal + sensor) live in
151
+ `sites.yaml`, searched in the current directory and `~/.config/harp/`.
152
+ Precedence: **CLI option > config value > built-in default**. Details in the
153
+ [usage guide](https://szaghi.github.io/harp/guide/usage).
154
+
155
+ ## Development
156
+
157
+ ```bash
158
+ make dev # editable install with dev extras into .venv
159
+ make test # pytest with coverage
160
+ make lint # ruff check + format check (read-only)
161
+ make fmt # ruff auto-fix + format
162
+ ```
163
+
164
+ Releases: `./release.sh --major|--minor|--patch|X.Y.Z` (trunk model on `main`;
165
+ tag push triggers CI → PyPI).
166
+
167
+ ## Authors
168
+
169
+ **Stefano Zaghi** ([@szaghi](https://github.com/szaghi))
170
+ >HPC/CFD researcher by day, balcony astrophotographer by night. Owns a Newton 200/800 f/4 and a balcony whose entire southern hemisphere is a wall. Measured the horizon with a phone compass while fending off a magnetized railing, then wrote a planner rather than accept that M8 belongs to the neighbours.
171
+
172
+ **Claude** ([Anthropic](https://www.anthropic.com))
173
+ >Large language model, second author, zero telescopes. Has never seen the night sky — or anything else — yet computed where the Moon would be at 03:46 and was right. Refactored the whole toolkit between dusk and dawn, no coffee involved; accepts payment in tokens and byte-identical CSVs.
174
+
175
+ ## License
176
+
177
+ Multi-licensed under GPL-3.0-or-later, BSD-2-Clause, BSD-3-Clause, and MIT —
178
+ choose the one that fits your use. See [`licensing/`](licensing/).
@@ -0,0 +1,140 @@
1
+ <div align="center">
2
+
3
+ # HARP
4
+
5
+ #### *image the sky your balcony can actually see*
6
+
7
+ ### **H**orizon-**A**ware **R**ecommender and **P**lanner
8
+
9
+ > A CLI planner for deep-sky astrophotography sessions. Given a date, a site, your
10
+ > telescope + camera, the **real horizon of your spot** and the Moon, HARP ranks the
11
+ > targets you can actually image tonight — usable windows, Moon impact, and mosaic
12
+ > framing tailored to your rig.
13
+
14
+ [![Version](https://img.shields.io/pypi/v/harp-astro?label=version)](https://pypi.org/project/harp-astro/)
15
+ [![CI](https://github.com/szaghi/harp/actions/workflows/ci.yml/badge.svg)](https://github.com/szaghi/harp/actions/workflows/ci.yml)
16
+ [![Python](https://img.shields.io/badge/python-3.11%2B-blue?logo=python&logoColor=white)](https://www.python.org/)
17
+ [![GitHub issues](https://img.shields.io/github/issues/szaghi/harp.svg)](https://github.com/szaghi/harp/issues)
18
+
19
+ [![License: GPL v3](https://img.shields.io/badge/license-GPL%20v3-blue)](licensing/LICENSE.gpl3.md)
20
+ [![License: BSD-2](https://img.shields.io/badge/license-BSD--2--Clause-blue)](licensing/LICENSE.bsd-2.md)
21
+ [![License: BSD-3](https://img.shields.io/badge/license-BSD--3--Clause-blue)](licensing/LICENSE.bsd-3.md)
22
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](licensing/LICENSE.mit.md)
23
+
24
+ <div>
25
+ <table>
26
+ <tr>
27
+ <td><b>🧱 Horizon-aware visibility</b><br><sub>Measure your site's obstructions once as an azimuth-dependent mask (<code>.hrz</code>, N.I.N.A.-compatible). A target counts as observable only when its altitude clears the ridge/wall <em>in its own direction</em> — not against an idealized flat horizon. <a href="https://szaghi.github.io/harp/guide/usage#build-a-horizon-file">Horizon guide</a></sub></td>
28
+ <td><b>⏱️ Continuous imaging windows</b><br><sub>Per target: total usable hours during astronomical darkness plus the longest <em>continuous</em> run before it enters a blocked sector — the number you actually size exposures and mosaic panels on. <a href="https://szaghi.github.io/harp/guide/usage#reading-the-output">Reading the output</a></sub></td>
29
+ </tr>
30
+ <tr>
31
+ <td><b>🏆 Desirability ranking</b><br><sub>Every target gets a 0-100 score: a weighted geometric mean of continuous window, total hours, peak altitude (inverse-airmass), Moon verdict, and how well the object fills your field of view — so one hopeless factor sinks a target instead of averaging away. <code>--sort hours</code> restores the classic order.</sub></td>
32
+ <td><b>🌙 Moon impact model</b><br><sub>Phase and separation folded into a per-target verdict — <code>none</code>, <code>ok(NB)</code>, <code>low/med/high</code> — with narrowband auto-derived from the object type: planetaries, supernova remnants and HII regions shrug at a Moon that ruins broadband RGB.</sub></td>
33
+ </tr>
34
+ <tr>
35
+ <td><b>🖼️ Mosaic framing &amp; panel coordinates</b><br><sub>Your focal length + sensor decide <code>1 frame</code> or <code>mosaic NxM</code>; <code>harp mosaic</code> then emits the actual per-panel RA/Dec centers (overlap-aware, position-angle rotated, correct at any declination) — plus single-frame crop suggestions for the monsters. <a href="https://szaghi.github.io/harp/guide/usage#mosaic-panel-coordinates">Mosaic guide</a></sub></td>
36
+ <td><b>🎯 N.I.N.A. integration</b><br><sub>The same <code>.hrz</code> horizon drives both tools, and <code>--nina</code> exports ranked targets or mosaic panels as CSVs N.I.N.A.'s sequencer imports directly — verified against N.I.N.A.'s actual parser source. Plan in HARP, shoot in N.I.N.A., retype nothing. <a href="https://szaghi.github.io/harp/guide/usage#nina-integration">N.I.N.A. guide</a></sub></td>
37
+ </tr>
38
+ <tr>
39
+ <td><b>🔭 Offline catalogues + your own</b><br><sub>Curated large emission nebulae (deliberately <em>not</em> magnitude-filtered), full Messier/NGC/IC via <a href="https://github.com/mattiaverga/PyOngc">pyongc</a> (<code>--catalogs M,NGC,IC</code>), and a user targets file that overrides everything (<code>--targets</code>). Cross-identification dedup: M42 and NGC1976 are one object, M43 stays its own. No network at run time.</sub></td>
40
+ <td><b>📈 Table, CSV, charts</b><br><sub>A ranked terminal table, a CSV for your session log, and altitude charts with the horizon obstruction band and the usable window overlaid — one command, all artifacts, all greppable and scriptable.</sub></td>
41
+ </tr>
42
+ </table>
43
+ </div>
44
+
45
+ **[Full documentation](https://szaghi.github.io/harp/)** — installation, usage, horizon measuring, configuration
46
+
47
+ </div>
48
+
49
+ ---
50
+
51
+ ## What HARP does
52
+
53
+ ```bash
54
+ harp plan # tonight, default site/optics from config
55
+ harp plan 2026-08-15 --site balcony --optics newton800
56
+ harp plan --catalogs M,NGC,IC --targets my_targets.yaml # full catalog + your objects
57
+ harp plan --nina tonight.csv # export ranked targets for N.I.N.A.
58
+ harp mosaic IC1396 --pa 30 --nina panels.csv # per-panel coords -> N.I.N.A. sequencer
59
+ harp list # sites and optics defined in the config
60
+ harp horizon points.yaml -o balcony.hrz # measured vertices -> .hrz horizon file
61
+ ```
62
+
63
+ ```
64
+ === Night 2026-08-15 | Castelli Balcony 41.7380,12.8899 ===
65
+ Astronomical darkness: 21:53 -> 04:32 local
66
+ Moon: ~12% illuminated | above horizon: below horizon all night
67
+ Setup: 800 mm + custom 23.5x15.7
68
+ Field of view: 101' x 67' | horizon: balcony.hrz
69
+
70
+ # object score kind const hrs cont window altMx az moonSep Moon frame
71
+ --------------------------------------------------------------------------------------------------------
72
+ 1 NGC281 Pacman 99 Nebula Cas 6.7 6.7 21:53-04:28 75 0 127 none 1 frame
73
+ 2 NGC7380 Wizard 99 Nebula Cep 5.2 5.2 21:53-03:03 73 0 124 none 1 frame
74
+ 3 NGC1039 99 Open Clus Per 6.7 6.7 21:53-04:28 71 78 128 none 1 frame
75
+ 4 IC59/63 Ghost of Cas 99 Nebula Cas 6.7 6.7 21:53-04:28 71 360 122 none 1 frame
76
+ 5 Sh2-155 Cave 98 Nebula Cep 5.8 5.8 21:53-03:38 69 0 121 none 1 frame
77
+ ```
78
+
79
+ ![Altitude charts](examples/altitude_charts.example.png)
80
+
81
+ The typical flow: **measure the horizon once → generate the `.hrz` → load it
82
+ in N.I.N.A. and in HARP → plan the night → export the ranked targets (or the
83
+ mosaic panels) straight into N.I.N.A.'s sequencer.** See
84
+ [`examples/`](examples/) for a working config, horizon file, and sample outputs.
85
+
86
+ ## The name
87
+
88
+ A *harp* is the celestial Lyre — the constellation **Lyra**, home of Vega and the
89
+ Ring Nebula. And the acronym leads with the input most planners ignore: your
90
+ horizon.
91
+
92
+ ## Installation
93
+
94
+ ```bash
95
+ pip install harp-astro
96
+ ```
97
+
98
+ The distribution is `harp-astro` (the bare PyPI name is squatted by an empty
99
+ project; a PEP 541 request is pending) — the installed package and the CLI
100
+ command are plain `harp`.
101
+
102
+ From source:
103
+
104
+ ```bash
105
+ git clone https://github.com/szaghi/harp
106
+ cd harp
107
+ make dev
108
+ ```
109
+
110
+ ## Configuration
111
+
112
+ Sites (position + `.hrz` + timezone) and optical setups (focal + sensor) live in
113
+ `sites.yaml`, searched in the current directory and `~/.config/harp/`.
114
+ Precedence: **CLI option > config value > built-in default**. Details in the
115
+ [usage guide](https://szaghi.github.io/harp/guide/usage).
116
+
117
+ ## Development
118
+
119
+ ```bash
120
+ make dev # editable install with dev extras into .venv
121
+ make test # pytest with coverage
122
+ make lint # ruff check + format check (read-only)
123
+ make fmt # ruff auto-fix + format
124
+ ```
125
+
126
+ Releases: `./release.sh --major|--minor|--patch|X.Y.Z` (trunk model on `main`;
127
+ tag push triggers CI → PyPI).
128
+
129
+ ## Authors
130
+
131
+ **Stefano Zaghi** ([@szaghi](https://github.com/szaghi))
132
+ >HPC/CFD researcher by day, balcony astrophotographer by night. Owns a Newton 200/800 f/4 and a balcony whose entire southern hemisphere is a wall. Measured the horizon with a phone compass while fending off a magnetized railing, then wrote a planner rather than accept that M8 belongs to the neighbours.
133
+
134
+ **Claude** ([Anthropic](https://www.anthropic.com))
135
+ >Large language model, second author, zero telescopes. Has never seen the night sky — or anything else — yet computed where the Moon would be at 03:46 and was right. Refactored the whole toolkit between dusk and dawn, no coffee involved; accepts payment in tokens and byte-identical CSVs.
136
+
137
+ ## License
138
+
139
+ Multi-licensed under GPL-3.0-or-later, BSD-2-Clause, BSD-3-Clause, and MIT —
140
+ choose the one that fits your use. See [`licensing/`](licensing/).
@@ -0,0 +1,114 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ # Distribution name: the bare "harp" is squatted on PyPI by an empty project
7
+ # (PEP 541 request pending); import package and CLI command remain "harp".
8
+ name = "harp-astro"
9
+ version = "0.1.0"
10
+ description = "HARP - Horizon-Aware Recommender and Planner for deep-sky astrophotography sessions"
11
+ readme = "README.md"
12
+ license = { text = "GPL-3.0-or-later OR BSD-2-Clause OR BSD-3-Clause OR MIT" }
13
+ requires-python = ">=3.11"
14
+ authors = [
15
+ { name = "Stefano Zaghi", email = "stefano.zaghi@gmail.com" },
16
+ ]
17
+ keywords = ["astronomy", "astrophotography", "deep-sky", "planner", "session", "telescope"]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Environment :: Console",
21
+ "Intended Audience :: Science/Research",
22
+ "Intended Audience :: End Users/Desktop",
23
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
24
+ "License :: OSI Approved :: BSD License",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Programming Language :: Python :: 3",
27
+ "Programming Language :: Python :: 3.11",
28
+ "Programming Language :: Python :: 3.12",
29
+ "Topic :: Scientific/Engineering :: Astronomy",
30
+ ]
31
+ dependencies = [
32
+ "typer>=0.12",
33
+ "rich>=13",
34
+ "numpy>=1.26",
35
+ "astropy>=6.0",
36
+ "astroplan>=0.9",
37
+ "pyongc>=1.1",
38
+ "matplotlib>=3.8",
39
+ "pyyaml>=6.0",
40
+ ]
41
+
42
+ [project.optional-dependencies]
43
+ dev = ["pytest>=8", "pytest-cov>=5", "build>=1.2", "ruff>=0.8"]
44
+
45
+ [project.urls]
46
+ Homepage = "https://szaghi.github.io/harp/"
47
+ Documentation = "https://szaghi.github.io/harp/"
48
+ Repository = "https://github.com/szaghi/harp"
49
+ "Bug Tracker" = "https://github.com/szaghi/harp/issues"
50
+
51
+ [project.scripts]
52
+ harp = "harp.cli:app"
53
+
54
+ [tool.setuptools.packages.find]
55
+ where = ["src"]
56
+
57
+ [tool.setuptools.package-data]
58
+ "harp" = ["py.typed"]
59
+
60
+ [tool.pytest.ini_options]
61
+ testpaths = ["tests"]
62
+ addopts = "--cov=harp --cov-report=term-missing"
63
+
64
+ [tool.coverage.run]
65
+ source = ["harp"]
66
+ branch = true
67
+ omit = ["*/harp/__main__.py"]
68
+
69
+ [tool.coverage.report]
70
+ exclude_lines = [
71
+ "pragma: no cover",
72
+ "if __name__ == .__main__.:",
73
+ "if TYPE_CHECKING:",
74
+ ]
75
+
76
+ # ── Ruff ──────────────────────────────────────────────────────────────────────
77
+
78
+ [tool.ruff]
79
+ target-version = "py311"
80
+ line-length = 100
81
+
82
+ [tool.ruff.lint]
83
+ select = [
84
+ "E", # pycodestyle errors
85
+ "W", # pycodestyle warnings
86
+ "F", # pyflakes
87
+ "I", # isort
88
+ "N", # pep8-naming
89
+ "UP", # pyupgrade
90
+ "B", # flake8-bugbear
91
+ "SIM", # flake8-simplify
92
+ "RUF", # ruff-specific rules
93
+ "S", # flake8-bandit (security)
94
+ "T20", # flake8-print
95
+ "PIE", # flake8-pie
96
+ "PT", # flake8-pytest-style
97
+ "RET", # flake8-return
98
+ "C4", # flake8-comprehensions
99
+ ]
100
+ ignore = [
101
+ "E501", # line length — handled by formatter
102
+ "B008", # function call in default argument — typer's Option/Argument pattern
103
+ "T201", # print — CLI tool prints to the terminal by design
104
+ ]
105
+
106
+ [tool.ruff.lint.per-file-ignores]
107
+ "tests/**" = ["S101", "PT011"]
108
+
109
+ [tool.ruff.lint.isort]
110
+ known-first-party = ["harp"]
111
+
112
+ [tool.ruff.format]
113
+ quote-style = "double"
114
+ indent-style = "space"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,12 @@
1
+ """HARP - Horizon-Aware Recommender and Planner.
2
+
3
+ A CLI planner that selects deep-sky targets for an astrophotography session
4
+ from the observing date, site location, telescope+camera rig, the site's free
5
+ horizon profile, and the Moon status.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ # Version mirror — pyproject.toml is the canonical source; release.sh keeps
11
+ # both in sync.
12
+ __version__ = "0.1.0"
@@ -0,0 +1,8 @@
1
+ """Allow running as ``python -m harp``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from harp.cli import app
6
+
7
+ if __name__ == "__main__":
8
+ app()