Building SMPLAuth
January 17, 2025โข814 words
Table of Contents
Packages
๐Python
- Version: 3.13.1
Installed Libraries
Package | Version |
---|---|
Uvicorn | 0.34.0 |
FastAPI | 0.115.6 |
Pydantic Settings | 2.7.1 |
Setting Up the Project
๐In an attempt to keep SMPL scalable, I created a directory called 'smpl' in my DEV directory then accessed that directory
mkdir smpl
cd smpl
Then I created a directory called 'smplauth' where I will create the api then accessed that directory
mkdir smplauth
cd smplauth
Using PyCharm CE, I then opened the smplauth directory, which configured a base project for me containing main.py
I am using Python 3.13.1
I set up and activated a virtual environment
python3 -m venv venv
source venv/bin/activate
I installed FastAPI
pip install fastapi
As a test, I added the following code to main.py:
# main.py
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
In order to run a dev server, I installed Uvicorn
Note: FastAPI does have a dev server but I couldn't get it working within PyCharm. Maybe your luck will be better
pip install uvicorn
Then I ran it in the terminal
uvicorn main:app --reload
I then navigated to my localhost to see the message "{"Hello":"World"}"
I also tested the query in the address bar as a test
http://localhost:8000/items/420?q=heya
It worked as I got "{"item_id":420,"q":"heya"}". yay!
Setting Up the Docs
๐I want the user to get redirected to the docs if they hit the main ("/") endpoint. FastAPI is pretty cool in that they automatically generate docs.
# main.py
# removed
# from typing import Union
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
app = FastAPI()
# removed
# @app.get("/")
# async def read_root():
# return {"Hello": "World"}
# removed
# @app.get("/items/{item_id}")
# async def read_item(item_id: int, q: Union[str, None] = None):
# return {"item_id": item_id, "q": q}
# added
@app.get("/")
async def redirect_to_docs():
return RedirectResponse(url="/redoc")
The updated main.py
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/")
async def redirect_to_docs():
return RedirectResponse(url="/redoc")
I wanted to get a head start on including the proper information for the API
# main.py
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
# updated
app = FastAPI(
title="SMPLAuth API",
description="A simple auth API.",
version="0.0.1",
contact={
"name": "Steve Xero",
"url": "https://stevexero.com",
"email": "hello@stevexero.com",
},
license_info={
"name": "TBD",
"url": "https://smplauth.com/license",
},
)
@app.get("/")
async def hello():
return RedirectResponse(url="/redoc")
Setting Up the Config
๐Instead of having possibly changing information within my code, I like to have a config file where I can update any info as needed.
In the terminal, create a settings.py file.
touch settings.py
We'll need to install Pydantic Settings
pip install pydantic-settings
Note: Remember to also install in PyCharm if needed
Then within that file:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
title: str = "SMPLAuth API"
description: str = "A simple auth API."
version: str = "0.0.1"
contact_name: str = "Steve Xero"
contact_url: str = "https://stevexero.com"
contact_email: str = "hello@stevexero.com"
license_name: str = "TBD"
license_url: str = "https://smplauth.com/license"
redirect_url: str = "/redoc"
class Config:
env_file = ".env" # Specify the environment file to load variables from (will use later)
settings = Settings()
Updated main.py
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
#added
from settings import settings
#updated
app = FastAPI(
title=settings.title,
description=settings.description,
version=settings.version,
contact={
"name": settings.contact_name,
"url": settings.contact_url,
"email": settings.contact_email,
},
license_info={
"name": settings.license_name,
"url": settings.license_url,
},
)
#updated
@app.get("/")
async def hello():
return RedirectResponse(url=settings.redirect_url)
Setting Up the Repo
๐I felt like this was a good time to set up the repo
In GitHub, I created a new repo named smplauth and followed the instructions. I've kept it bare-bones and added a temporary README.
Here's a great tutorial if you want to know how to set up a repo
I also felt like this would be a good time to create a project view for SMPLAuth to begin keeping track of things to be done. It's only for myself, for now, but maybe as the project grows more people will jump on board.