DEPRECATED - Official Python Client for the Discogs API

Overview

⚠️ DEPRECATED

This repository is no longer maintained. You can still use a REST client like Requests or other third-party Python library to access the Discogs REST API.




Discogs API Client

This is the official Discogs API client for Python. It enables you to query the Discogs database for information on artists, releases, labels, users, Marketplace listings, and more. It also supports OAuth 1.0a authorization, which allows you to change user data such as profile information, collections and wantlists, inventory, and orders.

Build Status Coverage Status

Installation

Install the client from PyPI using your favorite package manager.

$ pip install discogs_client

Quickstart

Instantiating the client object

>>> import discogs_client
>>> d = discogs_client.Client('ExampleApplication/0.1')

Authorization (optional)

There are a couple of different authorization methods you can choose from depending on your requirements.

OAuth authentication

This method will allow your application to make requests on behalf of any user who logs in.

For this, specify your app's consumer key and secret:

>>> d.set_consumer_key('key-here', 'secret-here')
>>> # Or you can do this when you instantiate the Client

Then go through the OAuth 1.0a process. In a web app, we'd specify a callback_url. In this example, we'll use the OOB flow.

>>> d.get_authorize_url()
('request-token', 'request-secret', 'authorize-url-here')

The client will hang on to the access token and secret, but in a web app, you'd want to persist those and pass them into a new Client instance on the next request.

Next, visit the authorize URL, authenticate as a Discogs user, and get the verifier:

>>> d.get_access_token('verifier-here')
('access-token-here', 'access-secret-here')

Now you can make requests on behalf of the user.

>>> me = d.identity()
>>> "I'm {0} ({1}) from {2}.".format(me.name, me.username, me.location)
u"I'm Joe Bloggs (example) from Portland, Oregon."
>>> len(me.wantlist)
3
>>> me.wantlist.add(d.release(5))
>>> len(me.wantlist)
4

User-token authentication

This is one of the simplest ways to authenticate and become able to perform requests requiring authentication, such as search (see below). The downside is that you'll be limited to the information only your user account can see (i.e., no requests on behalf of other users).

For this, you'll need to generate a user-token from your developer settings on the Discogs website.

>>> d = discogs_client.Client('ExampleApplication/0.1', user_token="my_user_token")

Fetching data

Use methods on the client to fetch objects. You can search for objects:

>>> results = d.search('Stockholm By Night', type='release')
>>> results.pages
1
>>> artist = results[0].artists[0]
>>> artist.name
u'Persuader, The'

Or fetch them by ID:

>>> artist.id
1
>>> artist == d.artist(1)
True

You can drill down as far as you like.

>>> releases = d.search('Bit Shifter', type='artist')[0].releases[1].\
...     versions[0].labels[0].releases
>>> len(releases)
134

Artist

Query for an artist using the artist's name:

>>> artist = d.artist(956139)
>>> print artist
<Artist "...">
>>> 'name' in artist.data.keys()
True

Special properties

Get a list of Artists representing this artist's aliases:

>>> artist.aliases
[...]

Get a list of Releases by this artist by page number:

>>> artist.releases.page(1)
[...]

Release

Query for a release using its Discogs ID:

>>> release = d.release(221824)

Special properties

Get the title of this Release:

>>> release.title
u'...'

Get a list of all Artists associated with this Release:

>>> release.artists
[<Artist "...">]

Get the tracklist for this Release:

>>> release.tracklist
[...]

Get the MasterRelease for this Release:

>>> release.master
<MasterRelease "...">

Get a list of all Labels for this Release:

>>> release.labels
[...]

MasterRelease

Query for a master release using its Discogs ID:

>>> master_release = d.master(120735)

Special properties

Get the key Release for this MasterRelease:

>>> master_release.main_release
<Release "...">

Get the title of this MasterRelease:

>>> master_release.title
u'...'
>>> master_release.title == master_release.main_release.title
True

