5. spot-sdk Shared Package¶
Date: 2025-11-04
Status: Accepted
Deciders: Core Team
Related: ADR-001 (Microservices), ADR-003 (Pydantic), ADR-004 (Separate Repos)
Context¶
With separate repositories for each analyzer, we need a way to:
- Share interface definitions across all services
- Define common data models (Email, AnalysisResult, etc.)
- Ensure analyzers implement compatible interfaces
- Version the contract independently from implementations
- Support multiple programming languages (Python, TypeScript)
- Make it easy for external developers to create custom analyzers
Requirements:
- Single source of truth for all interfaces
- Semantic versioning for compatibility tracking
- Language-agnostic contract definitions
- Easy to consume from analyzer projects
- Support for both internal and external developers
Decision¶
Create spot-sdk as a separate repository and package containing:
- Python SDK (spot-sdk-python) with Pydantic models
- TypeScript SDK (spot-sdk-typescript) with type definitions
- OpenAPI specifications for HTTP endpoints
- Interface definitions (AnalyzerInterface ABC)
- Common enums (ThreatLevel, IndicatorType)
Published to GitLab package registry for internal use.
Rationale¶
- Single Source of Truth: All interfaces defined in one place
- Versioning: Semantic versioning allows tracking compatibility
- Language Support: Generate SDKs for multiple languages
- External Friendly: Third parties can create analyzers
- Type Safety: Strong contracts prevent integration issues
- Documentation: Interfaces serve as API documentation
- Tooling: OpenAPI specs enable code generation
Consequences¶
Positive¶
- Clear contracts prevent integration bugs
- Analyzers can be developed independently
- Version incompatibility detected early
- External developers can create analyzers
- Automatic API documentation from schemas
- Type checking in IDE prevents errors
- Can generate clients in any language
Negative¶
- Need to maintain separate package
- Breaking changes require coordination
- Version management overhead
- Publish/consume workflow complexity
- Need to version and release contracts separately
Alternatives Considered¶
Alternative 1: Copy contracts to each repo¶
- Pros:
- No external dependency
- Each repo self-contained
- Simple to understand
- Cons:
- Contracts drift over time
- Manual synchronization needed
- No single source of truth
- Version tracking impossible
- Changes require updates in multiple places
- Why rejected: Too error-prone, defeats purpose of contracts
Alternative 2: Platform repo as dependency¶
- Pros:
- No additional repository
- Contracts live with main code
- Cons:
- Analyzers depend on entire platform
- Cannot version contracts independently
- External developers need access to platform repo
- Circular dependency issues
- Tighter coupling than desired
- Why rejected: Creates unwanted coupling between platform and analyzers
Alternative 3: Protocol Buffers¶
- Pros:
- Language-agnostic binary format
- Efficient serialization
- Built-in versioning
- Industry standard
- Cons:
- Less human-readable
- More complex toolchain
- Overkill for HTTP/JSON APIs
- Less Python-idiomatic
- Steeper learning curve
- Why rejected: JSON/Pydantic simpler for our HTTP-based architecture
Implementation Notes¶
Package structure:
spot-sdk/
├── interfaces/ # Python interfaces and models
│ ├── analyzer.py # AnalyzerInterface ABC
│ ├── email.py # Email data models
│ ├── results.py # AnalysisResult models
│ ├── orchestrator.py # Orchestration models
│ └── workflow.py # Workflow models
├── sdk/
│ ├── python/ # Python SDK (Pydantic models)
│ └── typescript/ # TypeScript SDK (generated)
├── openapi/ # OpenAPI specifications
├── docs/
│ └── ANALYZER_DEVELOPMENT.md
└── pyproject.toml # Package metadata
Consumption in analyzers:
Usage example:
from spot_sdk import Email, AnalysisResult, AnalyzerInterface
class MyAnalyzer(AnalyzerInterface):
async def analyze(self, email: Email) -> AnalysisResult:
# Implementation
pass
Versioning:
- MAJOR: Breaking changes to interfaces
- MINOR: Backward-compatible additions
- PATCH: Bug fixes, documentation
References¶
- Semantic Versioning
- OpenAPI Specification
- Repository:
spot-sdk/ - Guide:
spot-sdk/docs/ANALYZER_DEVELOPMENT.md