Skip to main content

discogs-sdk

PyPI version Python versions CI PyPI downloads License

discogs-sdk is a modern Python client for the Discogs API covering every documented v2 endpoint, with a fluent chainable syntax and built-in response caching.

from discogs_sdk import Discogs

with Discogs() as client:
    release = client.releases.get(352665)
    print(f"{release.title} ({release.year})")

    for result in client.search(query="Nine Inch Nails", type="artist"):
        print(result.title)

Installation

pip install discogs-sdk
# or
uv add discogs-sdk

Requires Python 3.10+.

Features

  • Complete Endpoint Coverage — Every route in the Discogs API v2 documentation
  • Fluent API — Chain sub-resources naturally: client.releases.get(id).rating.get()
  • Lazy Loading — No HTTP calls until you actually need the data
  • Effortless Pagination — Browse results without managing pages or offsets
  • Rate Limit Aware — Bounded retries with Retry-After support, the live budget on client.ratelimit, and a structured event per request
  • Built-in Caching — Optional TTL-based caching reduces API calls
  • Flexible Auth — Supports personal tokens, consumer key/secret, or full OAuth 1.0a
  • Type Safe — Get autocomplete and IDE support
  • Async & Sync — Full support for both synchronous and asynchronous workflows

How it compares

The established alternative is python3-discogs-client. Both load data lazily, paginate automatically, support OAuth 1.0a and back off on HTTP 429, so the differences that matter are:

discogs-sdk python3-discogs-client
Documented v2 API coverage Complete Partial †
Sync and async Both Sync only
Responses Typed Pydantic models Untyped attributes
Response cache In-memory or SQLite None

† No inventory export or upload, release ratings or have/want stats, collection fields, folder creation, contributions or submissions.

Coming from python3-discogs-client? The migration guide maps each of its idioms to discogs-sdk and names the behaviour that differs.

Quick start

Create a personal access token in your Discogs developer settings and export it; the client reads it from the environment (other auth modes):

export DISCOGS_TOKEN="your-token-here"
from discogs_sdk import Discogs

with Discogs() as client:
    release = client.releases.get(352665)  # no request yet
    print(release.title)  # the GET is sent here → "The Downward Spiral"

    for rel in client.artists.get(3857).releases.list(sort="year"):
        print(f"{rel.title} ({rel.year})")

The async client has the same API. Await a lazy resource to fetch it, and iterate pages with async for:

import asyncio

from discogs_sdk import AsyncDiscogs


async def main():
    async with AsyncDiscogs() as client:
        release = await client.releases.get(352665)
        print(release.title)

        async for result in client.search(query="Nine Inch Nails", type="artist"):
            print(result.title)


asyncio.run(main())

Behaviors to know

  • Lazy loading. .get() sends no request; the first data attribute access does, and that is where NotFoundError is raised. More
  • Async. await a proxy for its data and use async for on pages. Awaiting returns the model, which has no sub-resources, so keep the proxy to chain (artist_proxy.releases.list()). More
  • Pagination cost. search() and most .list() methods fetch pages on demand. Each page is a GET against the rate limit (60/min authenticated, 25/min anonymous); a cache hit costs nothing (one request if the entry no longer parses) and retries can cost more. More
  • Retries. Reads retry; a mutation is never replayed after an ambiguous failure. More
  • Caching. Off by default; only GET/HEAD are cached; a successful write clears the cache. More

Design principles

