The Pinecone Python SDK provides a client for the Pinecone vector database. Use it to create and manage indexes, upsert and query records, and run inference operations from Python.
Requires Python 3.10+.
Upgrading from 9.x? create and configure moved from spec=/dimension= to schema=/deployment=; see the v10 migration guide for the field-by-field mapping.
pip install pineconeAn index declares its fields as a schema. Declaring a schema makes it a document
index: you read and write it through index.documents, and each record is a JSON
document whose fields you named yourself.
from pinecone import DenseVectorQuery, Pinecone
pc = Pinecone(api_key="your-api-key") # or omit and set PINECONE_API_KEY
# Create an index. This blocks until the index is ready.
pc.indexes.create(
name="movie-recommendations",
schema={"fields": {"your_vector": {"type": "dense_vector", "dimension": 3, "metric": "cosine"}}},
deployment={"deployment_type": "managed", "cloud": "aws", "region": "us-east-1"},
)
# Get a data-plane handle for that index
index = pc.index("movie-recommendations")
# Upsert documents. Each one needs an `_id`; every other key is either a field
# you declared in the schema or arbitrary metadata.
index.documents.upsert(
namespace="movies-en",
documents=[
{"_id": "movie-001", "your_vector": [0.1, 0.2, 0.3], "title": "Arrival"},
{"_id": "movie-002", "your_vector": [0.4, 0.5, 0.6], "title": "Interstellar"},
],
)
# Search. `score_by` names the field to compare against.
results = index.documents.search(
namespace="movies-en",
top_k=5,
score_by=[DenseVectorQuery(field="your_vector", values=[0.1, 0.2, 0.3])],
include_fields=["title"],
)
for doc in results.matches:
print(doc.id, doc.score)Upserts apply asynchronously, so a document may not be visible to the next search immediately.
Indexes created another way use other methods: an index created with the
deprecated top-level dimension=/metric= uses index.upsert / index.query, and
a legacy integrated index (pc.indexes.create_for_model(...)) uses
index.upsert_records / index.search. For new indexes that embed text for you,
give a document index a field with integrated embedding. See the
quickstart and the
documentation.
The SDK provides an async client for use with asyncio. Its index() is a
coroutine, and the handle it returns is a context manager:
import asyncio
from pinecone import AsyncPinecone, DenseVectorQuery
async def main():
async with AsyncPinecone(api_key="your-api-key") as pc:
index = await pc.index("movie-recommendations")
async with index:
results = await index.documents.search(
namespace="movies-en",
top_k=5,
score_by=[DenseVectorQuery(field="your_vector", values=[0.1, 0.2, 0.3])],
include_fields=["title"],
)
for doc in results.matches:
print(doc.id, doc.score)
asyncio.run(main())from pinecone import Pinecone
pc = Pinecone(
api_key="your-api-key", # or omit and set PINECONE_API_KEY
timeout=60, # request timeout in seconds; index handles inherit it
)Setting PINECONE_DEBUG=1 before importing pinecone sets the pinecone logger
to DEBUG. The SDK installs no log handler, so configure one to see the output:
import logging
logging.basicConfig()Clone the repository and install the dev dependency group with uv, which is what CI does:
uv sync --group devuv run pytest tests/unit/ -x -v # tests
uv run mypy --strict pinecone/ # type checking
uv run ruff check --fix # linting
uv run ruff format # formattingThe unit suite must leave the working tree clean: git status is expected to report
no changes after a bare uv run pytest tests/unit. Use tmp_path /
tmp_path_factory if a test genuinely needs a file on disk.
Integration suites that hit a real backend are opt-in because they cost money;
each module documents its own gate. Before any release that touches retry logic, HTTP
transport, the AIMD adaptive-concurrency limiter, or the batch-upsert path, run
tests/integration/test_retry_smoke.py with PINECONE_API_KEY and
PINECONE_RETRY_SMOKE=1 set.
Apache-2.0. See LICENSE for details.