Skip to content

Commit

Permalink
Merge pull request #92 from ikemHood/main
Browse files Browse the repository at this point in the history
fixed: fixed all pylint errors
  • Loading branch information
djeck1432 authored Oct 24, 2024
2 parents bae873e + 49d53e1 commit b82f722
Show file tree
Hide file tree
Showing 23 changed files with 295 additions and 21 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Pylint

on: [push]
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
Expand Down
8 changes: 8 additions & 0 deletions web_app/alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""
Alembic migration environment configuration.
This module sets up the environment for Alembic database migrations,
including database URL configuration, logging setup, and migration
execution modes (online and offline). It integrates with SQLAlchemy models
and provides the core functionality needed for database schema version control.
"""
from logging.config import fileConfig

from sqlalchemy import engine_from_config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,29 @@


def column_exists(table_name: str, column_name: str) -> bool:
"""Check if a column exists in the specified table.
Args:
table_name (str): Name of the table to check
column_name (str): Name of the column to look for
Returns:
bool: True if the column exists, False otherwise
"""
bind = op.get_bind()
inspector = Inspector.from_engine(bind)
columns = [column.get('name') for column in inspector.get_columns(table_name)]
return column_name in columns

def enum_type_exists(enum_name: str) -> bool:
"""Check if an enum type exists in the database.
Args:
enum_name (str): Name of the enum type to check
Returns:
bool: True if the enum type exists, False otherwise
"""
bind = op.get_bind()
result = bind.execute(text(
"SELECT EXISTS (SELECT 1 FROM pg_type WHERE typname = :enum_name);"
Expand All @@ -33,13 +50,28 @@ def enum_type_exists(enum_name: str) -> bool:


def upgrade() -> None:
"""Upgrade the database schema.
This function performs the following operations:
- Creates an enum type 'status_enum' if it doesn't exist
- Adds a 'status' column to the 'position' table if it doesn't exist
- Adds a 'contract_address' column to the 'user' table if it doesn't exist
- Drops the 'deployed_transaction_hash' column from the 'user' table if it exists
"""
# Create enum type 'status_enum' if it doesn't exist
if not enum_type_exists('status_enum'):
op.execute("CREATE TYPE status_enum AS ENUM ('pending', 'opened', 'closed')")

# Add status column to position table if it doesn't exist
if not column_exists('position', 'status'):
op.add_column('position', sa.Column('status', sa.Enum('pending', 'opened', 'closed', name='status_enum'), nullable=True))
op.add_column(
'position',
sa.Column(
'status',
sa.Enum('pending', 'opened', 'closed', name='status_enum'),
nullable=True
)
)

# Add contract_address column to user table if it doesn't exist
if not column_exists('user', 'contract_address'):
Expand All @@ -50,6 +82,14 @@ def upgrade() -> None:
op.drop_column('user', 'deployed_transaction_hash')

def downgrade() -> None:
"""Downgrade the database schema.
This function performs the following operations:
- Drops the 'status' column from the 'position' table if it exists
- Drops the enum type 'status_enum' if there are no columns using it
- Drops the 'contract_address' column from the 'user' table if it exists
- Adds the 'deployed_transaction_hash' column to the 'user' table if it doesn't exist
"""
# Drop status column from position table if it exists
if column_exists('position', 'status'):
op.drop_column('position', 'status')
Expand All @@ -64,4 +104,12 @@ def downgrade() -> None:

# Add deployed_transaction_hash column to user table if it doesn't exist
if not column_exists('user', 'deployed_transaction_hash'):
op.add_column('user', sa.Column('deployed_transaction_hash', sa.VARCHAR(), autoincrement=False, nullable=True))
op.add_column(
'user',
sa.Column(
'deployed_transaction_hash',
sa.VARCHAR(),
autoincrement=False,
nullable=True
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@


def upgrade() -> None:
"""Upgrade the database schema.
This function performs the following operations:
- Create 'user' table if it does not exist
- Create 'position' table if it does not exist
"""
# ### commands auto generated by Alembic - please adjust! ###

# Create 'user' table if it does not exist
Expand Down Expand Up @@ -52,6 +58,12 @@ def upgrade() -> None:
# ### end Alembic commands ###

def downgrade() -> None:
"""Downgrade the database schema.
This function performs the following operations:
- Drop 'position' table if it exists
- Drop 'user' table if it exists
"""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_position_user_id'), table_name='position')
op.drop_table('position')
Expand Down
7 changes: 6 additions & 1 deletion web_app/api/dashboard.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
This module handles dashboard-related API endpoints.
"""

import collections

from fastapi import APIRouter
Expand All @@ -19,7 +23,8 @@
)
async def get_dashboard(wallet_id: str) -> DashboardResponse:
"""
This endpoint fetches the user's dashboard data, including balances, multipliers, start dates, and ZkLend position.
This endpoint fetches the user's dashboard data,
including balances, multipliers, start dates, and ZkLend position.
### Parameters:
- **wallet_id**: User's wallet ID
Expand Down
13 changes: 12 additions & 1 deletion web_app/api/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""
Main FastAPI application module for the SPOTNET API.
This module sets up the FastAPI application
and includes middleware for session management and CORS.
It also includes routers for the dashboard, position, and user endpoints.
"""

import os
from uuid import uuid4

Expand All @@ -11,7 +19,10 @@

app = FastAPI(
title="SPOTNET API",
description="An API that supports depositing collateral, borrowing stablecoins, trading on AMMs, and managing user positions on Starknet.",
description=(
"An API that supports depositing collateral, borrowing stablecoins, "
"trading on AMMs, and managing user positions on Starknet."
),
version="0.1.0",
license_info={
"name": "MIT License",
Expand Down
36 changes: 32 additions & 4 deletions web_app/api/position.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
This module handles position-related API endpoints.
"""

from fastapi import APIRouter, Request, HTTPException

from web_app.api.serializers.transaction import (
Expand All @@ -13,7 +17,13 @@
position_db_connector = PositionDBConnector() # Initialize the PositionDBConnector


@router.post("/api/create-position", tags=["Position Operations"], response_model=LoopLiquidityData, summary="Create a new position", response_description="Returns the new position and transaction data.")
@router.post(
"/api/create-position",
tags=["Position Operations"],
response_model=LoopLiquidityData,
summary="Create a new position",
response_description="Returns the new position and transaction data.",
)
async def create_position_with_transaction_data(
form_data: PositionFormData
) -> LoopLiquidityData:
Expand Down Expand Up @@ -53,7 +63,13 @@ async def create_position_with_transaction_data(
return LoopLiquidityData(**deposit_data)


@router.get("/api/get-repay-data", tags=["Position Operations"], response_model=RepayTransactionDataResponse, summary="Get repay data", response_description="Returns the repay transaction data.")
@router.get(
"/api/get-repay-data",
tags=["Position Operations"],
response_model=RepayTransactionDataResponse,
summary="Get repay data",
response_description="Returns the repay transaction data.",
)
async def get_repay_data(
supply_token: str, wallet_id: str
) -> RepayTransactionDataResponse:
Expand All @@ -78,7 +94,13 @@ async def get_repay_data(
return repay_data


@router.get("/api/close-position", tags=["Position Operations"], response_model=str, summary="Close a position", response_description="Returns the position status")
@router.get(
"/api/close-position",
tags=["Position Operations"],
response_model=str,
summary="Close a position",
response_description="Returns the position status",
)
async def close_position(position_id: str) -> str:
"""
Close a position.
Expand All @@ -93,7 +115,13 @@ async def close_position(position_id: str) -> str:
return position_status


@router.get("/api/open-position", tags=["Position Operations"], response_model=str, summary="Open a position", response_description="Returns the positions status")
@router.get(
"/api/open-position",
tags=["Position Operations"],
response_model=str,
summary="Open a position",
response_description="Returns the positions status",
)
async def open_position(position_id: str) -> str:
"""
Open a position.
Expand Down
27 changes: 27 additions & 0 deletions web_app/api/serializers/dashboard.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"""
This module defines the serializers for the dashboard data.
"""
from datetime import datetime
from decimal import Decimal
from typing import Dict, List, Optional, Any
Expand All @@ -7,16 +10,25 @@


class Data(BaseModel):
"""
Data class for position details.
"""
collateral: bool
debt: bool


class TotalBalances(RootModel):
"""
TotalBalances class for total balances.
"""
# Since the keys are dynamic (addresses), we use a generic Dict
root: Dict[str, str]


class Position(BaseModel):
"""
Position class for position details.
"""
data: Data
token_address: Optional[str] = Field(None, alias="tokenAddress")
total_balances: TotalBalances = Field(alias="totalBalances")
Expand All @@ -40,16 +52,25 @@ def convert_total_balances(cls, balances):
return converted_balances

class Config:
"""
Configuration for the Position class.
"""
populate_by_name = True


class Product(BaseModel):
"""
Product class for product details.
"""
name: str
health_ratio: str
positions: List[Position]


class ZkLendPositionResponse(BaseModel):
"""
ZkLendPositionResponse class for ZkLend position details.
"""
products: List[Product] = Field(default_factory=list)

@field_validator("products", mode="before")
Expand All @@ -66,10 +87,16 @@ def convert_products(cls, products):
return converted_products

class Config:
"""
Configuration for the ZkLendPositionResponse class.
"""
populate_by_name = True


class DashboardResponse(BaseModel):
"""
DashboardResponse class for dashboard details.
"""
balances: Dict[str, Any] = Field(
...,
example={"ETH": 5.0, "USDC": 1000.0},
Expand Down
4 changes: 4 additions & 0 deletions web_app/api/serializers/position.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
This module defines the serializers for the position data.
"""

from pydantic import BaseModel, field_validator


Expand Down
16 changes: 16 additions & 0 deletions web_app/api/serializers/transaction.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
This module defines the serializers for the transaction data.
"""

from pydantic import BaseModel, field_validator


Expand Down Expand Up @@ -25,6 +29,10 @@ def convert_int_to_str(cls, value) -> str:


class DepositData(BaseModel):
"""
Pydantic model for the deposit data.
"""

token: str
amount: str
multiplier: str
Expand Down Expand Up @@ -85,8 +93,16 @@ class UpdateUserContractRequest(BaseModel):


class DeploymentStatus(BaseModel):
"""
Pydantic model for the deployment status.
"""

is_contract_deployed: bool


class ContractAddress(BaseModel):
"""
Pydantic model for the contract address.
"""

contract_address: str | None
Loading

0 comments on commit b82f722

Please sign in to comment.