├── .gitignore ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.mkd ├── discogs_client ├── __init__.py ├── client.py ├── exceptions.py ├── fetchers.py ├── models.py ├── tests │ ├── __init__.py │ ├── make_symlinks.py │ ├── res │ │ ├── artists │ │ │ ├── 1 │ │ │ │ ├── releases_per_page=50&page=1.json │ │ │ │ └── releases_per_page=50&page=2.json │ │ │ ├── 1.json │ │ │ ├── 2.json │ │ │ └── 3.json │ │ ├── database │ │ │ └── search_q=trash80&per_page=50&page=1.json │ │ ├── labels │ │ │ ├── 1.json │ │ │ └── 31405.json │ │ ├── marketplace │ │ │ └── fee │ │ │ │ └── 20.5000 │ │ │ │ └── EUR.json │ │ ├── masters │ │ │ ├── 4242 │ │ │ │ └── versions_per_page=50&page=1.json │ │ │ └── 4242.json │ │ ├── oauth │ │ │ └── identity.json │ │ ├── releases │ │ │ ├── 1.json │ │ │ ├── 2.json │ │ │ ├── 3.json │ │ │ ├── 3329867.json │ │ │ └── 79.json │ │ └── users │ │ │ ├── example.json │ │ │ └── example │ │ │ └── wants_per_page=50&page=1.json │ ├── test_core.py │ ├── test_fetchers.py │ ├── test_models.py │ └── test_utils.py └── utils.py ├── docs ├── authentication.md └── quickstart.md ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.egg-info 3 | dist/ 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.3" 5 | - "3.4" 6 | - "3.5" 7 | - "3.6" 8 | install: 9 | - pip install -r requirements.txt 10 | script: 11 | - nosetests --with-coverage --cover-package=discogs_client 12 | after_success: 13 | - coveralls 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2015 Discogs. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY DISCOGS ''AS IS'' AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 15 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 16 | SHALL DISCOGS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 17 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 19 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 21 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 22 | OF SUCH DAMAGE. 23 | 24 | The views and conclusions contained in the software and documentation are those 25 | of the authors and should not be interpreted as representing official policies, 26 | either expressed or implied, of Discogs. 27 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include discogs_client/tests *.py 2 | recursive-include discogs_client/tests/res *.json 3 | recursive-exclude discogs_client/tests make_symlinks.py 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | 3 | clean: 4 | find . -name '*.pyc' -delete 5 | find . -name __pycache__ -delete 6 | -------------------------------------------------------------------------------- /README.mkd: -------------------------------------------------------------------------------- 1 | # :warning: DEPRECATED 2 | 3 | This repository is no longer maintained. You can still use a REST client like 4 | [Requests](https://pypi.org/project/requests/) or other third-party Python 5 | library to access the [Discogs REST API](https://www.discogs.com/developers). 6 | 7 | --- 8 | --- 9 | --- 10 | 11 | # Discogs API Client 12 | 13 | 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. 14 | 15 | [![Build Status](https://travis-ci.org/discogs/discogs_client.png?branch=master)](https://travis-ci.org/discogs/discogs_client) 16 | [![Coverage Status](https://coveralls.io/repos/discogs/discogs_client/badge.png)](https://coveralls.io/r/discogs/discogs_client) 17 | 18 | ## Installation 19 | 20 | Install the client from PyPI using your favorite package manager. 21 | 22 | ```sh 23 | $ pip install discogs_client 24 | ``` 25 | 26 | ## Quickstart 27 | 28 | ### Instantiating the client object 29 | 30 | ```python 31 | >>> import discogs_client 32 | >>> d = discogs_client.Client('ExampleApplication/0.1') 33 | ``` 34 | 35 | ### Authorization (optional) 36 | 37 | There are a couple of different authorization methods you can choose from depending on your requirements. 38 | 39 | #### OAuth authentication #### 40 | 41 | This method will allow your application to make requests on behalf of any user who logs in. 42 | 43 | For this, specify your app's consumer key and secret: 44 | 45 | ```python 46 | >>> d.set_consumer_key('key-here', 'secret-here') 47 | >>> # Or you can do this when you instantiate the Client 48 | ``` 49 | 50 | 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. 51 | 52 | ```python 53 | >>> d.get_authorize_url() 54 | ('request-token', 'request-secret', 'authorize-url-here') 55 | ``` 56 | 57 | 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. 58 | 59 | Next, visit the authorize URL, authenticate as a Discogs user, and get the verifier: 60 | 61 | ```python 62 | >>> d.get_access_token('verifier-here') 63 | ('access-token-here', 'access-secret-here') 64 | ``` 65 | 66 | Now you can make requests on behalf of the user. 67 | 68 | ```python 69 | >>> me = d.identity() 70 | >>> "I'm {0} ({1}) from {2}.".format(me.name, me.username, me.location) 71 | u"I'm Joe Bloggs (example) from Portland, Oregon." 72 | >>> len(me.wantlist) 73 | 3 74 | >>> me.wantlist.add(d.release(5)) 75 | >>> len(me.wantlist) 76 | 4 77 | ``` 78 | 79 | #### User-token authentication #### 80 | 81 | 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). 82 | 83 | For this, you'll need to generate a user-token from your developer settings on the Discogs website. 84 | 85 | ```python 86 | >>> d = discogs_client.Client('ExampleApplication/0.1', user_token="my_user_token") 87 | ``` 88 | 89 | ### Fetching data 90 | 91 | Use methods on the client to fetch objects. You can search for objects: 92 | 93 | ```python 94 | >>> results = d.search('Stockholm By Night', type='release') 95 | >>> results.pages 96 | 1 97 | >>> artist = results[0].artists[0] 98 | >>> artist.name 99 | u'Persuader, The' 100 | ``` 101 | 102 | Or fetch them by ID: 103 | 104 | ```python 105 | >>> artist.id 106 | 1 107 | >>> artist == d.artist(1) 108 | True 109 | ``` 110 | 111 | You can drill down as far as you like. 112 | 113 | ```python 114 | >>> releases = d.search('Bit Shifter', type='artist')[0].releases[1].\ 115 | ... versions[0].labels[0].releases 116 | >>> len(releases) 117 | 134 118 | ``` 119 | 120 | ## Artist 121 | 122 | Query for an artist using the artist's name: 123 | 124 | >>> artist = d.artist(956139) 125 | >>> print artist 126 | 127 | >>> 'name' in artist.data.keys() 128 | True 129 | 130 | ### Special properties 131 | 132 | Get a list of `Artist`s representing this artist's aliases: 133 | 134 | >>> artist.aliases 135 | [...] 136 | 137 | Get a list of `Release`s by this artist by page number: 138 | 139 | >>> artist.releases.page(1) 140 | [...] 141 | 142 | ## Release 143 | 144 | Query for a release using its Discogs ID: 145 | 146 | >>> release = d.release(221824) 147 | 148 | ### Special properties 149 | 150 | Get the title of this `Release`: 151 | 152 | >>> release.title 153 | u'...' 154 | 155 | Get a list of all `Artist`s associated with this `Release`: 156 | 157 | >>> release.artists 158 | [] 159 | 160 | Get the tracklist for this `Release`: 161 | 162 | >>> release.tracklist 163 | [...] 164 | 165 | Get the `MasterRelease` for this `Release`: 166 | 167 | >>> release.master 168 | 169 | 170 | Get a list of all `Label`s for this `Release`: 171 | 172 | >>> release.labels 173 | [...] 174 | 175 | ## MasterRelease 176 | 177 | Query for a master release using its Discogs ID: 178 | 179 | >>> master_release = d.master(120735) 180 | 181 | ### Special properties 182 | 183 | Get the key `Release` for this `MasterRelease`: 184 | 185 | >>> master_release.main_release 186 | 187 | 188 | Get the title of this `MasterRelease`: 189 | 190 | >>> master_release.title 191 | u'...' 192 | >>> master_release.title == master_release.main_release.title 193 | True 194 | 195 | Get a list of `Release`s representing other versions of this `MasterRelease` by page number: 196 | 197 | >>> master_release.versions.page(1) 198 | [...] 199 | 200 | Get the tracklist for this `MasterRelease`: 201 | 202 | >>> master_release.tracklist 203 | [...] 204 | 205 | ## Label 206 | 207 | Query for a label using the label's name: 208 | 209 | >>> label = d.label(6170) 210 | 211 | ### Special properties 212 | 213 | Get a list of `Release`s from this `Label` by page number: 214 | 215 | >>> label.releases.page(1) 216 | [...] 217 | 218 | Get a list of `Label`s representing sublabels associated with this `Label`: 219 | 220 | >>> label.sublabels 221 | [...] 222 | 223 | Get the `Label`'s parent label, if it exists: 224 | 225 | >>> label.parent_label 226 |