Skip to content

feat(doctor): add readiness checks - #182

Open
djgormley wants to merge 3 commits into
CHIMEFRB:mainfrom
WVURAIL:djg/feat-doctor
Open

feat(doctor): add readiness checks#182
djgormley wants to merge 3 commits into
CHIMEFRB:mainfrom
WVURAIL:djg/feat-doctor

Conversation

@djgormley

@djgormley djgormley commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Adds human and JSON readiness checks for configuration, server responses, certificates, Minoc, and Luskan without printing sensitive values.

@djgormley
djgormley requested a review from tjzegmott August 25, 2026 17:31
@djgormley
djgormley marked this pull request as ready for review August 25, 2026 17:31
@djgormley djgormley self-assigned this Aug 25, 2026
@djgormley djgormley added the FEATURE New Feature Request label Aug 25, 2026
@djgormley djgormley changed the title feat: add readiness checks feat(doctor): add readiness checks Aug 25, 2026
@CHIMEFRB CHIMEFRB deleted a comment from codecov-commenter Aug 27, 2026

@tjzegmott tjzegmott left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments I wrote last week. I haven't been able to get back to this, but wanted to post what I had so far.

Comment thread dtcli/doctor.py
Comment on lines +28 to +35
def _load_config() -> Optional[Dict[str, Any]]:
"""Load the configuration without printing its contents."""
try:
with open(CONFIG) as stream:
config = yaml.safe_load(stream)
except (OSError, UnicodeError, yaml.YAMLError):
return None
return config if isinstance(config, dict) else None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A function to read the config already exists in config.py, it is called procure. It returns the entire dictionary, or if a key is given, the value of that key only. The specific exception checks can be added there.

Comment thread dtcli/doctor.py
Comment on lines +38 to +57
def _check_config() -> Tuple[Dict[str, Any], Optional[Dict[str, Any]]]:
"""Load and validate the configuration."""
config = _load_config()
if config is None:
return _result(False, "Configuration could not be loaded."), None

server = config.get("server")
certificate = config.get("vospace_certfile")
site = config.get("site")
root_mounts = config.get("root_mounts")
parsed = urlparse(server) if isinstance(server, str) else None
valid_server = bool(parsed and parsed.scheme in ("http", "https") and parsed.netloc)
valid_mount = (
isinstance(site, str)
and isinstance(root_mounts, dict)
and isinstance(root_mounts.get(site), str)
)
if not valid_server or not isinstance(certificate, str) or not valid_mount:
return _result(False, "Configuration is missing required values."), None
return _result(True, "Configuration is ready."), config

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be broken up: the validation of the config file should exist in config.py. Moulding that into the shape that doctor needs can remain here.

Comment thread dtcli/doctor.py
Comment on lines +63 to +66
response = requests.get(
server.rstrip("/") + "/query/dataset/scopes",
timeout=REQUEST_TIMEOUT,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a health check endpoint that might be better for this, it returns the following json:

❯ http get https://frb.chimenet.ca/datatrail/health/check
╭────────────────────────┬────────────────────────────────────────────╮
│ status                 │ ok                                         │
│                        │ ╭──────────┬─────────────────────────────╮ │
│ checks                 │ │          │ ╭──────────────────┬──────╮ │ │
│                        │ │ database │ │ status           │ ok   │ │ │
│                        │ │          │ │ response_time_ms │ 7.58 │ │ │
│                        │ │          │ ╰──────────────────┴──────╯ │ │
│                        │ │          │ ╭──────────────────┬──────╮ │ │
│                        │ │ api      │ │ status           │ ok   │ │ │
│                        │ │          │ │ response_time_ms │ 8.25 │ │ │
│                        │ │          │ ╰──────────────────┴──────╯ │ │
│                        │ ╰──────────┴─────────────────────────────╯ │
│ timestamp              │ 2026-08-31T19:57:21.140372+00:00           │
│ total_response_time_ms │ 8.25                                       │
╰────────────────────────┴────────────────────────────────────────────╯

@djgormley

Copy link
Copy Markdown
Contributor Author

Some comments I wrote last week. I haven't been able to get back to this, but wanted to post what I had so far.

Dope thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FEATURE New Feature Request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants