# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a Go port of the [yandex-music-api](https://github.com/MarshalX/yandex-music-api) Python library. The original Python library is in `yandex-music-api-python/` and serves as the reference implementation. The Python library provides: - **Sync and async HTTP clients** for Yandex Music API - **Ynison protocol support** for player synchronization across devices - **Radio sessions** (My Wave, generative stations) - **High-level wrapper objects** (Track, Album, Artist, Playlist, etc.) - **Schema mismatch handling** for API evolution - **Multiple JSON backend support** (orjson, pydantic-core, ujson, stdlib json) ## Python Library Architecture (Reference) ### Core Structure ``` yandex_music/ ├── client.py # Sync Client (main entry point) ├── client_async.py # Async ClientAsync ├── _client_base.py # Shared base class with common attributes ├── base.py # YandexMusicObject base model with de_json/de_list ├── exceptions.py # Custom exceptions ├── utils/ │ ├── request.py # Sync HTTP request handling │ ├── request_async.py # Async HTTP request handling │ ├── json_backend.py # Pluggable JSON backends │ └── schema_mismatch.py # Schema mismatch reporting ├── _client/ # Generated sync method mixins (20+ files) ├── _client_async/ # Generated async method mixins ├── track/, album/, artist/, playlist/, etc. # Model packages ├── ynison/ # Ynison protocol (WebSocket) │ ├── client.py # Sync Ynison client │ ├── client_async.py # Async Ynison client │ └── models/ # Protobuf-generated models └── supplement/ # Lyrics, video supplements ``` ### Key Patterns - **Mixin-based Client**: `Client` inherits from 20+ mixins (AccountMixin, AlbumsMixin, TracksMixin, etc.) - **Model deserialization**: Each model has `de_json(data, client)` and `de_list(list_data, client)` classmethods - **Request signing**: Requests to `api.music.yandex.net` are signed with a custom algorithm - **Device auth**: OAuth Device Flow for token acquisition - **Generated code**: Sync/async clients and models are partially code-generated from OpenAPI spec ## Go Project Structure (Target) ``` yandex-music-api-go/ ├── go.mod ├── go.sum ├── cmd/ │ └── examples/ # Example applications ├── internal/ │ ├── client/ # Core HTTP client │ │ ├── client.go # Main Client struct │ │ ├── request.go # Request building/signing │ │ └── auth.go # Device auth, token handling │ ├── models/ # Data models (Track, Album, Artist, etc.) │ │ ├── base.go # BaseModel interface │ │ ├── track.go │ │ ├── album.go │ │ └── ... │ ├── ynison/ # Ynison WebSocket client │ │ ├── client.go │ │ └── proto/ # Protobuf-generated Go code │ └── utils/ │ ├── json.go # JSON handling │ └── schema.go # Schema mismatch handling ├── yandexmusic/ # Public API package (re-exports) │ ├── client.go # Public Client interface │ └── models.go # Public model types └── tests/ # Integration tests ``` ## Development Commands ### Go Toolchain ```bash # Initialize module (run once) go mod init github.com/your-org/yandex-music-api-go # Download dependencies go mod tidy # Build go build ./... # Run tests go test ./... # Run tests with coverage go test -cover ./... # Run single test go test -v -run TestName ./path/to/package # Lint (requires golangci-lint) golangci-lint run # Format go fmt ./... # Vet go vet ./... # Generate code (if using code generation) go generate ./... ``` ### Protobuf (for Ynison) ```bash # Install protoc and plugins go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest go install github.com/bufbuild/buf/cmd/buf@latest # optional, for buf.yaml workflow # Generate from .proto files protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ internal/ynison/proto/*.proto # Or with buf buf generate ``` ## Key Implementation Notes ### Request Signing The Python library signs requests with a custom algorithm. Port this exactly from `yandex_music/utils/request.py`: - Request parameters are sorted and concatenated - Signed with a secret key - Signature added as `sign` parameter ### JSON Handling Go's standard `encoding/json` is fast enough. No need for multiple backends. Use `json.RawMessage` for flexible fields. ### Schema Mismatch Handling Port the Python `SchemaMismatch` logic: - Track unknown fields in API responses - Configurable: ignore, warn, or strict (error) - Callback support for custom handling (e.g., Sentry) ### Ynison Protocol - Uses WebSocket with protobuf messages - Python uses `betterproto` for protobuf; Go uses standard `protobuf` module - Port the message types from `yandex_music/ynison/models/` ### Model Structure Follow Python patterns: ```go // Base interface for all models type Model interface { // DeJSON deserializes from JSON DeJSON(data []byte, client *Client) (Model, error) // DeList deserializes a list DeList(data []byte, client *Client) ([]Model, error) } ``` ### Client Design - Single `Client` struct with methods (not mixins - Go doesn't have them) - Group methods by feature using separate files: `client_tracks.go`, `client_albums.go`, etc. - Support both sync and async (context-based) patterns ## Testing Strategy - Unit tests for models (de/serialization) - Integration tests against mock server (use `httptest`) - Test schema mismatch handling - Test request signing ## License LGPL-3.0-only (same as Python library) ## References - Python library: `yandex-music-api-python/` - OpenAPI spec: https://ym.marshal.dev/api/openapi.json - Documentation: https://ym.marshal.dev/ - Telegram: https://t.me/yandex_music_api