Compare commits

...

4 Commits

Author SHA1 Message Date
7627e9e273 Merge pull request '1.0.2' (#7) from dev into latest
All checks were successful
Build And Publish Package / publish (push) Successful in 26s
Reviewed-on: #7
2026-04-14 23:38:44 +03:00
3cbed95c08 Фикс схемы недавних треков
All checks were successful
Verify Dev Build / publish (push) Successful in 25s
2026-04-14 23:24:50 +03:00
c15db42e5b Merge pull request '1.0.1' (#6) from dev into latest
All checks were successful
Build And Publish Package / publish (push) Successful in 23s
Reviewed-on: #6
2026-04-14 16:45:21 +03:00
80a97758a6 Попытка фикса валидации даты выхода
All checks were successful
Verify Dev Build / publish (push) Successful in 30s
2026-04-14 16:43:25 +03:00
2 changed files with 31 additions and 10 deletions

View File

@ -1,6 +1,6 @@
[project] [project]
name = "oxidespotify" name = "oxidespotify"
version = "1.0.0" version = "1.0.2"
description = "Client for Spotify API" description = "Client for Spotify API"
readme = "README.md" readme = "README.md"
authors = [{ name = "Miwory", email = "miwory.uwu@gmail.com" }] authors = [{ name = "Miwory", email = "miwory.uwu@gmail.com" }]

View File

@ -1,7 +1,13 @@
from datetime import datetime from datetime import date, datetime
from typing import Literal from typing import Annotated, Literal
from pydantic import BaseModel, HttpUrl, RootModel, field_validator from pydantic import (
BaseModel,
BeforeValidator,
HttpUrl,
RootModel,
field_validator,
)
class Error(Exception): class Error(Exception):
@ -22,6 +28,21 @@ class InternalError(Error):
pass pass
def normalize_spotify_date(v: str) -> str:
parts = v.split('-')
if len(parts) == 1:
return f'{v}-01-01'
if len(parts) == 2:
return f'{v}-01'
return v
PrecisionedReleaseDate = Annotated[
date, BeforeValidator(normalize_spotify_date)
]
class Token(BaseModel): class Token(BaseModel):
token_type: Literal['Bearer'] token_type: Literal['Bearer']
access_token: str access_token: str
@ -72,8 +93,8 @@ class Paginated(BaseModel):
limit: int limit: int
next: HttpUrl | None next: HttpUrl | None
offset: int = 0 offset: int = 0
previous: HttpUrl | None previous: HttpUrl | None = None
total: int total: int = 0
class ExternalUrls(BaseModel): class ExternalUrls(BaseModel):
@ -134,7 +155,7 @@ class BaseAlbum(BaseModel):
id: str id: str
images: list[Image] images: list[Image]
name: str name: str
release_date: datetime release_date: PrecisionedReleaseDate
release_date_precision: Literal['year', 'month', 'day'] release_date_precision: Literal['year', 'month', 'day']
restrictions: Restriction | None = None restrictions: Restriction | None = None
type: Literal['album'] type: Literal['album']
@ -206,7 +227,7 @@ class AudioBookChapter(BaseModel):
is_playable: bool is_playable: bool
languages: list[str] languages: list[str]
name: str name: str
release_date: datetime release_date: PrecisionedReleaseDate
release_date_precision: Literal['year', 'month', 'day'] release_date_precision: Literal['year', 'month', 'day']
resume_point: ResumePoint resume_point: ResumePoint
type: Literal['episode'] type: Literal['episode']
@ -287,7 +308,7 @@ class Devices(BaseModel):
class RecentlyPlayedTrack(BaseModel): class RecentlyPlayedTrack(BaseModel):
track: Track track: Track
played_at: datetime played_at: datetime
context: Context context: Context | None = None
class RecentlyPlayedTracks(Paginated): class RecentlyPlayedTracks(Paginated):
@ -323,7 +344,7 @@ class PlaylistTracks(Paginated):
class SimplifiedPlaylistTracks(Paginated): class SimplifiedPlaylistTracks(Paginated):
href: HttpUrl href: HttpUrl
total: int total: int = 0
class Playlist(BaseModel): class Playlist(BaseModel):