|
| 1 | +## Pinecone v7 integration |
| 2 | + |
| 3 | +This guide shows how to use Semantic Router with the Pinecone Python SDK v7+, including cloud vs local setup, shared-index reuse, and namespaces for isolation. |
| 4 | + |
| 5 | +### Install |
| 6 | + |
| 7 | +```bash |
| 8 | +pip install "semantic-router[pinecone]" |
| 9 | +``` |
| 10 | + |
| 11 | +### Environment variables |
| 12 | + |
| 13 | +- `PINECONE_API_KEY` (required): Your Pinecone API key |
| 14 | +- `PINECONE_API_BASE_URL` (optional): |
| 15 | + - Cloud: `https://api.pinecone.io` (default if a real API key is set) |
| 16 | + - Local emulator: `http://localhost:5080` or `http://pinecone:5080` |
| 17 | +- `PINECONE_INDEX_NAME` (recommended on cloud): Name of an existing index to reuse |
| 18 | + |
| 19 | +Why set `PINECONE_INDEX_NAME`? Pinecone serverless has per-project index limits. Reusing a shared index avoids 403 quota errors. Semantic Router will automatically isolate data using namespaces. |
| 20 | + |
| 21 | +### Basic usage (cloud) |
| 22 | + |
| 23 | +```python |
| 24 | +import os |
| 25 | +from semantic_router.encoders import OpenAIEncoder |
| 26 | +from semantic_router.index.pinecone import PineconeIndex |
| 27 | +from semantic_router.route import Route |
| 28 | +from semantic_router.routers import SemanticRouter |
| 29 | + |
| 30 | +# Required |
| 31 | +os.environ["PINECONE_API_KEY"] = "<your-key>" |
| 32 | + |
| 33 | +# Strongly recommended: reuse an existing index to avoid quota |
| 34 | +os.environ["PINECONE_INDEX_NAME"] = "semantic-router-shared" |
| 35 | + |
| 36 | +encoder = OpenAIEncoder(name="text-embedding-3-small") |
| 37 | + |
| 38 | +# Use a namespace for isolation (otherwise the router will use the requested |
| 39 | +# index name internally as the namespace when reusing a shared index) |
| 40 | +index = PineconeIndex(index_name="demo-index", namespace="demo", dimensions=1536) |
| 41 | + |
| 42 | +routes = [ |
| 43 | + Route(name="greeting", utterances=["hello", "hi"]), |
| 44 | + Route(name="goodbye", utterances=["bye", "goodbye"]), |
| 45 | +] |
| 46 | + |
| 47 | +router = SemanticRouter(encoder=encoder, routes=routes, index=index, auto_sync="local") |
| 48 | + |
| 49 | +print(router(text="hi there").name) # -> greeting |
| 50 | +``` |
| 51 | + |
| 52 | +Notes: |
| 53 | +- If the shared index exists, Semantic Router reuses it and writes route vectors under your `namespace`. |
| 54 | +- If you do not set `PINECONE_INDEX_NAME`, creating a new index requires `dimensions`. If index creation is forbidden (quota), a clear error is raised asking you to set `PINECONE_INDEX_NAME`. |
| 55 | +- You do not need to set `PINECONE_API_BASE_URL` for cloud; override it only when using the local emulator for testing. |
| 56 | + |
| 57 | +### Local emulator |
| 58 | + |
| 59 | +```bash |
| 60 | +export PINECONE_API_KEY=pclocal |
| 61 | +export PINECONE_API_BASE_URL=http://localhost:5080 |
| 62 | +``` |
| 63 | + |
| 64 | +In local mode, Semantic Router connects to the emulator at `http://localhost:5080` (or `http://pinecone:5080` in containerized CI) and adds a short delay after create to account for readiness. |
| 65 | + |
| 66 | +### Async usage |
| 67 | + |
| 68 | +```python |
| 69 | +import asyncio |
| 70 | +from semantic_router.routers import SemanticRouter |
| 71 | + |
| 72 | +async def main(): |
| 73 | + result = await router.acall("hello") |
| 74 | + print(result.name) |
| 75 | + |
| 76 | +asyncio.run(main()) |
| 77 | +``` |
| 78 | + |
| 79 | +Internally, the library resolves the Pinecone v7 data-plane host and uses the correct `/vectors/query` endpoint for async queries. |
| 80 | + |
| 81 | +### Error handling and retries |
| 82 | + |
| 83 | +- 403 (quota): The library attempts to reuse an existing index. If none is available, it raises an error advising you to set `PINECONE_INDEX_NAME`. |
| 84 | +- 404 (eventual consistency): Readiness checks and upserts include brief bounded retries. |
| 85 | + |
| 86 | +### CI tips (GitHub Actions) |
| 87 | + |
| 88 | +- Set secrets: |
| 89 | + - `PINECONE_API_KEY` |
| 90 | + - `PINECONE_INDEX_NAME` (existing shared index) |
| 91 | +- Ensure the environment uses cloud: |
| 92 | + |
| 93 | +```yaml |
| 94 | +env: |
| 95 | + PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }} |
| 96 | + PINECONE_INDEX_NAME: ${{ secrets.PINECONE_INDEX_NAME }} |
| 97 | + |
| 98 | +steps: |
| 99 | + - name: Run tests |
| 100 | + run: | |
| 101 | + PINECONE_API_BASE_URL="https://api.pinecone.io" \ |
| 102 | + pytest -q |
| 103 | +``` |
| 104 | +
|
| 105 | +Tests that require Pinecone will automatically skip in cloud mode if `PINECONE_INDEX_NAME` isn’t provided, avoiding quota-based failures. |
| 106 | + |
| 107 | +### Requirements recap |
| 108 | + |
| 109 | +- Pinecone Python client v7+ |
| 110 | +- Semantic Router ≥ version including Pinecone v7 support (this branch) |
| 111 | +- Recommended on cloud: `PINECONE_INDEX_NAME` pointing at an existing index |
| 112 | + |
0 commit comments