You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:14:55