Get a list of Releases representing other versions of this MasterRelease by page number:

>>> master_release.versions.page(1)
[...]

Get the tracklist for this MasterRelease:

>>> master_release.tracklist
[...]

Label

Query for a label using the label's name:

>>> label = d.label(6170)

Special properties

Get a list of Releases from this Label by page number:

>>> label.releases.page(1)
[...]

Get a list of Labels representing sublabels associated with this Label:

>>> label.sublabels
[...]

Get the Label's parent label, if it exists:

>>> label.parent_label
<Label "Warp Records Limited">

Contributing

  1. Fork this repo
  2. Create a feature branch
  3. Open a pull-request

For more information

Check the included documentation, or just spin up a REPL and use dir() on things :)

Comments
  • Make discogs_client python 2 & python 3 compatible

    Make discogs_client python 2 & python 3 compatible

    This PR makes discogs_client python 2 and python 3 compatible.

    Notables changes include:

    • switch from python-oauth2 (no py3k compatibility) to oauthlib (→ helps with #40)
    • fix numerous pep8 error
    • make tests deterministic
    opened by brunal 20
  • Add user token authentication

    Add user token authentication

    I've just added user_token "authentication".

    Can't figure out how to add a test for it, but you can use this for testing:

    __author__ = 'aweil'
    import os
    import unittest
    import discogs_client
    
    class UserTokenTest(unittest.TestCase):
        def setUp(self):
            with open(os.path.expanduser('~/.discogs_user_token'), 'rb') as f:
                self.discosgs_token = f.read().strip()
    
        def test_search(self):
            d = discogs_client.Client('TenukiWebApp1/0.1', user_token=self.discosgs_token)
            query_releases = d.search('Bit Shifter', type='artist')[0].releases[1].versions[0].labels[0].releases
            self.assertTrue( len(query_releases)>0)
    
    if __name__ == '__main__':
        unittest.main()
    

    Please let me know when/where to add documentation when available and if you want I to documentate it in the readme.

    opened by tenuki 10
  • Detailed exceptions for token request failures

    Detailed exceptions for token request failures

    This adds richer exception information when the request token request fails. This is important because it can fail for several different reasons, including:

    • bad timestamp
    • bad consumer
    • bad signature

    This makes it at least possible to tell what's going wrong.

    Before:

    $ python -c "import discogs_client ; discogs_client.Client('[...]', '[...]', '[...]').get_authorize_url()"
    [...]
    discogs_client.exceptions.HTTPError: 401: Invalid response from request token URL.
    

    After:

    $ python -c "import discogs_client ; discogs_client.Client('[...]', '[...]', '[...]').get_authorize_url()"
    [...]
    discogs_client.exceptions.AuthorizationError: 401: Could not get request token. Response: 'Invalid consumer.'
    

    This came up in https://github.com/sampsyo/beets/issues/1417.

    opened by sampsyo 9
  • discogs_client doesnt honor Discogs rate limits

    discogs_client doesnt honor Discogs rate limits

    Discogs has recently lowered their rate limit from 240 reqs/min to 60 reqs/min. This obviously means that some applications will hit the limit quite soon.

    opened by T-101 8
  • Checkout fails on Windows due to invalid file names

    Checkout fails on Windows due to invalid file names

    Git checkout of repository fails.... error: unable to create file discogs_client/tests/res/artists/1/releases?per_page=50&page=1.json (Invalid argument) error: unable to create file discogs_client/tests/res/artists/1/releases?per_page=50&page=2.json (Invalid argument) error: unable to create file discogs_client/tests/res/database/search?q=trash80&per_page=50&page=1.json (Invalid argument) error: unable to create file discogs_client/tests/res/masters/4242/versions?per_page=50&page=1.json (Invalid argument) error: unable to create file discogs_client/tests/res/users/example/wants?per_page=50&page=1.json (Invalid argument)

    opened by zoomorph 8
  • requests.get has wrong parameters

    requests.get has wrong parameters

    With the current git clone (but I think this was also present with the version coming from pypi) I get the following traceback:

    >>> r = discogs.Release( 934425 )
    >>> t = r.tracklist[9]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/discogs_client-1.1.0-py2.7.egg/discogs_client.py", line 165, in tracklist
        for track in self.data.get('tracklist', []):
      File "/usr/local/lib/python2.7/dist-packages/discogs_client-1.1.0-py2.7.egg/discogs_client.py", line 52, in data
        if self._response.content and self._response.status_code == 200:
      File "/usr/local/lib/python2.7/dist-packages/discogs_client-1.1.0-py2.7.egg/discogs_client.py", line 38, in _response
        self._cached_response = requests.get(self._uri, self._params, self._headers)
    TypeError: get() takes exactly 1 argument (3 given)
    

    during the install (python setup.py install) it installed version 0.6.1 of the python-requests library.

    I was doing a fork but right now git push doesn't seem to be working, so here is just the trivial patch as plain text:

    diff --git a/discogs_client.py b/discogs_client.py
    index f52d769..ee2e48d 100644
    --- a/discogs_client.py
    +++ b/discogs_client.py
    @@ -35,7 +35,7 @@ class APIBase(object):
             if not self._cached_response:
                 if not self._check_user_agent():
                     raise DiscogsAPIError, 'Invalid or no User-Agent set'
    -            self._cached_response = requests.get(self._uri, self._params, self._headers)
    +            self._cached_response = requests.get(self._uri, params=self._params, headers=self._headers)
     
             return self._cached_response
    
    
    opened by matigit 7
  • TypeError: __repr__ returned non-string (type bytes)

    TypeError: __repr__ returned non-string (type bytes)

    Here is a minimal example of my attempts to interact with the Discogs API:

    from SensitiveInformation.discogs_application_info import provide_discogs_auth, provide_verifier
    import discogs_client
    
    discogs_consumer_key, discogs_consumer_secret = provide_discogs_auth()
    discogs = discogs_client.Client(user_agent="ThoughfulMachineLearning",
                                    consumer_key=discogs_consumer_key,
                              consumer_secret=discogs_consumer_secret)
    discogs_auth_url = discogs.get_authorize_url()
    discogs.get_access_token(verifier=provide_verifier())
    discogs.identity()
    

    The functions provide_discogs_auth and provide_verifier simply return the consumer key & secret and the verifier from user authorization. get_access_token returns the access key and secret as expected.

    However, on the last line, when I make an API call, I get:

    Out[38]: In[39]: discogs.identity()
    Traceback (most recent call last):
    Out[39]:   File "/usr/local/lib/python3.4/dist-packages/IPython/core/formatters.py", line 219, in catch_format_error
        r = method(self, *args, **kwargs)
      File "/usr/local/lib/python3.4/dist-packages/IPython/core/formatters.py", line 690, in __call__
        printer.pretty(obj)
      File "/usr/local/lib/python3.4/dist-packages/IPython/lib/pretty.py", line 407, in pretty
        return _default_pprint(obj, self, cycle)
      File "/usr/local/lib/python3.4/dist-packages/IPython/lib/pretty.py", line 527, in _default_pprint
        _repr_pprint(obj, p, cycle)
      File "/usr/local/lib/python3.4/dist-packages/IPython/lib/pretty.py", line 709, in _repr_pprint
        output = repr(obj)
    TypeError: __repr__ returned non-string (type bytes)
    

    Not sure if this is related to IPython or the client library, but would appreciate help either way. Thanks.

    opened by tchakravarty 6
  • Fix Issue #37

    Fix Issue #37

    Fix Issue #37 -- allow to clone properly on Windows.

    • Renamed all test files to replace '?' with '_'
    • Changed FileSystemFetcher to likewise replace '?' with '_' when loading a test file
    • Added logic to FileSystemFetcher to check for all permutations of parameters contained in a test file's name.
    • Removed symlinks from repo.
    • The repo now clones cleanly on Windows.
    • Unit tests passed.
    opened by leo-dor 6
  • Non-ASCII searches fail because python-oauth2 is broken

    Non-ASCII searches fail because python-oauth2 is broken

    Searching for a non-ASCII term causes this error:

    >>> import discogs_client
    >>> c = discogs_client.Client('user_agent', 'bogus_key', 'bogus_secret')
    >>> c.search(u'caf\xe9'.encode('utf8')).page(1)
    Traceback (most recent call last):
    [ ... snip ... ]
      File "/usr/local/lib/python2.7/site-packages/oauth2/__init__.py", line 442, in to_url
        urllib.urlencode(query, True), fragment)
      File "/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1357, in urlencode
        l.append(k + '=' + quote_plus(str(elt)))
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 3-4: ordinal not in range(128)
    

    This is due to a known bug in python-oauth2: https://github.com/simplegeo/python-oauth2/issues/154. That library, unfortunately, appears to be abandoned: the last commit was in 2011 (c.f. this lament over the sorry state of Python OAuth libraries).

    It's worth noting that this was not an issue when sending non-ASCII requests without OAuth authentication because they don't go through the broken library. This has only come up recently because the search API now requires authentication, so we're now these previously-working requests are now hitting this bug.

    As unattractive as it seems, I think the only solution may be to move to a more modern OAuth library. Personally, I've had success with rauth.

    opened by sampsyo 6
  • Release attributes return different values depending on previosly accessed fiels

    Release attributes return different values depending on previosly accessed fiels

    from discogs_client import Client, Release
    
    
    client = Client('python')
    releases = [i for i in client.search('Flying Horseman') if isinstance(i, Release)]
    
    r = releases[3]
    print r.title           # Flying Horseman - City Same City
    print r.data['title']   # Flying Horseman - City Same City
    print r.master.title    # City Same City
    print r.title           # City Same City
    

    This behavior is really strange: Accessing Release.master.title also changes Release.title. I can't find a way to get just album name without artist, it works only if I access master first.

    opened by andriykohut 6
  • incorrect tracklist for versions with more than one side CD

    incorrect tracklist for versions with more than one side CD

    let us say i want to get a tracklist of this version of a release - https://www.discogs.com/Edward-Ka-Spel-Dream-Logik-Part-Two/master/277838 - works fine because it has only one side

    but

    let us say i want to get a tracklist of this version of a release which is double side LTD - https://www.discogs.com/Edward-Ka-Spel-Dream-Logik-Part-Two/release/1425757

    it returns a buggy list with two more strings which ARE NOT TRACKS but names of each side.

    opened by ExperimentalHypothesis 5
