I'm trying to make a GitHub bot that posts issues when a complementary app throws errors, but I'm having trouble trying to get an access token. This is my code so far:
import asyncio
import random
import webbrowser
import aiohttp.web
randgen = random.SystemRandom()
# The task is relatively simple. Query for the client ID, client secret, and then produces a URL.
# It opens this URL in a web-browser, then sets up a server on port 12345, waiting for an appropriate response.
# Using this code, it finishes the rest of the flow.
class Authorizer:
def __init__(self):
self.client_id = self.client_secret = ""
self.redirect_url = "http://localhost:12345/callback"
self.scopes = ["public_repo"]
self.state = 0
self.done = False
async def handler(self, request: aiohttp.web.Request):
code = request.query["code"]
async with aiohttp.ClientSession() as client:
async with client.post("https://github.com/login/oauth/access_token",
data=dict(client_id=self.client_id, client_secret=self.client_secret, code=code, state=self.state),
headers=dict(Accept="application/json")) as request:
json = await request.json()
assert str(json["state"]) == self.state
resp = "Access Token: " + json["access_token"]
print(resp)
self.done = True
return aiohttp.web.Response(text=resp)
async def start(self):
self.client_id = input("App Client ID: ")
self.client_secret = input("App Client Secret: ")
self.state = randgen.randint(1, 1000)
scope_str = ' '.join(self.scopes)
url = f"https://github.com/login/oauth/authorize?client_id={self.client_secret}&redirect_uri={self.redirect_url}&scope=" \
f"{scope_str}&state={self.state}"
print("Opening URL: " + url)
webbrowser.open(url)
self.server = aiohttp.web.Server(self.handler)
self.runner = aiohttp.web.ServerRunner(self.server)
await self.runner.setup()
self.site = aiohttp.web.TCPSite(self.runner, 'localhost', 12345)
await self.site.start()
while not self.done:
await asyncio.sleep(1)
await self.site.stop()
input("Complete! Make sure you take your access token with you! Now hit enter to exit.")
if __name__ == '__main__':
auth = Authorizer()
loop = asyncio.get_event_loop()
loop.run_until_complete(auth.start())
I get an error, where the constructed URL gives me a 404 error. Getting rid of the state, redirect URL, and scopes don't change the error. I looked at the official docs when making this, so I don't understand why the constructed error is giving me a 404.