starbash 0.2.4__tar.gz → 0.2.6__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 (66) hide show
  1. {starbash-0.2.4 → starbash-0.2.6}/PKG-INFO +4 -4
  2. {starbash-0.2.4 → starbash-0.2.6}/pyproject.toml +26 -22
  3. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/__init__.py +6 -0
  4. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/analytics.py +12 -5
  5. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/app.py +35 -25
  6. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/check_version.py +2 -2
  7. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/commands/info.py +6 -6
  8. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/commands/process.py +6 -6
  9. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/commands/repo.py +10 -9
  10. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/commands/select.py +12 -11
  11. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/commands/user.py +5 -5
  12. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/database.py +2 -1
  13. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/doit.py +68 -22
  14. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/dwarf3.py +13 -6
  15. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/linux.py +1 -1
  16. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/main.py +1 -1
  17. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/parameters.py +3 -2
  18. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/paths.py +2 -2
  19. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/processed_target.py +7 -5
  20. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/processing.py +8 -2
  21. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/recipes/osc.py +4 -4
  22. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/score.py +8 -8
  23. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/selection.py +2 -1
  24. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/sim_siril/connection.py +3 -2
  25. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/templates/userconfig.toml +5 -0
  26. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/tool/__init__.py +9 -3
  27. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/tool/base.py +152 -46
  28. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/tool/context.py +13 -11
  29. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/tool/graxpert.py +6 -1
  30. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/tool/python.py +14 -8
  31. starbash-0.2.6/src/starbash/tool/rcastro.py +162 -0
  32. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/tool/siril.py +19 -5
  33. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/windows.py +1 -1
  34. starbash-0.2.4/src/repo/__init__.py +0 -8
  35. starbash-0.2.4/src/repo/http_client.py +0 -5
  36. starbash-0.2.4/src/repo/manager.py +0 -146
  37. starbash-0.2.4/src/repo/repo.py +0 -693
  38. {starbash-0.2.4 → starbash-0.2.6}/LICENSE +0 -0
  39. {starbash-0.2.4 → starbash-0.2.6}/README.md +0 -0
  40. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/aliases.py +0 -0
  41. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/commands/__init__.py +0 -0
  42. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/defaults/__init__.py +0 -0
  43. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/defaults/starbash.toml +0 -0
  44. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/doit_types.py +0 -0
  45. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/exception.py +0 -0
  46. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/filtering.py +0 -0
  47. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/icon.py +0 -0
  48. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/os.py +0 -0
  49. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/processing_like.py +0 -0
  50. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/recipes/README.md +0 -0
  51. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/recipes/__init__.py +0 -0
  52. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/rich.py +0 -0
  53. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/safety.py +0 -0
  54. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/sim_siril/__init__.py +0 -0
  55. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/sim_siril/enums.py +0 -0
  56. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/sim_siril/utility.py +0 -0
  57. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/stage_utils.py +0 -0
  58. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/stages.py +0 -0
  59. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/templates/__init__.py +0 -0
  60. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/templates/repo/master.toml +0 -0
  61. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/templates/repo/processed.toml +0 -0
  62. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/templates/target/master.toml +0 -0
  63. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/templates/target/processed.toml +0 -0
  64. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/toml.py +0 -0
  65. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/ui/main.py +0 -0
  66. {starbash-0.2.4 → starbash-0.2.6}/src/starbash/url.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: starbash
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: A tool for automating/standardizing/sharing astrophotography workflows.
5
5
  License-File: LICENSE
6
6
  Author: Kevin Hester
@@ -13,14 +13,14 @@ Classifier: Programming Language :: Python :: 3.14
13
13
  Requires-Dist: astropy (>=7.1.1,<8.0.0)
14
14
  Requires-Dist: doit (>=0.36.0,<0.37.0)
15
15
  Requires-Dist: graxpert[cpuonly] (>=3.2.0a2,<4.0.0)
16
- Requires-Dist: multidict (>=6.7.0,<7.0.0)
16
+ Requires-Dist: numpy (==2.2.6)
17
17
  Requires-Dist: platformdirs (>=4.5.0,<5.0.0)
18
- Requires-Dist: requests-cache (>=1.2.1,<2.0.0)
18
+ Requires-Dist: pyqt6 (>=6.10.1,<7.0.0)
19
19
  Requires-Dist: restrictedpython (>=8.1,<9.0)
