Skip to content

Add Python and Go vector search samples; align TypeScript with constitution - #1516

Open
Dina Berry (MSFT) (diberry) wants to merge 2 commits into
microsoft:masterfrom
diberry:squad/vector-search-multi-language
Open

Dina Berry (MSFT) (diberry) wants to merge 2 commits into
microsoft:masterfrom
diberry:squad/vector-search-multi-language

Conversation

@diberry

Copy link
Copy Markdown
Contributor

Summary

Implements the second wave of the Azure SQL vector search constitution (.github/instructions/vector-search-constitution.instructions.md) for TypeScript, Python, and Go. .NET and Java remain constitution-defined future languages and are not implemented in this PR.

Depends on: #1515 (constitution PR, not yet merged). The constitution file itself is intentionally not included in this PR — this PR reads it from origin/constitution/azure-sql-vector-search as the governing input and implements against it, so the two PRs can be reviewed and merged independently, with this one rebasing on #1515's actual merged content when it lands.

Tracking: AB#580700

What changed, per language

TypeScript (vector-search-query-typescript/) — audit and alignment, no behavior change

  • Added ESLint (flat config) + Prettier, with npm run lint / format / format:check. Fixed the two findings ESLint surfaced (an unsafe as any cast on tedious's addParameter, and missing Node globals in the plain-JS typecheck helper).
  • CI: added lint + format:check steps ahead of the existing type-check step.
  • Added output/sample-output.txt — the real, previously captured run output already published in this sample's README, now also committed as the standalone reference file the constitution requires. Added a .gitignore carve-out so this file isn't silently re-ignored by the existing blanket output/ rule.

Python (vector-search-query-python/) — new

  • pyodbc (driver) + azure-identity (Entra auth via the documented SQL_COPT_SS_ACCESS_TOKEN pattern) + openai's AzureOpenAI class (embeddings). .env-based configuration (sample.env template).
  • Same table shape, same ≥1,000-row DiskANN gate (falls back to exact automatically), same JSON-cast vector binding, same dataset/query as TypeScript — implemented idiomatically, not transliterated.
  • requirements.txt (>=-pinned) + requirements-dev.txt (ruff, mypy, pytest) + pyproject.toml. 22 unit tests, all passing, covering config/table-name/dataset validation without requiring Azure connectivity.
  • CI: ruff check, ruff format --check, mypy, pytest.

Go (vector-search-query-go/) — new

  • github.com/microsoft/go-mssqldb + its azuread subpackage (fedauth=ActiveDirectoryDefault; the driver handles Entra auth internally) + github.com/Azure/azure-sdk-for-go/sdk/azidentity + github.com/openai/openai-go/v3 with its azure subpackage (embeddings).
  • Package-currency finding, verified live, not guessed: github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai — the package the constitution's initial authoring named for the embeddings role — changed function as of its v0.8.0 release (2025-06-03): it's no longer a standalone client and now only supplies Azure-specific extension types to the official openai-go client. Confirmed directly against azopenai v0.9.0's own source and test files before writing this code. For a plain embeddings call, azopenai itself isn't needed at all. This requires a follow-up correction to constitution PR (ignore) Add Azure SQL vector search sample constitution #1515's ASV-CORE-37/ASV-LANG-GO-5 Go row — flagging it here rather than silently absorbing it.
  • Idiomatic Go layout: cmd/query + cmd/embed binaries, internal/config + internal/hotels shared packages. Same table shape/gate/binding as every other language. 6 unit tests (go test), all passing.
  • CI: gofmt -l, go vet, go build, go test.

Explicit no-live-execution disclosure

No authorized live Azure SQL Database or Azure OpenAI environment was available while authoring this PR. Python's and Go's output/sample-output.txt files and README "Expected output" sections say so explicitly and use placeholder values — they are not captured real runs and must not be treated as end-to-end validated evidence. What was validated locally instead, for both languages: full static analysis (lint/format/vet/type-check), successful build, and unit tests for every pure/testable code path. TypeScript's output/sample-output.txt is a real captured run, carried over unchanged from its existing, already-published README section.

Validation evidence

Language Build Lint/Format Type-check/Vet Unit tests
TypeScript npm run build npm run lint ✅ / npm run format:check (part of build)
Python python -m py_compile ruff check ✅ / ruff format --check mypy src pytest — 22 passed
Go go build ./... gofmt -l . (clean) ✅ go vet ./... go test ./... — 6 passed

Scope

  • Reuses the existing shared data/ (HotelsData_Vector.json) and infra/ (Azure SQL Database + Azure OpenAI Bicep) unchanged.
  • No .NET, no Java, no new scenario, no documentation article.
  • Updated samples/features/vector-search/README.md's language table with Python/Go rows and their validation status.

Checklist

  • Branch created from upstream/master (not from the unmerged constitution branch)
  • Constitution file itself excluded from this PR's diff
  • TypeScript audited against every applicable constitution requirement; gaps fixed
  • Python and Go implemented idiomatically per language, not transliterated from TypeScript
  • Package identities verified against current official sources (npm, PyPI, Maven Central, pkg.go.dev) — one currency finding flagged above, not silently guessed
  • CI added/updated for all three languages: install, lint/format, build/typecheck, unit tests
  • No secrets committed; local pattern-based secret scan clean (GitHub Advanced Security scanning unavailable on this fork tier)
  • No live Azure output fabricated; explicit no-live-run disclosure where applicable
  • Only intended paths staged (git diff --stat reviewed before commit)
  • Not yet merged — stopping here per instruction for review

…tution

Implements the second wave of the Azure SQL vector search constitution
(.github/instructions/vector-search-constitution.instructions.md on
branch constitution/azure-sql-vector-search, PR microsoft#1515):
TypeScript, Python, and Go for the vector-search scenario. .NET and Java
remain constitution-defined future languages and are intentionally not
implemented in this PR.

## TypeScript (vector-search-query-typescript/) — audit and alignment

- Added ESLint (flat config, typescript-eslint recommended) and Prettier,
  with npm run lint / format / format:check scripts. Fixed the two
  findings ESLint surfaced: an unsafe �s any cast on
  tedious's addParameter (now typed via (typeof TYPES)[keyof typeof TYPES])
  and missing Node globals in the plain-JS typecheck helper script.
- Added CI steps for lint and format:check ahead of the existing
  type-check step.
- Added output/sample-output.txt: the real, previously captured run
  output already published in this sample's README "Expected output"
  section, now also committed as the required standalone reference file.
  Carved out .gitignore's output/ exclusion (output/* + negated
  !output/sample-output.txt) so this committed file is not silently
  re-ignored.
- No behavior changes; only type-safety and tooling additions plus the
  reformatting Prettier's format:check gate requires.

## Python (vector-search-query-python/) — new, idiomatic implementation

- pyodbc (SQL driver) + azure-identity (Entra auth, via the documented
  SQL_COPT_SS_ACCESS_TOKEN pattern since pyodbc has no built-in
  DefaultAzureCredential integration) + openai's AzureOpenAI class
  (embeddings). Configuration via .env (sample.env template), matching
  the constitution's per-language config-mechanism table.
- Same table shape, same DiskANN >=1,000-row gate (falls back to exact
  automatically), same JSON-cast vector binding, same canonical query and
  hotel dataset as the TypeScript reference — not transliterated, but
  idiomatic Python (dataclass config, context-managed cursor, batched
  fast_executemany insert).
- requirements.txt (>=-pinned) + requirements-dev.txt (ruff, mypy,
  pytest) + pyproject.toml. 22 unit tests cover configuration validation,
  table-name validation, and dataset-shape validation without requiring
  Azure connectivity.
- CI: ruff check, ruff format --check, mypy, pytest.

## Go (vector-search-query-go/) — new, idiomatic implementation

- github.com/microsoft/go-mssqldb + its azuread subpackage (driver name
  "azuresql", fedauth=ActiveDirectoryDefault DSN parameter — the driver
  handles Entra token acquisition internally, unlike TS/Python) +
  github.com/Azure/azure-sdk-for-go/sdk/azidentity (embeddings-call
  credential) + github.com/openai/openai-go/v3 with its azure subpackage
  (embeddings).
- IMPORTANT CURRENCY FINDING, not guessed: github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai
  — the package the constitution's initial authoring named for this role
  — changed function as of its v0.8.0 release (2025-06-03) and is no
  longer a standalone client; it is now only a companion package
  providing Azure-specific extension types to the official openai-go
  client. Verified live against the actual v0.9.0 source and its own
  example/test files before writing this code. For a plain embeddings
  call, azopenai itself is not required at all. This finding requires a
  follow-up correction to the constitution's ASV-CORE-37/ASV-LANG-GO-5
  Go row on PR microsoft#1515 (or a fast-follow PR after it merges) — flagged in
  the PR description, not silently absorbed.
- Idiomatic Go module layout: cmd/query (search scenario) and cmd/embed
  (embedding regeneration) binaries, internal/config and internal/hotels
  shared packages. Same table shape, same DiskANN gate, same JSON-cast
  vector binding as every other language. 6 unit tests (go test) cover
  configuration validation and dataset-shape/vector-serialization
  validation without requiring Azure connectivity.
- CI: gofmt -l (format check), go vet, go build, go test.

## Explicit no-live-execution disclosure (both new languages)

No authorized live Azure SQL Database or Azure OpenAI environment was
available while authoring this PR. Python's and Go's output/sample-output.txt
and README "Expected output" sections say so explicitly and are marked
as NOT a captured real run (placeholder values only) — they must not be
treated as validated end-to-end evidence. What was validated locally
without live Azure access, for both languages: static analysis (lint/
format/vet/type-check), full local build, and unit tests for all
pure/testable logic (config validation, vector serialization, dataset
validation). TypeScript's output/sample-output.txt is the one real
captured run, carried over from its existing README section.

## Shared changes

- samples/features/vector-search/README.md: added Python and Go rows to
  the language table with explicit status (implemented + statically
  validated vs. TypeScript's implemented + live-validated), and
  generalized the .env setup instructions to name all three languages.
- Reused the existing shared data/ (HotelsData_Vector.json) and infra/
  (Azure SQL Database + Azure OpenAI Bicep) unchanged. No new platform,
  scenario, or documentation article added.

Depends on constitution PR microsoft#1515 (not yet
merged) as the governing source; this PR's constitution reference
resolves once microsoft#1515 merges.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…on ruff/README)

Validated via a same-repo draft PR on the fork per the fork-workflow
skill (upstream PR microsoft#1516 correctly skips CI for fork-originated PRs by
design, matching the existing TypeScript CI's fork-PR guard, so this
was the only way to get real CI execution before review).

- Go: go.mod's go directive was auto-set to 1.26.1 by the local
  toolchain used to write this sample, but CI pins go-version: "1.25"
  per the constitution's stated Go 1.25+ minimum (ASV-LANG-GO-2). Ran
  go mod tidy to reset the directive to 1.25.0 and correctly split
  direct vs. indirect requires (previously everything was marked
  indirect). Rebuilt/vetted/tested locally afterward — unchanged, still
  green.
- Python: 
uff format --check . also scans embedded Python code
  blocks inside README.md by default and wanted to reformat one,
  which would have altered published documentation prose formatting.
  Added �xtend-exclude = ["README.md"] to pyproject.toml, matching
  the same doc-vs-code formatting boundary already established for
  TypeScript's Prettier config (.prettierignore excludes README.md).

Re-verified all three languages' full local check suites still pass
after these fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@diberry

Copy link
Copy Markdown
Contributor Author

CI validation evidence

This PR is from a fork, so — matching the existing TypeScript CI's established security pattern (if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) — all three new/updated workflows correctly skip on this upstream PR to prevent unauthorized minute consumption from external actors. This is by design, not a gap.

To get real automated CI execution before this PR is reviewed, I validated via a temporary same-repo draft PR on the fork (diberry#1, now closed), per the fork-workflow pattern. Results after one round of fixes:

Workflow Result
Vector Search TypeScript — Build ✅ pass
Vector Search Python — Build ✅ pass
Vector Search Go — Build ✅ pass

Two real issues were caught and fixed this way (commit bbb57f58):

  1. Go: go.mod's go directive was auto-set to 1.26.1 by the local toolchain used to author the sample, which is newer than CI's pinned go-version: "1.25" (matching the constitution's stated Go 1.25+ minimum). Fixed via go mod tidy, which reset it to 1.25.0 and also correctly split direct vs. indirect requires.
  2. Python: ruff format --check . scans embedded Python code blocks inside README.md by default and wanted to reformat one — which would have altered published documentation prose. Added extend-exclude = ["README.md"] to pyproject.toml, matching the doc-vs-code formatting boundary already established for TypeScript's Prettier config.

All three languages' full local check suites (build, lint/format, type-check/vet, unit tests) were re-verified green after these fixes, and the fork's CI runs above are the independent, automated confirmation of the same result.

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