Spotipy Types - Implementation Plan
Plans a Pydantic v2 type stub package for the Spotify Web API, auto-generated from the official OpenAPI schema.
What this file does
Plans a Pydantic v2 type stub package for the Spotify Web API, auto-generated from the official OpenAPI schema.
When to use it
- You want typed spotipy responses with IDE autocomplete
- You need runtime validation of Spotify API data
- You are building a tool that consumes Spotify Web API responses
- You want to regenerate models when the Spotify schema updates
Assumes this stack
Spotipy Types - Implementation Plan
A standalone type stub package for spotipy using Pydantic models generated from the official Spotify Web API OpenAPI schema.
Overview
This repository provides complete Python type hints for the Spotify Web API by auto-generating Pydantic v2 models from the official OpenAPI schema. This enables full IDE autocomplete, type checking, and runtime validation when working with spotipy.
Repository Structure
spotipy-types/
├── src/
│ └── spotipy_types/ # Generated package
│ ├── __init__.py # Re-exports all models
│ ├── models.py # Generated from OpenAPI (~3K lines)
│ └── _version.py # Version info (matches schema date)
├── schemas/
│ └── spotify_openapi.yaml # Official Spotify OpenAPI schema
├── scripts/
│ └── generate_models.py # Code generation automation
├── tests/
│ └── test_models.py # Validation tests
├── .github/
│ └── workflows/
│ ├── generate.yml # Auto-regenerate on schema updates
│ └── publish.yml # PyPI publishing
├── pyproject.toml # Package configuration
├── README.md # Usage documentation
├── LICENSE # MIT License
└── Makefile # Convenience commands
Phase 1: Repository Setup
1.1 Initialize Package Structure
- Create
pyproject.tomlwith hatchling build backend - Set package metadata:
- Name:
spotipy-types - Version:
2025.5.18(matches schema version) - Python:
>=3.11 - Dependencies:
pydantic>=2.0.0
- Name:
1.2 Configuration Files
.gitignore- Standard Python ignores + generated filesLICENSE- MIT LicenseMakefilewith commands:make generate- Run datamodel-codegenmake test- Run pytestmake lint- Run ruff and mypymake build- Build wheelmake publish- Publish to PyPI
Phase 2: Code Generation Setup
2.1 Install datamodel-codegen
pip install datamodel-code-generator
2.2 Generation Script (scripts/generate_models.py)
datamodel-codegen \
--input schemas/spotify_openapi.yaml \
--input-file-type openapi \
--output src/spotipy_types/models.py \
--output-model-type pydantic_v2.BaseModel \
--use-union-operator \
--use-standard-collections \
--use-default-kwarg \
--target-python-version 3.11 \
--use-field-description \
--wrap-string-literal \
--field-constraints \
--collapse-root-models \
--set-default-enum-member
2.3 Post-Generation Processing
- Add module docstring with version info
- Ensure all imports are properly organized
- Verify no circular import issues
- Add
__all__export list
Phase 3: Package Implementation
3.1 Generated Models (src/spotipy_types/models.py)
Expected content:
- ~120 Pydantic model classes
- ~3,000 lines of generated code
- All Spotify API response types:
- TrackObject, AlbumObject, ArtistObject
- PlaylistObject, EpisodeObject, ShowObject
- UserObject, DeviceObject, ContextObject
- AudioFeaturesObject, AudioAnalysisObject
- SearchResponse, PagingObject, CursorPagingObject
- And 100+ more...
3.2 Package Initialization (src/spotipy_types/__init__.py)
"""Spotipy Types - Pydantic models for the Spotify Web API."""
from spotipy_types._version import __version__
from spotipy_types.models import (
TrackObject,
AlbumObject,
ArtistObject,
# ... all 120+ models
)
__all__ = [
"__version__",
"TrackObject",
"AlbumObject",
"ArtistObject",
# ... all exports
]
3.3 Version Module (src/spotipy_types/_version.py)
"""Version information."""
__version__ = "2025.5.18"
__schema_version__ = "2025.5.18"
__schema_source__ = "https://github.com/sonallux/spotify-web-api"
Phase 4: Testing & Validation
4.1 Test Suite (tests/test_models.py)
Tests should cover:
- Model instantiation with valid data
- Required field validation
- Optional field handling
- Nested object validation
- Enum validation
- Union type handling (TrackObject | EpisodeObject)
- JSON serialization/deserialization roundtrip
4.2 Type Checking
- Run mypy on generated code
- Verify no typing errors
- Check import resolution
Phase 5: CI/CD Automation
5.1 GitHub Actions: Generate Workflow (.github/workflows/generate.yml)
Triggered on:
- PRs that modify
schemas/spotify_openapi.yaml - Manual dispatch
Steps:
- Checkout code
- Install datamodel-codegen
- Run generation script
- Check if models changed
- Create PR with regenerated models
- Run tests on regenerated code
5.2 GitHub Actions: Publish Workflow (.github/workflows/publish.yml)
Triggered on:
- Tags matching
v*pattern
Steps:
- Checkout code
- Install build tools
- Run tests
- Build wheel and sdist
- Publish to PyPI
Phase 6: Documentation
6.1 README.md Sections
-
Installation
pip install spotipy-types -
Basic Usage
from spotipy_types import TrackObject, AlbumObject import spotipy from spotipy.oauth2 import SpotifyClientCredentials # Get typed results from spotipy sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials()) # Type hint for IDE autocomplete track: TrackObject = sp.track("11dFghVXANMlKmJXsNCbNl") print(track.name) # IDE suggests this print(track.artists[0].name) # Full nested type support -
Validation
from spotipy_types import TrackObject # Runtime validation of API responses raw_data = {"id": "abc123", "name": "Song Name", ...} track = TrackObject.model_validate(raw_data) -
Type Checking with mypy
# mypy will catch type errors track: TrackObject = sp.track("some_id") # This will fail mypy - id is a string, not int print(track.id + 1) # Error: can't add int to str -
Supported Models
- List all 120+ generated models
- Link to full API reference
-
Versioning
- Package version matches schema version
- Pin to specific version for reproducibility
-
Development
- How to regenerate models
- How to contribute
6.2 Changelog.md
Track changes between schema versions:
- Added fields
- Removed fields
- Type changes
- Breaking changes
Technical Decisions
Why Pydantic v2?
- Best-in-class Python data validation
- Excellent IDE support via type hints
- JSON Schema compatibility
- Active development and large ecosystem
Why Python 3.11+?
- Union operator syntax (
X | YvsUnion[X, Y]) - Better performance
- Modern typing features
- Cleaner generated code
Why Full Models vs Stubs?
- Runtime validation catches API changes
- Serialization/deserialization support
- Better than static stubs for dynamic data
Schema Analysis
Source Schema: spotify_schema.txt
- Format: OpenAPI 3.0.3 (already converted)
- Size: ~260KB, 6,945 lines
- Components section: Line 3,525
- Schemas section: Line 4,085
Key Schema Patterns
- Heavy Reference Usage: Deep chains (AlbumObject → ArtistObject → ImageObject)
- Union Types:
items: TrackObject | EpisodeObjectfor polymorphic responses - Inheritance via allOf: Composition pattern for shared fields
- Nullable Fields:
display_name: string | nullwithnullable: true
Expected Generated Code Stats
- Total lines: ~3,000
- Model classes: ~120
- Average class size: 15-30 fields
- Most complex models: TrackObject, AlbumObject, EpisodeObject
Usage Examples
Example 1: Type-Safe Track Access
from spotipy_types import TrackObject
import spotipy
sp = spotipy.Spotify(auth=token)
track: TrackObject = sp.track("track_id")
# Full autocomplete support
artist_names = [a.name for a in track.artists]
duration_ms = track.duration_ms
is_explicit = track.explicit
Example 2: Search Response Handling
from spotipy_types import SearchResponse
results = sp.search(q="radiohead", type="track")
search_response = SearchResponse.model_validate(results)
# Type-safe access to paginated results
tracks = search_response.tracks.items
for track in tracks:
print(f"{track.name} by {track.artists[0].name}")
Example 3: Playlist Management
from spotipy_types import PlaylistObject, PlaylistTrackObject
playlist: PlaylistObject = sp.playlist("playlist_id")
tracks: list[PlaylistTrackObject] = playlist.tracks.items
for item in tracks:
track = item.track
added_by = item.added_by.display_name
Migration Path for Existing Spotipy Users
Before (no types)
import spotipy
sp = spotipy.Spotify(auth=token)
track = sp.track("id") # Returns dict
print(track["name"]) # No autocomplete, typo-prone
After (with spotipy-types)
import spotipy
from spotipy_types import TrackObject
sp = spotipy.Spotify(auth=token)
track: TrackObject = sp.track("id") # Same call, typed result
print(track.name) # IDE autocomplete works!
Future Enhancements
- Async Support: Models work with async spotipy clients
- Optional Validation: Allow passthrough mode for performance
- Partial Models: Generate subset models for specific use cases
- Documentation Links: Add docstring links to Spotify API docs
- Example Data: Include example instances for each model
Timeline
- Phase 1: 15 minutes - Repository setup
- Phase 2: 20 minutes - Code generation configuration
- Phase 3: 15 minutes - Package structure and exports
- Phase 4: 20 minutes - Testing and validation
- Phase 5: 20 minutes - CI/CD automation
- Phase 6: 15 minutes - Documentation
Total: ~2 hours to fully functional package
Success Metrics
- Package installs successfully via pip
- All 120+ models import without errors
- mypy passes with zero errors
- Basic smoke tests pass
- Example usage works in IDE with autocomplete
- Published to PyPI
Notes
- Schema source: https://github.com/sonallux/spotify-web-api
- Package will be community-maintained
- Follows semantic versioning for schema updates
- Generated code is committed for transparency
- Original schema preserved for regeneration
Next Step: Proceed to Phase 1 - Create pyproject.toml and repository structure
What's inside
6 phases, 120+ model classes, 2 CI workflows, 3 usage examples, and a migration path.
Change this for your project
- Replace
spotipy-typeswith your own package name - Replace
2025.5.18with your target schema version - Replace
https://github.com/sonallux/spotify-web-apiwith your schema source URL
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Auto-generate models from an official OpenAPI schema to stay in sync with API changes
- Use a Makefile to wrap code generation, testing, and publishing commands
- Commit generated code for transparency and reproducibility
Related Documents
MCP Integration Workflows and Orchestration Guide
Defines enterprise-grade integration patterns, orchestration strategies, and advanced workflows for MCP servers with code examples.
AI-Generated Short-Form Video Platform
Defines a modular SaaS pipeline that transforms uploaded MP4 videos into polished short-form clips using AI agents and human review.
Valet V1 — Architecture & Implementation Plan
Defines a hosted background coding agent platform with isolated sandboxed dev environments, multiplayer sessions, and YAML-driven workflows.
GitHub Topics & Skills Monitor
Provides a structured GitHub monitoring strategy with search queries, watchlist, and notification options for AI skills, agents, and MCP servers.