Skip to content

Full update opencode big pickle - #6

Merged
Jun Aishima (JunAishima) merged 20 commits into
NSLS2:mainfrom
JunAishima:full-update-opencode-big-pickle
Oct 2, 2026
Merged

Jun Aishima (JunAishima) merged 20 commits into
NSLS2:mainfrom
JunAishima:full-update-opencode-big-pickle

Conversation

@JunAishima

Copy link
Copy Markdown
Contributor

Update to similar ways of doing things as the https://github.com/NSLS2/nsls2-workflows-template repo, such as standardizing Tiled API key handling, adding Slack messaging, and adding .env file for Prefect and Tiled config parameters.

 * match the version used at NSLS-II
 * Assisted-by: opencode:big-pickle
 * the call to this was already removed in the previous
   commit
Copilot AI lite review requested due to automatic review settings September 18, 2026 20:50

Copilot AI 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.

🟡 Changes recommended

Unresolved critical and moderate issues affect TES processing, credential exposure, notifications, and container configuration.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Updates UCAL workflows to centralize Tiled access, add Slack notifications, and configure container runtime settings.

Changes:

  • Adds shared Tiled helpers, API-key handling, and validation.
  • Adds Slack notification and dry-run support.
  • Updates Prefect mounts, Docker configuration, environment settings, and ignore rules.
File summaries
File Summary
process_tes.py Uses shared Tiled helpers for TES processing.
prefect.yaml Adds the worker application mount.
export_tools.py Removes legacy Tiled initialization.
end_of_run_workflow.py Adds notifications, dry-run handling, and API-key parameters.
end_of_run_export.py Uses shared run retrieval.
Dockerfile Updates Pixi configuration and copies .env.
data_validation.py Adds Tiled access and stream-validation tasks.
.gitignore Refreshes Python ignore patterns.
.env Defines Prefect and Tiled settings.
Review details

Suppressed comments (1)

Dockerfile:10

  • Copying .env into the image does not load it. No code calls load_dotenv on this file (the only call reads /srv/container.secret), and Docker does not source copied files, so PREFECT_LOGGING_EXTRA_LOGGERS and TILED_RETRY_ATTEMPTS are absent from the container. Set these as image/runtime environment variables or explicitly load .env before the affected libraries initialize.
COPY .env .
  • Files reviewed: 8/9 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread end_of_run_workflow.py
Comment thread process_tes.py Outdated
Comment thread end_of_run_workflow.py
Comment thread end_of_run_workflow.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 18, 2026 20:58

Copilot AI 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.

🟡 Changes recommended

Unresolved issues affect Slack notifications, API-key propagation, beamline selection, and environment loading.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (8)

Previously missed (1) — in code that hasn't changed since the last review.

end_of_run_export.py:34

  • export_all_streams still accepts beamline_acronym, and general_data_export still forwards it, but this lookup ignores it because get_run hard-codes ucal/raw. Non-ucal callers therefore export data from the wrong catalog; propagate the beamline or remove the unused parameter.

Dockerfile:10

  • Copying .env into the image does not load it into the process environment. The only dotenv call in the changed code parses /srv/container.secret, so PREFECT_LOGGING_EXTRA_LOGGERS and TILED_RETRY_ATTEMPTS from this file are ignored unless they are separately injected by the deployment.
COPY .env .

end_of_run_workflow.py:88

  • The slack decorator is defined but never applied, so none of the new Slack notifications run and failures/successes are not reported. Apply it to this flow (with @flow outermost, e.g. @flow followed by @slack) so the deployment still receives a Prefect flow.
@flow
def end_of_run_workflow(stop_doc, api_key=None, dry_run=False, reprocess_tes=False):

end_of_run_workflow.py:103

  • The same explicit api_key is also dropped before export. general_data_export and export_all_streams call get_run without it, so an invocation with a supplied key can validate one Tiled client but export through the secret-file fallback; propagate the key through the export path.
        exit_status = stop_doc.get("exit_status", "No Status")
        if exit_status == "success":
            general_data_export(uid)

end_of_run_workflow.py:100

  • The flow accepts an explicit api_key and uses it for validation and lookup, but this call drops it. process_tes consequently falls back to /srv/container.secret, so callers that provide a key can use different credentials or fail during TES processing; thread the key through this path.
    if not dry_run:
        process_tes(uid, reprocess=reprocess_tes)
        # Here is where exporters could be added

