src/openaivec/: core batched wrappers (_responses.py,_embeddings.py), batching/caching internals (_cache/proxy.py,_cache/optimize.py,_cache/_backend.py), provider/DI setup (_provider.py,_di.py), schema inference (_schema/), and integrations (pandas_ext/,spark_ext.py,duckdb_ext.py).src/openaivec/task/: function-style task factories by domain (nlp/,customer_support/,table/) plus registry plumbing in_registry.py.tests/: mirrors the source layout, including focused suites intests/_cache/andtests/_schema/.docs/holds MkDocs sources,site/generated pages, andartifacts/scratch assets kept out of releases.
- Remote batched execution goes through
BatchCache/AsyncBatchCacheinopenaivec._cache; proxies dedupe inputs in-order, require same-length outputs, and release in-flight waiters on failure. The cache layer is pluggable viaCacheBackend(default: in-memoryOrderedDict);DuckDBCacheBackendprovides persistent cross-session caching. batch_sizebehavior is shared across sync/async proxies:NoneenablesBatchSizeSuggesterauto-tuning (target ~30-60s per batch), positive values force fixed chunks, and<= 0processes all items in one call.- Progress bars appear only when
show_progress=Trueand the runtime is notebook-like. _responses.py/_embeddings.pyare batched OpenAI wrappers with retry/backoff; structured outputs use Pydanticresponse_format, and_responses.pyretries schema failures with validation feedback (max_validation_retries).parsehelpers infer schema whenresponse_format=None; pass explicit models when deterministic output shape is required.- Reuse caches from
*_with_cachehelpers (or Spark UDF-local caches) per operation and clear them (clear/aclose) when finished to avoid unbounded cache growth. duckdb_ext.pyprovides DuckDB UDF registration (responses_udf,embeddings_udf,task_udf),similarity_searchfor top-k cosine queries, andpydantic_to_duckdb_ddlfor schema-to-DDL conversion. UseDuckDBCacheBackendas thecachefield ofBatchCachefor persistent cross-session caching. DuckDB is a core dependency.
- Export tasks as factory functions (for example
nlp.sentiment_analysis()), not constant task instances. - Each task module should define a
TASK_SPECentry fortask._registry, and task response models should reject unknown fields (ConfigDict(extra="forbid")). - Use
PreparedTaskfor reusable instruction/schema pairs; it is immutable and intentionally does not store default API kwargs.
uv sync --all-extras --devprepares extras and tooling; iterate withuv run pytest -m "not slow and not requires_api"before a fulluv run pytest.- Run focused suites for touched subsystems when possible (for example
uv run pytest tests/_cache tests/_schema). uv run ruff check . --fixenforces style,uv run pyrightguards API changes, anduv buildvalidates the distribution.- Use
uv pip install -e .only when external tooling requires an editable install.
- Target Python 3.10+, rely on absolute imports, and keep helpers private with leading underscores; expose symbols via explicit
__all__(internal modules can keep__all__ = []unless specific exports are required). - Apply Google-style docstrings with
(type)Args, Returns/Raises sections, double-backtick literals, and doctest-styleExample:blocks (>>>) when useful. - Keep sync/async APIs behaviorally aligned (
.ai.*vs.aio.*,Batch*vsAsyncBatch*), dataframe accessors descriptive (responses,extract,fillna), and raise narrow exceptions (ValueError,TypeError).
- Pytest discovers
tests/test_*.py; parametrize to cover pandas vectorization, Spark UDFs, and async pathways. - Use markers consistently:
@pytest.mark.requires_api,@pytest.mark.slow,@pytest.mark.spark,@pytest.mark.integration,@pytest.mark.asyncio; skip gracefully when credentials or optional deps are missing. - Add regression tests before fixes, assert on structure/length/order rather than verbatim text, and prefer shared fixtures over heavy mocking.
- Commits follow
type(scope): summary(e.g.,fix(pandas): guard empty batch) and avoid merge commits within feature branches. - Pull requests explain motivation, outline the solution, link issues, list doc updates, and include the latest
uv run pytestanduv run ruff check . --fixoutput; attach screenshots for doc or tutorial changes.
- Auth precedence is
OPENAI_API_KEYfirst, then Azure (AZURE_OPENAI_BASE_URL+AZURE_OPENAI_API_VERSION, with optionalAZURE_OPENAI_API_KEYfor API-key auth). - Azure endpoints should end with
/openai/v1/(legacy paths work but emit warnings). - For Spark, call
setup/setup_azurebefore registering UDFs so local and executor environments stay in sync. - Keep local secrets under
artifacts/, never commit credentials, and rely on CI-managed secrets when extending automation.