# Architecture Overview

## Introduction

The Pinecone Python SDK is designed as a layered system with clear separation of concerns, enabling maintainability, testability, and extensibility. This document provides a high-level overview of the system architecture.

## Design Principles

### 1. Separation of Concerns

The SDK separates public interfaces from implementation details, ensuring:
- Users interact with stable, well-documented APIs
- Internal implementations can evolve without breaking changes
- Protocol definitions serve as explicit contracts

### 2. Explicit Dependencies

All dependencies between components are explicit:
- No circular dependencies
- Clear dependency flow from public API → protocols → implementations
- Type annotations make relationships visible

### 3. Type Safety

Strong typing throughout the system:
- Protocol-based interfaces for flexibility
- Runtime type checking where needed
- Full mypy compliance

## System Architecture

### High-Level View

```mermaid
graph TB
    User[User Code]

    subgraph SDK["Pinecone Python SDK"]
        Public["Public API<br/>__init__.py"]
        Protocol["Protocol Layer<br/>__interface__/"]
        Internal["Implementation Layer<br/>_internal/"]

        Public --> Protocol
        Protocol --> Internal
    end

    subgraph External["External Services"]
        API["Pinecone API<br/>(REST/gRPC)"]
        Auth["Authentication<br/>Service"]
    end

    User --> Public
    Internal --> API
    Internal --> Auth

    style Public fill:#e1f5ff
    style Protocol fill:#fff3e0
    style Internal fill:#f3e5f5
```

### Three-Layer Architecture

The SDK implements a strict three-layer architecture:

```mermaid
graph LR
    subgraph Layer1["Layer 1: Public API"]
        A1[pinecone/__init__.py]
        A2[Top-level exports]
        A3[Client construction]
    end

    subgraph Layer2["Layer 2: Protocols"]
        B1[__interface__/]
        B2[Type contracts]
        B3[Method signatures]
    end

    subgraph Layer3["Layer 3: Implementation"]
        C1[_internal/]
        C2[HTTP clients]
        C3[Serialization]
        C4[Error handling]
    end

    A1 --> B1
    B1 --> C1

    style Layer1 fill:#e1f5ff
    style Layer2 fill:#fff3e0
    style Layer3 fill:#f3e5f5
```

#### Layer 1: Public API

**Location:** `pinecone/__init__.py`

**Responsibilities:**
- Export stable, user-facing APIs
- Re-export implementations from `_internal/`
- Provide top-level client construction
- Define the user experience

**Rules:**
- Never contains implementation logic
- Only imports from `__interface__` and `_internal`
- Maintains backward compatibility

#### Layer 2: Protocol Layer

**Location:** `pinecone/__interface__/`

**Responsibilities:**
- Define type protocols for all public interfaces
- Specify method signatures and return types
- Document interface contracts
- Enable duck typing and testing

**Rules:**
- Uses `typing.Protocol` with `@runtime_checkable`
- No implementation code, only specifications
- Protocol methods must be complete with types

#### Layer 3: Implementation Layer

**Location:** `pinecone/_internal/`

**Responsibilities:**
- Implement protocols from `__interface__`
- Handle HTTP communication
- Manage serialization/deserialization
- Process errors and retries

**Rules:**
- Not directly importable by users
- Must implement corresponding protocols
- Can use any internal dependencies

## Component Architecture

### Client Architecture

```mermaid
graph TB
    subgraph UserCode["User Code"]
        U[User Application]
    end

    subgraph PublicAPI["Public API Layer"]
        PC[Pinecone Client]
    end

    subgraph Protocols["Protocol Layer"]
        IPC[IPineconeClient]
        IIC[IIndexClient]
        IDC[IDataClient]
    end

    subgraph Implementation["Implementation Layer"]
        PCI[PineconeClientImpl]
        ICI[IndexClientImpl]
        DCI[DataClientImpl]
        HTTP[HTTP Client]
        SER[Serializers]
        ERR[Error Handlers]
    end

    subgraph External["External Services"]
        REST[REST API]
        GRPC[gRPC API]
    end

    U --> PC
    PC -.implements.-> IPC
    IPC --> PCI

    PCI --> ICI
    ICI -.implements.-> IIC

    PCI --> DCI
    DCI -.implements.-> IDC

    ICI --> HTTP
    DCI --> HTTP
    HTTP --> REST
    HTTP --> GRPC

    ICI --> SER
    DCI --> SER

    ICI --> ERR
    DCI --> ERR

    style PublicAPI fill:#e1f5ff
    style Protocols fill:#fff3e0
    style Implementation fill:#f3e5f5
```

### Request Flow

```mermaid
sequenceDiagram
    participant User
    participant Public as Public API
    participant Protocol as Protocol Layer
    participant Impl as Implementation
    participant HTTP as HTTP Client
    participant API as Pinecone API

    User->>Public: client.index("my-index")
    Public->>Protocol: Validate interface contract
    Protocol->>Impl: Call implementation
    Impl->>HTTP: Build HTTP request
    HTTP->>API: Execute request
    API-->>HTTP: Response
    HTTP-->>Impl: Parse response
    Impl->>Impl: Handle errors
    Impl->>Impl: Deserialize data
    Impl-->>Protocol: Return typed result
    Protocol-->>Public: Return to user
    Public-->>User: Typed response
```

## Module Organization

### Directory Structure