Releases(v2.3.0)
AutomaTik is an automation system for MikroTik devices with simplicity and security in mind.

AutomaTik Installation AutomaTik is an automation system for MikroTik devices with simplicity and security in mind. Winbox is the main tool for MikroT

Osman Kazdal 4 Dec 05, 2022
SEMID - OSINT module with lots of discord functions

SEMID Framework About Semid is a framework with different Discord functions and

Hima 20 Sep 23, 2022
Python Discord Server Nuker

Untitled Nuker Python Discord Server Nuker Features: Ban Everyone Kick Everyone Rename Everyone Spam To All Channels Delete All Channels Delete All Ro

22 Dec 22, 2022
Add members to unlimited telegram channels and groups

Program Features 📌 Coded with Python version 10. 📌 without the need for a proxy. 📌 without the need for a Telegram ID. 📌 Ability to add infinite p

hack4lx 10 Nov 25, 2022
Trading through Binance's API using Python & sqlite

pycrypt Automate trading crypto using Python to pull data from Binance's API and analyse trends. May or may not consistently lose money but oh well it

Maxim 4 Sep 02, 2022
This Server Cloner can clone the server you want with all the perms of roles in every particular channel.

Server-Cloner-with-perms 🚀 This Server Cloner can clone the server you want with all the perms of roles in every particular channel. Features Clone C