end_of_run_workflow.py:103

  • The top-level api_key is used for validation and the initial lookup, but it is not passed to either process_tes or general_data_export. Supplying a key therefore makes only part of the workflow use it; those downstream calls fall back to /srv/container.secret and can fail or access a different Tiled account. Thread the key through both downstream flow APIs and their Tiled tasks.
    if not dry_run:
        process_tes(uid, reprocess=reprocess_tes)
        # Here is where exporters could be added
        exit_status = stop_doc.get("exit_status", "No Status")
        if exit_status == "success":
            general_data_export(uid)

end_of_run_workflow.py:45

  • The failure handler starts after the Tiled lookup, so an authentication/network/UID error from get_run escapes without any Slack failure notification. Include this lookup in the guarded path and use a fallback when scan metadata cannot be fetched, so the notifier still reports the original failure.
        run = get_run(uid, api_key=api_key)
        scan_id = run.start["scan_id"]

process_tes.py:32

  • The flow accepts an explicit api_key and passes it through validation, but this nested flow calls get_catalog() and get_run() without that key, forcing both tasks to fall back to /srv/container.secret. A caller supplying a valid key can therefore still fail during TES processing when that mounted secret is unavailable or differs; add an api_key parameter to process_tes and propagate it to both tasks and this call.
    catalog = get_catalog()
    run = get_run(uid)
  • Files reviewed: 8/9 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread process_tes.py Outdated
Copilot AI review requested due to automatic review settings September 18, 2026 21:43

Copilot AI 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.

🟡 Changes recommended

Unresolved export signature mismatches and API-key/error-handling issues block safe approval.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (6)

end_of_run_export.py:34

  • get_run is defined with only (uid, api_key=None), so every invocation of this task raises TypeError: got an unexpected keyword argument 'dry_run' before any export can run. Remove this unsupported argument; dry-run handling already belongs to the export operations below.
    run = get_run(uid, api_key=api_key, dry_run=dry_run)

end_of_run_export.py:47

  • The new dry-run branches skip the XDI/HDF5 writes, but create_export_path(base_export_path) above still creates a directory before reaching them. Consequently dry_run=True mutates the proposal filesystem; guard base-directory creation as well if dry-run is intended to perform no writes.
    if not dry_run:
        create_export_path(xdi_export_path)
        exportToXDI(xdi_export_path, run)
    else:
        logger.info(f"dry_run: not exporting to {xdi_export_path}")

end_of_run_workflow.py:63

  • traceback.format_exception_only is called with only the exception instance; the supported Python runtimes require the exception type and value, so this error handler raises another TypeError and suppresses the original failure/Slack notifications. Pass both type(e) and e.
            tb = traceback.format_exception_only(e)

end_of_run_workflow.py:45

  • This Tiled lookup is outside the try that emits failure notifications. If authentication, connectivity, or UID lookup fails, the flow raises before any mon-prefect/mon-prefect-ucal failure message is sent, which defeats the new failure-alerting path for a common failure mode. Include this setup in the guarded error-handling path (while preserving the scan ID fallback).
        run = get_run(uid, api_key=api_key)
        scan_id = run.start["scan_id"]

process_tes.py:32

  • process_tes still exposes beamline_acronym, but these calls now use get_catalog/get_run, whose catalog path is hard-coded to ucal; passing any other beamline silently processes the wrong catalog. Either propagate the beamline through the data-access helpers or remove this parameter from the public flow.
    catalog = get_catalog()
    run = get_run(uid)

process_tes.py:32

  • The parent flow accepts an explicit api_key, but TES processing now calls both Tiled helpers without it; they therefore fall back to /srv/container.secret. A caller using an explicit key, or a worker without that mounted secret, can pass validation/export setup and then fail here. Add api_key to process_tes and pass it to both helper calls, then forward it from the parent flow.
    catalog = get_catalog()
    run = get_run(uid)
  • Files reviewed: 8/9 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread end_of_run_export.py Outdated
Comment thread end_of_run_workflow.py Outdated
Comment thread end_of_run_workflow.py Outdated
 * use dry_run to get around tasks that write files
 * move getting run inside try block so that exceptions are handled
   during Slack handling
 * minor fixes