20
20
  Requires-Dist: rich (>=14.2.0,<15.0.0)
21
21
  Requires-Dist: sentry-sdk (>=2.42.1,<3.0.0)
22
22
  Requires-Dist: textual (>=6.8.0,<7.0.0)
23
- Requires-Dist: tomlkit (>=0.13.3,<0.14.0)
23
+ Requires-Dist: toml-repo (>=0.1.2,<0.2.0)
24
24
  Requires-Dist: typer (>=0.20.0,<0.21.0)
25
25
  Requires-Dist: update-checker (>=0.18.0,<0.19.0)
26
26
  Project-URL: Documentation, https://github.com/geeksville/starbash/blob/main/README.md
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "starbash"
3
- version = "0.2.4"
3
+ version = "0.2.6"
4
4
  description = "A tool for automating/standardizing/sharing astrophotography workflows."
5
5
  authors = ["Kevin Hester <kevinh@geeksville.com>"]
6
6
  readme = "README.md"
@@ -9,13 +9,13 @@ repository = "https://github.com/geeksville/starbash"
9
9
  documentation = "https://github.com/geeksville/starbash/blob/main/README.md" # FIXME provide something better
10
10
  packages = [
11
11
  { include = "starbash", from = "src" },
12
- { include = "repo", from = "src" },
13
12
  ]
14
13
 
15
14
  [tool.poetry.dependencies]
16
15
  python = ">=3.12,<3.15" # RestrictedPython doesn't yet work on 3.15
17
- tomlkit = ">=0.13.3,<0.14.0"
18
- multidict = ">=6.7.0,<7.0.0"
16
+
17
+ # Note: to use toml-repo from the local submodule rather than pypi use:
18
+ # toml-repo = {path = "toml-repo", develop = true}
19
19
  rich = ">=14.2.0,<15.0.0"
20
20
  restrictedpython = ">=8.1,<9.0"
21
21
  astropy = ">=7.1.1,<8.0.0"
@@ -23,7 +23,6 @@ platformdirs = ">=4.5.0,<5.0.0"
23
23
  typer = "^0.20.0"
24
24
  sentry-sdk = "^2.42.1"
25
25
  update-checker = "^0.18.0"
26
- requests-cache = "^1.2.1"
27
26
  doit = "^0.36.0"
28
27
  textual = "^6.8.0"
29
28
 
@@ -31,13 +30,14 @@ textual = "^6.8.0"
31
30
  # graxpert = {path = "GraXpert", extras = ["cpuonly"], develop = true}
32
31
  graxpert = {version = "^3.2.0a2", extras = ["cpuonly"]}
33
32
 
34
- # The following two libs are only needed for the experiment of running siril scripts directly...
33
+ # The following two libs are only needed for the (temporary) experiment of running siril scripts directly...
35
34
  # experimenting with siril-scripts/processing/VeraLux_HyperMetric_Stretch.py
36
- #numpy = "2.2.6"
37
- #pyqt6 = "^6.10.1"
35
+ numpy = "2.2.6"
36
+ pyqt6 = "^6.10.1"
37
+ toml-repo = "^0.1.2"
38
38
 
39
39
  [tool.poetry.group.dev.dependencies]
40
- pytest = ">=8.4.2,<9.0.0"
40
+ pytest = ">=8.4.2,<10.0.0"
41
41
  pytest-cov = "^6.0.0"
42
42
  pytest-xdist = "^3.8.0"
43
43
  pre-commit = "^4.3.0"
