feat: add proxy query endpoint with filtering and sorting
This commit is contained in:
parent
a38d6a5e36
commit
2ba579754c
@ -9,7 +9,8 @@ from proxy_pool.config import get_settings
|
|||||||
from proxy_pool.db.session import create_session_factory
|
from proxy_pool.db.session import create_session_factory
|
||||||
from proxy_pool.plugins.discovery import discover_plugins
|
from proxy_pool.plugins.discovery import discover_plugins
|
||||||
from proxy_pool.plugins.registry import PluginRegistry
|
from proxy_pool.plugins.registry import PluginRegistry
|
||||||
from proxy_pool.proxy.router import router as proxy_router
|
from proxy_pool.proxy.router import proxy_router
|
||||||
|
from proxy_pool.proxy.router import router as source_router
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ def create_app() -> FastAPI:
|
|||||||
)
|
)
|
||||||
|
|
||||||
app.include_router(health_router)
|
app.include_router(health_router)
|
||||||
|
app.include_router(source_router)
|
||||||
app.include_router(proxy_router)
|
app.include_router(proxy_router)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@ -6,14 +6,19 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
|
|
||||||
from proxy_pool.common.dependencies import get_db, get_registry
|
from proxy_pool.common.dependencies import get_db, get_registry
|
||||||
from proxy_pool.plugins.registry import PluginRegistry
|
from proxy_pool.plugins.registry import PluginRegistry
|
||||||
from proxy_pool.proxy.models import ProxySource
|
from proxy_pool.proxy.models import Proxy, ProxySource
|
||||||
from proxy_pool.proxy.schemas import (
|
from proxy_pool.proxy.schemas import (
|
||||||
|
ProxyListParams,
|
||||||
|
ProxyListResponse,
|
||||||
|
ProxyResponse,
|
||||||
ProxySourceCreate,
|
ProxySourceCreate,
|
||||||
ProxySourceResponse,
|
ProxySourceResponse,
|
||||||
ProxySourceUpdate,
|
ProxySourceUpdate,
|
||||||
)
|
)
|
||||||
|
from proxy_pool.proxy.service import query_proxies
|
||||||
|
|
||||||
router = APIRouter(prefix="/sources", tags=["sources"])
|
router = APIRouter(prefix="/sources", tags=["sources"])
|
||||||
|
proxy_router = APIRouter(prefix="/proxies", tags=["proxies"])
|
||||||
|
|
||||||
|
|
||||||
@router.get("", response_model=list[ProxySourceResponse])
|
@router.get("", response_model=list[ProxySourceResponse])
|
||||||
@ -124,3 +129,47 @@ async def delete_source(
|
|||||||
)
|
)
|
||||||
await db.delete(source)
|
await db.delete(source)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
@proxy_router.get("", response_model=ProxyListResponse)
|
||||||
|
async def list_proxies(
|
||||||
|
params: ProxyListParams = Depends(),
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> ProxyListResponse:
|
||||||
|
proxies, total = await query_proxies(
|
||||||
|
db,
|
||||||
|
status=params.status,
|
||||||
|
protocol=params.protocol,
|
||||||
|
anonymity=params.anonymity,
|
||||||
|
country=params.country,
|
||||||
|
min_score=params.min_score,
|
||||||
|
max_latency_ms=params.max_latency_ms,
|
||||||
|
min_uptime_pct=params.min_uptime_pct,
|
||||||
|
verified_within_minutes=params.verified_within_minutes,
|
||||||
|
sort_by=params.sort_by,
|
||||||
|
sort_order=params.sort_order,
|
||||||
|
limit=params.limit,
|
||||||
|
offset=params.offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ProxyListResponse(
|
||||||
|
items=[ProxyResponse.model_validate(p) for p in proxies],
|
||||||
|
total_count=total,
|
||||||
|
limit=params.limit,
|
||||||
|
offset=params.offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@proxy_router.get("/{proxy_id}", response_model=ProxyResponse)
|
||||||
|
async def get_proxy(
|
||||||
|
proxy_id: UUID,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> ProxyResponse:
|
||||||
|
proxy = await db.get(Proxy, proxy_id)
|
||||||
|
if proxy is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Proxy not found",
|
||||||
|
) from None
|
||||||
|
|
||||||
|
return ProxyResponse.model_validate(proxy)
|
||||||
|
|||||||
@ -51,3 +51,25 @@ class ProxyResponse(BaseModel):
|
|||||||
last_checked_at: datetime | None
|
last_checked_at: datetime | None
|
||||||
first_seen_at: datetime
|
first_seen_at: datetime
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyListParams(BaseModel):
|
||||||
|
status: ProxyStatus | None = None
|
||||||
|
protocol: ProxyProtocol | None = None
|
||||||
|
anonymity: AnonymityLevel | None = None
|
||||||
|
country: str | None = Field(default=None, min_length=2, max_length=2)
|
||||||
|
min_score: float | None = Field(default=None, ge=0.0, le=1.0)
|
||||||
|
max_latency_ms: float | None = Field(default=None, gt=0)
|
||||||
|
min_uptime_pct: float | None = Field(default=None, ge=0.0, le=100.0)
|
||||||
|
verified_within_minutes: int | None = Field(default=None, gt=0)
|
||||||
|
sort_by: str = Field(default="score")
|
||||||
|
sort_order: str = Field(default="desc", pattern="^(asc|desc)$")
|
||||||
|
limit: int = Field(default=50, ge=1, le=200)
|
||||||
|
offset: int = Field(default=0, ge=0)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyListResponse(BaseModel):
|
||||||
|
items: list[ProxyResponse]
|
||||||
|
total_count: int
|
||||||
|
limit: int
|
||||||
|
offset: int
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user