Requests are now paced to the documented Discogs rate limit and retried when Discogs pushes back.
NOTE Sustained lookups are slower than 0.2.0 by design. The old fixed 0.5s pause allowed about 120 requests a minute against a 60 a minute limit, so a long run earned a 429 and gave up.
- A trailing
int $page = 1on every endpoint Discogs paginates, so results past the first page are reachable at all —get_artist_releases,get_label_releases,get_master_versions,get_collection_items_by_folder,get_user_lists,get_wantlist,search_album,search_artist,search_masterandsearch_release- previously only page 1 was ever requested, so
get_label_releases(1)reached 50 of 592 releases andsearch_album()reached 10 of 487 matches, with no way to ask for the rest - the
paginationblock Discogs returns tells you how many pages there are - NOTE
get_artist_releases()repeats a few records across page boundaries and returns 49 rows for a page size of 50. That is Discogs itself, on the raw endpoint, under every sort option — collect its pages keyed onid. The other paged endpoints do not do this - a page below 1 is clamped to 1 rather than sent, since Discogs rejects it
- endpoints that return a single object are unchanged:
get_list,get_profile,get_collection_foldersand the individual artist, label, master and release lookups
- previously only page 1 was ever requested, so
DiscogsException, thrown in place ofException, carrying the HTTP statusgetStatusCode()tells a missing record (404) apart from a rate limit (429) or an outage (5xx)isRateLimited()for the 429 case- extends
Exception, so an existingcatch (Exception $error)still works
- Automatic retry for
429,500,502,503and504, up to three attempts per call- honours the
Retry-Afterheader when Discogs sends one X-Discogs-Ratelimit-Remainingwidens the gap between requests as the window is used up
- honours the
- Requests are spaced by elapsed time rather than a fixed pause after each one, so a slow response no longer adds its duration to the next wait
- Usernames are URL encoded, so one containing
/,?,#or&reaches the intended endpoint instead of altering the request - Tested against PHP 8.2, 8.3, 8.4 and 8.5, all of them gated
- 8.5 is the version Ampache 8 runs, and nothing previously covered it
- Only
src/, the docs andcomposer.jsonare published nowphpstan.neon,rector.php,phpunit.xml,.php-cs-fixer.phpand.github/are markedexport-ignore, so they no longer land in a consumer'svendor/directory
- The declared license was wrong.
composer.jsonhas saidMITsince the initial commit, contradicting the AGPL-3.0 text inLICENSE.mdand the AGPL-3.0-or-later header on every source file. It now readsAGPL-3.0-or-later, which is what this library has always been under — it is an export of the AGPL-licensed Ampache Discogs plugin, so MIT was never a license it could offer.- this corrects the metadata to match the license that already applied; it does not relicense anything and does not change what you may do with the code
- anyone who relied on the
MITdeclaration — an automated license audit, a dependency policy check — was given the wrong answer and should re-run it - the
-or-latersuffix matches the header wording; a bareAGPL-3.0is a deprecated SPDX identifier thatcomposer validate --strictrejects
search_release()returned masters mixed in with the releases- it sent
type=releases, which Discogs does not recognise, and an unknown type is ignored rather than rejected, so the search came back unfiltered
- it sent
- The scripts in
examples/stopped before their first request, passingnullwhere the constructor requires a string
Missing functions and examples have been added.
This is probably the most that the library will need to do but if there's more that you need open an issue.
- New Functions
Export of data functions from the Ampache Discogs plugin.
The code will be expanded to make it more usable for other projects but the focus here is on keeping it small and simple.
All data is JSON decoded with objects converted into associative arrays.