@@ -61,9 +61,9 @@ markers = [
61
61
  # By default, exclude slow and integration tests
62
62
  # --tb=line shows minimal tracebacks (just one line per failure)
63
63
  # --tb=short shows shorter tracebacks
64
- # -rA shows summary of all test outcomes at end
64
+ # -rfE shows summary of failed and error test outcomes at end (not passed)
65
65
  # --ignore excludes third-party test directories
66
- addopts = "-m 'not slow and not integration' -n auto --tb=short -rA --ignore=GraXpert --ignore=textual --ignore=starbash-recipes"
66
+ addopts = "-m 'not slow and not integration' -n auto --tb=short -rfE --ignore=GraXpert --ignore=textual --ignore=starbash-recipes"
67
67
 
68
68
  # Note: To limit captured output further, you can:
69
69
  # 1. Use --tb=line for minimal tracebacks
@@ -117,19 +117,22 @@ exclude = [
117
117
  [tool.ruff.lint]
118
118
  # Enable these rule sets
119
119
  select = [
120
- "E", # pycodestyle errors
121
- "F", # pyflakes
122
- "I", # isort (import sorting)
123
- "W", # pycodestyle warnings
124
- "UP", # pyupgrade
125
- "B", # flake8-bugbear
120
+ "E", # pycodestyle errors
121
+ "F", # pyflakes
122
+ "I", # isort (import sorting)
123
+ "W", # pycodestyle warnings
124
+ "UP", # pyupgrade
125
+ "B", # flake8-bugbear
126
+ "ANN", # flake8-annotations (type annotation enforcement)
126
127
  ]
127
128
 
128
129
  # Ignore specific rules that are too noisy for this codebase
129
130
  ignore = [
130
- "E501", # Line too long (handled by formatter)
131
- "B904", # Within an `except` clause, raise exceptions with `raise ... from err`
132
- "B006", # Do not use mutable data structures for argument defaults
131
+ "E501", # Line too long (handled by formatter)
132
+ "B904", # Within an `except` clause, raise exceptions with `raise ... from err`
133
+ "B006", # Do not use mutable data structures for argument defaults
134
+ "ANN401", # Dynamically typed expressions (Any) are sometimes necessary
135
+ "ANN204", # Missing return type for __init__ / __new__ / __post_init__
133
136
  ]
134
137
 
135
138
  [tool.ruff.lint.per-file-ignores]
@@ -142,14 +145,15 @@ ignore = [
142
145
  "F401", # Imported but unused
143
146
  "F841", # Local variable assigned but never used
144
147
  "PLC0415", # Import should be at top of file
148
+ "ANN", # Type annotations not required in tests
145
149
  ]
146
150
 
147
151
  [tool.basedpyright]
148
152
  # Enable import validation to catch runtime import errors at analysis time
149
153
  include = ["src"]
150
154
  exclude = ["**/__pycache__", ".venv", "build", "dist"]
151
- extraPaths = ["GraXpert"] # Include local GraXpert package for type checking
152
- typeCheckingMode = "basic" # Catches import errors without being overly strict
155
+ extraPaths = ["GraXpert", "toml-repo"] # Include local sources for type checking
156
+ typeCheckingMode = "standard" # Standard type checking: catches type errors, missing annotations, etc.
153
157
  reportMissingImports = true
154
158
  reportImportCycles = true
155
159
  reportUndefinedVariable = true
@@ -5,6 +5,12 @@ from typing import Any
5
5
 
6
6
  from rich.console import Console
7
7
 
8
+ # Configure toml_repo for starbash's conventions before any repo operations
9
+ from toml_repo import set_config_suffix, set_pkg_resource_root
10
+
11
+ set_config_suffix("starbash.toml")
12
+ set_pkg_resource_root("starbash")
13
+
8
14
  # Common type aliases for clarity
9
15
  type StageDict = dict[str, Any] # a processing stage definition from our toml
10
16
  type InputDef = dict[Any, Any] # an input definition within a stage
@@ -1,6 +1,8 @@
1
1
  import logging
2
2
  import os
3
3
  import platform
4
+ import types
5
+ from typing import Any
4
6
 
5
7
  from sentry_sdk.integrations.excepthook import ExcepthookIntegration
6
8
 
@@ -121,17 +123,22 @@ def analytics_exception(exc: BaseException) -> bool:
121
123
  class NopAnalytics:
122
124
  """Used when users have disabled analytics/crash reporting."""
123
125
 
124
- def __enter__(self):
126
+ def __enter__(self) -> "NopAnalytics":
125
127
  return self
126
128
 
127
- def __exit__(self, exc_type, exc_value, traceback):
129
+ def __exit__(
130
+ self,
131
+ exc_type: type[BaseException] | None,
132
+ exc_value: BaseException | None,
133
+ traceback: types.TracebackType | None,
134
+ ) -> bool:
128
135
  return False
129
136
 
130
- def set_data(self, key, value):
137
+ def set_data(self, key: str, value: Any) -> None:
131
138
  pass
132
139
 
133
140
 
134
- def analytics_start_span(**kwargs):
141
+ def analytics_start_span(**kwargs: Any) -> Any:
135
142
  """Start an analytics/tracing span if analytics is enabled, otherwise return a no-op context manager."""
136
143
  if analytics_allowed:
137
144
  import sentry_sdk
@@ -141,7 +148,7 @@ def analytics_start_span(**kwargs):
141
148
  return NopAnalytics()
142
149
 
143
150
 
144
- def analytics_start_transaction(**kwargs):
151
+ def analytics_start_transaction(**kwargs: Any) -> Any:
145
152
  """Start an analytics/tracing transaction if analytics is enabled, otherwise return a no-op context manager."""
146
153
  if analytics_allowed:
147
154
  import sentry_sdk
@@ -1,6 +1,7 @@
1
1
  import faulthandler
2
2
  import logging
3
3
  import sys
4
+ import types
4
5
  from importlib.metadata import version
5
6
  from pathlib import Path
6
7
  from sqlite3 import OperationalError
@@ -12,9 +13,9 @@ import typer
12
13
  from astropy.io import fits
13
14
  from rich.logging import RichHandler
14
15
  from rich.progress import track
16
+ from toml_repo import Repo, RepoManager, get_config_suffix
15
17
 
16
18
  import starbash
17
- from repo import Repo, RepoManager, repo_suffix
18
19
  from starbash.aliases import (
19
20
  Aliases,
20
21
  get_aliases,
@@ -44,7 +45,7 @@ from starbash.paths import get_user_config_dir, get_user_config_path
44
45
  from starbash.score import ScoredCandidate, score_candidates
45
46
  from starbash.selection import Selection, build_search_conditions
46
47
  from starbash.toml import toml_from_template
47
- from starbash.tool import preflight_tools
48
+ from starbash.tool import init_tools
48
49
  from starbash.windows import windows_init
49
50
 
50
51
  critical_keys = [Database.DATE_OBS_KEY, Database.IMAGETYP_KEY]
@@ -52,7 +53,7 @@ critical_keys = [Database.DATE_OBS_KEY, Database.IMAGETYP_KEY]
52
53
  force_local_recipes = False # Set to True to always use local recipes for testing
53
54
 
54
55
 
55
- def setup_logging(console: rich.console.Console):
56
+ def setup_logging(console: rich.console.Console) -> None:
56
57
  """
57
58
  Configures basic logging.
58
59
  """
@@ -129,11 +130,13 @@ def remap_expected_errors(exc: BaseException | None) -> BaseException | None:
129
130
  return None
130
131
 
131
132
  # Some OSErrors definitely don't indicate a code level bug...
132
- expected_errors = [ "Read-only file system" ]
133
+ expected_errors = [ "Read-only file system", "No space left on device" ]
134
+ # Update: I give up, keep seeing misc reports from field. I think all OSErrors should be considered
135
+ # 'not a bug' until proven otherwise.
133
136
 
134
137
  if isinstance(exc, OperationalError):
135
138
  return NonSoftwareError(f"[red]Database IO error:[/red] {exc}")
136
- elif isinstance(exc, FileNotFoundError):
139
+ elif isinstance(exc, OSError): # Was FileNotFoundError
137
140
  return NonSoftwareError(f"[red]OS error:[/red] {exc}")
138
141
  elif isinstance(exc, OSError):
139
142
  exc_str = str(exc)
@@ -197,7 +200,8 @@ class Starbash:
197
200
 
198
201
  # Initialize selection state (stored in user config repo)
199
202
  self.selection = Selection(self.user_repo)
200
- preflight_tools()
203
+ tool_prefs: dict[str, Any] = self.user_repo.get("tool", {})
204
+ init_tools(tool_prefs) # Preflight check all known tools to see if they are available
201
205
 
202
206
  def _install_local_recipes(self) -> bool:
203
207
  """Use our local github submodule for recipes during development.
@@ -294,7 +298,7 @@ class Starbash:
294
298
  def __enter__(self) -> "Starbash":
295
299
  return self
296
300
 
297
- def __exit__(self, exc_type, exc, tb) -> bool:
301
+ def __exit__(self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None) -> bool:
298
302
  from starbash import _is_test_env
299
303
  from starbash.exception import UserHandledError
300
304
 
@@ -376,7 +380,7 @@ class Starbash:
376
380
  p = Path(path)
377
381
  console = starbash.console
378
382
 
379
- repo_toml = p / repo_suffix # the starbash.toml file at the root of the repo
383
+ repo_toml = p / get_config_suffix() # the starbash.toml file at the root of the repo
380
384
  if repo_toml.exists():
381
385
  logging.debug("Using existing repository config file: %s", repo_toml)
382
386
  else:
@@ -384,7 +388,7 @@ class Starbash:
384
388
  console.print(f"Creating {repo_type} repository: {p}")
385
389
  toml_from_template(
386
390
  f"repo/{repo_type}",
387
- p / repo_suffix,
391
+ p / get_config_suffix(),
388
392
  overrides={
389
393
  "REPO_TYPE": repo_type,
390
394
  "REPO_PATH": str(p),
@@ -697,14 +701,16 @@ class Starbash:
697
701
 
698
702
  # Convert absolute path to relative path within repo
699
703
  relative_path = f.relative_to(path)
704
+ # Use POSIX-style forward slashes for consistency across platforms
705
+ relative_path_str = relative_path.as_posix()
700
706
 
701
- found = self.db.get_image(repo.url, str(relative_path))
707
+ found = self.db.get_image(repo.url, relative_path_str)
702
708
 
703
709
  # for debugging sometimes we want to limit scanning to a single directory or file
704
710
  # debug_target = "masters-raw/2025-09-09/DARK"
705
711
  debug_target = None
706
712
  if debug_target:
707
- if str(relative_path).startswith(debug_target):
713
+ if relative_path_str.startswith(debug_target):
708
714
  logging.error("Debugging %s...", f)
709
715
  found = False
710
716
  else:
@@ -730,8 +736,8 @@ class Starbash:
730
736
  for key, value in extra_metadata.items():
731
737
  headers.setdefault(key, value)
732
738
 
733
- # Store relative path in database
734
- headers["path"] = str(relative_path)
739
+ # Store relative path in database (use POSIX-style forward slashes for consistency)
740
+ headers["path"] = relative_path_str
735
741
  if self._extend_image_header(headers, f):
736
742
  image_doc_id = self.db.upsert_image(headers, repo.url)
737
743
  headers[Database.ID_KEY] = image_doc_id
@@ -753,7 +759,7 @@ class Starbash:
753
759
  # (otherwise invariants will get messed up)
754
760
  self._add_session(headers)
755
761
 
756
- def reindex_repo(self, repo: Repo, subdir: str | None = None):
762
+ def reindex_repo(self, repo: Repo, subdir: str | None = None) -> None:
757
763
  """Reindex all repositories managed by the RepoManager."""
758
764
 
759
765
  # make sure this new repo is listed in the repos table
@@ -770,20 +776,24 @@ class Starbash:
770
776
  # used to debug
771
777
 
772
778
  # Find all FITS files under this repo path
779
+ all_files = list(path.rglob("*.fit")) + list(path.rglob("*.fits"))
773
780
  for f in track(
774
- list(path.rglob("*.fit*")),
781
+ all_files,
775
782
  description=f"Indexing {repo.url}...",
776
783
  ):
777
- # progress.console.print(f"Indexing {f}...")
778
- if repo_kind == "master":
779
- # for master repos we only add to the image table
780
- self.add_image(repo, f, force=True)
781
- elif repo_kind == "processed":
782
- pass # we never add processed images to our db
783
- else:
784
- self.add_image_and_session(repo, f, force=starbash.force_regen)
785
-
786
- def reindex_repos(self):
784
+ try:
785
+ # progress.console.print(f"Indexing {f}...")
786
+ if repo_kind == "master":
787
+ # for master repos we only add to the image table
788
+ self.add_image(repo, f, force=True)
789
+ elif repo_kind == "processed":
790
+ pass # we never add processed images to our db
791
+ else:
792
+ self.add_image_and_session(repo, f, force=starbash.force_regen)
793
+ except OSError as e:
794
+ logging.error(f'Skipping "{f}" due to: [red]{e}[/red]')
795
+
796
+ def reindex_repos(self) -> None:
787
797
  """Reindex all repositories managed by the RepoManager."""
788
798
  logging.debug("Reindexing all repositories...")
789
799
 
@@ -11,7 +11,7 @@ __all__ = [
11
11
  _is_connected: bool | None = None
12
12
 
13
13
 
14
- def is_connected(host="8.8.8.8", port=53, timeout=3) -> bool:
14
+ def is_connected(host: str = "8.8.8.8", port: int = 53, timeout: int = 3) -> bool:
15
15
  """
16
16
  Host: 1.1.1.1 (Cloudflare DNS) or 8.8.8.8 (Google DNS) (it is important to not use domain names)
17
17
  Port: 53/tcp
@@ -37,7 +37,7 @@ def is_connected(host="8.8.8.8", port=53, timeout=3) -> bool:
37
37
  socket.setdefaulttimeout(old_timeout)
38
38
 
39
39
 
40
- def check_version():
40
+ def check_version() -> None:
41
41
  """Check if a newer version of starbash is available on PyPI."""
42
42
  try:
43
43
  if is_connected():
@@ -62,21 +62,21 @@ def dump_column(sb: Starbash, human_name: str, column_name: str) -> None:
62
62
 
63
63
 
64
64
  @app.command()
65
- def target():
65
+ def target() -> None:
66
66
  """List targets (filtered based on the current selection)."""
67
67
  with Starbash("info.target") as sb:
68
68
  dump_column(sb, "Target", Database.OBJECT_KEY)
69
69
 
70
70
 
71
71
  @app.command()
72
- def telescope():
72
+ def telescope() -> None:
73
73
  """List telescopes/instruments (filtered based on the current selection)."""
74
74
  with Starbash("info.telescope") as sb:
75
75
  dump_column(sb, "Telescope", Database.TELESCOP_KEY)
76
76
 
77
77
 
78
78
  @app.command()
79
- def filter():
79
+ def filter() -> None:
80
80
  """List all filters (filtered based on the current selection)."""
81
81
  with Starbash("info.filter") as sb:
82
82
  dump_column(sb, "Filter", Database.FILTER_KEY)
@@ -93,7 +93,7 @@ def master(
93
93
  str | None,
94
94
  kind_arg,
95
95
  ] = None,
96
- ):
96
+ ) -> None:
97
97
  """List all precalculated master images (darks, biases, flats)."""
98
98
  with Starbash("info.master") as sb:
99
99
  from starbash import console
@@ -146,13 +146,13 @@ def masters(
146
146
  str | None,
147
147
  kind_arg,
148
148
  ] = None,
149
- ):
149
+ ) -> None:
150
150
  """Alias for 'info master' command."""