Gripz 0 Feb 17, 2022
Using twitter lists as your feed

Twitlists A while ago, Twitter changed their timeline to be algorithmically-fed rather than a simple reverse-chronological feed. In particular, they p

Peyton Walters 5 Nov 21, 2022
A course on getting started with the Twitter API v2 for academic research

Getting started with the Twitter API v2 for academic research Welcome to this '101 course' on getting started with academic research using the Twitter

@TwitterDev 426 Jan 04, 2023
ANKIT-OS/TG-MUSIC-PLAYER a special repository. Its Is A Telegram Bot To Play To Play Music In Voice Chat

🔥 🎶 TG MUSIC PLAYER 🎶 🔥 The owner would not be responsible for any kind of bans due to the bot. • ⚡ INSTALLING ⚡ • • 🛠️ Lᴀɴɢᴜᴀɢᴇs Aɴᴅ Tᴏᴏʟs 🔰 •

ANKIT KUMAR 1 Dec 27, 2021
A bot can play all variants, but standard are abit weak, so if you need strongest you can change fsf instead of stockfish_14_Dev

MAINTAINERS Drdisrespect1 and drrespectable lichess-bot Engine communication code taken from https://github.com/ShailChoksi/lichess-bot by ShailChoksi

RPNS Nimsilu 1 Dec 12, 2021
Slack->DynamDB->Some applications

