Skip to content

Enforce mutually exclusive api_key and limited_access_key inputs in NucleusClient and fix all remaining Sphinx doc build warnings#457

Open
edwinpav wants to merge 4 commits intomasterfrom
edwinpav/de-7532-mutually-exclusive-api-keys
Open

Enforce mutually exclusive api_key and limited_access_key inputs in NucleusClient and fix all remaining Sphinx doc build warnings#457
edwinpav wants to merge 4 commits intomasterfrom
edwinpav/de-7532-mutually-exclusive-api-keys

Conversation

@edwinpav
Copy link
Copy Markdown
Contributor

@edwinpav edwinpav commented Apr 14, 2026

Summary

Resolves https://linear.app/scale-epd/issue/DE-7532 and https://linear.app/scale-epd/issue/DE-7605

Enforces mutually exclusive authentication for the Nucleus Python SDK: callers must use either a standard Scale API key (api_key / NUCLEUS_API_KEY) or a Nucleus-only limited access key (limited_access_key), not both. This release also includes doc / Sphinx fixes, a small import cleanup, and v0.17.14.

TODO:

  • deploy new version

Behavior changes

  • NucleusClient: Raises ValueError if both credential paths apply (e.g. both parameters, or NUCLEUS_API_KEY in the environment together with limited_access_key).
  • Connection: Raises ValueError if Basic Auth and x-limited-access-key would both be sent (defense in depth).
  • CLI (nu): Raises if both NUCLEUS_API_KEY and NUCLEUS_LIMITED_ACCESS_KEY are set.
  • Pytest (conftest.py): Raises if both NUCLEUS_PYTEST_API_KEY and NUCLEUS_PYTEST_LIMITED_ACCESS_KEY are set.
  • scripts/load_test.py: Raises if both api_key and limited_access_key resolve from flags/env.

Migration: Anyone who previously passed both keys (or had NUCLEUS_API_KEY set while using limited_access_key) must pick one mode and unset the other.

Documentation & Sphinx

  • NucleusClient: Class docstring updated (auth rules, examples, auth doc link).
  • Methods: Docstring fixes and clarity (list_jobs, get_job, get_slice, delete_slice, download_pointcloud_task, make_request, valid_dirname, create_dataset metadata schema, create_launch_model / create_launch_model_from_dir with .. note:: blocks and directory example).
  • docs/conf.py: Dropped inherited-members from autoapi (avoids pydantic BaseModel doc RST issues); added suppress_warnings = ["toc.not_included"] for orphan autoapi pages.

Remaining 13 api doc build warnings resolved

After (left) vs Before (right) docs

nucleusclient constructor list_jobs create_launch_model create_launch_model_from_dir get_slice delete_slice make_request valid_dirname

Other

  • CHANGELOG.md: Entry for 0.17.14.
  • pyproject.toml: Version 0.17.14.

Greptile Summary

This PR enforces mutually exclusive authentication (api_key vs limited_access_key) across NucleusClient, Connection, the CLI, conftest, and the load-test script, and includes a batch of Sphinx/docstring fixes. The validation logic is consistent and correct — the effective_basic_key computation in NucleusClient.__init__ correctly accounts for the NUCLEUS_API_KEY environment variable, and the defense-in-depth check in Connection protects direct callers who bypass NucleusClient.

Confidence Score: 5/5

Safe to merge — validation logic is correct across all entry points, no P0/P1 issues found.

All remaining findings are P2 style suggestions (exception type inconsistency between CLI and SDK layers). The core mutual-exclusion logic is correctly implemented, the env-var fallback is handled properly, and the defense-in-depth check in Connection is appropriate.

No files require special attention.

Important Files Changed

Filename Overview
nucleus/init.py Core validation added: effective_basic_key computed from api_key or NUCLEUS_API_KEY env var; ValueError raised if limited_access_key is also present. Docstrings corrected throughout (get_job copy-paste, get_slice/delete_slice ID type, make_request param name, create_dataset schema, list_jobs phantom param).
nucleus/connection.py Defense-in-depth check added: raises ValueError if both api_key and x-limited-access-key header are present, guarding direct Connection usage outside NucleusClient.
cli/client.py Pre-flight check for both NUCLEUS_API_KEY and NUCLEUS_LIMITED_ACCESS_KEY being set; raises RuntimeError before delegating to NucleusClient.
conftest.py CLIENT fixture changed to raise RuntimeError when both pytest API keys are set, replacing the old behavior of silently passing both to NucleusClient.
scripts/load_test.py Added mutually-exclusive guard after the existing at-least-one check; raises RuntimeError before NucleusClient is called.
docs/conf.py Removed inherited-members from autoapi options to suppress pydantic BaseModel RST warnings; added suppress_warnings for orphan autoapi pages.
pyproject.toml Version bumped from 0.17.13 to 0.17.14.
CHANGELOG.md New 0.17.14 entry documenting the mutual-exclusion change and docstring fixes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[NucleusClient init] --> B{api_key arg provided?}
    B -- yes --> C[effective = api_key arg]
    B -- no --> D[effective = NUCLEUS_API_KEY env var]
    C --> E{limited_access_key AND effective both truthy?}
    D --> E
    E -- yes --> F[raise ValueError - mutually exclusive]
    E -- no --> G{api_key is None AND limited_access_key?}
    G -- yes --> H[self.api_key = None, add limited-access header]
    G -- no --> I[self.api_key from _set_api_key, no header]
    H --> J[Connection init]
    I --> J
    J --> K{both api_key AND limited-access header present?}
    K -- yes --> L[raise ValueError - defense in depth]
    K -- no --> M{neither auth present?}
    M -- yes --> N[raise NoAPIKey]
    M -- no --> O[Connection ready]
Loading

Fix All in Cursor Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: cli/client.py
Line: 17-20

Comment:
**Exception type inconsistency with `NucleusClient`**

The CLI raises `RuntimeError` here, while `NucleusClient.__init__` raises `ValueError` for the same condition. Callers who catch the exception by type (e.g. test harnesses or wrapper scripts) will need to handle two different exception types depending on whether the check fires at the CLI layer or the SDK layer. Consider raising `ValueError` to match the SDK convention.

```suggestion
            raise ValueError(
                "Both NUCLEUS_API_KEY and NUCLEUS_LIMITED_ACCESS_KEY are set. "
                "Please set only one."
            )
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Undo removal of unused imports" | Re-trigger Greptile

@edwinpav edwinpav self-assigned this Apr 14, 2026
@edwinpav edwinpav changed the title Enforce mutually exclusive api_key and limited_access_key in NucleusClient Enforce mutually exclusive api_key and limited_access_key inputs in NucleusClient Apr 14, 2026
Comment thread nucleus/__init__.py
to retrieve your API keys. **Only** optional when ``limited_access_key`` is provided.
api_key: One of ``api_key`` or ``limited_access_key`` must be provided; you cannot pass
both. For standard Scale API key authentication, pass the key here. Follow `this guide
<https://scale.com/docs/api-reference/authentication>`_ to retrieve API keys. If you omit
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.

Update link because the old one is outdated and returns a 404 now

@edwinpav edwinpav changed the title Enforce mutually exclusive api_key and limited_access_key inputs in NucleusClient Enforce mutually exclusive api_key and limited_access_key inputs in NucleusClient and fix all remaining Sphinx doc build warnings Apr 14, 2026
@edwinpav edwinpav requested a review from a team April 14, 2026 21:07
@edwinpav edwinpav marked this pull request as ready for review April 14, 2026 21:07
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.

1 participant