SPB Git

spb/trouve-ka Public

Trouve-KA — moteur de recherche web indépendant, Québec-first. Crawler distribué, index OpenSearch, ranking bilingue, galerie d'images. En prod : www.trouve-ka.com

Python 76.8% TypeScript 15.7% SQL 3.9% Shell 1.4% CSS 1.3% Dockerfile 0.7%
2.6 KB · 105 lines python
Raw Blame History
1# Trouve-KA — types partagés du pipeline2# Author: Simon-Pierre Boucher3# Contact: contact@spboucher.ai45"""Modèles Pydantic partagés entre crawler, parser, classifier, indexer et API."""67from datetime import datetime8from enum import StrEnum910from pydantic import BaseModel, Field111213class ErrorCode(StrEnum):14    DNS = "dns"15    TIMEOUT = "timeout"16    TLS = "tls"17    HTTP_4XX = "http_4xx"18    HTTP_5XX = "http_5xx"19    ROBOTS_DENIED = "robots_denied"20    PARSE_FAILED = "parse_failed"21    UNSUPPORTED_CONTENT = "unsupported_content"22    TOO_LARGE = "too_large"23    DUPLICATE = "duplicate"24    SPAM = "spam"25    NOT_QUEBEC = "not_quebec"26    SSRF_BLOCKED = "ssrf_blocked"27    TOO_MANY_REDIRECTS = "too_many_redirects"28    CONNECTION = "connection"29    OK = "ok"303132class Outcome(StrEnum):33    INDEXED = "indexed"34    DUPLICATE = "duplicate"35    UNCHANGED = "unchanged"36    ERROR = "error"37    NOT_QUEBEC = "not_quebec"38    ROBOTS_BLOCKED = "robots_blocked"39    REDIRECT = "redirect"404142class FetchResult(BaseModel):43    url: str44    final_url: str45    status_code: int | None = None46    error_code: ErrorCode = ErrorCode.OK47    content_type: str | None = None48    charset: str | None = None49    body: bytes | None = None50    etag: str | None = None51    last_modified: str | None = None52    duration_ms: int = 053    redirect_chain: list[str] = Field(default_factory=list)545556class ExtractedLink(BaseModel):57    url: str58    anchor: str = ""59    nofollow: bool = False606162class ParsedPage(BaseModel):63    url: str64    canonical_url: str | None = None65    title: str = ""66    description: str = ""67    body: str = ""68    headings: list[str] = Field(default_factory=list)69    language: str | None = None70    links: list[ExtractedLink] = Field(default_factory=list)71    published_at: datetime | None = None72    modified_at: datetime | None = None73    author: str | None = None74    image_url: str | None = None75    noindex: bool = False76    nofollow_page: bool = False77    structured_hints: list[str] = Field(default_factory=list)  # textes JSON-LD/OG utiles au scoring787980class QuebecSignals(BaseModel):81    score: float = 0.082    locations: list[str] = Field(default_factory=list)83    reasons: list[str] = Field(default_factory=list)848586class SearchResult(BaseModel):87    title: str88    url: str89    display_url: str90    snippet: str91    domain: str92    language: str | None = None93    quebec_score: float = 0.094    badges: list[str] = Field(default_factory=list)95    published_at: datetime | None = None969798class SearchResponse(BaseModel):99    query: str100    total: int101    took_ms: int102    page: int103    limit: int104    results: list[SearchResult]105