Skip to main content

Modern Python client for the Discogs API

Project description

discogs-sdk

PyPI version Python versions CI PyPI downloads License

A typed Python client for the Discogs API. Sync and async, with Pydantic models, automatic pagination, and lazy resource loading.

from discogs_sdk import Discogs

# Reads DISCOGS_TOKEN from environment
with Discogs() as client:
    release = client.releases.get(352665)
    print(f"{release.title} ({release.year})")
    # The Downward Spiral (1994)

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

Features

  • Sync and asyncDiscogs for synchronous code, AsyncDiscogs for async/await
  • Typed models — every response is a Pydantic v2 model with extra="allow" for undocumented fields
  • Lazy resources.get() returns a lightweight proxy; HTTP fires only when you access data
  • Auto-pagination — iterate results with for/async for; pages are fetched on demand
  • Sub-resource chainingclient.releases.get(id).rating.get() — intermediate accessors never trigger HTTP
  • Automatic retries — retries on 429/5xx with exponential backoff and Retry-After support
  • Three auth modes — personal token, consumer key/secret, or full OAuth 1.0a
  • Optional cachingcache=True enables hishel-backed HTTP caching

Why discogs-sdk?

  • Typed models — Pydantic v2 models give you autocomplete and IDE support instead of untyped dicts
  • Lazy loading that respects rate limits.get() returns a proxy; HTTP fires only when you access data, minimizing calls against the 60 req/min limit
  • Sync + async from one codebase — async-first source with auto-generated sync client, identical APIs
  • Auto-pagination — iterate results with for/async for; no manual page math
  • Modern stack — built on httpx and Pydantic v2, not requests and raw dicts

How it compares

Feature discogs-sdk python3-discogs-client Raw API
Typed models (Pydantic) Yes No No
Async support Yes No Manual
Auto-pagination Yes Yes Manual
Lazy loading Yes No N/A
Rate limit handling Automatic retry Manual Manual
OAuth 1.0a Yes Yes Manual
HTTP caching Built-in opt-in No Manual

Installation

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

With HTTP caching support:

pip install discogs-sdk[cache]
# or
uv add discogs-sdk[cache]

Requires Python 3.10+.

Quick start

Authentication

Set your personal access token from your Discogs developer settings as an environment variable:

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

client = Discogs()  # reads DISCOGS_TOKEN from environment

You can also pass credentials explicitly:

client = Discogs(token="your-token-here")

The SDK supports three auth modes: personal token, consumer key/secret, and OAuth 1.0a. All credentials resolve via constructor arg > environment variable (DISCOGS_TOKEN, DISCOGS_CONSUMER_KEY, etc.). See examples/authentication.py for the full OAuth flow.

[!TIP] Use a .env file with python-dotenv or direnv to avoid exporting tokens manually in every shell.

[!NOTE] Discogs enforces a 60 requests/minute rate limit. The SDK handles this automatically with exponential backoff and Retry-After support — no manual throttling needed.

Fetching resources

# Releases, artists, masters, labels
release = client.releases.get(352665)
print(release.title)  # lazy — HTTP fires here → "The Downward Spiral"

artist = client.artists.get(3857)
print(artist.name)  # "Nine Inch Nails"

master = client.masters.get(3719)
label = client.labels.get(647)

Search

for result in client.search(query="Pretty Hate Machine", type="release", year="1989"):
    print(f"[{result.type}] {result.title}")
    # [release] Nine Inch Nails - Pretty Hate Machine

Sub-resources

# Community rating
rating = client.releases.get(352665).rating.get()
print(f"Average: {rating.rating.average}")  # Average: 4.49

# Artist releases with sorting
for rel in client.artists.get(3857).releases.list(sort="year", sort_order="desc"):
    print(f"{rel.title} ({rel.year})")

# Master versions with filters
for v in client.masters.get(3719).versions.list(format="Vinyl", country="US"):
    print(f"{v.title} [{v.format}]")

Async usage

import asyncio
from discogs_sdk import AsyncDiscogs

async def main():
    async with AsyncDiscogs() as client:  # reads DISCOGS_TOKEN from environment
        # Must await lazy resources in async mode
        release = await client.releases.get(352665)
        print(release.title)

        # Async iteration for paginated results
        async for result in client.search(query="Nine Inch Nails"):
            print(result.title)

asyncio.run(main())

Marketplace

# Listings
listing = client.marketplace.listings.get(123456789)
new = client.marketplace.listings.create(
    release_id=352665, condition="Very Good Plus (VG+)", price=25.00,
)
client.marketplace.listings.update(new.id, price=22.50)
client.marketplace.listings.delete(new.id)

# Orders
for order in client.marketplace.orders.list(status="Payment Received"):
    print(f"Order {order.id}: {order.status}")

# Fee lookup
fee = client.marketplace.fee.get(price=25.00, currency="USD")

Collection

user = client.users.get("your_username")

# Folders
folders = user.collection.folders.list()
user.collection.folders.create(name="Industrial")

# Browse folder contents
for item in user.collection.folders.get(0).releases.list(sort="added"):
    print(item.basic_information.title)

# Add a release
user.collection.folders.get(1).releases.create(release_id=352665)

# Deep chaining: folder -> release -> instance -> fields
user.collection.folders.get(1).releases.get(352665).instances.get(
    98765
).fields.update(field_id=1, value="Signed copy")

# Collection value
value = user.collection.value.get()
print(f"Median: {value.median}, Maximum: {value.maximum}")

# Wantlist
user.wantlist.create(release_id=352665, notes="Original pressing", rating=4)
for want in user.wantlist.list():
    print(want.basic_information.title)

Error handling

from discogs_sdk import NotFoundError, RateLimitError, AuthenticationError

try:
    release = client.releases.get(999999999)
    _ = release.title
except NotFoundError:
    print("Not found")
except RateLimitError as exc:
    print(f"Rate limited, retry after {exc.retry_after}s")
except AuthenticationError:
    print("Bad credentials")

The full exception hierarchy:

DiscogsError
+-- DiscogsConnectionError
+-- DiscogsAPIError
    +-- AuthenticationError  (401)
    +-- ForbiddenError       (403)
    +-- NotFoundError        (404)
    +-- ValidationError      (422)
    +-- RateLimitError       (429)

API coverage

Area Resources
Database Releases, Artists, Masters, Labels, Search
Marketplace Listings, Orders, Order Messages, Fees
Collection Folders, Releases, Instances, Custom Fields, Value
User Profile, Identity, Wantlist, Contributions, Submissions, Inventory, Lists
Inventory Exports (request/download CSV), Uploads (add/change/delete CSV)
Lists Get list by ID, browse user lists

Examples

The examples/ directory has runnable scripts for every feature:

Configuration

Parameter Default Description
token None Personal access token
consumer_key None OAuth consumer key
consumer_secret None OAuth consumer secret
access_token None OAuth access token
access_token_secret None OAuth access token secret
base_url https://api.discogs.com API base URL
timeout 30.0 Request timeout in seconds
max_retries 3 Max retries on 429/5xx/connection errors
cache False Enable HTTP caching (requires discogs-sdk[cache])
http_client None Custom httpx.Client or httpx.AsyncClient

Credentials are resolved in order: constructor args > environment variables.

Field naming

Model fields use clean Python names. Where the Discogs API uses inconsistent or cryptic keys, the SDK provides a readable alias while still accepting the raw API name during deserialization:

API field Python attribute Models
uri150 uri_150 Image
anv name_variation ArtistCredit
extraartists extra_artists Release, Track
namevariations name_variations Artist
qty quantity Format
catno catalog_number LabelCredit, Company, LabelRelease, SearchResult
sublabels sub_labels Label
curr_abbr currency_code OriginalPrice, User
curr_id currency_id OriginalPrice
created_ts created_at Export, Upload, List_
finished_ts finished_at Export, Upload
modified_ts modified_at List_

Both names work when constructing models manually (Image(uri150="...") and Image(uri_150="...") are equivalent). When accessing attributes, use the Python name: image.uri_150.

Contributing

Contributions are welcome. See CONTRIBUTING.md for guidelines.

License

discogs-sdk is licensed under the Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

discogs_sdk-0.1.0.tar.gz (30.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

discogs_sdk-0.1.0-py3-none-any.whl (55.6 kB view details)

Uploaded Python 3

File details

Details for the file discogs_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: discogs_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 30.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for discogs_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0c79550223456d63c68b88065edced3a2dd78544576b857267b8c8261db8ae36
MD5 0d4a4582651c0b22f3f49e7dddc6f420
BLAKE2b-256 e0eb7f717cefe455f489582d980e2965a307f4ac6ffdc56e120f00ba9d9916da

See more details on using hashes here.

Provenance

The following attestation bundles were made for discogs_sdk-0.1.0.tar.gz:

Publisher: publish.yml on jmfontaine/discogs-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discogs_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: discogs_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 55.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for discogs_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 03214006fa1b063e22edeaefb290ad9416a7db0205c6e53db2d0ffcb78b9cfe7
MD5 ad2fdf5cc07771fc8d82864b115d4723
BLAKE2b-256 4d436000d89e115e4ea2f758f704a2bfff65ecfc3b66b22398abc0359a3fa5d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for discogs_sdk-0.1.0-py3-none-any.whl:

Publisher: publish.yml on jmfontaine/discogs-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page