```
pinecone/
├── __init__.py                  # Public exports only
├── __interface__/               # Protocol definitions
│   ├── __init__.py
│   ├── client.py               # Client protocols
│   ├── index.py                # Index data plane protocol (includes Metadata, SparseValues)
│   ├── indexes/                # Index management namespace
│   │   ├── __init__.py
│   │   ├── types.py            # Control plane types (MetricType, IndexSpec, etc.)
│   │   ├── config.py           # Index configuration
│   │   ├── info.py             # Index metadata
│   │   ├── namespace.py        # Sync operations
│   │   └── async_namespace.py  # Async operations
│   ├── collections/            # Collection management namespace
│   │   ├── __init__.py
│   │   ├── types.py            # Collection types (CollectionStatus)
│   │   ├── info.py             # Collection metadata
│   │   └── namespace.py        # Operations
│   ├── backups/                # Backup management namespace
│   │   ├── __init__.py
│   │   ├── types.py            # Backup types (BackupStatus)
│   │   ├── info.py             # Backup metadata
│   │   └── namespace.py        # Operations
│   └── inference/              # Inference operation namespace
│       ├── __init__.py
│       ├── types.py            # Inference types (EmbedParameters, etc.)
│       ├── usage.py            # Token usage
│       ├── results.py          # Rerank results
│       ├── responses.py        # API responses
│       ├── namespace.py        # Sync operations
│       └── async_namespace.py  # Async operations
├── _internal/                   # Implementation layer
│   ├── __init__.py
│   ├── adapters/               # Response adapters
│   │   ├── __init__.py
│   │   └── inference_adapter.py
│   ├── constants.py            # Shared constants
│   ├── http/                   # HTTP client logic
│   │   ├── __init__.py
│   │   ├── async_client.py    # Async HTTP client
│   │   ├── base.py            # Base HTTP functionality
│   │   ├── client.py          # Sync HTTP client
│   │   └── config.py          # HTTP configuration
│   ├── logging.py              # Logging utilities
│   └── migrate/                # Migration tooling
│       ├── __init__.py
│       └── __main__.py
├── models/                      # Data models (public)
│   ├── __init__.py
│   └── inference.py            # Inference request/response models
├── client.py                    # Sync client implementation
├── async_client.py             # Async client implementation
├── inference.py                # Sync inference implementation
├── async_inference.py          # Async inference implementation
├── exceptions.py               # Exception hierarchy
└── py.typed                    # PEP 561 marker
```

## Design Decisions

### Why Three Layers?

1. **Stability:** Public API can remain stable while implementations evolve
2. **Testing:** Protocols enable easy mocking and testing
3. **Documentation:** Clear contracts make the API self-documenting
4. **Flexibility:** Multiple implementations can satisfy the same protocol

### Why Protocols Over ABCs?

- **Structural Subtyping:** No need to inherit from base classes
- **Duck Typing:** More Pythonic, supports existing code
- **Flexibility:** Third parties can implement without modification
- **Testing:** Easier to create test doubles

### Why Internal Package?

- **Encapsulation:** Implementation details hidden from users
- **Refactoring:** Internal code can change without breaking users
- **Import Safety:** Prevents accidental use of internal APIs
- **Documentation:** Clear signal about what's public vs private

## Error Handling Architecture

```mermaid
graph TB
    subgraph User["User Code"]
        UC[User Call]
    end

    subgraph SDK["SDK"]
        API[Public API]
        Impl[Implementation]
        HTTP[HTTP Client]
    end

    subgraph Error["Error Processing"]
        Parse[Parse Response]
        Map[Map to SDK Error]
        Enhance[Add Context]
    end

    subgraph Exception["Exception Hierarchy"]
        Base[PineconeException]
        API_ERR[PineconeApiException]
        Net[NetworkError]
        Auth[AuthenticationError]
        Val[ValidationError]
    end

    UC --> API
    API --> Impl
    Impl --> HTTP
    HTTP --> Parse
    Parse --> Map
    Map --> Enhance
    Enhance --> Base
    Base --> API_ERR
    Base --> Net
    Base --> Auth
    Base --> Val

    style Error fill:#ffebee
    style Exception fill:#fce4ec
```

## Async Architecture

The SDK supports both synchronous and asynchronous usage:

```mermaid
graph LR
    subgraph Sync["Synchronous API"]
        S1[PineconeClient]
        S2[Blocking calls]
        S3[requests/httpx]
    end

    subgraph Async["Asynchronous API"]
        A1[AsyncPineconeClient]
        A2[Async/await]
        A3[httpx.AsyncClient]
    end

    subgraph Shared["Shared Components"]
        P[Protocols]
        M[Models]
        V[Validators]
    end

    S1 --> P
    A1 --> P
    S3 --> M
    A3 --> M

    style Sync fill:#e8f5e9
    style Async fill:#e3f2fd
    style Shared fill:#fff3e0
```

## Extension Points

The architecture supports extension through:

1. **Protocol Implementation:** Create custom clients implementing protocols
2. **HTTP Client Replacement:** Swap HTTP implementation
3. **Middleware:** Add request/response processing
4. **Custom Serializers:** Handle custom data types

## Performance Considerations

See [Performance Conventions](../conventions/performance.md) for details on:
- Connection pooling
- Request batching
- Caching strategies
- Resource management

## Related Documentation

- [API Structure](./api-structure.md) - Detailed API organization
- [Specifications](./specifications.md) - Protocol specifications
- [Verification](./verification.md) - Testing and CI
- [Architecture Conventions](../conventions/architecture.md) - Coding conventions
- [Type Conventions](../conventions/types.md) - Type system usage
- [Error Conventions](../conventions/errors.md) - Error handling patterns

---

*Last audited: February 5, 2026*
