Skip to content

Conversation

@jairad26
Copy link
Contributor

@jairad26 jairad26 commented Nov 26, 2025

Description of changes

Summarize the changes made by this PR.

  • Improvements & Bug fixes
    • Since chroma cloud splade & qwen are both authenticated using the same api key as Chroma Cloud, as a fallback we can iterate through the available clients and use the first api key found when the host is api.trychroma.com
  • New functionality
    • ...

Test plan

How are these changes tested?
Added tests for extraction function

  • Tests pass locally with pytest for python, yarn test for js, cargo test for rust

Migration plan

Are there any migrations, or any forwards/backwards compatibility changes needed in order to make sure this change deploys reliably?

Observability plan

What is the plan to instrument and monitor this change?

Documentation Changes

Are all docstrings for user-facing APIs updated if required? Do we need to make documentation changes in the docs section?

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link

Reviewer Checklist

Please leverage this checklist to ensure your code review is thorough before approving

Testing, Bugs, Errors, Logs, Documentation

  • Can you think of any use case in which the code does not behave as intended? Have they been tested?
  • Can you think of any inputs or external events that could break the code? Is user input validated and safe? Have they been tested?
  • If appropriate, are there adequate property based tests?
  • If appropriate, are there adequate unit tests?
  • Should any logging, debugging, tracing information be added or removed?
  • Are error messages user-friendly?
  • Have all documentation changes needed been made?
  • Have all non-obvious changes been commented?

System Compatibility

  • Are there any potential impacts on other parts of the system or backward compatibility?
  • Does this change intersect with any items on our roadmap, and if so, is there a plan for fitting them together?

Quality

  • Is this code of a unexpectedly high quality (Readability, Modularity, Intuitiveness)

@jairad26 jairad26 force-pushed the jai/cloud-ef-api-key-extraction branch 2 times, most recently from 994803a to a92603d Compare November 26, 2025 19:35
@jairad26 jairad26 marked this pull request as ready for review November 26, 2025 19:36
@propel-code-bot
Copy link
Contributor

propel-code-bot bot commented Nov 26, 2025

Add fallback API-key extraction from existing Chroma Cloud clients

Introduces a static helper SharedSystemClient.get_chroma_cloud_api_key_from_clients() that walks all cached ServerAPI instances and extracts the first X-Chroma-Token header found for Chroma Cloud endpoints. Both ChromaCloudSpladeEmbeddingFunction and ChromaCloudQwenEmbeddingFunction now try this helper when the CHROMA_API_KEY environment variable is absent. A full pytest suite is added to validate many edge-cases (missing headers, non-cloud URLs, no session, multiple clients, etc.).

Key Changes

• Added SharedSystemClient.get_chroma_cloud_api_key_from_clients() with header-based key discovery
• Updated chroma_cloud_qwen_embedding_function.py and chroma_cloud_splade_embedding_function.py to use the new helper before raising missing-key errors
• Added comprehensive tests in chromadb/test/api/test_shared_system_client.py (≈160 lines) covering success and failure paths
• Minor typing additions: imported Optional and removed unused SparseVector import

Affected Areas

chromadb/api/shared_system_client.py
chromadb/utils/embedding_functions/chroma_cloud_qwen_embedding_function.py
chromadb/utils/embedding_functions/chroma_cloud_splade_embedding_function.py
• Unit test suite

This summary was automatically generated by @propel-code-bot

The first api key found, or None if no client instances have api keys set.
"""
# Check FastAPI instances' session headers - this is where both paths converge
for system in SharedSystemClient._identifier_to_system.values():
Copy link
Contributor

Choose a reason for hiding this comment

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

Critical

[Logic] Race condition: _identifier_to_system dictionary is accessed without synchronization. If multiple threads call get_chroma_cloud_api_key_from_clients() while another thread modifies the dictionary (via __init__ or clear_system_cache()), this can raise RuntimeError: dictionary changed size during iteration or return inconsistent results.

@staticmethod
def get_chroma_cloud_api_key_from_clients() -> Optional[str]:
    # Create snapshot to avoid concurrent modification issues
    systems_snapshot = list(SharedSystemClient._identifier_to_system.values())
    for system in systems_snapshot:
        # ... rest of logic

Alternatively, protect dictionary access with a lock if thread-safety is required.

Context for Agents
Race condition: `_identifier_to_system` dictionary is accessed without synchronization. If multiple threads call `get_chroma_cloud_api_key_from_clients()` while another thread modifies the dictionary (via `__init__` or `clear_system_cache()`), this can raise `RuntimeError: dictionary changed size during iteration` or return inconsistent results.

```python
@staticmethod
def get_chroma_cloud_api_key_from_clients() -> Optional[str]:
    # Create snapshot to avoid concurrent modification issues
    systems_snapshot = list(SharedSystemClient._identifier_to_system.values())
    for system in systems_snapshot:
        # ... rest of logic
```

Alternatively, protect dictionary access with a lock if thread-safety is required.

File: chromadb/api/shared_system_client.py
Line: 108

Comment on lines +130 to +141
except Exception:
# if we can't access the ServerAPI instance or it doesn't have _session,
# continue to the next system instance
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

Important

[Reliability] The broad except Exception silently catches all errors, including critical issues like AttributeError from API changes or KeyError from malformed data structures. This makes debugging difficult when the code fails.

except AttributeError as e:
    # ServerAPI doesn't have expected attributes (_session or _api_url)
    logger.debug(f"Skipping system {system_id}: {e}")
    continue
except Exception as e:
    # Unexpected errors should be logged for investigation
    logger.warning(f"Unexpected error extracting API key from system: {e}")
    continue

This distinguishes expected structural variations from genuine errors that need attention.

Context for Agents
The broad `except Exception` silently catches all errors, including critical issues like `AttributeError` from API changes or `KeyError` from malformed data structures. This makes debugging difficult when the code fails.

```python
except AttributeError as e:
    # ServerAPI doesn't have expected attributes (_session or _api_url)
    logger.debug(f"Skipping system {system_id}: {e}")
    continue
except Exception as e:
    # Unexpected errors should be logged for investigation
    logger.warning(f"Unexpected error extracting API key from system: {e}")
    continue
```

This distinguishes expected structural variations from genuine errors that need attention.

File: chromadb/api/shared_system_client.py
Line: 133

# If not found in env var, try to get it from existing client instances
if not self.api_key:
raise ValueError(f"The {api_key_env_var} environment variable is not set.")
from chromadb.api.shared_system_client import SharedSystemClient
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please do not do inline imports. Why is this needed?

@jairad26 jairad26 force-pushed the jai/cloud-ef-api-key-extraction branch from a92603d to 1e64695 Compare November 26, 2025 19:46
@jairad26 jairad26 force-pushed the jai/cloud-ef-api-key-extraction branch from 1e64695 to 6abaca0 Compare November 26, 2025 19:48
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