feat: add proxy source crud and wire into app
This commit is contained in:
parent
d249020773
commit
ca58dd94db
@ -4,10 +4,12 @@ from contextlib import asynccontextmanager
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from redis.asyncio import from_url as redis_from_url
|
from redis.asyncio import from_url as redis_from_url
|
||||||
|
|
||||||
|
from proxy_pool.common.router import router as health_router
|
||||||
from proxy_pool.config import get_settings
|
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
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -57,7 +59,7 @@ def create_app() -> FastAPI:
|
|||||||
lifespan=lifespan,
|
lifespan=lifespan,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Register routers here as we build them
|
app.include_router(health_router)
|
||||||
# app.include_router(...)
|
app.include_router(proxy_router)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
126
src/proxy_pool/proxy/router.py
Normal file
126
src/proxy_pool/proxy/router.py
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
from sqlalchemy import select
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from proxy_pool.common.dependencies import get_db, get_registry
|
||||||
|
from proxy_pool.plugins.registry import PluginRegistry
|
||||||
|
from proxy_pool.proxy.models import ProxySource
|
||||||
|
from proxy_pool.proxy.schemas import (
|
||||||
|
ProxySourceCreate,
|
||||||
|
ProxySourceResponse,
|
||||||
|
ProxySourceUpdate,
|
||||||
|
)
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/sources", tags=["sources"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("", response_model=list[ProxySourceResponse])
|
||||||
|
async def list_sources(
|
||||||
|
is_active: bool | None = None,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> list[ProxySourceResponse]:
|
||||||
|
query = select(ProxySource)
|
||||||
|
if is_active is not None:
|
||||||
|
query = query.where(ProxySource.is_active == is_active)
|
||||||
|
query = query.order_by(ProxySource.created_at.desc())
|
||||||
|
|
||||||
|
result = await db.execute(query)
|
||||||
|
sources = result.scalars().all()
|
||||||
|
return [ProxySourceResponse.model_validate(s) for s in sources]
|
||||||
|
|
||||||
|
|
||||||
|
@router.post(
|
||||||
|
"",
|
||||||
|
response_model=ProxySourceResponse,
|
||||||
|
status_code=status.HTTP_201_CREATED,
|
||||||
|
)
|
||||||
|
async def create_source(
|
||||||
|
body: ProxySourceCreate,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
registry: PluginRegistry = Depends(get_registry),
|
||||||
|
) -> ProxySourceResponse:
|
||||||
|
# Validate parser exists
|
||||||
|
try:
|
||||||
|
registry.get_parser(body.parser_name)
|
||||||
|
except Exception:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||||
|
detail=f"No parser registered with name '{body.parser_name}'",
|
||||||
|
) from None
|
||||||
|
|
||||||
|
source = ProxySource(
|
||||||
|
url=body.url,
|
||||||
|
parser_name=body.parser_name,
|
||||||
|
cron_schedule=body.cron_schedule,
|
||||||
|
default_protocol=body.default_protocol,
|
||||||
|
)
|
||||||
|
db.add(source)
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(source)
|
||||||
|
|
||||||
|
return ProxySourceResponse.model_validate(source)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{source_id}", response_model=ProxySourceResponse)
|
||||||
|
async def get_source(
|
||||||
|
source_id: UUID,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> ProxySourceResponse:
|
||||||
|
source = await db.get(ProxySource, source_id)
|
||||||
|
if source is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Source not found",
|
||||||
|
)
|
||||||
|
return ProxySourceResponse.model_validate(source)
|
||||||
|
|
||||||
|
|
||||||
|
@router.patch("/{source_id}", response_model=ProxySourceResponse)
|
||||||
|
async def update_source(
|
||||||
|
source_id: UUID,
|
||||||
|
body: ProxySourceUpdate,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
registry: PluginRegistry = Depends(get_registry),
|
||||||
|
) -> ProxySourceResponse:
|
||||||
|
source = await db.get(ProxySource, source_id)
|
||||||
|
if source is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Source not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
update_data = body.model_dump(exclude_unset=True)
|
||||||
|
|
||||||
|
if "parser_name" in update_data:
|
||||||
|
try:
|
||||||
|
registry.get_parser(update_data["parser_name"])
|
||||||
|
except Exception:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||||
|
detail=f"No parser registered with name '{update_data['parser_name']}'",
|
||||||
|
) from None
|
||||||
|
|
||||||
|
for field, value in update_data.items():
|
||||||
|
setattr(source, field, value)
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(source)
|
||||||
|
|
||||||
|
return ProxySourceResponse.model_validate(source)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{source_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
|
async def delete_source(
|
||||||
|
source_id: UUID,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> None:
|
||||||
|
source = await db.get(ProxySource, source_id)
|
||||||
|
if source is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Source not found",
|
||||||
|
)
|
||||||
|
await db.delete(source)
|
||||||
|
await db.commit()
|
||||||
Loading…
x
Reference in New Issue
Block a user