ruff linting + import sorts

This commit is contained in:
Shroominic
2025-06-13 16:48:24 +02:00
parent f8dc04cd07
commit 3af5bc02c9
19 changed files with 103 additions and 59 deletions
+1
View File
@@ -1,4 +1,5 @@
import os
import openai
client = openai.OpenAI(
+14
View File
@@ -44,3 +44,17 @@ markers = [
"integration: marks tests as integration tests",
"unit: marks tests as unit tests",
]
[tool.ruff.lint]
exclude = ["gptassistant/bot/prompts.py"]
select = ["E", "F", "I"]
ignore = ["E501"]
[tool.mypy]
python_version = "3.11"
ignore_missing_imports = true
disallow_untyped_defs = true
check_untyped_defs = true
disallow_untyped_calls = true
disallow_incomplete_defs = true
disallow_untyped_decorators = true
+18 -10
View File
@@ -1,17 +1,19 @@
from typing import Annotated
from fastapi import APIRouter, Header, HTTPException, Depends
from fastapi import APIRouter, Depends, Header, HTTPException
from .auth import validate_bearer_key
from .cashu import (
refund_balance,
credit_balance,
WALLET,
credit_balance,
delete_key_if_zero_balance,
refund_balance,
)
from .db import ApiKey, AsyncSession, get_session
wallet_router = APIRouter(prefix="/v1/wallet")
async def get_key_from_header(
authorization: Annotated[str, Header(...)],
session: AsyncSession = Depends(get_session),
@@ -24,6 +26,7 @@ async def get_key_from_header(
detail="Invalid authorization. Use 'Bearer <cashu-token>' or 'Bearer <api-key>'",
)
# TODO: remove this endpoint when frontend is updated
@wallet_router.get("/")
async def account_info(key: ApiKey = Depends(get_key_from_header)) -> dict:
@@ -32,6 +35,7 @@ async def account_info(key: ApiKey = Depends(get_key_from_header)) -> dict:
"balance": key.balance,
}
@wallet_router.get("/info")
async def wallet_info(key: ApiKey = Depends(get_key_from_header)) -> dict:
return {
@@ -55,10 +59,10 @@ async def refund_wallet_endpoint(
session: AsyncSession = Depends(get_session),
) -> dict:
remaining_balance_msats = key.balance
if remaining_balance_msats == 0:
raise HTTPException(status_code=400, detail="No balance to refund")
# Perform refund operation first, before modifying balance
if key.refund_address:
await refund_balance(remaining_balance_msats, key, session)
@@ -67,17 +71,19 @@ async def refund_wallet_endpoint(
# Convert msats to sats for cashu wallet
remaining_balance_sats = remaining_balance_msats // 1000
if remaining_balance_sats == 0:
raise HTTPException(status_code=400, detail="Balance too small to refund (less than 1 sat)")
raise HTTPException(
status_code=400, detail="Balance too small to refund (less than 1 sat)"
)
token = await WALLET.send(remaining_balance_sats)
result = {"msats": remaining_balance_msats, "recipient": None, "token": token}
# Only after successful refund, zero out the balance
key.balance = 0
session.add(key)
await session.commit()
await delete_key_if_zero_balance(key, session)
return result
@@ -85,4 +91,6 @@ async def refund_wallet_endpoint(
"/{path:path}", methods=["GET", "POST", "PUT", "DELETE"], include_in_schema=False
)
async def wallet_catch_all(path: str):
raise HTTPException(status_code=404, detail="Not found check /docs for available endpoints")
raise HTTPException(
status_code=404, detail="Not found check /docs for available endpoints"
)
+1 -1
View File
@@ -5,8 +5,8 @@ from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from sqlmodel import select
from .db import ApiKey, create_session
from .cashu import WALLET
from .db import ApiKey, create_session
admin_router = APIRouter(prefix="/admin")
+2 -3
View File
@@ -1,12 +1,11 @@
import asyncio
import hashlib
import os
import json
import os
from typing import Optional
from fastapi import HTTPException, Request
from sqlmodel import update, col
from sqlmodel import col, update
from .cashu import credit_balance, pay_out
from .db import ApiKey, AsyncSession
+3 -3
View File
@@ -1,11 +1,11 @@
import os
import asyncio
import os
import time
from sixty_nuts import Wallet
from sqlmodel import select, func, col, update
from .db import ApiKey, AsyncSession, get_session
from sqlmodel import col, func, select, update
from .db import ApiKey, AsyncSession, get_session
RECEIVE_LN_ADDRESS = os.environ["RECEIVE_LN_ADDRESS"]
MINT = os.environ.get("MINT", "https://mint.minibits.cash/Bitcoin")
+4 -4
View File
@@ -1,10 +1,10 @@
from contextlib import asynccontextmanager
import os
from contextlib import asynccontextmanager
from typing import AsyncGenerator
from sqlmodel import Field, SQLModel
from sqlalchemy.ext.asyncio.engine import create_async_engine
from sqlmodel.ext.asyncio.session import AsyncSession
from sqlalchemy.ext.asyncio.engine import create_async_engine
from sqlmodel import Field, SQLModel
from sqlmodel.ext.asyncio.session import AsyncSession
DATABASE_URL = os.environ.get("DATABASE_URL", "sqlite+aiosqlite:///keys.db")
+7 -6
View File
@@ -1,12 +1,13 @@
from fastapi import APIRouter
import asyncio
import json
import websockets
import random
import string
import re
import httpx
import os
import random
import re
import string
import httpx
import websockets
from fastapi import APIRouter
providers_router = APIRouter(prefix="/v1/providers")
+8 -6
View File
@@ -1,19 +1,21 @@
import asyncio
from contextlib import asynccontextmanager
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from .db import init_db
from .admin import admin_router
from .proxy import proxy_router
from .account import wallet_router
from .models import MODELS, update_sats_pricing
from .cashu import check_for_refunds, init_wallet, close_wallet
from .admin import admin_router
from .cashu import check_for_refunds, close_wallet, init_wallet
from .db import init_db
from .discovery import providers_router
from .models import MODELS, update_sats_pricing
from .proxy import proxy_router
__version__ = "0.0.1"
@asynccontextmanager
async def lifespan(_: FastAPI):
await init_db()
+1
View File
@@ -2,6 +2,7 @@ import asyncio
import json
import os
from pathlib import Path
from pydantic.v1 import BaseModel
from .price import sats_usd_ask_price
+3 -2
View File
@@ -1,7 +1,8 @@
import os
import httpx
import asyncio
import logging
import os
import httpx
# artifical spread to cover conversion fees
EXCHANGE_FEE = float(os.environ.get("EXCHANGE_FEE", "1.005")) # 0.5% default
+6 -6
View File
@@ -1,13 +1,13 @@
import os
import json
from fastapi import APIRouter, Request, BackgroundTasks, Depends
from fastapi.responses import Response, StreamingResponse
import httpx
import os
import re
from .cashu import pay_out
import httpx
from fastapi import APIRouter, BackgroundTasks, Depends, Request
from fastapi.responses import Response, StreamingResponse
from .auth import validate_bearer_key, pay_for_request, adjust_payment_for_tokens
from .auth import adjust_payment_for_tokens, pay_for_request, validate_bearer_key
from .cashu import pay_out
from .db import AsyncSession, get_session
UPSTREAM_BASE_URL = os.environ["UPSTREAM_BASE_URL"]
+3 -2
View File
@@ -1,8 +1,9 @@
import httpx
import json
import asyncio
import json
from typing import TypedDict
import httpx
class ModelArchitecture(TypedDict):
modality: str
+6 -5
View File
@@ -1,14 +1,15 @@
import asyncio
import os
from typing import AsyncGenerator, Generator
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
import pytest_asyncio
from typing import AsyncGenerator, Generator
from fastapi.testclient import TestClient
from httpx import AsyncClient, ASGITransport
from sqlmodel import SQLModel
from httpx import ASGITransport, AsyncClient
from sqlalchemy.ext.asyncio import create_async_engine
from sqlmodel import SQLModel
from sqlmodel.ext.asyncio.session import AsyncSession
from unittest.mock import patch, MagicMock, AsyncMock
# Save original environment variables
ORIGINAL_ENV = os.environ.copy()
@@ -55,8 +56,8 @@ with patch("sixty_nuts.Wallet") as mock_wallet_class:
# Make the Wallet class return our mock when instantiated
mock_wallet_class.return_value = mock_wallet
from router.main import app
from router.db import get_session
from router.main import app
@pytest.fixture(scope="session")
+5 -3
View File
@@ -1,9 +1,11 @@
import pytest
import pytest_asyncio
import hashlib
import uuid
from unittest.mock import patch, AsyncMock
from unittest.mock import AsyncMock, patch
import pytest
import pytest_asyncio
from httpx import AsyncClient
from router.db import ApiKey, AsyncSession
+2 -1
View File
@@ -1,6 +1,7 @@
from unittest.mock import patch
import pytest
from httpx import AsyncClient
from unittest.mock import patch
@pytest.mark.asyncio
+12 -3
View File
@@ -1,7 +1,16 @@
import pytest
import asyncio
from unittest.mock import patch, AsyncMock
from router.models import Model, Architecture, Pricing, TopProvider, update_sats_pricing, MODELS
from unittest.mock import AsyncMock, patch
import pytest
from router.models import (
MODELS,
Architecture,
Model,
Pricing,
TopProvider,
update_sats_pricing,
)
@pytest.fixture
+5 -3
View File
@@ -1,10 +1,12 @@
import pytest
import pytest_asyncio
import json
import os
import uuid
from unittest.mock import AsyncMock, patch
import pytest
import pytest_asyncio
from httpx import AsyncClient
from router.db import ApiKey, AsyncSession
@@ -260,7 +262,7 @@ async def test_proxy_with_model_based_pricing(
with patch.dict(os.environ, {"MODEL_BASED_PRICING": "true"}):
with patch("os.path.exists", return_value=True):
# Mock a model with pricing
from router.models import MODELS, Model, Pricing, Architecture, TopProvider
from router.models import MODELS, Architecture, Model, Pricing, TopProvider
test_model = Model(
id="gpt-4",
+2 -1
View File
@@ -2,8 +2,9 @@ import asyncio
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from tests.conftest import TEST_ENV
from router.main import app, lifespan
from tests.conftest import TEST_ENV
@pytest.mark.asyncio