/
oauth2_async.py
executable file
·116 lines (91 loc) · 3.26 KB
/
oauth2_async.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import os
import aiofiles
import webbrowser
import json as stdlib_json
from sanic import Sanic, response
from sanic.exceptions import abort
from sanic.response import json
from pyfy import AsyncSpotify, ClientCreds, AuthError
try:
from spt_keys import KEYS
except: # noqa: E722
from spt_keys_template import KEYS
app = Sanic(__name__)
local_address = "localhost"
local_port = "5000"
local_full_address = local_address + ":" + str(local_port)
spt = AsyncSpotify()
client = ClientCreds()
state = "123"
@app.route("/authorize")
def authorize(request):
export_keys()
client.load_from_env()
spt.client_creds = client
if spt.is_oauth_ready:
return response.redirect(spt.auth_uri(state=state))
else:
return (
json(
{
"error_description": "Client needs client_id, client_secret and a redirect uri in order to handle OAauth properly"
}
),
500,
)
@app.route("/callback/spotify") # You have to register this callback
async def spotify_callback(request):
if request.args.get("error"):
return json(dict(error=request.args.get("error_description")))
elif request.args.get("code"):
grant = request.args.get("code")
callback_state = request.args.get("state")
if callback_state != state:
abort(401)
try:
user_creds = await spt.build_user_creds(grant=grant)
async with aiofiles.open(os.getcwd() + "SPOTIFY_CREDS.json", "w") as file:
await file.write(stdlib_json.dumps(user_creds.__dict__))
except AuthError as e:
return json(dict(error_description=e.msg, error_code=e.code), e.code)
else:
await spt.populate_user_creds()
print(os.getcwd())
return await response.file(os.getcwd() + "SPOTIFY_CREDS.json")
# return response.json(dict(user_creds=user_creds.__dict__, check_if_active=app.url_for('is_active', _scheme='http', _external=True, _server=local_full_address)), 200)
else:
return response.text("Something is wrong with your callback")
@app.route("/is_active")
async def is_active(request):
return json(
dict(
is_active=await spt.is_active,
your_tracks=app.url_for(
"tracks", _scheme="http", _external=True, _server=local_full_address
),
your_playlists=app.url_for(
"playlists", _scheme="http", _external=True, _server=local_full_address
),
)
)
@app.route("/dump_creds")
def dump_creds(request):
# TODO: save both client and user creds and send to user as json files to downlaod
return response.text("Not Implemented")
@app.route("/")
def index(request):
return response.text("OK")
@app.route("/tracks")
async def tracks(request):
return json(await spt.user_tracks())
@app.route("/playlists")
async def playlists(request):
return json(await spt.user_playlists())
def export_keys():
for k, v in KEYS.items():
if v:
os.environ[k] = v
print("export " + k + "=" + v)
if __name__ == "__main__":
webbrowser.open_new_tab("http://" + local_full_address + "/authorize")
app.run(host=local_address, port=str(local_port), debug=True)