Skip to content

fix(cli): prevent adb config from crashing or creating empty configs#679

Open
ad-claw000 wants to merge 32 commits into
developfrom
fix/370-adb-config-create-empty-file
Open

fix(cli): prevent adb config from crashing or creating empty configs#679
ad-claw000 wants to merge 32 commits into
developfrom
fix/370-adb-config-create-empty-file

Conversation

@ad-claw000
Copy link
Copy Markdown
Contributor

@ad-claw000 ad-claw000 commented May 19, 2026

Closes #370.

This PR fixes multiple issues reported in #370 that caused adb config to break:

  • adb config create crashed on NoneType when no name was provided in non-interactive mode.
  • adb config activate wrote an empty dictionary {} if the config file didn't exist, which resulted in a broken JSON structure that corrupted future executions with a KeyError: 'active'.
  • Updated get_configurations to use .get('active') to fail gracefully if the config file was already corrupted by the above bug.

Additionally:

  • Adds the external_network marker to the SPARQL test to replace a problematic pytest collection hook, ensuring cloud tests can be properly filtered out in CI environments lacking credentials.
  • Fixes RangeType.TIME formatting logic to correctly use modulo 60 for minutes, preventing cumulative minute totals.

@ad-claw000 ad-claw000 self-assigned this May 19, 2026
@ad-claw000 ad-claw000 requested a review from luisremis May 19, 2026 05:08
Closes #370
- Fixed `adb config create` crashing on NoneType when no name is provided in non-interactive mode.
- Fixed `adb config activate` writing an empty dictionary if the config file does not exist, which previously led to an empty config file that corrupted future executions with KeyError.
- Updated `get_configurations` to safely retrieve 'active' key.
@ad-claw000 ad-claw000 force-pushed the fix/370-adb-config-create-empty-file branch from fdac0e2 to 53883e2 Compare May 20, 2026 01:05
Copy link
Copy Markdown
Contributor Author

@ad-claw000 ad-claw000 left a comment

Choose a reason for hiding this comment

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

Applied autopep8 formatting to the new log messages to fix the pre-commit CI failure.

Copilot AI review requested due to automatic review settings May 21, 2026 07:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to harden the adb config CLI workflow to avoid crashes and config-file corruption (as described in #370), primarily by making config reading/writing more defensive when config files are missing or malformed. It also includes a number of formatting-only changes, updates the test container setup to use ephemeral host ports, and adds a new unit test module for aperturedb.Images.

Changes:

  • Make adb config handling more resilient to missing/corrupted config files (e.g., avoid KeyError on missing "active", prevent writing empty configs on activation failures, and improve non-interactive create validation).
  • Update test docker-compose + runner script to use random host ports and discover them via docker compose port.
  • Add test/test_Images.py and apply formatting changes across tests/examples/library code.

Reviewed changes

Copilot reviewed 17 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
aperturedb/cli/configure.py Implements the CLI robustness fixes for create/activate/get_key and makes config parsing more defensive.
test/run_test_container.sh Discovers runtime ports from docker-compose and returns GATEWAY:PORT for the started instance.
test/docker-compose.yml Switches to ephemeral host port mappings (0) for lenz/nginx services.
test/test_Images.py Adds unit tests for rotate/resolve and basic Images behaviors using mocks.
test/test_Stats.py Formatting-only change to assertion style.
test/test_Server.py Formatting-only change to function call and assertion formatting.
test/test_Datawizard.py Formatting-only f-string spacing change.
test/conftest.py Formatting-only change to long error message construction.
aperturedb/Utils.py Refactors long HTML string building for readability; minor formatting change in percentage calculation.
aperturedb/Query.py Adjusts time formatting logic and formatting style.
aperturedb/ParallelQuerySet.py Splits long log messages for readability.
aperturedb/ParallelQuery.py Splits long log message for readability.
aperturedb/Descriptors.py Docstring clarifications and parameter documentation updates.
aperturedb/CSVWriter.py Improves assertion message formatting for readability.
aperturedb/CommonLibrary.py Improves assertion formatting/readability for required configuration fields.
examples/loading_with_models/get_tl_embeddings.py Formatting-only f-string spacing change.
examples/CelebADataKaggle.py Splits a long f-string assignment for readability.
.github/workflows/pr.yaml Extends cleanup step to remove prior test logs as well as db artifacts.
.github/workflows/checks.yml Bumps pre-commit workflow Python version to 3.12.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread aperturedb/cli/configure.py
Comment thread aperturedb/cli/configure.py
Comment thread test/test_Images.py Outdated
@ad-claw000
Copy link
Copy Markdown
Contributor Author

Addressed the review comments:

  • Fixed get_active_config() to explicitly check for falsy active before invoking .startswith().
  • Updated get_key() to determine and use the correct config collection (global vs local) based on where the name is found, avoiding KeyError and writing user keys into the right file.
  • Fixed the flaky test_resolve_rotate assertion to allow for 9 or 10 to tolerate floating point differences across platforms.
  • Fixed a bug where activate or get_key could crash with an unhandled FileNotFoundError if the global config file does not exist, and an UnboundLocalError in create when reading an empty corrupted config.

See commits 3d938b3 and c421064 for the fixes.

Copilot AI review requested due to automatic review settings May 21, 2026 15:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 4 comments.

Comment thread aperturedb/cli/configure.py
Comment thread aperturedb/Descriptors.py Outdated
Comment thread aperturedb/Descriptors.py
Comment thread aperturedb/Query.py Outdated
@ad-claw000
Copy link
Copy Markdown
Contributor Author

I will address the 4 unresolved review comments:

  1. I will preserve the active key when rewriting the global config in get_key.
  2. I will fix the constraints docstring to match the Constraints object.
  3. I will update find_similar to return the parsed entities.
  4. I will revert the CLIP time range formatting changes in Query.get_specific and move them to a separate PR.

Copilot AI review requested due to automatic review settings May 23, 2026 04:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

aperturedb/cli/configure.py:132

  • get_active_config can still crash with a KeyError when active is set but the referenced config name is missing from both all_configs["local"] and all_configs["global"], or when "global" is not present. Consider explicitly checking for membership in both scopes and exiting with a helpful message (similar to the not active case) instead of indexing directly.
    if active.startswith("env:"):
        return all_configs["environment"][active[4:]]
    else:
        return all_configs["local"][active] if "local" in all_configs and active in all_configs["local"] \
            else all_configs["global"][active]

aperturedb/cli/configure.py:447

  • In the global-config fallback, this mutates gc by unconditionally setting target_configs["active"] = ga and may write it back as JSON null if the global config file was missing an active key. Consider avoiding writing the active field here unless you’re intentionally changing it (e.g., don’t set it when ga is falsy, or work on a copy) so adb config get-key doesn’t accidentally alter activation state while just adding a user key.
        target_configs = configs
        target_path = config_path
        if name not in configs and name in gc:
            target_configs = gc
            target_configs["active"] = ga
            target_path = global_config_path

        if user is None:
            key_user = target_configs[name].username
        else:
            key_user = user

        if target_configs[name].has_user_keys():
            user_key = target_configs[name].get_user_key(key_user)

        if user_key is None:
            conn = __create_connector(target_configs[name])

            user_key = keys.generate_user_key(conn, key_user)
            target_configs[name].add_user_key(key_user, user_key)
            _write_config(target_path, target_configs)

Comment thread aperturedb/cli/configure.py
Comment thread aperturedb/Descriptors.py Outdated
Comment thread aperturedb/Descriptors.py Outdated
Copilot AI review requested due to automatic review settings May 24, 2026 20:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread test/test_SPARQL.py
- Raised typer.Exit(code=2) in get_key exception handlers (FileNotFoundError, JSONDecodeError) to ensure a non-zero exit code when config files are corrupted or missing.
- Reverted CLIP time range formatting in Query.get_specific to use f-strings instead of .format(), as requested by reviewer to move this refactor to a separate PR.
@ad-claw000
Copy link
Copy Markdown
Contributor Author

Addressed the remaining actionable review comments:

  • Raised typer.Exit(code=2) inside get_key's FileNotFoundError / JSONDecodeError exceptions to prevent silent continuation with exit code 0 when config files are corrupted or missing.
  • Reverted the CLIP time range formatting changes in Query.get_specific back to f-strings as requested, so they can be moved to a separate PR.

See commit d0eb7f9.

Copilot AI review requested due to automatic review settings May 25, 2026 05:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread aperturedb/Query.py Outdated
Copilot AI review requested due to automatic review settings May 25, 2026 06:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread aperturedb/cli/configure.py Outdated
Comment thread aperturedb/Query.py
Copilot AI review requested due to automatic review settings May 25, 2026 11:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comment thread test/test_SPARQL.py
Copilot AI review requested due to automatic review settings May 26, 2026 20:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

test/test_SPARQL.py:66

  • After removing the pytest_collection_modifyitems hook, this module no longer applies the external_network marker to the SPARQL tests/fixtures. That means CI can’t reliably filter these network-dependent tests out (and they may run unexpectedly). Add an explicit marker (e.g., pytestmark = pytest.mark.external_network at module scope or @pytest.mark.external_network on test_sparql / the load_cookbook fixture) so the marker is always present.

# Test functions that depends on the setup


@pytest.fixture
def sparql(db):
    sparql = SPARQL(db)

Comment thread aperturedb/cli/configure.py Outdated
Copilot AI review requested due to automatic review settings May 27, 2026 05:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

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.

adb config create leads to an empty file in local config.

3 participants