The SDK does more than relay requests: it pages, retries, renames keys and parses timestamps. These rules say what it may and may not do, and every new feature is checked against them.

  • Requests stay predictable. A low-level method sends only the requests its documentation names. Combining calls is fine; the method documents the cost, and every call is observable through on_request. Auto-paging sends one GET per page as you iterate (cost), a lazy proxy sends one GET on its first data access (lazy loading), and a retried read emits one RequestEvent whose attempts counts every send (observability).
  • Data may be normalized (names, types, timestamps, URLs) when nothing is lost, because raw keeps the original; when the result is computed from the response alone; and when the normalization is documented. Examples are renamed keys, timestamps parsed into aware datetimes and the absolute uri on search results. A guess the SDK cannot avoid is measured, documented and checkable through raw, like the America/Los_Angeles zone it assumes for a timestamp sent without an offset.
  • Data is never made up. The SDK invents no value that the API did not send or that cannot be computed from what it sent, such as a guessed currency. A timestamp it cannot parse becomes None, not an estimate.
  • Helpers may combine calls for common use cases. They send requests only through the SDK's public methods, so the cache, retries and on_request apply to them as to any other call.
  • Defaults are safe, sane and unsurprising. In particular, helpers don't cap their effort by default. A caller who wants a bound passes one, and a capped result says whether it is complete.
  • Undocumented behaviour is quarantined. A helper that depends on API behaviour Discogs does not document lives in discogs_sdk.experimental. It documents that dependency and its consequences, such as whether its result can be trusted to be complete; it raises when it detects that the behaviour clearly no longer holds; and it may change or be removed without a deprecation period. Core methods never depend on undocumented behaviour.

Experimental helpers

discogs_sdk.experimental holds helpers that depend on API behaviour Discogs does not document, under the rules above: each may change or be removed without a deprecation period.

releases_added_since() answers a question the API has no filter for: which releases matching a search were added to Discogs on or after a date. It takes a Discogs client; async_releases_added_since() takes an AsyncDiscogs one.

from datetime import date

from discogs_sdk import Discogs
from discogs_sdk.experimental import releases_added_since

with Discogs() as client:
    result = releases_added_since(client, date(2026, 10, 1), artist="Nine Inch Nails")
    for release in result.releases:  # newest first
        print(release.date_added, release.title)
    print(result.complete)  # False only when max_requests stopped the scan
  • Completeness assumes an undocumented sort. The helper searches with sort="date_added" and sort_order="desc", which Discogs answers newest-added first without documenting it, and looks up each result to read its date_added, stopping at the first release added before the date. Every release it returns has a verified date, but a newer release that Discogs sorts after an older one is never seen. A date_added newer than the one before it shows the sort is not holding and raises DiscogsError.
  • Cost. One search request per page scanned, plus one lookup per release in the window, plus one for the release that ends the scan (none when the results run out first). A release without a date_added is skipped and costs a lookup too. Cache hits cost nothing, and each retry is one more send.
  • No cap by default. max_requests=N bounds the HTTP sends, retries included. Once the sends reach it the helper returns what it found with complete=False; a request already started may still retry, so the total can exceed N by up to client.max_retries.

A date means the start of that day in UTC; a datetime must be timezone-aware. type may only be "release", and sort, sort_order and page belong to the helper: passing them raises ValueError before any request.

Documentation

The full guide lives in docs/:

Examples

The examples/ directory has runnable scripts for every feature:

Contributing

Contributions are welcome. See CONTRIBUTING.md for guidelines.

License

discogs-sdk is licensed under the Apache License 2.0.

Metadata

Release files for discogs-sdk 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for discogs-sdk 0.8.0
File Size Uploaded
discogs_sdk-0.8.0.tar.gz 114.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for discogs-sdk 0.8.0
File Interpreter ABI Platform
discogs_sdk-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 259.3 kB

Release files / discogs_sdk-0.8.0.tar.gz

Download URL discogs_sdk-0.8.0.tar.gz
Size 114.9 kB
Tags Source
SHA-256 checksum
How to use checksums
93b2a5db282ed5c22e74a144e2f1bac8a0996ef6df1f9f2c5fb349d489be0810
BLAKE2b-256 checksum
How to use checksums
64f0bd722a57cdc5e987d0a0a8c8d311c8f19cdb7f1886b7e7b2c8bc78f6f234
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / discogs_sdk-0.8.0-py3-none-any.whl

Download URL discogs_sdk-0.8.0-py3-none-any.whl
Size 144.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bab9fe916537cb1798357a8c710d0dc37c542c56e7a19eb991681cbf0874a360
BLAKE2b-256 checksum
How to use checksums
30dc947b43dc2aa60a2c60d1ae0b2bfeb43a8e15315213e9c83cb7dcaab5741e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.1

2 release files

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page