151
151
  master(kind)
152
152
 
153
153
 
154
154
  @app.callback(invoke_without_command=True)
155
- def main_callback(ctx: typer.Context):
155
+ def main_callback(ctx: typer.Context) -> None:
156
156
  """Show user preferences location and other app info.
157
157
 
158
158
  This is the default command when no subcommand is specified.
@@ -39,7 +39,7 @@ def siril(
39
39
  help="Automatically launch Siril GUI after generating directory tree",
40
40
  ),
41
41
  ] = False,
42
- ):
42
+ ) -> None:
43
43
  """Generate Siril directory tree and optionally run Siril GUI.
44
44
 
45
45
  Creates a properly structured directory tree for Siril processing with
@@ -64,7 +64,7 @@ def siril(
64
64
 
65
65
  # Get images for this session
66
66
 
67
- def session_to_dir(src_session: SessionRow, subdir_name: str):
67
+ def session_to_dir(src_session: SessionRow, subdir_name: str) -> None:
68
68
  """Copy the images from the specified session to the subdir"""
69
69
  img_dir = output_dir / subdir_name
70
70
  img_dir.mkdir(parents=True, exist_ok=True)
@@ -196,7 +196,7 @@ def auto(
196
196
  help="Don't automatically generated master frames",
197
197
  ),
198
198
  ] = False,
