Install Fastapi
https://github.com/tiangolo/fastapi
pip install fastapi
C:\fastAPI\registration>pip install fastapi
C:\fastAPI\registration>pip install "uvicorn[standard]"
Install sqlalchemy jinja2
pip install python-multipart sqlalchemy jinja2
C:\fastAPI\registration>pip install python-multipart sqlalchemy jinja2
Create main.py
registration/main.py
registration/main.py
#registration/main.py from fastapi import FastAPI, Request, Depends, Form, status from fastapi.templating import Jinja2Templates import models from database import engine, sessionlocal from sqlalchemy.orm import Session from fastapi import responses from sqlalchemy.exc import IntegrityError from fastapi.responses import RedirectResponse from forms import UserCreateForm models.Base.metadata.create_all(bind=engine) templates = Jinja2Templates(directory="templates") app = FastAPI() def get_db(): db = sessionlocal() try: yield db finally: db.close() @app.get("/") async def home(request: Request, db: Session = Depends(get_db)): return templates.TemplateResponse("index.html", {"request": request}) @app.post("/register/") async def register(request: Request, username: str = Form(...), email: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)): form = UserCreateForm(request) await form.load_data() print("submited") if await form.is_valid(): try: print(username) print(email) print(password) total_row = db.query(models.User).filter(models.User.email == email).first() print(total_row) if total_row == None: print("Save") users = models.User(username=username, email=email, password=password) db.add(users) db.commit() return responses.RedirectResponse( "/", status_code=status.HTTP_302_FOUND ) else: print("taken email") errors = ["The email has already been taken"] except IntegrityError: return {"msg":"Error"} else: print("Error Form") errors = form.errors return templates.TemplateResponse("index.html", {"request": request, "errors": errors})registration/database.py
#registration/database.py from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base DB_URL = 'sqlite:///fastapidb.sqlite3' engine = create_engine(DB_URL, connect_args={'check_same_thread': False}) sessionlocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base()registration/models.py
#registration/models.py from sqlalchemy import Column, Integer, String from database import Base class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(150)) email = Column(String(150)) password = Column(String(150)) def __repr__(self): return '<User %r>' % (self.id)registration/forms.py
#registration/forms.py from typing import List from typing import Optional from fastapi import Request class UserCreateForm: def __init__(self, request: Request): self.request: Request = request self.errors: List = [] self.username: Optional[str] = None self.email: Optional[str] = None self.password: Optional[str] = None async def load_data(self): form = await self.request.form() self.username = form.get("username") self.email = form.get("email") self.password = form.get("password") async def is_valid(self): if not self.username or not len(self.username) > 3: self.errors.append("Username should be > 3 chars") if not self.email or not (self.email.__contains__("@")): self.errors.append("Email is required") if not self.password or not len(self.password) >= 4: self.errors.append("Password must be > 4 chars") if not self.errors: return True return Falsemake templates inside the templates directory
registration/templates/base.html
//registration/templates/index.html {% extends 'base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="text-danger font-weight-bold"> <ul> {% for error in errors %} <li class="alert alert-danger">{{error}}</li> {% endfor %} </ul> </div> </div> <div class="row my-5"> <form action = "/register" method = "post"> <div class="mb-3"> <label>Username</label> <input type="text" required class="form-control" name="username" value="" placeholder="username"> </div> <div class="mb-3"> <label>Email</label> <input type="text" required placeholder="Your email" name="email" value="" class="form-control"> </div> <div class="mb-3"> <label>Password</label> <input type="password" required placeholder="Choose a secure password" value="" name="password" class="form-control"> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </div> <style> ul { list-style-type: none; } </style> {% endblock content %}registration/temmplates/base.html
//registration/temmplates/base.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>FastAPI Registration Form with sqlalchemy Jinja2 Template - Cairocoders</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <h1 class="page-header text-center">FastAPI Registration Form Validation with sqlalchemy Jinja2 Template</h1> {% block content %} {% endblock content %} </div> </body> </html>run the FastAPI app
C:\fastAPI\registration>uvicorn main:app --reload
with uvicorn using the file_name:app_instance
open the link on the browser http://127.0.0.1:8000/
http://127.0.0.1:8000/docs