Skip to content

Make sync-experiment Tiled-based (rebased) - #307

Open
Nathanael (Nate) Maytan (nmaytan) wants to merge 32 commits into
NSLS2:mainfrom
nmaytan:sync_experiment_tiled-on-main
Open

Nathanael (Nate) Maytan (nmaytan) wants to merge 32 commits into
NSLS2:mainfrom
nmaytan:sync_experiment_tiled-on-main

Conversation

@nmaytan

@nmaytan Nathanael (Nate) Maytan (nmaytan) commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

See #234 for previous notes/context. This rebased PR supersedes the old one. It includes some additional fixes and improvements.

Some work is still needed after the rebase:

  • The Redis client/db used for API key store needs to be made to use secure Redis, and also needs a dedicated db index (or maybe not depending how prefixing works in Redis now?)
  • We should make secure Redis default to True? Or even better, remove this flag completely and only use secure Redis?
  • Normalized beamline vs not for Redis location and prefix? Get on the same page about prefixing in general (and greedy RedisJSONDict ingestion)
  • The host resolver needs to be retooled to be more robust
  • Check that pixi has the right requirements for the new version
  • Add Redis parameters to doctstrings
  • Double check that I strung the Redis parameters through everywhere
  • Possibly reorder the argsparse section, as well as the added function arguments

And some things to callout:

  • I added the beamline TLA to the Redis location and prefix for better disambiguation - avoids endstation/endstation and endstation/beamline naming conflicts (multiple beamlines may have an ARPES endstation, for example)
    • I had done this for the key prefixes in the previous PR, but the rebase is almost all Redis changes, so I point it out explicitly here
  • I changed the enable-ssl flag to capitalized -S, since -s is used in the new version for an important function (switching between authorized proposals)

I also updated the pixi-.lock after dependency changes:

$ pixi lock
[...]
✔ Updated lock file
Environment: default
  - P ldap3           2.9.1
  - P pyasn1          0.6.4

Environment: dev
  - P ldap3           2.9.1
  - P pyasn1          0.6.4
  + P pytest-asyncio  1.4.0

Environment: py311
  - P ldap3           2.9.1
  - P pyasn1          0.6.4
  + P pytest-asyncio  1.4.0

Environment: py312
  - P ldap3           2.9.1
  - P pyasn1          0.6.4
  + P pytest-asyncio  1.4.0

Environment: py313
  - P ldap3           2.9.1
  - P pyasn1          0.6.4
  + P pytest-asyncio  1.4.0

And hardened the decisions made about when to clear the active API key, or retain it and insist upon successful revocation:

Situation HTTP / Result Redis Key Operation
No key stored No request Unchanged / empty Continues
Valid key, revocation succeeds 204 Cleared Continues
Key expired before context creation 401 Cleared Continues
Key expired before which_api_key() 401 Cleared Continues
Key manually deleted before validation 401 Cleared Continues
Valid key lacks revoke scope 401 from revoke Retained Aborts
Revocation explicitly forbidden 403 Retained Aborts
Key disappears after validation 404 from revoke Cleared Continues
Network error or timeout Request error Retained Aborts
Tiled server error 5xx Retained Aborts
Unexpected context creation error Any other error Retained Aborts
Redis clearing fails after revocation Redis error Possibly retained Aborts; retry later detects unusable key
logout() or close() fails Cleanup error Already cleared or retained based on preceding result Aborts

Experiments (proposals) are "authorized". Then, one of the authorized
experiments is "activated". Multiple proposals may be authorized at the
same time, but only one proposal can be active at a time.

This should make more clear what the tool is doing, and how the policy
works, as opposed to before (authorize/activate vs activate/select or
activate/load).

Includes some other minor word fixes.
Copilot AI balanced review requested due to automatic review settings October 8, 2026 01:39

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

CLI failures, inconsistent Redis handling, and insecure API-key transport and revocation block approval.

9 open findings
What changed in this PR

Migrates beamline experiment authentication from LDAP to Tiled, continuing #234’s multi-proposal workflow.

Changes:

  • Adds proposal authorization, switching, and unsync operations.
  • Introduces Redis-backed API-key storage and revocation.
  • Updates beamline/endstation namespaces and CLI options.
File Description
nslsii/​sync_experiment/​sync_experiment.py Implements Tiled authentication, proposal workflows, and Redis integration.
nslsii/​sync_experiment/​__init__.py Exports the new sync, unsync, and switching APIs.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment thread nslsii/sync_experiment/sync_experiment.py
Comment on lines +94 to +98
apikey_redis_client = redis.Redis(
host=f"info.{normalized_beamline}.nsls2.bnl.gov",
port=6379,
db=15,
decode_responses=True,

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.

This is known and mentioned in the OP already.

Comment thread nslsii/sync_experiment/sync_experiment.py
Comment thread nslsii/sync_experiment/sync_experiment.py Outdated
Comment thread nslsii/sync_experiment/sync_experiment.py Outdated
return proposal_data
md_redis_client = open_redis_client(
redis_ssl=redis_ssl,
redis_location=redis_location,

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.

This is one of the things I needed to dig into from the prefix change. However, the hostname list in the utils should be removed, and the resolver needs to be made more robust than its current naive sub-string check.

Comment thread nslsii/sync_experiment/sync_experiment.py Outdated
Comment thread nslsii/sync_experiment/sync_experiment.py Outdated
Comment thread nslsii/sync_experiment/sync_experiment.py
Copilot AI balanced review requested due to automatic review settings October 8, 2026 03:01

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 nslsii/sync_experiment/sync_experiment.py Outdated
Comment thread nslsii/sync_experiment/sync_experiment.py
Comment thread nslsii/sync_experiment/sync_experiment.py Outdated
Comment thread nslsii/sync_experiment/sync_experiment.py
Comment thread nslsii/sync_experiment/sync_experiment.py Outdated
Copilot AI balanced review requested due to automatic review settings October 8, 2026 04:15

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

Redis normalization causes Tiled profile selection to reject valid SST beamline profiles.

3 open findings
6 resolved since last review
Previously missed (2)

In code that hasn't changed since last review

Medium severity Preserve beamline for Tiled profile lookup

nslsii/​sync_experiment/​sync_experiment.py:115

For beamline='sst1' with an sst1 Tiled profile and no endstation, this passes sst to profile lookup and raises Cannot find Tiled profile, ignoring the configured profile. Revocation uses the same normalized name. Preserve the requested beamline for Tiled profile selection in both authentication and revocation, and pass the Redis namespace separately.

Medium severity Restore successful-response error payload handling

nslsii/​sync_experiment/​sync_experiment.py:659

The removed validate_proposal handled an error_message inside the proposal payload even when HTTP status was successful. That response now reaches proposal['instruments'] and raises KeyError, hiding the server's explanation. Restore the error-payload check before accessing proposal fields.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

tiled_context.revoke_api_key(first_eight)


def revoke_active_api_key(redis_client, beamline, endstation):
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.

2 participants