Python Boto3를 이용한 Spotify 음악데이터 DynamoDB 저장&활용
.
Data_Engineering_TIL(20200607)
[참고사항]
-
‘Spotify API 음악데이터 저장을 위한 python 기본활용’를 이어서 참고할 것
-
URL : https://minman2115.github.io/DE_TIL91/
[학습내용]
-
먼저 shell에서 aws configure로 IAM credential을 등록해준다.
-
등록한 아이디에 해당하는 계정 콘솔로가서 DynamoDB를 아래 그림과 같이 생성해준다.
테이블 이름 : pms-dynamodb-test, 파티션 키 : artist_id (문자열), 정렬 키 : id (문자열), 총 읽기/쓰기 용량 : 5, 읽기/쓰기모드 : provisioned, 암호화 옵션 : 기본값
** 참고사항
index를 만들어서(create index) 같은 테이블에서도 여러개의 파티션 키를 지정해서 쓸 수 있다.
아래그림과 같은 방식으로 만들어주면 되는데 이번 실습에서는 만들지 않고 진행한다.
- 그러면 아래와 같이 코딩해서 실행해본다.
하나의 아티스트에 대해서 track을 id값으로 나누어서 데이터를 저장하는 것이고, put item이라는 것을 이용해서 single 단위로 데이터를 넣는 것이다.
import sys
import os
import boto3
import requests
import base64
import json
import logging
import pymysql
import io
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')
host = "pms-rdstest-rds.xxxxxxxxxxxxxxxx.ap-northeast-2.rds.amazonaws.com"
port = 3306
username = "admin"
database = "pmstest"
password = "xxxxxxxxxxxxxxxxxxxxxxxxx"
client_id = "xxxxxxxxxxxxxxxxxxxxx"
client_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
try:
conn = pymysql.connect(host, user=username, passwd=password, db=database, port=port, use_unicode=True, charset='utf8')
cursor = conn.cursor()
except:
logging.error("could not connect to rds")
sys.exit(1)
headers = get_headers(client_id, client_secret)
table = dynamodb.Table('pms-dynamodb-test')
cursor.execute('SELECT id FROM pmstest.artists limit 1')
## 아티스트 1명에 대해서만 시범적으로 돌려보자
for (artist_id, ) in cursor.fetchall():
URL = "https://api.spotify.com/v1/artists/{}/top-tracks".format(artist_id)
params = {'country': 'US'}
r = requests.get(URL, params=params, headers=headers)
raw = json.loads(r.text)
print(raw)
for track in raw['tracks']:
data = {'artist_id': artist_id}
data.update(track)
table.put_item(Item=data)
return None
def get_headers(client_id, client_secret):
endpoint = "https://accounts.spotify.com/api/token"
encoded = base64.b64encode("{}:{}".format(client_id, client_secret).encode('utf-8')).decode('ascii')
headers = {"Authorization": "Basic {}".format(encoded)}
payload = {"grant_type": "client_credentials"}
r = requests.post(endpoint, data=payload, headers=headers)
access_token = json.loads(r.text)['access_token']
headers = {"Authorization": "Bearer {}".format(access_token)}
return headers
if __name__=='__main__':
main()
실행 후 아래 그림과 같이 다이나모 디비에 10개의 데이터가 들어온 것을 확인할 수 있다.
다이나모 디비 테이블에 country 인덱스도 추가해서 돌리고 싶을때는 아래와 같이 코딩해서 실행하면 된다.
import sys
import os
import boto3
import requests
import base64
import json
import logging
import pymysql
import io
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')
host = "pms-rdstest-rds.xxxxxxxxxxxxxxxx.ap-northeast-2.rds.amazonaws.com"
port = 3306
username = "admin"
database = "pmstest"
password = "xxxxxxxxxxxxxxxxxxxxxxxxx"
client_id = "xxxxxxxxxxxxxxxxxxxxx"
client_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
try:
conn = pymysql.connect(host, user=username, passwd=password, db=database, port=port, use_unicode=True, charset='utf8')
cursor = conn.cursor()
except:
logging.error("could not connect to rds")
sys.exit(1)
headers = get_headers(client_id, client_secret)
table = dynamodb.Table('pms-dynamodb-test')
cursor.execute('SELECT id FROM pmstest.artists')
countries = ['US', 'CA']
for country in countries:
for (artist_id, ) in cursor.fetchall():
URL = "https://api.spotify.com/v1/artists/{}/top-tracks".format(artist_id)
params = {'country': 'US'}
r = requests.get(URL, params=params, headers=headers)
raw = json.loads(r.text)
for track in raw['tracks']:
data = {'artist_id': artist_id, 'country': country}
data.update(track)
table.put_item(Item=data)
return None
def get_headers(client_id, client_secret):
endpoint = "https://accounts.spotify.com/api/token"
encoded = base64.b64encode("{}:{}".format(client_id, client_secret).encode('utf-8')).decode('ascii')
headers = {"Authorization": "Basic {}".format(encoded)}
payload = {"grant_type": "client_credentials"}
r = requests.post(endpoint, data=payload, headers=headers)
access_token = json.loads(r.text)['access_token']
headers = {"Authorization": "Bearer {}".format(access_token)}
return headers
if __name__=='__main__':
main()
그러면 저장한 데이터를 아래와 같이 코드를 작성하여 특정 아이템을 get해보자.
import sys
import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
table = dynamodb.Table('pms-dynamodb-test')
response = table.get_item(Key={'artist_id':'4H2b90USTVSstPktwUsDZE'})
print(response)
return None
if __name__=='__main__':
main()
코드를 실행하면 아래와 같이 애러 메세지가 뜰 것이다.
Traceback (most recent call last):
File "dynamodb_12.8.py", line 23, in <module>
main()
File "dynamodb_12.8.py", line 16, in main
response = table.get_item(Key={'artist_id':'4H2b90USTVSstPktwUsDZE'})
File "C:\ProgramData\Anaconda3\lib\site-packages\boto3\resources\factory.py", line 520, in do_action
response = action(self, *args, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\boto3\resources\action.py", line 83, in __call__
response = getattr(parent.meta.client, operation_name)(**params)
File "C:\ProgramData\Anaconda3\lib\site-packages\botocore\client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\botocore\client.py", line 661, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the GetItem operation: The provided key element does not match the schema
다이나모 디비에서 키값을 artist_id로 해놓은 것도 있지만 id도 있었다. 따라서 get item을 하려면 아래 코드와 같이 id까지 전부 있어야지만 애러 없이 잘 가져올 수 있다.
import sys
import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
table = dynamodb.Table('pms-dynamodb-test')
response = table.get_item(Key={'artist_id':'4H2b90USTVSstPktwUsDZE','id':'0S84tthIVDN3rEVOejJVsM'})
print(response)
return None
if __name__=='__main__':
main()
실행결과는 아래와 같다.
{'Item': {'is_playable': True, 'duration_ms': Decimal('289680'), 'external_ids': {'isrc': 'USWB19700654'}, 'uri': 'spotify:track:0S84tthIVDN3rEVOejJVsM', 'name': 'In All My Wildest Dreams', 'album': {'total_tracks': Decimal('15'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273cf2c98d323ca13efb591780f', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02cf2c98d323ca13efb591780f', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851cf2c98d323ca13efb591780f', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1997-07-25', 'name': 'Sample This', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/0sQhUzdfLrBtQ8v2Hsl6Pp', 'id': '0sQhUzdfLrBtQ8v2Hsl6Pp', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/0sQhUzdfLrBtQ8v2Hsl6Pp'}, 'uri': 'spotify:album:0sQhUzdfLrBtQ8v2Hsl6Pp'}, 'popularity': Decimal('38'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0S84tthIVDN3rEVOejJVsM', 'track_number': Decimal('7'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0S84tthIVDN3rEVOejJVsM'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2d4692c1ca3c983fd59c5c8ac81f4278d2d6bda9?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0S84tthIVDN3rEVOejJVsM', 'explicit': False, 'type': 'track'}, 'ResponseMetadata': {'RequestId': 'SJHE8GK8N3OOM586BPSIFLLU1NVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'SJHE8GK8N3OOM586BPSIFLLU1NVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '3653699256', 'content-type': 'application/x-amz-json-1.0', 'content-length': '2238', 'date': 'Sun, 07 Jun 2020 13:43:06 GMT'}, 'RetryAttempts': 0}}
그러나 현실적으로 쓰일때는 artist_id나 id 값을 전부 알아서 하드코딩하는 일은 거의 없을 것이다.
현실적으로는 artist_id나 id 둘중하나만 알아서 필터링해서 가져오는 경우가 많을 것이다.
다이나모 디비의 boto3에서는 query와 scan이라는 것을 지원하는데 이걸 활용하면 된다.
import sys
import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
table = dynamodb.Table('pms-dynamodb-test')
response = table.query(KeyConditionExpression=Key('artist_id').eq('4H2b90USTVSstPktwUsDZE'))
# artist_id가 4H2b90USTVSstPktwUsDZE인것(eq=equal)을 쿼리
print(response)
return None
if __name__=='__main__':
main()
실행결과는 아래와 같다.
해당 artist_id에 대한 아이템을 가져오게 된다.
{'Items': [{'is_playable': True, 'duration_ms': Decimal('289680'), 'external_ids': {'isrc': 'USWB19700654'}, 'uri': 'spotify:track:0S84tthIVDN3rEVOejJVsM', 'name': 'In All My Wildest Dreams', 'album': {'total_tracks': Decimal('15'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273cf2c98d323ca13efb591780f', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02cf2c98d323ca13efb591780f', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851cf2c98d323ca13efb591780f', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1997-07-25', 'name': 'Sample This', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/0sQhUzdfLrBtQ8v2Hsl6Pp', 'id': '0sQhUzdfLrBtQ8v2Hsl6Pp', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/0sQhUzdfLrBtQ8v2Hsl6Pp'}, 'uri': 'spotify:album:0sQhUzdfLrBtQ8v2Hsl6Pp'}, 'popularity': Decimal('38'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0S84tthIVDN3rEVOejJVsM', 'track_number': Decimal('7'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0S84tthIVDN3rEVOejJVsM'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2d4692c1ca3c983fd59c5c8ac81f4278d2d6bda9?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0S84tthIVDN3rEVOejJVsM', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('233920'), 'external_ids': {'isrc': 'USPRA0600008'}, 'uri': 'spotify:track:0WU4L5lelOjccOeydME65Z', 'name': "Everybody's Talking", 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('48'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0WU4L5lelOjccOeydME65Z', 'track_number': Decimal('8'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0WU4L5lelOjccOeydME65Z'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/3bdbcd65ca07b1f9c93b8a1b7bf0ee3c74026c7b?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0WU4L5lelOjccOeydME65Z', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('307333'), 'external_ids': {'isrc': 'USPRA0600004'}, 'uri': 'spotify:track:0g7z3mwBdTn60MIL30TxhZ', 'name': 'Rio De Janeiro Blue', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('49'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0g7z3mwBdTn60MIL30TxhZ', 'track_number': Decimal('4'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0g7z3mwBdTn60MIL30TxhZ'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2db4951d4ea0d7e870e7001514b9436ddb35d06e?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0g7z3mwBdTn60MIL30TxhZ', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('297813'), 'external_ids': {'isrc': 'USPRA0600006'}, 'uri': 'spotify:track:1S0Gx1R13Somg6WKobPcMc', 'name': 'See Line Woman', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('38'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/1S0Gx1R13Somg6WKobPcMc', 'track_number': Decimal('6'), 'external_urls': {'spotify': 'https://open.spotify.com/track/1S0Gx1R13Somg6WKobPcMc'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/222a0aeb60863fea7c108492b9ad4c8743db82a3?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '1S0Gx1R13Somg6WKobPcMc', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('291266'), 'external_ids': {'isrc': 'USWB18900034'}, 'uri': 'spotify:track:2MX5LrnzqPKdiyxwFez2Ma', 'name': 'U Turn', 'album': {'total_tracks': Decimal('10'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273b693653b1ee0b7108208a568', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02b693653b1ee0b7108208a568', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851b693653b1ee0b7108208a568', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1989-03-10', 'name': 'Spellbound', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/7q0WkXf88v6eTtgqrckZHH', 'id': '7q0WkXf88v6eTtgqrckZHH', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/7q0WkXf88v6eTtgqrckZHH'}, 'uri': 'spotify:album:7q0WkXf88v6eTtgqrckZHH'}, 'popularity': Decimal('40'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/2MX5LrnzqPKdiyxwFez2Ma', 'track_number': Decimal('6'), 'external_urls': {'spotify': 'https://open.spotify.com/track/2MX5LrnzqPKdiyxwFez2Ma'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2b2d2357515b9165743500252b3aecd17fcc3b7b?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '2MX5LrnzqPKdiyxwFez2Ma', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('343480'), 'external_ids': {'isrc': 'USPRA9900006'}, 'uri': 'spotify:track:3CObSbajZV0iSviNXZFhfk', 'name': 'When Your Life Was Low', 'album': {'total_tracks': Decimal('11'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b2731f0ff9a82f509cfc550d15dc', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e021f0ff9a82f509cfc550d15dc', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d000048511f0ff9a82f509cfc550d15dc', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'release_date': '1999', 'name': 'The Song Lives On', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/1hRQZQa8ryz2oOunpCMf0Y', 'id': '1hRQZQa8ryz2oOunpCMf0Y', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/1hRQZQa8ryz2oOunpCMf0Y'}, 'uri': 'spotify:album:1hRQZQa8ryz2oOunpCMf0Y'}, 'popularity': Decimal('36'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/3CObSbajZV0iSviNXZFhfk', 'track_number': Decimal('6'), 'external_urls': {'spotify': 'https://open.spotify.com/track/3CObSbajZV0iSviNXZFhfk'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/8ff39f5cfc1e03907061eac8057668b6a58b31a8?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '3CObSbajZV0iSviNXZFhfk', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('253746'), 'external_ids': {'isrc': 'USPRA0600009'}, 'uri': 'spotify:track:50vVWF1lAFb1A4ZnIQWsr1', 'name': 'When I Need You', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('41'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/50vVWF1lAFb1A4ZnIQWsr1', 'track_number': Decimal('9'), 'external_urls': {'spotify': 'https://open.spotify.com/track/50vVWF1lAFb1A4ZnIQWsr1'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/beb8a06964dbc83fc017382775029b32c445648d?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '50vVWF1lAFb1A4ZnIQWsr1', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('240666'), 'external_ids': {'isrc': 'DEA890500467'}, 'uri': 'spotify:track:5G4mD6dNtV9V30npBbAj0i', 'name': 'One Day I Fly Away', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273a0a3e94b1ee94e8a284f84db', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02a0a3e94b1ee94e8a284f84db', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851a0a3e94b1ee94e8a284f84db', 'height': Decimal('64')}], 'artists': [{'name': 'Nils Landgren', 'href': 'https://api.spotify.com/v1/artists/6B3ZWSop1mrJd71rwFozVP', 'id': '6B3ZWSop1mrJd71rwFozVP', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/6B3ZWSop1mrJd71rwFozVP'}, 'uri': 'spotify:artist:6B3ZWSop1mrJd71rwFozVP'}, {'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '2005-10-28', 'name': 'Creole Love Call', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/1aV2jCH2ntuiZTpcrPcQvn', 'id': '1aV2jCH2ntuiZTpcrPcQvn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/1aV2jCH2ntuiZTpcrPcQvn'}, 'uri': 'spotify:album:1aV2jCH2ntuiZTpcrPcQvn'}, 'popularity': Decimal('44'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Nils Landgren', 'href': 'https://api.spotify.com/v1/artists/6B3ZWSop1mrJd71rwFozVP', 'id': '6B3ZWSop1mrJd71rwFozVP', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/6B3ZWSop1mrJd71rwFozVP'}, 'uri': 'spotify:artist:6B3ZWSop1mrJd71rwFozVP'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/5G4mD6dNtV9V30npBbAj0i', 'track_number': Decimal('7'), 'external_urls': {'spotify': 'https://open.spotify.com/track/5G4mD6dNtV9V30npBbAj0i'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/870bf61e6d74ac3c11557bc4cb90a0e38f575669?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '5G4mD6dNtV9V30npBbAj0i', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('349053'), 'external_ids': {'isrc': 'USPRA9900005'}, 'uri': 'spotify:track:5jdyZZl1zFVdzFvN2cWHWE', 'name': 'Street Life', 'album': {'total_tracks': Decimal('11'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b2731f0ff9a82f509cfc550d15dc', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e021f0ff9a82f509cfc550d15dc', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d000048511f0ff9a82f509cfc550d15dc', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'release_date': '1999', 'name': 'The Song Lives On', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/1hRQZQa8ryz2oOunpCMf0Y', 'id': '1hRQZQa8ryz2oOunpCMf0Y', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/1hRQZQa8ryz2oOunpCMf0Y'}, 'uri': 'spotify:album:1hRQZQa8ryz2oOunpCMf0Y'}, 'popularity': Decimal('34'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/5jdyZZl1zFVdzFvN2cWHWE', 'track_number': Decimal('5'), 'external_urls': {'spotify': 'https://open.spotify.com/track/5jdyZZl1zFVdzFvN2cWHWE'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/d1f1745e941edf1554b8d5e6e3a2362384feeb37?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '5jdyZZl1zFVdzFvN2cWHWE', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('308640'), 'external_ids': {'isrc': 'USWB10000263'}, 'uri': 'spotify:track:6rtGTWFi7HGoK9nCU7gsVA', 'name': 'Leading Me Back to You', 'album': {'total_tracks': Decimal('10'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273b693653b1ee0b7108208a568', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02b693653b1ee0b7108208a568', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851b693653b1ee0b7108208a568', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1989-03-10', 'name': 'Spellbound', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/7q0WkXf88v6eTtgqrckZHH', 'id': '7q0WkXf88v6eTtgqrckZHH', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/7q0WkXf88v6eTtgqrckZHH'}, 'uri': 'spotify:album:7q0WkXf88v6eTtgqrckZHH'}, 'popularity': Decimal('44'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Michael Franks', 'href': 'https://api.spotify.com/v1/artists/0AVE7rDx4X9w0pW1XlN1om', 'id': '0AVE7rDx4X9w0pW1XlN1om', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0AVE7rDx4X9w0pW1XlN1om'}, 'uri': 'spotify:artist:0AVE7rDx4X9w0pW1XlN1om'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/6rtGTWFi7HGoK9nCU7gsVA', 'track_number': Decimal('5'), 'external_urls': {'spotify': 'https://open.spotify.com/track/6rtGTWFi7HGoK9nCU7gsVA'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/b7934da9819d134159f3ee9e887e48231c958518?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '6rtGTWFi7HGoK9nCU7gsVA', 'explicit': False, 'type': 'track'}], 'Count': 10, 'ScannedCount': 10, 'ResponseMetadata': {'RequestId': '7H6M7F5KLI7CU874978HCHV70NVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '7H6M7F5KLI7CU874978HCHV70NVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '1967264896', 'content-type': 'application/x-amz-json-1.0', 'content-length': '27027', 'date': 'Sun, 07 Jun 2020 13:52:02 GMT'}, 'RetryAttempts': 0}}
또는 그중에서 Items만 가져올 수도 있다.
import sys
import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
table = dynamodb.Table('pms-dynamodb-test')
response = table.query(KeyConditionExpression=Key('artist_id').eq('4H2b90USTVSstPktwUsDZE'))
# artist_id가 4H2b90USTVSstPktwUsDZE인것(eq=equal)을 쿼리
print(response['Items'])
print(len(response['Items']))
return None
if __name__=='__main__':
main()
실행결과는 아래와 같다.
[{'is_playable': True, 'duration_ms': Decimal('289680'), 'external_ids': {'isrc': 'USWB19700654'}, 'uri': 'spotify:track:0S84tthIVDN3rEVOejJVsM', 'name': 'In All My Wildest Dreams', 'album': {'total_tracks': Decimal('15'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273cf2c98d323ca13efb591780f', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02cf2c98d323ca13efb591780f', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851cf2c98d323ca13efb591780f', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1997-07-25', 'name': 'Sample This', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/0sQhUzdfLrBtQ8v2Hsl6Pp', 'id': '0sQhUzdfLrBtQ8v2Hsl6Pp', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/0sQhUzdfLrBtQ8v2Hsl6Pp'}, 'uri': 'spotify:album:0sQhUzdfLrBtQ8v2Hsl6Pp'}, 'popularity': Decimal('38'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0S84tthIVDN3rEVOejJVsM', 'track_number': Decimal('7'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0S84tthIVDN3rEVOejJVsM'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2d4692c1ca3c983fd59c5c8ac81f4278d2d6bda9?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0S84tthIVDN3rEVOejJVsM', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('233920'), 'external_ids': {'isrc': 'USPRA0600008'}, 'uri': 'spotify:track:0WU4L5lelOjccOeydME65Z', 'name': "Everybody's Talking", 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('48'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0WU4L5lelOjccOeydME65Z', 'track_number': Decimal('8'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0WU4L5lelOjccOeydME65Z'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/3bdbcd65ca07b1f9c93b8a1b7bf0ee3c74026c7b?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0WU4L5lelOjccOeydME65Z', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('307333'), 'external_ids': {'isrc': 'USPRA0600004'}, 'uri': 'spotify:track:0g7z3mwBdTn60MIL30TxhZ', 'name': 'Rio De Janeiro Blue', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('49'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0g7z3mwBdTn60MIL30TxhZ', 'track_number': Decimal('4'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0g7z3mwBdTn60MIL30TxhZ'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2db4951d4ea0d7e870e7001514b9436ddb35d06e?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0g7z3mwBdTn60MIL30TxhZ', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('297813'), 'external_ids': {'isrc': 'USPRA0600006'}, 'uri': 'spotify:track:1S0Gx1R13Somg6WKobPcMc', 'name': 'See Line Woman', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('38'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/1S0Gx1R13Somg6WKobPcMc', 'track_number': Decimal('6'), 'external_urls': {'spotify': 'https://open.spotify.com/track/1S0Gx1R13Somg6WKobPcMc'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/222a0aeb60863fea7c108492b9ad4c8743db82a3?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '1S0Gx1R13Somg6WKobPcMc', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('291266'), 'external_ids': {'isrc': 'USWB18900034'}, 'uri': 'spotify:track:2MX5LrnzqPKdiyxwFez2Ma', 'name': 'U Turn', 'album': {'total_tracks': Decimal('10'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273b693653b1ee0b7108208a568', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02b693653b1ee0b7108208a568', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851b693653b1ee0b7108208a568', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1989-03-10', 'name': 'Spellbound', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/7q0WkXf88v6eTtgqrckZHH', 'id': '7q0WkXf88v6eTtgqrckZHH', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/7q0WkXf88v6eTtgqrckZHH'}, 'uri': 'spotify:album:7q0WkXf88v6eTtgqrckZHH'}, 'popularity': Decimal('40'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/2MX5LrnzqPKdiyxwFez2Ma', 'track_number': Decimal('6'), 'external_urls': {'spotify': 'https://open.spotify.com/track/2MX5LrnzqPKdiyxwFez2Ma'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2b2d2357515b9165743500252b3aecd17fcc3b7b?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '2MX5LrnzqPKdiyxwFez2Ma', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('343480'), 'external_ids': {'isrc': 'USPRA9900006'}, 'uri': 'spotify:track:3CObSbajZV0iSviNXZFhfk', 'name': 'When Your Life Was Low', 'album': {'total_tracks': Decimal('11'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b2731f0ff9a82f509cfc550d15dc', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e021f0ff9a82f509cfc550d15dc', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d000048511f0ff9a82f509cfc550d15dc', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'release_date': '1999', 'name': 'The Song Lives On', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/1hRQZQa8ryz2oOunpCMf0Y', 'id': '1hRQZQa8ryz2oOunpCMf0Y', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/1hRQZQa8ryz2oOunpCMf0Y'}, 'uri': 'spotify:album:1hRQZQa8ryz2oOunpCMf0Y'}, 'popularity': Decimal('36'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/3CObSbajZV0iSviNXZFhfk', 'track_number': Decimal('6'), 'external_urls': {'spotify': 'https://open.spotify.com/track/3CObSbajZV0iSviNXZFhfk'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/8ff39f5cfc1e03907061eac8057668b6a58b31a8?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '3CObSbajZV0iSviNXZFhfk', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('253746'), 'external_ids': {'isrc': 'USPRA0600009'}, 'uri': 'spotify:track:50vVWF1lAFb1A4ZnIQWsr1', 'name': 'When I Need You', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('41'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/50vVWF1lAFb1A4ZnIQWsr1', 'track_number': Decimal('9'), 'external_urls': {'spotify': 'https://open.spotify.com/track/50vVWF1lAFb1A4ZnIQWsr1'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/beb8a06964dbc83fc017382775029b32c445648d?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '50vVWF1lAFb1A4ZnIQWsr1', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('240666'), 'external_ids': {'isrc': 'DEA890500467'}, 'uri': 'spotify:track:5G4mD6dNtV9V30npBbAj0i', 'name': 'One Day I Fly Away', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273a0a3e94b1ee94e8a284f84db', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02a0a3e94b1ee94e8a284f84db', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851a0a3e94b1ee94e8a284f84db', 'height': Decimal('64')}], 'artists': [{'name': 'Nils Landgren', 'href': 'https://api.spotify.com/v1/artists/6B3ZWSop1mrJd71rwFozVP', 'id': '6B3ZWSop1mrJd71rwFozVP', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/6B3ZWSop1mrJd71rwFozVP'}, 'uri': 'spotify:artist:6B3ZWSop1mrJd71rwFozVP'}, {'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '2005-10-28', 'name': 'Creole Love Call', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/1aV2jCH2ntuiZTpcrPcQvn', 'id': '1aV2jCH2ntuiZTpcrPcQvn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/1aV2jCH2ntuiZTpcrPcQvn'}, 'uri': 'spotify:album:1aV2jCH2ntuiZTpcrPcQvn'}, 'popularity': Decimal('44'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Nils Landgren', 'href': 'https://api.spotify.com/v1/artists/6B3ZWSop1mrJd71rwFozVP', 'id': '6B3ZWSop1mrJd71rwFozVP', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/6B3ZWSop1mrJd71rwFozVP'}, 'uri': 'spotify:artist:6B3ZWSop1mrJd71rwFozVP'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/5G4mD6dNtV9V30npBbAj0i', 'track_number': Decimal('7'), 'external_urls': {'spotify': 'https://open.spotify.com/track/5G4mD6dNtV9V30npBbAj0i'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/870bf61e6d74ac3c11557bc4cb90a0e38f575669?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '5G4mD6dNtV9V30npBbAj0i', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('349053'), 'external_ids': {'isrc': 'USPRA9900005'}, 'uri': 'spotify:track:5jdyZZl1zFVdzFvN2cWHWE', 'name': 'Street Life', 'album': {'total_tracks': Decimal('11'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b2731f0ff9a82f509cfc550d15dc', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e021f0ff9a82f509cfc550d15dc', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d000048511f0ff9a82f509cfc550d15dc', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'release_date': '1999', 'name': 'The Song Lives On', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/1hRQZQa8ryz2oOunpCMf0Y', 'id': '1hRQZQa8ryz2oOunpCMf0Y', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/1hRQZQa8ryz2oOunpCMf0Y'}, 'uri': 'spotify:album:1hRQZQa8ryz2oOunpCMf0Y'}, 'popularity': Decimal('34'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Lalah Hathaway', 'href': 'https://api.spotify.com/v1/artists/0uNEy4544VZq2KOl7BsLuo', 'id': '0uNEy4544VZq2KOl7BsLuo', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0uNEy4544VZq2KOl7BsLuo'}, 'uri': 'spotify:artist:0uNEy4544VZq2KOl7BsLuo'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/5jdyZZl1zFVdzFvN2cWHWE', 'track_number': Decimal('5'), 'external_urls': {'spotify': 'https://open.spotify.com/track/5jdyZZl1zFVdzFvN2cWHWE'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/d1f1745e941edf1554b8d5e6e3a2362384feeb37?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '5jdyZZl1zFVdzFvN2cWHWE', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('308640'), 'external_ids': {'isrc': 'USWB10000263'}, 'uri': 'spotify:track:6rtGTWFi7HGoK9nCU7gsVA', 'name': 'Leading Me Back to You', 'album': {'total_tracks': Decimal('10'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273b693653b1ee0b7108208a568', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02b693653b1ee0b7108208a568', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851b693653b1ee0b7108208a568', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}], 'release_date': '1989-03-10', 'name': 'Spellbound', 'album_type': 'album', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/7q0WkXf88v6eTtgqrckZHH', 'id': '7q0WkXf88v6eTtgqrckZHH', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/7q0WkXf88v6eTtgqrckZHH'}, 'uri': 'spotify:album:7q0WkXf88v6eTtgqrckZHH'}, 'popularity': Decimal('44'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Michael Franks', 'href': 'https://api.spotify.com/v1/artists/0AVE7rDx4X9w0pW1XlN1om', 'id': '0AVE7rDx4X9w0pW1XlN1om', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/0AVE7rDx4X9w0pW1XlN1om'}, 'uri': 'spotify:artist:0AVE7rDx4X9w0pW1XlN1om'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/6rtGTWFi7HGoK9nCU7gsVA', 'track_number': Decimal('5'), 'external_urls': {'spotify': 'https://open.spotify.com/track/6rtGTWFi7HGoK9nCU7gsVA'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/b7934da9819d134159f3ee9e887e48231c958518?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '6rtGTWFi7HGoK9nCU7gsVA', 'explicit': False, 'type': 'track'}]
10
artist_id가 4H2b90USTVSstPktwUsDZE인것(eq=equal)을 쿼리하고, 인기도가 45이상인 것을 가져오고 싶을때를 가정하여 쿼리를 하면 아래와 같이 코딩하면 된다.
import sys
import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
table = dynamodb.Table('pms-dynamodb-test')
response = table.query(
KeyConditionExpression=Key('artist_id').eq('4H2b90USTVSstPktwUsDZE'),
FilterExpression=Attr('popularity').gt(45)
)
## gt = greater than
## eq = equal
print(response['Items'])
print(len(response['Items']))
return None
if __name__=='__main__':
main()
실행결과는 아래와 같다. 필터링해서 2개의 아이템만 가져왔다.
[{'is_playable': True, 'duration_ms': Decimal('233920'), 'external_ids': {'isrc': 'USPRA0600008'}, 'uri': 'spotify:track:0WU4L5lelOjccOeydME65Z', 'name': "Everybody's Talking", 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('48'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0WU4L5lelOjccOeydME65Z', 'track_number': Decimal('8'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0WU4L5lelOjccOeydME65Z'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/3bdbcd65ca07b1f9c93b8a1b7bf0ee3c74026c7b?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0WU4L5lelOjccOeydME65Z', 'explicit': False, 'type': 'track'}, {'is_playable': True, 'duration_ms': Decimal('307333'), 'external_ids': {'isrc': 'USPRA0600004'}, 'uri': 'spotify:track:0g7z3mwBdTn60MIL30TxhZ', 'name': 'Rio De Janeiro Blue', 'album': {'total_tracks': Decimal('13'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b27317d6026f533da4ad42c66663', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e0217d6026f533da4ad42c66663', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d0000485117d6026f533da4ad42c66663', 'height': Decimal('64')}], 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'release_date': '2007', 'name': 'Feeling Good', 'album_type': 'album', 'release_date_precision': 'year', 'href': 'https://api.spotify.com/v1/albums/489jRVamTAWOj7Gj1vFyqn', 'id': '489jRVamTAWOj7Gj1vFyqn', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/489jRVamTAWOj7Gj1vFyqn'}, 'uri': 'spotify:album:489jRVamTAWOj7Gj1vFyqn'}, 'popularity': Decimal('49'), 'artists': [{'name': 'Joe Sample', 'href': 'https://api.spotify.com/v1/artists/4H2b90USTVSstPktwUsDZE', 'id': '4H2b90USTVSstPktwUsDZE', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/4H2b90USTVSstPktwUsDZE'}, 'uri': 'spotify:artist:4H2b90USTVSstPktwUsDZE'}, {'name': 'Randy Crawford', 'href': 'https://api.spotify.com/v1/artists/1twC2fwPG5FkvYcMpVBQRz', 'id': '1twC2fwPG5FkvYcMpVBQRz', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/1twC2fwPG5FkvYcMpVBQRz'}, 'uri': 'spotify:artist:1twC2fwPG5FkvYcMpVBQRz'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/0g7z3mwBdTn60MIL30TxhZ', 'track_number': Decimal('4'), 'external_urls': {'spotify': 'https://open.spotify.com/track/0g7z3mwBdTn60MIL30TxhZ'}, 'artist_id': '4H2b90USTVSstPktwUsDZE', 'preview_url': 'https://p.scdn.co/mp3-preview/2db4951d4ea0d7e870e7001514b9436ddb35d06e?cid=f0cfebcb06b94d84a40ba945f39dab18', 'is_local': False, 'id': '0g7z3mwBdTn60MIL30TxhZ', 'explicit': False, 'type': 'track'}]
2
아니면 아티스트 아이디, 아이디 이런거 모르겠고, popularity가 90이 넘는것만 가져오고 싶다할때 아래와 같이 scan을 이용해서 코딩하면 된다.
import sys
import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
def main():
try:
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2', endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
except:
logging.error('could not connect to dynamodb')
sys.exit(1)
table = dynamodb.Table('pms-dynamodb-test')
response = table.scan(FilterExpression=Attr('popularity').gt(90))
print(response['Items'])
print(len(response['Items']))
return None
if __name__=='__main__':
main()
실행하면 popularity 90이 넘는 아이템 하나를 가져오게 된다.
[{'is_playable': True, 'duration_ms': Decimal('189486'), 'external_ids': {'isrc': 'USUM71913350'}, 'uri': 'spotify:track:2b8fOow8UzyDFAE27YhOZM', 'name': 'Memories', 'album': {'total_tracks': Decimal('1'), 'images': [{'width': Decimal('640'), 'url': 'https://i.scdn.co/image/ab67616d0000b273b8c0135a218de2d10a8435f5', 'height': Decimal('640')}, {'width': Decimal('300'), 'url': 'https://i.scdn.co/image/ab67616d00001e02b8c0135a218de2d10a8435f5', 'height': Decimal('300')}, {'width': Decimal('64'), 'url': 'https://i.scdn.co/image/ab67616d00004851b8c0135a218de2d10a8435f5', 'height': Decimal('64')}], 'artists': [{'name': 'Maroon 5', 'href': 'https://api.spotify.com/v1/artists/04gDigrS5kc9YWfZHwBETP', 'id': '04gDigrS5kc9YWfZHwBETP', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/04gDigrS5kc9YWfZHwBETP'}, 'uri': 'spotify:artist:04gDigrS5kc9YWfZHwBETP'}], 'release_date': '2019-09-20', 'name': 'Memories', 'album_type': 'single', 'release_date_precision': 'day', 'href': 'https://api.spotify.com/v1/albums/3nR9B40hYLKLcR0Eph3Goc', 'id': '3nR9B40hYLKLcR0Eph3Goc', 'type': 'album', 'external_urls': {'spotify': 'https://open.spotify.com/album/3nR9B40hYLKLcR0Eph3Goc'}, 'uri': 'spotify:album:3nR9B40hYLKLcR0Eph3Goc'}, 'popularity': Decimal('91'), 'artists': [{'name': 'Maroon 5', 'href': 'https://api.spotify.com/v1/artists/04gDigrS5kc9YWfZHwBETP', 'id': '04gDigrS5kc9YWfZHwBETP', 'type': 'artist', 'external_urls': {'spotify': 'https://open.spotify.com/artist/04gDigrS5kc9YWfZHwBETP'}, 'uri': 'spotify:artist:04gDigrS5kc9YWfZHwBETP'}], 'disc_number': Decimal('1'), 'href': 'https://api.spotify.com/v1/tracks/2b8fOow8UzyDFAE27YhOZM', 'track_number': Decimal('1'), 'external_urls': {'spotify': 'https://open.spotify.com/track/2b8fOow8UzyDFAE27YhOZM'}, 'artist_id': '04gDigrS5kc9YWfZHwBETP', 'preview_url': None, 'is_local': False, 'id': '2b8fOow8UzyDFAE27YhOZM', 'explicit': False, 'type': 'track'}]
1
단 scan을 할때 주의해야할 점이 있다.
key 값을 안쓰는 경우에는 모든 로우를 말그대로 scan하기 때문에 대용량일 경우에는 시간이 매우 소요될 수도 있다.