slack-event-subscriptions About The Project Do you want to get simple attendance checks? If you are using Slack, participants can just react on a spec

UpstageAI 26 May 28, 2022
Python functions for opentargets.org API

What is opy_Targets? Opentargets.org uses GraphQL API to explore it's content via coding. This ensemble of functions aim is to make it easy to use the

1 Jan 10, 2022
Template to create a telegram bot in python

Template for Telegram Bot Template to create a telegram bot in python. How to Run Set your telegram bot token as environment variable TELEGRAM_BOT_TOK

Ali Hejazizo 12 Aug 14, 2022
Sakamata-alpha-pycord - Sakamata bot alpha with pycord

sakamatabot このリポジトリは? ホロライブ所属VTuber沙花叉クロヱさんの非公式ファンDiscordサーバー「クロヱ水族館」の運営/管理補助を行う

sushichaaaan 1 May 04, 2022
tfquery: Run SQL queries on your Terraform infrastructure. Query resources and analyze its configuration using a SQL-powered framework.

🌩️ tfquery 🌩️ Run SQL queries on your Terraform infrastructure. Ask questions that are hard to answer 🚀 What is tfquery? tfquery is a framework tha

Mazin Ahmed 311 Dec 21, 2022
An advanced telegram movie information finder bot

An advanced telegram movie information finder bot

Fayas Noushad 22 Aug 23, 2022
This is a simple grabber written in Python which helps you to grab products from Willhaben.at

Willhaben Grabber This is a simple grabber written in Python which helps you to grab products from Willhaben.at General info The tool generates a sear

Ramo 0 Feb 16, 2022
a simple quant trading bot with CLI interface

shepherd a simple quant trading bot with CLI interface CLI shell command docs coming soon after I brush up the code and add more features :) Minimal R

m00n 0 Jun 06, 2022
eBay Scraper Homework 3 With Python

eBay Scraper Homework 3 Description of Code My ebay-dl.py file is programmed with python to download 6 key pieces of information - name, if there are

1 Nov 10, 2021
Live Coding - Mensageria na AWS com Amazon SNS e Amazon SQS

Live Coding - Mensageria na AWS com Amazon SNS e Amazon SQS Repositório para o Live Coding do dia 08/12/2021 Serviços utilizados Amazon SNS Amazon SQS

Cassiano Ricardo de Oliveira Peres 3 Mar 01, 2022