199
- ):
199
+ ) -> None:
200
200
  """Automatic processing with sensible defaults.
201
201
 
202
202
  If session number is specified, processes only that session.
@@ -254,7 +254,7 @@ def auto(
254
254
  )
255
255
  def doit(
256
256
  ctx: typer.Context,
257
- ):
257
+ ) -> None:
258
258
  """(private) for developer debugging of the underlying 'doit' dependency system.
259
259
 
260
260
  You probably don't need to use this - unless you are a starbash developer.
@@ -268,7 +268,7 @@ def doit(
268
268
 
269
269
 
270
270
  @app.command()
271
- def masters():
271
+ def masters() -> None:
272
272
  """Generate master flats, darks, and biases from selected raw frames.
273
273
 
274
274
  Analyzes the current selection to find all available calibration frames
@@ -289,7 +289,7 @@ def masters():
289
289
 
290
290
 
291
291
  @app.callback(invoke_without_command=True)
292
- def main_callback(ctx: typer.Context):
292
+ def main_callback(ctx: typer.Context) -> None:
293
293
  """Process images using automated workflows.
294
294
 
295
295
  These commands handle calibration, registration, stacking, and
@@ -1,11 +1,12 @@
1
1
  import logging
2
+ from collections.abc import Generator
2
3
  from textwrap import dedent
3
4
  from typing import Annotated
4
5
 
5
6
  import typer
7
+ from toml_repo import Repo
6
8
 
7
9
  import starbash
8
- from repo import Repo
9
10
  from starbash import console
10
11
  from starbash.app import Starbash
11
12
  from starbash.paths import get_user_documents_dir
@@ -13,7 +14,7 @@ from starbash.paths import get_user_documents_dir
13
14
  app = typer.Typer(invoke_without_command=True)
14
15
 
15
16
 
16
- def repo_enumeration(sb: Starbash):
17
+ def repo_enumeration(sb: Starbash) -> dict[int, Repo]:
17
18
  """return a dict of int (1 based) to Repo instances"""
18
19
  verbose = False # assume not verbose for enum picking
19
20
  repos = sb.repo_manager.repos if verbose else sb.repo_manager.regular_repos
@@ -21,7 +22,7 @@ def repo_enumeration(sb: Starbash):
21
22
  return {i + 1: repo for i, repo in enumerate(repos)}
22
23
 
23
24
 
24
- def complete_repo_by_num(incomplete: str):
25
+ def complete_repo_by_num(incomplete: str) -> Generator[tuple[str, str], None, None]:
25
26
  # We need to use stderr_logging to prevent confusing the bash completion parser
26
27
  starbash.log_filter_level = logging.ERROR # avoid showing output while doing completion
27
28
  with Starbash("repo.complete.num", stderr_logging=True) as sb:
@@ -30,7 +31,7 @@ def complete_repo_by_num(incomplete: str):
30
31
  yield (str(num), repo.url)
31
32
 
32
33
 
33
- def complete_repo_by_url(incomplete: str):
34
+ def complete_repo_by_url(incomplete: str) -> Generator[tuple[str, str], None, None]:
34
35
  # We need to use stderr_logging to prevent confusing the bash completion parser
35
36
  starbash.log_filter_level = logging.ERROR # avoid showing output while doing completion
36
37
  with Starbash("repo.complete.url", stderr_logging=True) as sb:
@@ -42,7 +43,7 @@ def complete_repo_by_url(incomplete: str):
42
43
 
43
44
 
44
45
  @app.command()
45
- def list():
46
+ def list() -> None:
46
47
  """
47
48
  lists all repositories.
48
49
  """
@@ -64,7 +65,7 @@ def list():
64
65
  @app.callback()
65
66
  def main(
66
67
  ctx: typer.Context,
67
- ):
68
+ ) -> None:
68
69
  """
69
70
  Manage repositories.
70
71
 
@@ -88,7 +89,7 @@ def add(
88
89
  "--processed",
89
90
  help="Mark this new repository for processed output files.",
90
91
  ),
91
- ):
92
+ ) -> None:
92
93
  """
