started actual fastapi server with DB

This commit is contained in:
Jack Case
2025-10-19 15:33:34 +00:00
parent 4931a785a1
commit e90bc1cc72
3 changed files with 69 additions and 0 deletions

12
slopserver/db.py Normal file
View File

@@ -0,0 +1,12 @@
from collections.abc import Iterable
from urllib.parse import ParseResult
from sqlalchemy import select
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session
from slopserver.models import Domain, Path, User
def select_slop(urls: list[ParseResult], engine: Engine) -> Iterable[Domain]:
query = select(Domain).where(Domain.domain_name.in_(url[1] for url in urls))
with Session(engine) as session:
rows = session.scalars(query).all()
return rows

View File

@@ -1,4 +1,8 @@
from typing import Annotated
from sqlmodel import Field, SQLModel, create_engine, Relationship from sqlmodel import Field, SQLModel, create_engine, Relationship
from pydantic import AfterValidator, BaseModel
from urllib.parse import urlparse, ParseResult
NAMING_CONVENTION = { NAMING_CONVENTION = {
"ix": "ix_%(column_0_label)s", "ix": "ix_%(column_0_label)s",
@@ -11,6 +15,10 @@ NAMING_CONVENTION = {
metadata = SQLModel.metadata metadata = SQLModel.metadata
metadata.naming_convention = NAMING_CONVENTION metadata.naming_convention = NAMING_CONVENTION
################################################
# Database Models
################################################
class Domain(SQLModel, table=True): class Domain(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True) id: int | None = Field(default=None, primary_key=True)
domain_name: str = Field(index=True, unique=True) domain_name: str = Field(index=True, unique=True)
@@ -31,3 +39,24 @@ class User(SQLModel, table=True):
salt: str salt: str
email_verified: bool = Field(default=False) email_verified: bool = Field(default=False)
################################################
# API Models
################################################
def url_validator(urls: list[str]) -> list[ParseResult]:
parsed_urls = list()
for url in urls:
try:
parsed = urlparse(url)
if not parsed.netloc:
raise ValueError(f"couldn't parse domain from '{url}'")
parsed_urls.append(parsed)
except ValueError as e:
raise ValueError(f"couldn't parse '{url}' as a URL")
return parsed_urls
class SlopReport(BaseModel):
"""Accept reports of one or more slop page URLs"""
slop_urls: Annotated[list[str], AfterValidator(url_validator)]

28
slopserver/server.py Normal file
View File

@@ -0,0 +1,28 @@
"""API Operations
- signup
- verify email
- Get auth token
- get top x reported domains
- get reports for given domains/pages
- post report
"""
from fastapi import FastAPI
from sqlalchemy import create_engine
from slopserver.models import Domain, Path, User
from slopserver.models import SlopReport
from slopserver.db import select_slop
app = FastAPI()
temp_engine = create_engine("postgresql+psycopg://slop-farmer@192.168.1.163/slop-farmer")
@app.post("/report/")
async def report_slop(report: SlopReport):
pass
@app.post("/check/")
async def check_slop(check: SlopReport):
slop_results = select_slop(check.slop_urls, temp_engine)
return slop_results