Skip to content
Back to skills

Python Bindings

ASecurity

"Operate hnswlib 0.9.0 Python Index and BFIndex for typed vector

  • 247 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 8, 2026
businesspythonc++railsapiperformance

Works with

  • api

Security analysis

A100/100

Pro scans all 9 files and shows the line behind each finding

Scanned September 8, 2026

npx -y skills add VectorSpaceLab/AREX-Skill --skill python-bindings --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Python Bindings?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Python Bindings
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/vectorspacelab-python-bindings/badge)](https://www.skillsdirectory.com/skills/vectorspacelab-python-bindings)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: python-bindings
description: "Operate hnswlib 0.9.0 Python Index and BFIndex for typed vector
  search, filtering, mutation, persistence, pickle, and recall checks."
metadata:
  disco-role: operating
disable-model-invocation: true
license: Apache 2.0
---

# Python bindings

Use this sub-skill when a Python task mentions `hnswlib.Index`, `hnswlib.BFIndex`,
NumPy vectors, `knn_query`, `add_items`, `save_index`, `load_index`, deletion,
replacement, pickle, filters, or recall. The contract covers the CPU-native
hnswlib 0.9.0 extension and its three exposed spaces: `l2`, `ip`, and
`cosine`. It does not provide a CUDA API.

## Operating contract

- Work with an installed `hnswlib` extension and NumPy arrays. The package's
  normal runtime dependency is NumPy; source builds additionally need the
  C++/pybind11 toolchain described in [troubleshooting.md](references/troubleshooting.md).
- Treat labels as integer, non-negative external identifiers. Use explicit,
  unique `np.int64` labels when persistence, updates, or external metadata must
  remain stable.
- Keep vectors as finite numeric data with shape `(rows, dim)` or a single
  vector of shape `(dim,)`. The binding force-casts input to contiguous
  `float32`, but applications should validate dimensionality before querying.
- Keep mutation, querying, resizing, and serialization phases coordinated. The
  extension releases the GIL around native work; Python-level safety is not a
  substitute for the operation compatibility rules in [workflows.md](references/workflows.md).

## Standard workflow

1. **Normalize the request.** Record `space`, `dim`, capacity, label policy,
   query `k`, filter cardinality, deletion/replacement needs, persistence path,
   and the target recall or exactness requirement.
2. **Check import/build state.** Import `hnswlib` and NumPy in the intended
   environment. If importing a source-built extension, use the compiler and
   native-linkage diagnosis in [troubleshooting.md](references/troubleshooting.md).
3. **Construct and initialize.** Create `Index(space, dim)`, then call
   `init_index(max_elements, M=16, ef_construction=200, random_seed=100,
   allow_replace_deleted=False)`. `Index` is not ready for insertion until
   `init_index` succeeds.
4. **Choose a stable data contract.** Convert vectors with
   `np.asarray(data, dtype=np.float32)` and assert `data.ndim in (1, 2)` and
   the trailing dimension equals `dim`. Use one scalar integer label only for
   one vector; otherwise pass one label per row. Omitted labels are assigned by
   the binding and are not a durable metadata scheme.
5. **Populate and tune.** Call `add_items(data, ids=None, num_threads=-1,
   replace_deleted=False)`. Reusing an existing label updates its vector.
   Set `index.ef` or call `set_ef`; choose `ef >= k` and increase it for recall
   at the cost of search time. Set `num_threads`/`set_num_threads` deliberately.
6. **Query and validate.** Call `knn_query(data, k=1, num_threads=-1,
   filter=None)`. The return is `(labels, distances)`, both shaped `(rows, k)`
   even for a single-vector query. A filter is a Python callable over external
   labels; use `num_threads=1` for filtered search and ensure every query has
   at least `k` eligible live items.
7. **Inspect data and metadata.** Use explicit label arrays with
   `get_items(ids, return_type="numpy"|"list")`; sort `get_ids_list()` before
   comparing it. Check `space`, `dim`, `M`, `ef_construction`, `ef`,
   `max_elements`, `element_count`, and their method equivalents as needed.
   In this binding, `get_items(None)` does not mean “all labels”; retrieve all
   vectors by passing `get_ids_list()` explicitly.
8. **Apply lifecycle mutations.** `mark_deleted(label)` hides a live label;
   `unmark_deleted(label)` restores it. For slot reuse, enable
   `allow_replace_deleted=True` at initialization or load, mark deletions, and
   pass `replace_deleted=True` with new labels. Without that policy, replacement
   raises; deletion alone does not create unbounded capacity.
9. **Persist or pickle safely.** Use a temporary/application-owned path with
   `save_index`, then create a fresh `Index` and `load_index(path,
   max_elements=0, allow_replace_deleted=...)`. Set `ef` again after
   `load_index`: index-file persistence does not preserve it. `pickle.dumps`
   and `pickle.loads` preserve the Python index state, including `ef`, but
   pickle/get-index-state operations must not overlap `add_items`.
10. **Measure recall when approximate results matter.** Build a same-space,
    same-dimension `BFIndex`, add the same labeled vectors, query both with a
    valid `k`, and compare label overlap. BFIndex is an exact linear-scan
    oracle, not a performance substitute. Use the bundled tiny checks first:
    `python scripts/python_lifecycle_smoke.py --help` and then run the selected
    smoke script from outside the checkout.

## API routing map

- Exact signatures, result shapes, properties, and BFIndex: [api-reference.md](references/api-reference.md).
- Build/query/persistence/mutation/recall recipes: [workflows.md](references/workflows.md).
- Shape, labels, dtype, metrics, normalization, and distances:
  [data-and-distance-semantics.md](references/data-and-distance-semantics.md).
- Installation, import, native flags, errors, concurrency, and recovery:
  [troubleshooting.md](references/troubleshooting.md).
- Deterministic executable checks:
  `scripts/python_lifecycle_smoke.py`, `scripts/python_filter_smoke.py`,
  `scripts/python_mutation_smoke.py`, and `scripts/python_pickle_smoke.py`.

## Hard guardrails

- Do not claim GPU or CUDA support. The exposed extension is CPU-native.
- Do not use `k` greater than the live/filtered population, or interpret an
  exception about a contiguous result array as a partial result.
- Do not assume `ef` is automatically adequate; set `ef >= k` after every
  index-file load and tune it against BFIndex when recall is material.
- Do not use negative labels, mismatched label counts, wrong vector dimensions,
  or a scalar label for multiple rows. Validate query dimensions too: the
  observed binding checks dimensions on insertion but does not provide the same
  explicit query-dimension guard.
- Do not call `mark_deleted` twice, unmark a label that is not marked, replace
  without the initialization/load policy, or insert beyond capacity without
  resizing/loading with a larger capacity.
- Do not compare cosine `get_items` output directly to the original unnormalized
  vectors; returned stored vectors are normalized.
- Do not overlap `add_items` with `knn_query`; concurrent additions are allowed
  with other additions, and concurrent queries with other queries. Python
  filters should run single-threaded. Resizing is not concurrent-safe with
  adding/querying, and pickle/getIndexParams is not concurrent-safe with
  adding.

## Completion checklist

Before handing off a Python integration, confirm:

- import and package/runtime facts were checked in the target environment;
- the metric, dimension, capacity, dtype, shapes, and labels are explicit;
- initialization precedes insertion and `ef >= k` is set for each query phase;
- result shapes and filter eligibility are asserted;
- explicit IDs are used for `get_items`, metadata, updates, and persistence;
- deletion/replacement flags match the intended lifecycle;
- file paths are temporary or application-owned and reload uses a compatible
  metric/dimension;
- `ef` is restored after file loading, while pickle behavior is tested separately;
- BFIndex is used for exact comparison when a recall claim is required; and
- no unsupported CUDA, malformed-query, unsafe-concurrency, or dependency claim
  has been smuggled into the integration.

Files in this skill

  • SKILL.md7.6 KB
  • references/api-reference.md7.3 KB
  • references/data-and-distance-semantics.md4.7 KB
  • references/troubleshooting.md8.9 KB
  • references/workflows.md6.6 KB
  • scripts/python_filter_smoke.py3.3 KB
  • scripts/python_lifecycle_smoke.py4.1 KB
  • scripts/python_mutation_smoke.py4.4 KB
  • scripts/python_pickle_smoke.py2.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.