93
94
  Add a repository. path is either a local path or a remote URL.
94
95
  """
@@ -155,7 +156,7 @@ def remove(
155
156
  str,
156
157
  typer.Argument(help="Repository number or URL", autocompletion=complete_repo_by_url),
157
158
  ],
158
- ):
159
+ ) -> None:
159
160
  """
160
161
  Remove a repository by number (from list).
161
162
  Use 'starbash repo' to see the repository numbers.
@@ -182,7 +183,7 @@ def reindex(
182
183
  autocompletion=complete_repo_by_url,
183
184
  ),
184
185
  ] = None,
185
- ):
186
+ ) -> None:
186
187
  """
187
188
  Reindex a repository by number.
188
189
  If no number is given, reindex all repositories.
@@ -2,6 +2,7 @@
2
2
 
3
3
  import logging
4
4
  from collections import Counter
5
+ from collections.abc import Generator
5
6
  from pathlib import Path
6
7
  from typing import Annotated, Any
7
8
 
@@ -35,7 +36,7 @@ def get_column(sb: Starbash, column_name: str) -> Counter:
35
36
  return all_counts
36
37
 
37
38
 
38
- def complete_date(incomplete: str, column_name: str):
39
+ def complete_date(incomplete: str, column_name: str) -> Generator[tuple[str, str], None, None]:
39
40
  """calls get_column() and assumes the returned str->count object has iso datetime strings as the keys
