chore: save local changes
This commit is contained in:
133
backend/app/routers/patent_search.py
Normal file
133
backend/app/routers/patent_search.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""Patent Search Router - Search for similar patents"""
|
||||
|
||||
import logging
|
||||
from typing import Optional, List
|
||||
|
||||
from fastapi import APIRouter
|
||||
from pydantic import BaseModel
|
||||
|
||||
from ..services.patent_search_service import patent_search_service
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/api/patent", tags=["patent"])
|
||||
|
||||
|
||||
# ===== Request/Response Models =====
|
||||
|
||||
class PatentSearchRequest(BaseModel):
|
||||
"""Patent search request"""
|
||||
query: str # Search query (description or keywords)
|
||||
max_results: int = 10 # Maximum results to return (1-20)
|
||||
|
||||
|
||||
class PatentResult(BaseModel):
|
||||
"""Single patent result"""
|
||||
publication_number: str
|
||||
title: str
|
||||
snippet: str
|
||||
publication_date: Optional[str] = None
|
||||
assignee: Optional[str] = None
|
||||
inventor: Optional[str] = None
|
||||
status: str # ACTIVE, NOT_ACTIVE, UNKNOWN
|
||||
pdf_url: Optional[str] = None
|
||||
thumbnail_url: Optional[str] = None
|
||||
|
||||
|
||||
class PatentSearchResponse(BaseModel):
|
||||
"""Patent search response"""
|
||||
query: str
|
||||
total_results: int
|
||||
patents: List[PatentResult]
|
||||
error: Optional[str] = None
|
||||
|
||||
|
||||
class BatchPatentSearchRequest(BaseModel):
|
||||
"""Batch patent search request - search multiple descriptions"""
|
||||
queries: List[str] # List of descriptions to search
|
||||
max_results_per_query: int = 5 # Max results per query
|
||||
|
||||
|
||||
class BatchPatentSearchResult(BaseModel):
|
||||
"""Results for a single query in batch search"""
|
||||
query: str
|
||||
total_results: int
|
||||
patents: List[PatentResult]
|
||||
error: Optional[str] = None
|
||||
|
||||
|
||||
class BatchPatentSearchResponse(BaseModel):
|
||||
"""Batch patent search response"""
|
||||
results: List[BatchPatentSearchResult]
|
||||
total_queries: int
|
||||
|
||||
|
||||
# ===== Endpoints =====
|
||||
|
||||
@router.post("/search", response_model=PatentSearchResponse)
|
||||
async def search_patents(request: PatentSearchRequest):
|
||||
"""
|
||||
Search for patents similar to the given description/query.
|
||||
|
||||
Uses Google Patents to find related patents based on keywords.
|
||||
"""
|
||||
logger.info(f"Patent search request: {request.query[:100]}...")
|
||||
|
||||
# Limit max_results to reasonable range
|
||||
max_results = min(max(1, request.max_results), 20)
|
||||
|
||||
result = await patent_search_service.search(
|
||||
query=request.query,
|
||||
max_results=max_results,
|
||||
)
|
||||
|
||||
return PatentSearchResponse(
|
||||
query=request.query,
|
||||
total_results=result.get("total_results", 0),
|
||||
patents=[PatentResult(**p) for p in result.get("patents", [])],
|
||||
error=result.get("error"),
|
||||
)
|
||||
|
||||
|
||||
@router.post("/search/batch", response_model=BatchPatentSearchResponse)
|
||||
async def batch_search_patents(request: BatchPatentSearchRequest):
|
||||
"""
|
||||
Search for patents for multiple descriptions at once.
|
||||
|
||||
Useful for checking multiple creative descriptions against patents.
|
||||
"""
|
||||
logger.info(f"Batch patent search: {len(request.queries)} queries")
|
||||
|
||||
# Limit results per query
|
||||
max_per_query = min(max(1, request.max_results_per_query), 10)
|
||||
|
||||
results: List[BatchPatentSearchResult] = []
|
||||
|
||||
for query in request.queries:
|
||||
result = await patent_search_service.search(
|
||||
query=query,
|
||||
max_results=max_per_query,
|
||||
)
|
||||
|
||||
results.append(BatchPatentSearchResult(
|
||||
query=query,
|
||||
total_results=result.get("total_results", 0),
|
||||
patents=[PatentResult(**p) for p in result.get("patents", [])],
|
||||
error=result.get("error"),
|
||||
))
|
||||
|
||||
return BatchPatentSearchResponse(
|
||||
results=results,
|
||||
total_queries=len(request.queries),
|
||||
)
|
||||
|
||||
|
||||
@router.get("/health")
|
||||
async def patent_search_health():
|
||||
"""Check if patent search service is working"""
|
||||
# Do a simple test search
|
||||
result = await patent_search_service.search("test", max_results=1)
|
||||
|
||||
if result.get("error"):
|
||||
return {"status": "unhealthy", "error": result["error"]}
|
||||
|
||||
return {"status": "healthy"}
|
||||
Reference in New Issue
Block a user