Skip to content

Commit

Permalink
Merge pull request #657 from fatiudeen/feat/close-margin-position-end…
Browse files Browse the repository at this point in the history
…point

Add close margin position endpoint
  • Loading branch information
djeck1432 authored Feb 27, 2025
2 parents c727728 + 5889e5e commit 0233910
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 93 deletions.
44 changes: 37 additions & 7 deletions margin_app/app/api/margin_position.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,60 @@
This module contains the API routes for margin positions.
"""

from fastapi import APIRouter, Depends
from typing import NoReturn
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from app.crud.margin_position import margin_position_crud
from app.schemas.margin_position import MarginPositionCreate, MarginPositionResponse
from app.schemas.margin_position import (
CloseMarginPositionResponse,
MarginPositionCreate,
MarginPositionResponse,
)

router = APIRouter()


@router.post("/open_margin_position", response_model=MarginPositionResponse)
async def open_margin_position(
position_data: MarginPositionCreate,
db: AsyncSession = Depends(margin_position_crud.session),
):
@router.post("/open", response_model=MarginPositionResponse)
async def open_margin_position(position_data: MarginPositionCreate):
"""
Opens a margin position by creating an entry record in the database.
:param position_data: MarginPositionCreate
:param db: AsyncSession
:return: MarginPositionResponse
"""
margin_position_crud.db = db
position = await margin_position_crud.open_margin_position(
user_id=position_data.user_id,
borrowed_amount=position_data.borrowed_amount,
multiplier=position_data.multiplier,
transaction_id=position_data.transaction_id,
)
return position


@router.post("/close/{position_id}", response_model=CloseMarginPositionResponse)
async def close_margin_position(position_id: UUID) -> CloseMarginPositionResponse:
"""
Close a margin position endpoint.
Args:
position_id (UUID): The unique identifier of the margin position to close
db (AsyncSession): Database session dependency injected by FastAPI
Returns:
CloseMarginPositionResponse: Object containing the position ID and its updated status
Raises:
HTTPException: 404 error if the position is not found
"""
status = await margin_position_crud.close_margin_position(position_id)

if not status:
raise HTTPException(
status_code=404, detail=f"Margin position with id {position_id} not found"
)

return CloseMarginPositionResponse(position_id=position_id, status=status)
100 changes: 15 additions & 85 deletions margin_app/app/main.py
Original file line number Diff line number Diff line change
@@ -1,107 +1,32 @@
"""
Main entry point for the application.
"""

import sys

from app.api.deposit import router as deposit_router
from app.api.margin_position import router as margin_position_router
from app.api.pools import router as pool_router
from app.api.user import router as user_router
from fastapi import FastAPI, Request
from loguru import logger
# Initialize FastAPI app
app = FastAPI()
app.include_router(pool_router, prefix="/api/pool", tags=["Pool"])
app.include_router(
margin_position_router, prefix="/api/margin_position", tags=["MarginPosition"]
)
app.include_router(user_router, prefix="/api/user", tags=["User"])
app.include_router(deposit_router, prefix="/api/deposit", tags=["Deposit"])


# Configure Loguru
logger.remove() # Remove default logger to configure custom settings
logger.add(
sys.stdout,
format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",
level="INFO",
enqueue=True,
backtrace=True,
diagnose=True,
)


@app.on_event("startup")
async def startup_event():
"""
Code to run when the app starts.
For example, database connection setup or loading configurations.
"""
logger.info("Application startup: Initializing resources.")


@app.on_event("shutdown")
async def shutdown_event():
"""
Code to run when the app shuts down.
For example, closing database connections or cleaning up.
"""
logger.info("Application shutdown: Cleaning up resources.")


@app.middleware("http")
async def log_requests(request: Request, call_next):
"""
Middleware to log HTTP requests and responses.
"""
logger.info(f"Request: {request.method} {request.url}")
response = await call_next(request)
logger.info(f"Response: {response.status_code} {request.url}")
return response


# Example route
@app.get("/")
async def read_root():
"""
Basic endpoint for testing.
"""
logger.info("Root endpoint accessed.")
return {"message": "Welcome to the FastAPI application!"}


# Additional route
@app.get("/health")
async def health_check():
"""
Health check endpoint.
"""
logger.info("Health check endpoint accessed.")
return {"status": "OK"}

"""
Main entry point for the application.
This module initializes the FastAPI application and includes all routers.
"""

import sys
from fastapi import FastAPI, Request
from loguru import logger

from app.api.deposit import router as deposit_router
from app.api.liquidation import router as liquidation_router
from app.api.margin_position import router as margin_position_router
from app.api.pools import router as pool_router
from app.api.user import router as user_router
from app.api.deposit import router as deposit_router

# Initialize FastAPI app
app = FastAPI()
app = FastAPI(
title="Margin Trading API",
description="API for managing margin trading positions",
version="1.0.0",
)

# Include routers
app.include_router(liquidation_router, prefix="/api/liquidation", tags=["Liquidation"])
app.include_router(pool_router, prefix="/api/pool", tags=["Pool"])
app.include_router(margin_position_router, prefix="/api/margin", tags=["MarginPosition"])
app.include_router(
margin_position_router, prefix="/api/margin-positions", tags=["margin-positions"]
)
app.include_router(user_router, prefix="/api/user", tags=["User"])
app.include_router(deposit_router, prefix="/api/deposit", tags=["Deposit"])

Expand All @@ -116,6 +41,7 @@ async def health_check():
diagnose=True,
)


@app.on_event("startup")
async def startup_event():
"""
Expand All @@ -124,6 +50,7 @@ async def startup_event():
"""
logger.info("Application startup: Initializing resources.")


@app.on_event("shutdown")
async def shutdown_event():
"""
Expand All @@ -132,6 +59,7 @@ async def shutdown_event():
"""
logger.info("Application shutdown: Cleaning up resources.")


@app.middleware("http")
async def log_requests(request: Request, call_next):
"""
Expand All @@ -142,6 +70,7 @@ async def log_requests(request: Request, call_next):
logger.info(f"Response: {response.status_code} {request.url}")
return response


# Example route
@app.get("/")
async def read_root():
Expand All @@ -151,6 +80,7 @@ async def read_root():
logger.info("Root endpoint accessed.")
return {"message": "Welcome to the FastAPI application!"}


# Additional route
@app.get("/health")
async def health_check():
Expand Down
34 changes: 33 additions & 1 deletion margin_app/app/schemas/margin_position.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,43 @@

from datetime import datetime
from decimal import Decimal
from enum import Enum
from uuid import UUID

from pydantic import BaseModel


class MarginPositionStatus(str, Enum):
"""
Enumeration of possible margin position statuses.
Attributes:
OPEN: Position is currently open
CLOSED: Position has been closed
"""

OPEN = "Open"
CLOSED = "Closed"


class CloseMarginPositionResponse(BaseModel):
"""
Response model for closing a margin position.
Attributes:
position_id (UUID): The unique identifier of the margin position
status (MarginPositionStatus): The current status of the margin position
"""

position_id: UUID
status: MarginPositionStatus

class Config:
"""Pydantic configuration class"""

from_attributes = True


class MarginPositionCreate(BaseModel):
"""
Pydantic model for creating a MarginPosition.
Expand Down Expand Up @@ -38,4 +70,4 @@ class Config:
Pydantic model configuration.
"""

orm_mode: True
orm_mode = True

0 comments on commit 0233910

Please sign in to comment.