40
41
  it merges the counts for all dates that are on the same local timezone day.
41
42
  in the returned str->count, just include the date portion (YYYY-MM-DD)."""
@@ -58,7 +59,7 @@ def complete_date(incomplete: str, column_name: str):
58
59
  yield (date, f"{count} sessions")
59
60
 
60
61
 
61
- def complete_column(incomplete: str, column_name: str):
62
+ def complete_column(incomplete: str, column_name: str) -> Generator[tuple[str, str], None, None]:
62
63
  # We need to use stderr_logging to prevent confusing the bash completion parser
63
64
  starbash.log_filter_level = logging.ERROR # avoid showing output while doing completion
64
65
  with Starbash("repo.complete.column", stderr_logging=True) as sb:
@@ -70,7 +71,7 @@ def complete_column(incomplete: str, column_name: str):
70
71
 
71
72
 
72
73
  @app.command(name="any")
73
- def clear():
74
+ def clear() -> None:
74
75
  """Remove any filters on sessions, etc... (select everything)."""
75
76
  with Starbash("selection.clear") as sb:
76
77
  sb.selection.clear()
@@ -87,7 +88,7 @@ def target(
87
88
  autocompletion=lambda incomplete: complete_column(incomplete, Database.OBJECT_KEY),
88
89
  ),
89
90
  ],
90
- ):
91
+ ) -> None:
91
92
  """Limit the current selection to only the named target."""
92
93
  with Starbash("selection.target") as sb:
93
94
  # For now, replace existing targets with this one
@@ -107,7 +108,7 @@ def telescope(
107
108
  autocompletion=lambda incomplete: complete_column(incomplete, Database.TELESCOP_KEY),
108
109
  ),
109
110
  ],
110
- ):
111
+ ) -> None:
111
112
  """Limit the current selection to only the named telescope."""
112
113
  with Starbash("selection.telescope") as sb:
113
114
  # For now, replace existing telescopes with this one
@@ -118,7 +119,7 @@ def telescope(
118
119
  do_list_sessions(sb, brief=not starbash.verbose_output)
119
120
 
120
121
 
121
- def complete_name(incomplete: str, names: list[str]):
122
+ def complete_name(incomplete: str, names: list[str]) -> Generator[str, None, None]:
122
123
  """Return typer style autocompletion from a list of string constants."""
123
124
  for name in names:
124
125
  if name.startswith(incomplete):
@@ -150,7 +151,7 @@ def date(
150
151
  autocompletion=lambda incomplete: complete_date(incomplete, Database.START_KEY),
151
152
  ),
152
153
  ] = None,
153
- ):
154
+ ) -> None:
154
155
  """Limit to sessions in the specified date range.
