Skip to content

Instantly share code, notes, and snippets.

@heiswayi
Created January 16, 2024 02:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heiswayi/a0ff3520c2abff39eb1182190ad9633c to your computer and use it in GitHub Desktop.
Save heiswayi/a0ff3520c2abff39eb1182190ad9633c to your computer and use it in GitHub Desktop.

To create a Python web API using FastAPI and Uvicorn as described, follow the steps below:

Firstly, install the required packages:

pip install fastapi uvicorn python-jose[cryptography]

Next, create your main file main.py with the following content:

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
import secrets
from pydantic import BaseModel

app = FastAPI()

SECRET_KEY = secrets.token_hex(32)  # Secret key for JWT token generation
ALGORITHM = "HS256"

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

class User(BaseModel):
    username: str
    password: str

class TokenData(BaseModel):
    username: str

class TokenDataOut(BaseModel):
    access_token: str
    token_type: str = "bearer"

@app.post("/token")
async def login(user: User = Depends(OAuth2PasswordRequestForm)):
    # Implement your authentication logic here, e.g., checking against a database, etc.
    if user.username != "test_user" or user.password != "test_password":
        raise HTTPException(status_code=401, detail="Invalid username or password")

    token_data = {"sub": user.username}
    access_token = create_access_token(data=token_data)
    return TokenDataOut(access_token=access_token)

def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

@app.post("/protected")
async def protected(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(status_code=401, detail="Could not validate credentials")

    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
    except JWTError:
        raise credentials_exception

    data = {"message": "This is the protected endpoint", "username": username}
    return JSONResponse(content=data)

Replace "test_user" and "test_password" with your actual users' data, or implement an authentication method as needed. In this example, we assume the user exists if the provided credentials are correct.

Finally, to run your FastAPI application using Uvicorn, execute the following command:

uvicorn main:app --reload

This will start a web server and your API will be accessible at http://127.0.0.1:8000. The first endpoint is located at /token, and the second protected endpoint is located at /protected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment