Pinecone向量数据库403权限异常解决求助(API密钥有效)
问题:Pinecone 403 ForbiddenException(Wrong API key)排查与解决
我正在Pinecone向量数据库中执行数据映射操作:已通过Airbyte将PostgreSQL内3张表的数据导入至Pinecone的foaps-aws索引,现需将映射后的数据写入foaps-merged索引用于搭建聊天机器人。但运行代码时触发ForbiddenException(403),响应头提示'Wrong API key',但我确认API密钥是有效的。
运行代码
from langchain.document_loaders import TextLoader from langchain.text_splitter import CharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Pinecone from langchain.llms import HuggingFaceHub from dotenv import load_dotenv import os from pinecone import Pinecone, ServerlessSpec from langchain import PromptTemplate from langchain.schema.runnable import RunnablePassthrough from langchain.schema.output_parser import StrOutputParser from langchain.chains import ConversationalRetrievalChain, RetrievalQA from langchain_pinecone import PineconeVectorStore from openai import OpenAI from langchain_openai import ChatOpenAI import logging import uuid import pinecone import requests import json # Setup logging logging.basicConfig(level=logging.INFO) load_dotenv() # Initialize Pinecone instance pc = Pinecone(api_key= os.getenv('PINECONE_API_KEY')) source_index_name = "foaps-aws" # Define target index (where merged data will be stored) target_index_name = 'foaps-merged' if source_index_name not in pc.list_indexes().names(): pc.create_index( name=source_index_name, dimension=1536, metric="cosine", spec=ServerlessSpec( cloud="aws", region="us-east-1" ) ) if target_index_name not in pc.list_indexes().names(): pc.create_index( name=target_index_name, dimension=1536, metric="cosine", spec=ServerlessSpec( cloud="aws", region="us-east-1" ) ) # index = pc.Index(source_index_name) def fetch_data_from_index(index_name): index = pinecone.Index(index_name, host="") total_vectors = index.describe_index_stats()['total_vector_count'] ids = [str(i) for i in range(total_vectors)] fetch_response = index.fetch(ids=ids) print(f"Fetched data from {index_name}: {fetch_response}") return fetch_response['vectors'] def process_and_merge_data(vectors): merged_data = {} for vector_id, vector in vectors.items(): metadata = vector['metadata'] stream_type = metadata.get('_ab_stream') if stream_type == 'public_combos': merged_data[vector_id] = { "combo_id": metadata["id"], "combo_name": metadata["name"], "combo_amount": metadata.get("amount", ""), "restaurant_id": metadata.get("restaurant_id", ""), "location_id": metadata.get("location_id", "") } elif stream_type == 'public_restaurants': if vector_id not in merged_data: merged_data[vector_id] = {"restaurant_id": metadata["id"], "restaurant_name": metadata["name"]} else: merged_data[vector_id]["restaurant_name"] = metadata["name"] elif stream_type == 'public_locations': if vector_id not in merged_data: merged_data[vector_id] = {"location_id": metadata["id"], "location_name": metadata["name"]} else: merged_data[vector_id]["location_name"] = metadata["name"] print(f"Merged data: {merged_data}") return merged_data def upsert_to_target_index(merged_data): target_index = pinecone.Index(target_index_name, host="") vectors_to_upsert = [] for vector_id, data in merged_data.items(): # Create a vector with metadata; values should be actual embedding vectors vector_values = [0.1] * 1536 # Placeholder for actual vector values vectors_to_upsert.append((vector_id, vector_values, data)) print(f"Vectors to upsert: {vectors_to_upsert}") vectors_to_upsert = [] for vector_id, data in merged_data.items(): # Create a vector with metadata; values should be actual embedding vectors vector_values = [0.1] * 1536 # Placeholder for actual vector values vectors_to_upsert.append({"id": vector_id, "values": vector_values, "metadata": data}) print(f"Vectors to upsert: {vectors_to_upsert}") if vectors_to_upsert: target_index.upsert(vectors=vectors_to_upsert) print("Data upsert complete.") else: print("No data to upsert.") def main(): vectors = fetch_data_from_index(source_index_name) merged_data = process_and_merge_data(vectors) upsert_to_target_index(merged_data) if __name__ == "__main__": main()
报错信息
Exception has occurred: ForbiddenException (403) Reason: Forbidden HTTP response headers: HTTPHeaderDict({'Date': 'Tue, 13 Aug 2024 06:44:50 GMT', 'Content-Type': 'text/plain', 'Content-Length': '9', 'Connection': 'keep-alive', 'x-pinecone-auth-rejected-reason': 'Wrong API key', 'www-authenticate': 'Wrong API key', 'server': 'envoy'}) HTTP response body: Forbidden File "C:\Users\FARAZ\Desktop\Projects\FIxed Bot\foaps.py", line 64, in fetch_data_from_index total_vectors = index.describe_index_stats()['total_vector_count'] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\FARAZ\Desktop\Projects\FIxed Bot\foaps.py", line 123, in main vectors = fetch_data_from_index(source_index_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\FARAZ\Desktop\Projects\FIxed Bot\foaps.py", line 128, in <module> main() pinecone.core.openapi.shared.exceptions.ForbiddenException: (403) Reason: Forbidden HTTP response headers: HTTPHeaderDict({'Date': 'Tue, 13 Aug 2024 06:44:50 GMT', 'Content-Type': 'text/plain', 'Content-Length': '9', 'Connection': 'keep-alive', 'x-pinecone-auth-rejected-reason': 'Wrong API key', 'www-authenticate': 'Wrong API key', 'server': 'envoy'}) HTTP response body: Forbidden
排查与修复步骤
1. 核心问题:新旧Pinecone SDK混用导致认证失败
代码中同时使用了两种Pinecone初始化方式:
- 新SDK:
from pinecone import Pinecone,已初始化带API密钥的pc实例 - 旧SDK:
import pinecone,直接调用pinecone.Index()时未传入API密钥,且传入空host参数
旧SDK的索引实例未继承新SDK的认证信息,导致请求时未携带有效API密钥,触发403错误。
2. 修复方案:统一使用新SDK获取索引实例
修改两个函数中创建索引实例的逻辑,通过已认证的pc实例获取索引:
修改fetch_data_from_index函数
def fetch_data_from_index(index_name): # 通过已认证的pc实例获取索引 index = pc.Index(index_name) total_vectors = index.describe_index_stats()['total_vector_count'] ids = [str(i) for i in range(total_vectors)] fetch_response = index.fetch(ids=ids) print(f"Fetched data from {index_name}: {fetch_response}") return fetch_response['vectors']
修改upsert_to_target_index函数
def upsert_to_target_index(merged_data): # 通过已认证的pc实例获取索引 target_index = pc.Index(target_index_name) vectors_to_upsert = [] for vector_id, data in merged_data.items(): # Create a vector with metadata; values should be actual embedding vectors vector_values = [0.1] * 1536 # Placeholder for actual vector values vectors_to_upsert.append({"id": vector_id, "values": vector_values, "metadata": data}) print(f"Vectors to upsert: {vectors_to_upsert}") if vectors_to_upsert: target_index.upsert(vectors=vectors_to_upsert) print("Data upsert complete.") else: print("No data to upsert.")
3. 额外检查项
- 确认
.env文件中PINECONE_API_KEY键名拼写正确,无多余空格或换行 - 验证API密钥所属的Pinecone项目与两个索引属于同一项目
- 检查索引的云服务商/区域是否与代码中
ServerlessSpec配置的aws/us-east-1一致
内容的提问来源于stack exchange,提问作者Faraz
相关产品推荐
相关产品推荐