155
156
 
156
157
  Examples:
@@ -184,7 +185,7 @@ def date(
184
185
  do_list_sessions(sb, brief=not starbash.verbose_output)
185
186
 
186
187
 
187
- def do_list_sessions(sb: Starbash, brief: bool = False):
188
+ def do_list_sessions(sb: Starbash, brief: bool = False) -> None:
188
189
  """List sessions (filtered based on the current selection)"""
189
190
 
190
191
  sessions = sb.search_session()
@@ -308,7 +309,7 @@ def list_sessions(
308
309
  "--brief",
309
310
  help="If there are many sessions, show only a few.",
310
311
  ),
311
- ):
312
+ ) -> None:
312
313
  """List sessions (filtered based on the current selection)"""
313
314
 
314
315
  with Starbash("selection.list") as sb:
@@ -351,7 +352,7 @@ def export(
351
352
  str,
352
353
  typer.Argument(help="Directory path to export to (if it doesn't exist it will be created)"),
353
354
  ],
354
- ):
355
+ ) -> None:
355
356
  """Export the images for the indicated session number.
356
357
 
357
358
  Uses symbolic links when possible, otherwise copies files.
@@ -377,7 +378,7 @@ def export(
377
378
 
378
379
 
379
380
  @app.callback(invoke_without_command=True)
380
- def show_selection(ctx: typer.Context):
381
+ def show_selection(ctx: typer.Context) -> None:
381
382
  """List information about the current selection.
382
383
 
383
384
  This is the default command when no subcommand is specified.