70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
import os
|
|
import sqlite3
|
|
from typing import Annotated, Optional
|
|
|
|
from fastapi import Depends, FastAPI
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import BaseModel, Field, condecimal, conint, constr, root_validator
|
|
|
|
import app.database as database
|
|
from app.order_processor import FailedToProcessOrderError, process_order
|
|
from app.types import Order, OrderSide, OrderType
|
|
|
|
app = FastAPI()
|
|
|
|
|
|
class CreateOrderModel(BaseModel):
|
|
type_: OrderType = Field(..., alias="type")
|
|
side: OrderSide
|
|
instrument: constr(min_length=12, max_length=12)
|
|
limit_price: Optional[condecimal(decimal_places=2)]
|
|
quantity: conint(gt=0)
|
|
|
|
@root_validator
|
|
def validator(cls, values: dict):
|
|
if values.get("type_") == "market" and values.get("limit_price"):
|
|
raise ValueError(
|
|
"Providing a `limit_price` is prohibited for type `market`"
|
|
)
|
|
|
|
if values.get("type_") == "limit" and not values.get("limit_price"):
|
|
raise ValueError("Attribute `limit_price` is required for type `limit`")
|
|
|
|
return values
|
|
|
|
|
|
class CreateOrderResponseModel(Order):
|
|
pass
|
|
|
|
|
|
async def get_db():
|
|
# Replace with proper db connection pooling implementation
|
|
db = database.connect(os.getenv("DB_CONNECTION"))
|
|
database.apply_database_schema(db)
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@app.post("/orders", status_code=201)
|
|
async def create_order(
|
|
model: CreateOrderModel, db: Annotated[sqlite3.Connection, Depends(get_db)]
|
|
):
|
|
try:
|
|
order = process_order(db, model)
|
|
return CreateOrderResponseModel(
|
|
id=order.id_,
|
|
created_at=order.created_at,
|
|
type=order.type_,
|
|
side=order.side,
|
|
instrument=order.instrument,
|
|
limit_price=order.limit_price,
|
|
quantity=order.quantity,
|
|
)
|
|
except FailedToProcessOrderError:
|
|
return JSONResponse(
|
|
content={"message": "Internal server error while placing the order"},
|
|
status_code=500,
|
|
)
|