Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The error is occurring because the URL object cannot be converted into bytes directly. To fix this error, you can use the str.encode() method to convert the URL object into bytes before passing it to the Authorization header.

Here's an example of how to modify the example code to fix the error:

import requests
from fastapi import FastAPI, Depends
from fastapi.responses import HTMLResponse
from authlib.integrations.requests_client import OAuth2Session

app = FastAPI()

# configure the oauth2 client
client_id = 'your_client_id_here'
client_secret = 'your_client_secret_here'
redirect_uri = 'http://localhost:8000/api/google/auth'
scope = 'email profile openid'
access_token_url = 'https://accounts.google.com/o/oauth2/token'
access_token_params = None
authorize_url = 'https://accounts.google.com/o/oauth2/auth'
authorize_params = None
api_base_url = 'https://www.googleapis.com/oauth2/v1/'
client = OAuth2Session(client_id, client_secret, redirect_uri=redirect_uri, scope=scope)
client.register('google', access_token_url=access_token_url, access_token_params=access_token_params,
                authorize_url=authorize_url, authorize_params=authorize_params, api_base_url=api_base_url)

# define a dependency to get the current user
def get_current_user(token: str = Depends(client.oauth2_token)) -> dict:
    url = 'https://www.googleapis.com/oauth2/v2/userinfo'
    headers = {'Authorization': f'Bearer {token.get("access_token")}'.encode()}
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()

# define the login route
@app.get('/login')
async def login() -> HTMLResponse:
    authorization_url, state = client.create_authorization_url('google')
    return HTMLResponse(f'<a href="{authorization_url}">Login with Google</a>')

# define the callback route
@app.get('/api/google/auth')
async def auth(code: str):
    token = client.fetch_token('google', authorization_response=code)
    return {'access_token': token.get('access_token'), 'token_type': token.get('token_type')}

# define a protected route
@app.get('/protected')
async def protected(current_user: dict = Depends(get_current_user)):
    return {'current_user': current_user}

In the getcurrentuser function, you can modify the Authorization header to encode the token as bytes before passing it to the headers dictionary. This should fix the TypeError and allow the code to run without issues.