Skip to content

Commit

Permalink
Error handling when account access has been revoked in one session bu…
Browse files Browse the repository at this point in the history
…t another session tries to make requests. Fixed Event loop runtime error on server shutdown. Updated reject button onclick confirmation pop-up.
  • Loading branch information
jaydeepjethwa committed Sep 1, 2022
1 parent b2950f1 commit 0c17416
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 53 deletions.
Binary file added app-ui/auth_screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 13 additions & 11 deletions app/auth/google_oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
# router for authorization urls
auth_router = APIRouter()

# httpx client for async support
client = httpx.AsyncClient()


@auth_router.get("/oauth2callback")
async def oauth2callback(request: Request, state: str = None, code: str = None):
Expand Down Expand Up @@ -55,7 +52,8 @@ async def oauth2callback(request: Request, state: str = None, code: str = None):
"grant_type": "authorization_code"
}

response = await client.post("https://oauth2.googleapis.com/token", data = data)
async with httpx.AsyncClient() as client:
response = await client.post("https://oauth2.googleapis.com/token", data = data)

request.session["credentials"] = response.json()

Expand All @@ -80,8 +78,11 @@ async def refresh_access_token(request: Request):
"grant_type": "refresh_token"
}

response = await client.post("https://oauth2.googleapis.com/token", data = data)
# yt refresh tokens don't expire hence no error in most cases
async with httpx.AsyncClient() as client:
response = await client.post("https://oauth2.googleapis.com/token", data = data)

if response.status_code == 400: # apps access to yt account has been revoked
return HTMLResponse(f"Web-app's access to your youtube account has been revoked. Please <a href={request.url_for('oauth2callback')}>authorize</a> to continue using the service.")

credentials = response.json()
request.session["credentials"]["access_token"] = credentials["access_token"]
Expand All @@ -105,16 +106,17 @@ async def revoke(request: Request):

# if not logged in login first
if "credentials" not in request.session:
return HTMLResponse(f"You need to <a href={request.url_for('oauth2callback')}>authorize</a> before testing the code to revoke credentials.")
return HTMLResponse(f"You need to <a href={request.url_for('oauth2callback')}>authorize</a> first before revoking the credentials.")

# get credentials from session
credentials = request.session["credentials"]

# revoke accesss
response = await client.post("https://oauth2.googleapis.com/revoke",
params = {"token": credentials["access_token"]},
headers = {"content-type": "application/x-www-form-urlencoded"}
)
async with httpx.AsyncClient() as client:
response = await client.post("https://oauth2.googleapis.com/revoke",
params = {"token": credentials["access_token"]},
headers = {"content-type": "application/x-www-form-urlencoded"}
)

# fails when quota exceeds or access token expires
if response.status_code == 403:
Expand Down
18 changes: 10 additions & 8 deletions app/library/youtube.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# clint secret key for sending requests to yt api
KEY = os.getenv("client_secret")

client = httpx.AsyncClient()

async def fetchChannelData(credentials: dict) -> dict:
"""Fetches youtube channel data for authorized google account.
Expand Down Expand Up @@ -36,8 +35,8 @@ async def fetchChannelData(credentials: dict) -> dict:
"part": "snippet,contentDetails,statistics",
"key": KEY
}

response = await client.get(request_uri, params = params, headers = headers)
async with httpx.AsyncClient() as client:
response = await client.get(request_uri, params = params, headers = headers)

# fails when quota exceeds or access token expires
if response.status_code == 403:
Expand Down Expand Up @@ -92,8 +91,8 @@ async def fetchVideoData(credentials: dict) -> dict:
"type": "video",
"key": KEY
}

response = await client.get(request_uri, params = params, headers = headers)
async with httpx.AsyncClient() as client:
response = await client.get(request_uri, params = params, headers = headers)

# fails when quota exceeds or access token expires
if response.status_code == 403:
Expand All @@ -120,7 +119,8 @@ async def fetchVideoData(credentials: dict) -> dict:
"key": KEY
}

response = await client.get(request_uri, params = params, headers = headers)
async with httpx.AsyncClient() as client:
response = await client.get(request_uri, params = params, headers = headers)

# fails when quota exceeds or access token expires
if response.status_code == 403:
Expand Down Expand Up @@ -183,7 +183,8 @@ async def fetchVideoComments(credentials: dict, video_id: str):
"key": KEY
}

response = await client.get(request_uri, params = params, headers = headers)
async with httpx.AsyncClient() as client:
response = await client.get(request_uri, params = params, headers = headers)

# fails when quota exceeds or access token expires
if response.status_code == 403:
Expand Down Expand Up @@ -237,7 +238,8 @@ async def rejectComments(credentials: dict, toxic_ids: list) -> None:
"key": KEY
}

response = await client.post(request_uri, params = params, headers = headers)
async with httpx.AsyncClient() as client:
response = await client.post(request_uri, params = params, headers = headers)

# fails when quota exceeds or access token expires
if response.status_code == 403:
Expand Down
2 changes: 1 addition & 1 deletion app/templates/video_analysis.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
if("{{ video['toxic_ids']|length }}" == 0) {
alert("No toxic comments found to reject.")
}
else if(confirm("Are you sure?") == true) {
else if(confirm("Are you sure you want to reject the toxic comments?\nThis action cannot be undone.") == true) {
document.getElementById("loader").style.display = "block";
document.getElementById("body-content").style.display = "none";
return true;
Expand Down
4 changes: 3 additions & 1 deletion app/views/video_analysis.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from fastapi import APIRouter, Request
from fastapi import APIRouter, Request, Response
from fastapi.responses import RedirectResponse, HTMLResponse

from library.youtube import fetchVideoComments, rejectComments
Expand Down Expand Up @@ -88,6 +88,8 @@ async def delete_graphs(video_id: str):
if os.path.exists(f"static/images/classification_graph_{video_id}.png"):
os.remove(f"static/images/classification_graph_{video_id}.png")

return Response(status_code = 200)


@analysis_view.get("/reject-comments/{video_id}")
async def reject_comments(request: Request, video_id: str):
Expand Down
69 changes: 37 additions & 32 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,40 +1,45 @@
cachetools==5.2.0
certifi==2022.5.18.1
charset-normalizer==2.0.12
colorama==0.4.4
filelock==3.7.1
google-api-core==2.8.1
google-api-python-client==2.49.0
google-auth==2.6.6
google-auth-httplib2==0.1.0
google-auth-oauthlib==0.5.1
googleapis-common-protos==1.56.2
httplib2==0.20.4
huggingface-hub==0.7.0
anyio==3.6.1
certifi==2022.6.15
charset-normalizer==2.1.1
click==8.1.3
colorama==0.4.5
cycler==0.11.0
fastapi==0.81.0
filelock==3.8.0
fonttools==4.37.1
h11==0.12.0
httpcore==0.15.0
httpx==0.23.0
huggingface-hub==0.9.1
idna==3.3
numpy==1.22.4
oauthlib==3.2.0
itsdangerous==2.1.2
Jinja2==3.1.2
kiwisolver==1.4.4
MarkupSafe==2.1.1
matplotlib==3.5.3
numpy==1.23.2
packaging==21.3
pandas==1.4.2
Pillow==9.1.1
protobuf==3.20.1
pyasn1==0.4.8
pyasn1-modules==0.2.8
pandas==1.4.4
Pillow==9.2.0
pydantic==1.10.1
pyparsing==3.0.9
python-dateutil==2.8.2
pytz==2022.1
python-dotenv==0.20.0
pytz==2022.2.1
PyYAML==6.0
regex==2022.6.2
requests==2.27.1
requests-oauthlib==1.3.1
rsa==4.8
regex==2022.8.17
requests==2.28.1
rfc3986==1.5.0
six==1.16.0
sniffio==1.2.0
starlette==0.19.1
tokenizers==0.12.1
torch==1.11.0+cu113
torchaudio==0.11.0+cu113
torchvision==0.12.0+cu113
torch==1.12.1+cu113
torchaudio==0.12.1+cu113
torchvision==0.13.1+cu113
tqdm==4.64.0
transformers==4.19.2
typing-extensions==4.2.0
uritemplate==4.1.1
urllib3==1.26.9
transformers==4.21.2
typing-extensions==4.3.0
urllib3==1.26.12
uvicorn==0.18.3
wordcloud==1.8.2.2

0 comments on commit 0c17416

Please sign in to comment.