Skip to content
Snippets Groups Projects
Commit f76be7cf authored by Nico Vermaas's avatar Nico Vermaas
Browse files

initial commit (ucac4 example)

parent c7d6b084
Branches
No related tags found
No related merge requests found
FROM python:3.9.7-slim
RUN apt-get update && apt-get install --no-install-recommends -y bash nano mc
ENV PYTHONUNBUFFERED 1
RUN mkdir /src
WORKDIR /src
COPY . /src/
RUN pip install -r requirements.txt
CMD ["uvicorn", "main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "8000"]
# build the image like this:
# docker build -t adex-fastapi:latest .
# log into the container
# docker exec -it adex-fastapi sh
from sqlalchemy.orm import Session
from .models import Star
from utils import timeit
@timeit
def get_stars(db: Session, skip: int = 0, limit: int = 1000):
return db.query(Star).offset(skip).limit(limit).all()
@timeit
def get_rectangle(db: Session, ra_min: float = 0.0, ra_max: float = 1.0, dec_min: float = 0.0, dec_max: float = 1.0, j_mag: int = 10000, limit: int = 1000):
list = db.query(Star).filter(
Star.ra > ra_min,
Star.ra < ra_max,
Star.dec > dec_min,
Star.dec < dec_max,
Star.j_mag < j_mag
).limit(limit).all()
print("retrieved "+str(len(list)) + ' stars')
return list
@timeit
def get_rectangle_query(stars, ra_min: float = 0.0, ra_max: float = 1.0, dec_min: float = 0.0, dec_max: float = 1.0, j_mag: int = 10000, limit: int = 1000):
query = stars.select().where(
Star.ra > ra_min,
Star.ra < ra_max,
Star.dec > dec_min,
Star.dec < dec_max,
Star.j_mag < j_mag
).limit(limit)
return query
\ No newline at end of file
import os
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# Note that we are using databases package as it uses asyncpg
# as an interface to talk to PostgreSQL database
import databases
# dev machine on SURFSara
# DATABASE_URL = "postgresql://postgres:secret@145.38.187.31/ucac4"
# mintbox docker
# DATABASE_URL = "postgresql://postgres:secret@postgres-ucac4/ucac4"
# mintbox
# DATABASE_URL = "postgresql://postgres:secret@192.168.178.37/ucac4"
# localhost
# DATABASE_URL = "postgresql://postgres:postgres@localhost/ucac4"
# read from environment
DATABASE_URL = os.environ.get('DATABASE_URL', 'postgresql://postgres:postgres@localhost/ucac4')
print('DATABASE_URL = '+DATABASE_URL)
my_database = databases.Database(DATABASE_URL) # asyncpg
metadata = sqlalchemy.MetaData() # asyncpg
engine = create_engine(
DATABASE_URL, pool_size=3, max_overflow=0
)
metadata.create_all(engine) # asyncpg
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
from sqlalchemy import Column, Integer, String, Float, DateTime
from .database import Base
# sql alchemy model
class Star(Base):
__tablename__ = "stars"
zone = Column(Integer, index=True)
mpos1 = Column(Integer, primary_key=True, index=True)
ra = Column(Float, index=True)
dec = Column(Float, index=True)
j_mag = Column(Integer, index=True)
v_mag = Column(Integer, index=True)
from datetime import datetime
from pydantic import BaseModel
from typing import Optional
# Pydantic models help you define request payload models
# and response models in Python Class object notation
class Star(BaseModel):
zone: int
mpos1: int
ra: float
dec: float
j_mag : Optional[float]
v_mag : Optional[float]
class Config:
orm_mode = True
\ No newline at end of file
main.py 0 → 100644
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from database.database import my_database
from routers import stars
# https://fastapi.tiangolo.com/tutorial/sql-databases/
app = FastAPI(
title="ADEX backend",
description="ADEX backend FastAPI",
version="0.0.1",
contact={
"name": "Nico Vermaas",
"email": "vermaas@astron.nl",
},
license_info={
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
},)
app.include_router(stars.router)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.on_event("startup")
async def startup():
await my_database.connect()
@app.on_event("shutdown")
async def shutdown():
await my_database.disconnect()
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
\ No newline at end of file
anyio==3.6.1
asyncpg==0.26.0
click==8.1.3
colorama==0.4.5
databases==0.6.1
fastapi==0.79.0
greenlet==1.1.2
gunicorn==20.1.0
h11==0.13.0
idna==3.3
pydantic==1.9.2
sniffio==1.2.0
SQLAlchemy==1.4.40
starlette==0.19.1
typing_extensions==4.3.0
uvicorn==0.18.2
psycopg2-binary==2.9.3
from typing import List
from fastapi import APIRouter, Query, Depends
from sqlalchemy.orm import Session
from utils import timeit
from database import crud, models, schemas
from database.database import SessionLocal, engine
from database.database import my_database
from database.models import Star
router = APIRouter(tags=["stars"],)
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# http://127.0.0.1:8000/stars/
# http://127.0.0.1:8000/stars/?skip=100&limit=100
@router.get("/stars/", tags=["stars"], response_model=List[schemas.Star])
async def get_stars(skip: int = 0, limit: int = 1000, db: Session = Depends(get_db)):
items = crud.get_stars(db, skip=skip, limit=limit)
return items
@router.get("/stars_rectangle/", tags=["stars"], response_model=List[schemas.Star])
async def get_stars_rectangle(ra_min: float = 0.0, ra_max: float = 1.0,
dec_min: float = 0.0, dec_max: float = 1.0,
j_mag: int = 10000, limit: int = 1000, db: Session = Depends(get_db)):
items = crud.get_rectangle(db, ra_min=ra_min, ra_max=ra_max, dec_min=dec_min, dec_max=dec_max, j_mag=j_mag, limit=limit)
return items
@timeit
@router.get("/stars_rectangle_async/", tags=["stars"], response_model=List[schemas.Star])
async def get_stars_rectangle_async(ra_min: float = 0.0, ra_max: float = 1.0,
dec_min: float = 0.0, dec_max: float = 1.0,
j_mag: int = 10000, limit: int = 1000):
query = crud.get_rectangle_query(Star.__table__, ra_min=ra_min, ra_max=ra_max, dec_min=dec_min, dec_max=dec_max, j_mag=j_mag, limit=limit)
return await my_database.fetch_all(query)
\ No newline at end of file
uvicorn main:app --reload
\ No newline at end of file
utils.py 0 → 100644
"""
common helper functions
"""
import logging;
from datetime import *
import time
logger = logging.getLogger(__name__)
# this is a decorator that can be put in front (around) a function all to measure its execution time
def timeit(method):
def timed(*args, **kw):
ts = time.time()
result = method(*args, **kw)
te = time.time()
if 'log_time' in kw:
name = kw.get('log_name', method.__name__.upper())
kw['log_time'][name] = int((te - ts) * 1000)
else:
print('execution time: %r %2.2f ms' % \
(method.__name__, (te - ts) * 1000))
return result
return timed
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment