Coverart archive no tiene limite de requests!
This commit is contained in:
@@ -34,7 +34,6 @@ def map_artist(mb_artist):
|
|||||||
|
|
||||||
|
|
||||||
def map_artist_credit(mb_artist_credit):
|
def map_artist_credit(mb_artist_credit):
|
||||||
pretty_print_json(mb_artist_credit)
|
|
||||||
return {
|
return {
|
||||||
'id': mb_artist_credit.get('artist').get('id'),
|
'id': mb_artist_credit.get('artist').get('id'),
|
||||||
'name': mb_artist_credit.get('artist').get('name'),
|
'name': mb_artist_credit.get('artist').get('name'),
|
||||||
|
|||||||
@@ -19,51 +19,83 @@ _log = logging.getLogger(__name__)
|
|||||||
_log.addHandler(logging.NullHandler())
|
_log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
|
|
||||||
@sleep_and_retry
|
def _do_request(url):
|
||||||
@limits(calls=1, period=1)
|
"""Does a request to an url
|
||||||
def _do_request(url, host=_mb_host):
|
|
||||||
"""Does a request to a path and returns the dictionary representing the json response
|
|
||||||
|
|
||||||
If the response is 200 it will return the full dictionary of the json that the response
|
|
||||||
contains, and if is a 307 code, it will create a dictionary containing the response code
|
|
||||||
and the link where is redirecting, any other response code will be just appended to a
|
|
||||||
dictionary and returning.
|
|
||||||
|
|
||||||
:param str url: URL where to do the request
|
:param str url: URL where to do the request
|
||||||
|
|
||||||
:return: The whole response object
|
|
||||||
:raises ValueError when user-agent isn't set
|
|
||||||
:raises ValueError when url isn't set
|
:raises ValueError when url isn't set
|
||||||
|
:return the request response
|
||||||
:returns A dictionary with the request response
|
|
||||||
it always has a status key with the status code by its value,
|
|
||||||
the rest of the response will be contained in the 'response' key
|
|
||||||
if the request didn't fail
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not _headers['user-agent']:
|
|
||||||
raise ValueError('User Agent isn\'t set')
|
|
||||||
if not url:
|
if not url:
|
||||||
raise ValueError('URL cant be empty')
|
raise ValueError('URL cant be empty')
|
||||||
|
|
||||||
_log.info(f'Doing request to "{url}" with headers {_headers}')
|
_log.info(f'Doing request to "{url}" with headers {_headers}')
|
||||||
r = requests.get(url, headers=_headers)
|
response = requests.get(url, headers=_headers)
|
||||||
|
|
||||||
_log.info(f'Request returned with status code {r.status_code}')
|
_log.info(f'Request returned with status code {response.status_code}')
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@sleep_and_retry
|
||||||
|
@limits(calls=1, period=1)
|
||||||
|
def _do_request_mb(url):
|
||||||
|
"""Does a request to a path of musicbrainz and returns the dictionary representing the json
|
||||||
|
response
|
||||||
|
|
||||||
|
If the response is 200 it will return the full dictionary of the json that the response
|
||||||
|
contains, and if is a code 500 it will inform of the server error, any other response
|
||||||
|
code will be just appended to a dictionary and returned.
|
||||||
|
|
||||||
|
:param str url: URL where to do the request
|
||||||
|
:raises ValueError when user-agent isn't set
|
||||||
|
:return: The dictionary with the response or the status and his an error message
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not _headers['user-agent']:
|
||||||
|
raise ValueError('User Agent isn\'t set')
|
||||||
|
|
||||||
|
r = _do_request(url)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
response = r.json(object_hook=sanitize_keys)
|
response = r.json(object_hook=sanitize_keys)
|
||||||
elif r.status_code == 500:
|
elif r.status_code == 500:
|
||||||
response = {'status': r.status_code, 'error': f'Error del servidor'}
|
response = {'status': r.status_code, 'error': f'Error del servidor'}
|
||||||
elif host == _ca_host:
|
else:
|
||||||
if r.status_code == 400:
|
response = {'status': r.status_code, 'error': r.json()['error']}
|
||||||
response = {'status': r.status_code, 'error': f'El mbid es invalido'}
|
|
||||||
elif r.status_code == 404:
|
return response
|
||||||
response = {'status': r.status_code, 'error': f'No encontrado'}
|
|
||||||
elif r.status_code == 405:
|
|
||||||
response = {'status': r.status_code, 'error': f'Metodo erroneo'}
|
def _do_request_ca(url):
|
||||||
elif r.status_code == 503:
|
"""Does a request to a path of cover art archive and returns the dictionary representing
|
||||||
response = {'status': r.status_code, 'error': f'Rate limit exedido'}
|
the json response
|
||||||
|
|
||||||
|
If the response is 200 it will return the full dictionary of the json that the response
|
||||||
|
contains, and if is a code 500 it will inform of the server error, any other response
|
||||||
|
code will be just appended to a dictionary and returned.
|
||||||
|
|
||||||
|
:param str url: URL where to do the request
|
||||||
|
:raises ValueError when user-agent isn't set
|
||||||
|
:return: The dictionary with the response or the status and his an error message
|
||||||
|
"""
|
||||||
|
if not _headers['user-agent']:
|
||||||
|
raise ValueError('User Agent isn\'t set')
|
||||||
|
|
||||||
|
r = _do_request(url)
|
||||||
|
|
||||||
|
if r.status_code == 200:
|
||||||
|
response = r.json(object_hook=sanitize_keys)
|
||||||
|
elif r.status_code == 500:
|
||||||
|
response = {'status': r.status_code, 'error': f'Error del servidor'}
|
||||||
|
elif r.status_code == 400:
|
||||||
|
response = {'status': r.status_code, 'error': f'El mbid es invalido'}
|
||||||
|
elif r.status_code == 404:
|
||||||
|
response = {'status': r.status_code, 'error': f'No encontrado'}
|
||||||
|
elif r.status_code == 405:
|
||||||
|
response = {'status': r.status_code, 'error': f'Metodo erroneo'}
|
||||||
|
elif r.status_code == 503:
|
||||||
|
response = {'status': r.status_code, 'error': f'Rate limit exedido'}
|
||||||
else:
|
else:
|
||||||
response = {'status': r.status_code, 'error': r.json()['error']}
|
response = {'status': r.status_code, 'error': r.json()['error']}
|
||||||
|
|
||||||
@@ -84,12 +116,12 @@ def _get(entity_type, mbid, includes=None):
|
|||||||
if includes is None:
|
if includes is None:
|
||||||
_log.info(f'Getting {entity_type} of mbid {mbid}')
|
_log.info(f'Getting {entity_type} of mbid {mbid}')
|
||||||
|
|
||||||
return _do_request(f'{_mb_host}/{entity_type}/{mbid}')
|
return _do_request_mb(f'{_mb_host}/{entity_type}/{mbid}')
|
||||||
else:
|
else:
|
||||||
_log.info(f'Getting {entity_type} of mbid {mbid} including {includes}')
|
_log.info(f'Getting {entity_type} of mbid {mbid} including {includes}')
|
||||||
_includes = quote('+'.join(includes))
|
_includes = quote('+'.join(includes))
|
||||||
|
|
||||||
return _do_request(f'{_mb_host}/{entity_type}/{mbid}?inc={_includes}')
|
return _do_request_mb(f'{_mb_host}/{entity_type}/{mbid}?inc={_includes}')
|
||||||
|
|
||||||
|
|
||||||
def _search(entity_type, query, includes=None, limit=25, offset=0):
|
def _search(entity_type, query, includes=None, limit=25, offset=0):
|
||||||
@@ -114,7 +146,7 @@ def _search(entity_type, query, includes=None, limit=25, offset=0):
|
|||||||
if includes is not None:
|
if includes is not None:
|
||||||
_query['inc'] = '+'.join(includes)
|
_query['inc'] = '+'.join(includes)
|
||||||
|
|
||||||
return _do_request(f'{_mb_host}/{entity_type}/?{urlencode(_query)}')
|
return _do_request_mb(f'{_mb_host}/{entity_type}/?{urlencode(_query)}')
|
||||||
|
|
||||||
|
|
||||||
def _browse(entity_type, params, includes=None, limit=25, offset=0):
|
def _browse(entity_type, params, includes=None, limit=25, offset=0):
|
||||||
@@ -142,7 +174,7 @@ def _browse(entity_type, params, includes=None, limit=25, offset=0):
|
|||||||
_log.info(f'Browsing {entity_type} with parameters {params} including {includes} at offset {offset} with limit of {limit}')
|
_log.info(f'Browsing {entity_type} with parameters {params} including {includes} at offset {offset} with limit of {limit}')
|
||||||
_query = urlencode({**params, 'inc': '+'.join(includes), 'limit': limit, 'offset': offset})
|
_query = urlencode({**params, 'inc': '+'.join(includes), 'limit': limit, 'offset': offset})
|
||||||
|
|
||||||
return _do_request(f'{_mb_host}/{entity_type}?{_query}')
|
return _do_request_mb(f'{_mb_host}/{entity_type}?{_query}')
|
||||||
|
|
||||||
|
|
||||||
def _ca(entity_type, mbid):
|
def _ca(entity_type, mbid):
|
||||||
@@ -158,7 +190,7 @@ def _ca(entity_type, mbid):
|
|||||||
|
|
||||||
_url = f'{_ca_host}/{entity_type}/{mbid}'
|
_url = f'{_ca_host}/{entity_type}/{mbid}'
|
||||||
|
|
||||||
return _do_request(_url, host=_ca_host)
|
return _do_request_ca(_url)
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
|
|||||||
@@ -11,21 +11,21 @@ class MusicBrainzTestCase(TestCase):
|
|||||||
|
|
||||||
def test_can_do_basic_request(self):
|
def test_can_do_basic_request(self):
|
||||||
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
||||||
musicbrainz._do_request(artist_url)
|
musicbrainz._do_request_mb(artist_url)
|
||||||
|
|
||||||
def test_do_request_response_format(self):
|
def test_do_request_response_format(self):
|
||||||
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
||||||
response = musicbrainz._do_request(artist_url)
|
response = musicbrainz._do_request_mb(artist_url)
|
||||||
self.assertIsInstance(response, dict)
|
self.assertIsInstance(response, dict)
|
||||||
self.assertEquals(response['status'], 200)
|
self.assertEquals(response['status'], 200)
|
||||||
self.assertIsInstance(response['response'], dict)
|
self.assertIsInstance(response['response'], dict)
|
||||||
|
|
||||||
def test_do_request_input_validation(self):
|
def test_do_request_input_validation(self):
|
||||||
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
||||||
self.assertRaises(ValueError, musicbrainz._do_request, None)
|
self.assertRaises(ValueError, musicbrainz._do_request_mb, None)
|
||||||
self.assertRaises(ValueError, musicbrainz._do_request, '')
|
self.assertRaises(ValueError, musicbrainz._do_request_mb, '')
|
||||||
musicbrainz._headers['user-agent'] = None
|
musicbrainz._headers['user-agent'] = None
|
||||||
self.assertRaises(ValueError, musicbrainz._do_request, artist_url)
|
self.assertRaises(ValueError, musicbrainz._do_request_mb, artist_url)
|
||||||
|
|
||||||
def test_cache(self):
|
def test_cache(self):
|
||||||
def fun():
|
def fun():
|
||||||
|
|||||||
Reference in New Issue
Block a user