Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ target/
.ipynb_checkpoints

# Oracle Parfait analysis cache
__parfait__/
__parfait__/
32 changes: 32 additions & 0 deletions .gitmessage
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Based on Conventional Commits 1.0.0:
# Conventional Commit format:
# <type>[optional scope][!]: <description>
#
# Examples:
# feat(query): add metadata filters
# fix: handle empty query results
# docs!: remove the legacy authentication flow
#
# Common types:
# feat New user-visible capability
# fix Corrected behavior or defect
# docs User documentation change
# perf User-visible performance improvement
# refactor Internal restructuring without intended behavior change
# test Test-only change
# build Build or packaging change
# ci Continuous-integration change
# chore Routine maintenance
# revert Revert a previous change
# style Formatting-only change
#
# Keep the description concise and imperative. Add an optional body after a
# blank line to explain motivation or implementation details.
#
# Use a footer for issue references or breaking-change details, for example:
# BREAKING CHANGE: describe the required migration
#
# To omit a redundant entry related to an unreleased feature, use:
# Changelog: skip
# To omit an unreleased feature and the revert that removes it, use:
# Changelog: retract <full SHA of the feat commit>
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ filters = {
Use only filter operators documented in `docs/source/rest_api.rst` or verified
by SDK tests. Do not copy filter syntax from another vector database product.

## Validation

- For SDK source or test changes, run `make check` and `git diff --check`
before handoff.
- Run focused tests for any changed development tool. Run `make build` when
packaging or build metadata changes.
- Run `make integration_test` only when the change can affect live VecDB
behavior and the required test environment is configured.
- Report any required validation that was not run.

## Quick Start

- Use the `README.md` Quickstart as the source of truth for runnable
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ All notable changes to this project will be documented in this file.
The format is based on the `Keep a Changelog <https://keepachangelog.com/en/1.1.0/>`__,
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`__.

1.0.3 - 2026-09-07
------------------

Added
~~~~~

- Added verified public-operation defaults for omitted arguments, including
``create_vector_table.table_params.auto_generate_id``,
``list_vectors.limit``, and ``query.include_vectors``.
- Added transport-neutral validation for parameter values
and cross-field combinations before requests are sent to ORDS.
- Added explicit authentication-mode detection for unauthenticated, basic,
and bearer configurations, including validation of incomplete or conflicting
credentials.

Changed
~~~~~~~

- Resource-name validation now rejects blank values and transport-unsafe NUL
or double-quote characters while leaving database-specific identifier rules
to Oracle Database.
- Upsert vector field names are normalized case-insensitively; unknown fields
and duplicate fields with different casing now produce clear validation
errors.
- Improved validation and error messages for vector index organizations,
distribution settings, quantization, metadata paths, query modes, and other
parameter dependencies.
- Improved ORDS exception normalization and diagnostics by redacting sensitive
request and response data, preserving useful error categories, and avoiding
duplicate raw transport exception context.

Fixed
~~~~~

- Fixed graph-index requests that omitted required distribution parameters from
reaching the service with an invalid request shape.

1.0.2 - 2026-08-19
------------------

Expand Down
17 changes: 17 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ git commit --signoff
Only pull requests from committers that can be verified as having signed the OCA
can be accepted.

### Commit messages

Use [Conventional Commits][conventional-commits] for commit subjects so future
release automation can derive changelog entries from commit history. Configure
the repository template once after cloning:

```bash
git config --local commit.template .gitmessage
```

Use this format and retain the OCA sign-off with `git commit -s`:

```text
<type>[optional scope][!]: <description>
```

## Pull request process

1. Ensure there is an issue created to track and discuss the fix or enhancement
Expand All @@ -53,3 +69,4 @@ like more specific guidelines, see the [Contributor Covenant Code of Conduct][CO

[OCA]: https://oca.opensource.oracle.com
[COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/
[conventional-commits]: https://www.conventionalcommits.org/en/v1.0.0/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Keep vectors alongside your operational data, combine semantic similarity with r

[![PyPI](https://img.shields.io/pypi/v/oracle-vecdb)](https://pypi.org/project/oracle-vecdb/)
[![Python](https://img.shields.io/pypi/pyversions/oracle-vecdb)](https://pypi.org/project/oracle-vecdb/)
[![License](https://img.shields.io/github/license/oracle/vecdb-python-sdk)](LICENSE.txt)
[![License](https://img.shields.io/github/license/oracle/vecdb-python-sdk)](./LICENSE.txt)

**⭐ [Star `oracle/vecdb-python-sdk`](https://github.com/oracle/vecdb-python-sdk) to follow the project and help more developers discover it.**

Expand Down
41 changes: 39 additions & 2 deletions src/oracle_vecdb/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@
VectorDebugFlags,
VectorEmbedInputItem,
)
from .validation import validate_resource_names
from .validation import (
set_default_arguments,
validate_common_spec_arguments,
validate_resource_names,
)
from .vecdb_exception import VecDBException
from .vecdb_errors import (
InvalidTableNameFormatError,
Expand Down Expand Up @@ -196,6 +200,7 @@ def __setattr__(self, name: str, value: Any) -> None:
def _get_active_service(self) -> VecDBServiceProtocol:
return self._get_ords_service()

@set_default_arguments
def describe_vector_database(self) -> DatabaseSummaryResponse:
"""
Get summary statistics for the entire vector database service.
Expand Down Expand Up @@ -230,6 +235,7 @@ def describe_vector_database(self) -> DatabaseSummaryResponse:
"""
return self._get_active_service().describe_vector_database()

@set_default_arguments
def list_vector_tables(
self, limit: Optional[int] = None, offset: Optional[int] = None
) -> VectorTableCollectionResponse:
Expand Down Expand Up @@ -327,6 +333,8 @@ def list_vector_tables(
limit=limit, offset=offset
)

@set_default_arguments
@validate_common_spec_arguments
@validate_resource_names(name=InvalidTableNameFormatError)
def create_vector_table(
self,
Expand Down Expand Up @@ -490,6 +498,7 @@ def create_vector_table(
debug_flags=debug_flags,
)

@set_default_arguments
@validate_resource_names(name=InvalidTableNameFormatError)
def describe_vector_table(self, name: str) -> VectorTableResponse:
"""
Expand Down Expand Up @@ -563,6 +572,7 @@ def describe_vector_table(self, name: str) -> VectorTableResponse:
name=name,
)

@set_default_arguments
@validate_resource_names(name=InvalidTableNameFormatError)
def drop_vector_table(self, name: str) -> DropVectorTableResponse:
"""
Expand Down Expand Up @@ -611,6 +621,7 @@ def drop_vector_table(self, name: str) -> DropVectorTableResponse:
name=name,
)

@set_default_arguments
@validate_resource_names(name=InvalidTableNameFormatError)
def update_vector_table_annotation(
self,
Expand Down Expand Up @@ -678,6 +689,7 @@ def update_vector_table_annotation(
debug_flags=debug_flags,
)

@set_default_arguments
@validate_resource_names(model_name=InvalidModelNameFormatError)
def generate_embedding(
self,
Expand Down Expand Up @@ -757,6 +769,7 @@ def generate_embedding(
debug_flags=debug_flags,
)

@set_default_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def upsert_vectors(
self,
Expand Down Expand Up @@ -962,6 +975,8 @@ def _submit_upsert_batch(
has_count = True
return total, has_count

@set_default_arguments
@validate_common_spec_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def list_vectors(
self,
Expand Down Expand Up @@ -1071,6 +1086,7 @@ def list_vectors(
)

# VectorApi methods
@set_default_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def delete_vectors(
self,
Expand Down Expand Up @@ -1129,6 +1145,7 @@ def delete_vectors(
debug_flags=debug_flags,
)

@set_default_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def load_vectors(
self,
Expand Down Expand Up @@ -1226,6 +1243,7 @@ def load_vectors(
debug_flags=debug_flags,
)

@set_default_arguments
def list_vector_load_jobs(
self, limit: Optional[int] = None, offset: Optional[int] = None
) -> JobCollectionResponse:
Expand Down Expand Up @@ -1281,6 +1299,7 @@ def list_vector_load_jobs(
limit=limit, offset=offset
)

@set_default_arguments
@validate_resource_names(load_job_name=InvalidLoadJobNameFormatError)
def describe_vector_load_job(self, load_job_name: str) -> JobResponse:
"""
Expand Down Expand Up @@ -1336,6 +1355,7 @@ def describe_vector_load_job(self, load_job_name: str) -> JobResponse:
load_job_name=load_job_name,
)

@set_default_arguments
@validate_resource_names(load_job_name=InvalidLoadJobNameFormatError)
def get_vector_load_job_log(self, load_job_name: str) -> JobLogResponse:
"""
Expand Down Expand Up @@ -1395,6 +1415,8 @@ def get_vector_load_job_log(self, load_job_name: str) -> JobLogResponse:
)

# SearchApi methods
@set_default_arguments
@validate_common_spec_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def query(
self,
Expand Down Expand Up @@ -1589,6 +1611,8 @@ def query(

# SummaryApi methods

@set_default_arguments
@validate_common_spec_arguments
def rerank(
self,
query: str,
Expand Down Expand Up @@ -1699,6 +1723,8 @@ def metadata_for(result):
# ModelApi methods

# IndexApi methods
@set_default_arguments
@validate_common_spec_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def create_index(
self,
Expand Down Expand Up @@ -1729,7 +1755,7 @@ def create_index(
may include ``auto_index``, ``include_paths``, and ``exclude_paths``.

Example:
``{'vector_index_params': {'organization': 'INMEMORY GRAPH', 'distance_metric': 'COSINE', 'advanced_params': {'neighbors': 32, 'efConstruction': 200}}, 'parallel_creation': 4}``
``{'vector_index_params': {'organization': 'INMEMORY GRAPH', 'distance_metric': 'COSINE', 'distribute_params': {'distribute_method': 'AUTO'}, 'advanced_params': {'neighbors': 32, 'efConstruction': 200}}, 'parallel_creation': 4}``

:type index_params: dict, optional
:param debug_flags: Debug configuration for detailed logging.
Expand Down Expand Up @@ -1832,6 +1858,7 @@ def create_index(
debug_flags=debug_flags,
)

@set_default_arguments
def list_index_jobs(
self, limit: Optional[int] = None, offset: Optional[int] = None
) -> JobCollectionResponse:
Expand Down Expand Up @@ -1878,6 +1905,7 @@ def list_index_jobs(
limit=limit, offset=offset
)

@set_default_arguments
@validate_resource_names(index_job_name=InvalidIndexJobNameFormatError)
def describe_index_job(self, index_job_name: str) -> JobResponse:
"""
Expand Down Expand Up @@ -1941,6 +1969,7 @@ def describe_index_job(self, index_job_name: str) -> JobResponse:
index_job_name=index_job_name,
)

@set_default_arguments
@validate_resource_names(index_job_name=InvalidIndexJobNameFormatError)
def get_index_job_log(self, index_job_name: str) -> JobLogResponse:
"""
Expand Down Expand Up @@ -2002,6 +2031,8 @@ def get_index_job_log(self, index_job_name: str) -> JobLogResponse:
index_job_name=index_job_name,
)

@set_default_arguments
@validate_common_spec_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def rebuild_index(
self,
Expand Down Expand Up @@ -2061,6 +2092,7 @@ def rebuild_index(

# InferenceApi methods

@set_default_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def describe_index(self, table_name: str) -> IndexDescriptionResponse:
"""
Expand Down Expand Up @@ -2099,6 +2131,7 @@ def describe_index(self, table_name: str) -> IndexDescriptionResponse:
table_name=table_name,
)

@set_default_arguments
@validate_resource_names(table_name=InvalidTableNameFormatError)
def drop_index(
self,
Expand Down Expand Up @@ -2160,6 +2193,7 @@ def drop_index(
debug_flags=debug_flags,
)

@set_default_arguments
def list_models(
self, limit: Optional[int] = None, offset: Optional[int] = None
) -> ModelCollectionResponse:
Expand Down Expand Up @@ -2229,6 +2263,7 @@ def list_models(
limit=limit, offset=offset
)

@set_default_arguments
@validate_resource_names(model_name=InvalidModelNameFormatError)
def load_model(
self,
Expand Down Expand Up @@ -2322,6 +2357,7 @@ def load_model(
debug_flags=debug_flags,
)

@set_default_arguments
@validate_resource_names(model_name=InvalidModelNameFormatError)
def describe_model(self, model_name: str) -> ModelResponse:
"""
Expand Down Expand Up @@ -2388,6 +2424,7 @@ def describe_model(self, model_name: str) -> ModelResponse:
model_name=model_name,
)

@set_default_arguments
@validate_resource_names(model_name=InvalidModelNameFormatError)
def drop_model(self, model_name: str) -> DropModelResponse:
"""
Expand Down
Loading