Deleted useless api code
This commit is contained in:
15
runner/__main__.py
Normal file
15
runner/__main__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import schedule
|
||||
|
||||
from . import models
|
||||
from .config import REFETCH_PERIOD_H
|
||||
from .database import engine
|
||||
from .job import job
|
||||
from .scheduler import run_continuously
|
||||
|
||||
models.Base.metadata.create_all(bind=engine)
|
||||
|
||||
schedule.every(REFETCH_PERIOD_H).hours.do(job)
|
||||
stop_run_continuously = run_continuously()
|
||||
|
||||
# First run
|
||||
job()
|
@@ -1,11 +1,4 @@
|
||||
import datetime
|
||||
from functools import reduce
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import HTTPException
|
||||
from parser import get_building_id
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.sql.expression import BinaryExpression
|
||||
|
||||
from . import models, schemas
|
||||
|
||||
@@ -30,80 +23,3 @@ def create_record(db: Session, record: schemas.Record):
|
||||
db.refresh(db_record)
|
||||
|
||||
return db_record
|
||||
|
||||
|
||||
def contains_lower(name, val):
|
||||
if isinstance(val, str):
|
||||
return getattr(models.Record, name).icontains(val)
|
||||
else:
|
||||
return getattr(models.Record, name) == val
|
||||
|
||||
|
||||
def and_if_can(a: BinaryExpression, b: Optional[BinaryExpression]) -> BinaryExpression:
|
||||
if b is not None:
|
||||
return a & b
|
||||
else:
|
||||
return a
|
||||
|
||||
|
||||
def search_each(db: Session, filters: schemas.RecordRequest) -> List[schemas.Record]:
|
||||
query = None
|
||||
|
||||
if filters.start:
|
||||
query = models.Record.start <= filters.start
|
||||
if filters.finish:
|
||||
query = and_if_can(models.Record.finish >= filters.finish, query)
|
||||
|
||||
filters = list(
|
||||
filter(lambda x: x[1] is not None and x[0] not in ("start, finish"), filters)
|
||||
)
|
||||
|
||||
query = reduce(
|
||||
lambda acc, ftr: and_if_can(contains_lower(*ftr), acc), filters, query
|
||||
)
|
||||
|
||||
if query is None:
|
||||
res = db.query(models.Record).all()
|
||||
else:
|
||||
res = db.query(models.Record).filter(query).all()
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def search_all(db: Session, prompt: str) -> List[schemas.Record]:
|
||||
prompt = prompt.strip()
|
||||
|
||||
query = reduce(
|
||||
lambda acc, name: acc | contains_lower(name, prompt),
|
||||
("region", "area", "town", "street", "branch", "res"),
|
||||
contains_lower("comment", prompt),
|
||||
)
|
||||
|
||||
building_id, *_ = get_building_id(prompt)
|
||||
|
||||
if building_id is not None:
|
||||
query |= models.Record.building_id == building_id
|
||||
|
||||
res = db.query(models.Record).filter(query).all()
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def check_outage(db: Session, building_id: int) -> schemas.CheckResponse:
|
||||
building_query = db.query(models.Record).filter(
|
||||
(models.Record.building_id == building_id)
|
||||
)
|
||||
|
||||
if building_query.count() == 0:
|
||||
raise HTTPException(404, "No such building")
|
||||
|
||||
now = datetime.datetime.now()
|
||||
|
||||
res = building_query.filter(
|
||||
(models.Record.start <= now) & (now <= models.Record.finish)
|
||||
).first()
|
||||
|
||||
if res is None:
|
||||
return {"is_outage": False}
|
||||
|
||||
return {"is_outage": True, "when_finish": res.finish}
|
||||
|
@@ -1,35 +0,0 @@
|
||||
import datetime
|
||||
|
||||
import schedule
|
||||
from fastapi import FastAPI
|
||||
|
||||
from . import models, router, schemas
|
||||
from .config import REFETCH_PERIOD_H
|
||||
from .database import engine
|
||||
from .job import job
|
||||
from .scheduler import run_continuously, run_threaded
|
||||
|
||||
models.Base.metadata.create_all(bind=engine)
|
||||
|
||||
start_stamp = datetime.datetime.now()
|
||||
|
||||
|
||||
async def lifespan(app: FastAPI):
|
||||
schedule.every(REFETCH_PERIOD_H).hours.do(job)
|
||||
stop_run_continuously = run_continuously()
|
||||
|
||||
run_threaded(job)
|
||||
|
||||
yield
|
||||
|
||||
stop_run_continuously()
|
||||
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
app.include_router(router.router)
|
||||
|
||||
|
||||
@app.get("/", response_model=schemas.Healthcheck)
|
||||
def Healthcheck():
|
||||
return {"up_since": start_stamp}
|
@@ -1,74 +0,0 @@
|
||||
from typing import Annotated, List
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from . import controller, schemas
|
||||
from .database import get_db
|
||||
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
|
||||
@router.get("/list", response_model=List[schemas.Record], summary="Search by filters")
|
||||
def list_rows(
|
||||
filters: Annotated[schemas.RecordRequest, Depends()], db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Searches rows with specified filters.
|
||||
|
||||
Case insensitive contains:
|
||||
- **region**
|
||||
- **area**
|
||||
- **town**
|
||||
- **street**
|
||||
- **start**
|
||||
- **finish**
|
||||
- **branch**
|
||||
- **res**
|
||||
- **comment**
|
||||
Exact match:
|
||||
- **index**
|
||||
- **building_id**
|
||||
- **lat**
|
||||
- **lng**
|
||||
Later or earlier than respectively:
|
||||
- **start**
|
||||
- **finish**
|
||||
"""
|
||||
return controller.search_each(db, filters)
|
||||
|
||||
|
||||
@router.get("/search", response_model=List[schemas.Record], summary="Search by query")
|
||||
def search_rows(query: str, db: Session = Depends(get_db)):
|
||||
"""
|
||||
Selects rows with cells containing case insensitive prompt as its part.
|
||||
In addition, geocoding is being applied to prompt and if building_id found, corresponding row is being returned.
|
||||
|
||||
Rows to be searched:
|
||||
- **region**
|
||||
- **area**
|
||||
- **town**
|
||||
- **street**
|
||||
- **branch**
|
||||
- **res**
|
||||
- **comment**
|
||||
"""
|
||||
return controller.search_all(db, query)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/check", response_model=schemas.CheckResponse, summary="Check when outage ends"
|
||||
)
|
||||
def check(building_id: int, db: Session = Depends(get_db)):
|
||||
"""
|
||||
Checks if there is an active outage for building_id and if there is, also returns when will it end
|
||||
"""
|
||||
return controller.check_outage(db, building_id)
|
||||
|
||||
|
||||
@router.put("/create", response_model=schemas.Record)
|
||||
def create_record(record: schemas.RecordCreate, db: Session = Depends(get_db)):
|
||||
"""
|
||||
Not for public usage
|
||||
"""
|
||||
return controller.create_record(db, record)
|
@@ -18,8 +18,3 @@ def run_continuously(interval=1):
|
||||
continuous_thread.start()
|
||||
|
||||
return cease_continuous_run.set
|
||||
|
||||
|
||||
def run_threaded(job):
|
||||
job_thread = threading.Thread(target=job)
|
||||
job_thread.start()
|
||||
|
@@ -1,43 +0,0 @@
|
||||
import datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class BaseRecord(BaseModel):
|
||||
index: Optional[int] = None
|
||||
region: Optional[str] = None
|
||||
area: Optional[str] = None
|
||||
town: Optional[str] = None
|
||||
street: Optional[str] = None
|
||||
branch: Optional[str] = None
|
||||
res: Optional[str] = None
|
||||
comment: Optional[str] = None
|
||||
building_id: Optional[int] = None
|
||||
lat: Optional[float] = None
|
||||
lng: Optional[float] = None
|
||||
|
||||
|
||||
class Record(BaseRecord):
|
||||
id: int
|
||||
start: datetime.datetime
|
||||
finish: datetime.datetime
|
||||
|
||||
|
||||
class RecordRequest(BaseRecord):
|
||||
start: Optional[datetime.datetime] = None
|
||||
finish: Optional[datetime.datetime] = None
|
||||
|
||||
|
||||
class RecordCreate(BaseRecord):
|
||||
start: datetime.datetime
|
||||
finish: datetime.datetime
|
||||
|
||||
|
||||
class CheckResponse(BaseModel):
|
||||
is_outage: bool
|
||||
when_finish: Optional[datetime.datetime] = None
|
||||
|
||||
|
||||
class Healthcheck(BaseModel):
|
||||
up_since: datetime.datetime
|
Reference in New Issue
Block a user