Skip to content

Instantly share code, notes, and snippets.

@INF800
Last active November 15, 2021 23:44
Show Gist options
  • Save INF800/8055e3f6b04ad706018390b319fa6e38 to your computer and use it in GitHub Desktop.
Save INF800/8055e3f6b04ad706018390b319fa6e38 to your computer and use it in GitHub Desktop.
FASTAPI Boilerplate
# i. engine, ii. base and iii. a session
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./database.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
# ----------------------------------------
# create fastapi app
# ----------------------------------------
from fastapi import FastAPI
app = FastAPI()
# ----------------------------------------
# setup templates folder
# ----------------------------------------
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates")
# ----------------------------------------
# setup db
# ----------------------------------------
import models
from sqlalchemy.orm import Session
from database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine) #creates tables
# stocks db will appear once you run uvicorn.
# get into sqlite and try `.schema`
# ----------------------------------------
# import custom modules
# ----------------------------------------
# ----------------------------------------
# dependency injection
# ----------------------------------------
from fastapi import Depends
def get_db():
""" returns db session """
try:
db = SessionLocal()
yield db
finally:
db.close
# ----------------------------------------
# bg tasks
# ----------------------------------------
from fastapi import BackgroundTasks
def fetch_real_time(pk: int):
pass
# ----------------------------------------
# define structure for requests (Pydantic & more)
# ----------------------------------------
from fastapi import Request # for get
from pydantic import BaseModel # for post
class StockRequest(BaseModel):
symbol: str
class CurPairRequest(BaseModel):
cur_pair: str
# ----------------------------------------
# ----------------------------------------
# routes and related funcs
# ----------------------------------------
# ----------------------------------------
@app.get("/")
def api_home(request: Request):
"""
home page to display all real time values
"""
context = {
"request": request
}
return templates.TemplateResponse("home.html", context)
@app.post("/api/curencypair")
async def add_currency_pairs(cur_pair_req: CurPairRequest, background_tasks: BackgroundTasks, db: Session = Depends(get_db)):
"""
adds given currecy pair TABLEs to db
"""
curPair = models.CurPairs()
curPair.cur_pair = cur_pair_req.cur_pair
db.add(curPair)
db.commit()
# in correct place
background_tasks.add_task(fetch_real_time, curPair.id)
return {"status": "ok"}
@app.delete("/api/curencypair")
def remove_currency_pair(cur_pair_req: CurPairRequest, db: Session = Depends(get_db)):
"""
Remove given curencypair TABLE from DB
"""
return None
@app.post("/api/stock")
async def add_stock(stock_req: StockRequest, background_tasks: BackgroundTasks,db: Session = Depends(get_db)):
"""
adds given stock to db
"""
stock = models.Stocks()
print(stock_req.symbol)
stock.symbol = stock_req.symbol
db.add(stock)
db.commit()
background_tasks.add_task(fetch_real_time, stock.id)
return None
@app.delete("/api/stock")
def remove_stock(stock_req: StockRequest, db: Session = Depends(get_db)):
"""
deletes given stock table from db
"""
return None
# ----------------------------------------
# end
# ----------------------------------------
import datetime
from sqlalchemy import Column, Integer, String, Numeric, DateTime
#from sqlalchemy.orm import relationship
from database import Base
class CurPairs(Base):
"""
Stores list of all cur pair table names that
should be displayed in real time
"""
__tablename__ = "CurPairs"
id = Column(Integer, primary_key=True, index=True)
time_stamp = Column(DateTime, default=datetime.datetime.utcnow)
cur_pair = Column(String, index=True)
price = Column(String)
change = Column(String)
per_change = Column(String)
fastapi
jinja2
uvicorn
sqlalchemy
gunicorn==20.0.4
{% extends "layout.html" %}
{% block content %}
<section>
<div>
<h3>Forex Currency Pairs</h3>
</div>
<div>
<!-- add / delete -->
</div>
<div>
<!-- table with cur-pair & live details -->
</div>
</section>
{% endblock %}
<html>
<head>
<title> Home </title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<head>
<body>
<h2> Live Stream Data </h2>
{% block content %}
{% endblock %}
</body>
</html>
@INF800
Copy link
Author

INF800 commented Jun 18, 2020

Dockerfile

FROM python:3.7.5
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

docker-compose.yml

version: '3'

services: # each service is a `docker container`
  web: # sudo docker-compose run web python manage.py shell #DJANGO Container
       # docker-compose run -p 8002:8002  web python -m uvicorn main:app --reload --host "0.0.0.0" --port 8002
    restart: always
    build: .
    command: python -m uvicorn main:app --reload --host "0.0.0.0" --port 8002 --reload   #gunicorn -k uvicorn.workers.UvicornWorker main:app 
    volumes:
      - .:/code
    ports:
      - "8002:8002"

# Note: `Dockerfile` build is also taken care by `docker-compose up`. 
#        Just copy paste the respective Dockerfile

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