Copilot AI review requested due to automatic review settings September 18, 2026 22:12

Copilot AI 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.

Comment thread end_of_run_workflow.py
Comment thread process_tes.py Outdated
Copilot AI review requested due to automatic review settings September 21, 2026 16:03

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Unresolved moderate issues affect configuration, beamline selection, credentials, notifications, API compatibility, and dry-run behavior.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
Resolved since last review (3)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Slack notification failures incorrectly fail workflow

end_of_run_workflow.py:60

This success notification is inside the same try block as the workflow. If Slack is unavailable after processing/export succeeds, notify raises, the handler sends failure notifications, and the flow is marked failed; a failure-notification error can also mask the original exception. Treat Slack sends as isolated best-effort operations so notification outages cannot change workflow status or hide the underlying error.

Copilot AI review requested due to automatic review settings September 21, 2026 16:11

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Moderate issues remain in flow credential handling and dry-run behavior.

Review effort: Lite
Findings: None

Resolved since last review (1)

Copilot AI review requested due to automatic review settings September 21, 2026 17:26

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Resolve API-key persistence exposure and ensure dry runs do not create processing artifacts.

Review effort: Lite
Findings: None

 * lots of calls to code that makes filesystem changes, so
   just bypass the module entirely
Copilot AI review requested due to automatic review settings September 23, 2026 15:48

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Address the undeclared python-dotenv dependency and prevent Tiled API keys from being persisted as flow parameters.

Review effort: Lite
Findings: None

 * has always been brought in as a dependency for something else, but
  just declare it
Copilot AI review requested due to automatic review settings September 23, 2026 15:56

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Four unresolved moderate findings must be addressed before approval.

Review effort: Lite
Findings: None

@JunAishima

Copy link
Copy Markdown
Contributor Author

fixes #5

@AbbyGi Abby Giles (AbbyGi) 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.

Looks good. Simple comment removal and a general comment

Comment thread data_validation.py Outdated
Comment thread data_validation.py Outdated
Comment thread data_validation.py Outdated
Comment thread end_of_run_workflow.py
Comment on lines +14 to +17
SLACK_GENERAL = "mon-prefect"
SLACK_BLUESKY = "mon-bluesky"
SLACK_UCAL = "mon-prefect-ucal"
SLACK_PROGRAM = "mon-prefect-spec"

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.

I think I like how all these variables are set up at the top. Maybe we can include this in the template and generalize SLACK_UCAL to something like SLACK_BL_ES? This would make it easier to check if the slack channels are set up correctly when adding new beamlines.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this general method of handling the exceptions that occur within the Slack messaging is good, but I want to go over this before the end of the cycle, move into template, and propagate to the other workflow repos.

Do you mean we should just keep SLACK_UCAL should be replaced with SLACK_BL_ES for all repos? that does make sense.

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.

Sounds good with the exception handling. Up to you if we want to start replacing SLACK_UCAL now or wait until we roll out the exception handling, but the template should definitely pull these variables out and use something like SLACK_BL_ES

Co-authored-by: Abby Giles <35899293+AbbyGi@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 30, 2026 20:26
Co-authored-by: Abby Giles <35899293+AbbyGi@users.noreply.github.com>
Co-authored-by: Abby Giles <35899293+AbbyGi@users.noreply.github.com>

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Resolve the Docker environment loading issue and prevent Tiled credentials from being serialized as Prefect flow parameters.

Review effort: Lite
Findings: None

Copilot AI lite review requested due to automatic review settings September 30, 2026 20:30

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Address the API-key exposure risk and ensure .env settings are loaded or provided through the runtime environment.

Review effort: Lite
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Copied .env is not loaded into the runtime environment

Dockerfile:10

Copying .env into the image does not load its values into the process environment. The only load_dotenv call in this PR reads /srv/container.secret, so PREFECT_LOGGING_EXTRA_LOGGERS and TILED_RETRY_ATTEMPTS from this file will not be applied at runtime (and Tiled is imported before that call). Set these through the deployment/container environment or explicitly load .env before importing the consumers.

@JunAishima
Jun Aishima (JunAishima) merged commit 98a1aa6 into NSLS2:main Oct 2, 2026
1 check passed
@JunAishima
Jun Aishima (JunAishima) deleted the full-update-opencode-big-pickle branch October 2, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants