Files
inversionitasbot/app/routes.py

194 lines
6.3 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from sqlalchemy.sql import func
from database import get_db
from models import NewsItem
from pydantic import BaseModel
from datetime import datetime
import logging
# Configuración del logging
LOG_FILE = "app.log"
logging.basicConfig(
filename=LOG_FILE, # Archivo de logs
level=logging.INFO, # Nivel de logging (DEBUG, INFO, WARNING, ERROR, CRITICAL)
format="%(asctime)s - %(levelname)s - %(message)s", # Formato de los logs
)
router = APIRouter()
# Modelo de datos de entrada
class NewsItemCreate(BaseModel):
titulo: str
contenido: str
autor: str | None = None
fuente: str | None = None
fecha: datetime | None = None
link: str
keyword: str | None = None
@router.get("/news/count/by-source")
def count_news_by_source(db: Session = Depends(get_db)):
results = (
db.query(NewsItem.fuente, func.count(NewsItem.id))
.group_by(NewsItem.fuente)
.all()
)
# Convertir resultados en una lista de diccionarios
response = [{"fuente": fuente, "count": count} for fuente, count in results]
return {"count_by_fuente": response}
@router.get("/news/count/by-author")
def count_news_by_author(db: Session = Depends(get_db)):
results = (
db.query(NewsItem.autor, func.count(NewsItem.id))
.group_by(NewsItem.autor)
.all()
)
# Convertir resultados en una lista de diccionarios
response = [{"autor": autor, "count": count} for autor, count in results]
return {"count_by_author": response}
@router.get("/news/{news_id}")
def get_news_by_id(news_id: int, db: Session = Depends(get_db)):
news_item = db.query(NewsItem).filter(NewsItem.id == news_id).first()
if not news_item:
raise HTTPException(status_code=404, detail="Noticia no encontrada")
return {
"id": news_item.id,
"titulo": news_item.titulo,
"contenido": news_item.contenido,
"autor": news_item.autor,
"fuente": news_item.fuente,
"fecha": news_item.fecha,
"link": news_item.link,
"critico": news_item.critico,
"favorable": news_item.favorable,
"keyword": news_item.keyword,
}
@router.get("/news/count/by-keyword")
def count_news_by_keyword(
fechaInicio: datetime | None = None,
fechaFin: datetime | None = None,
db: Session = Depends(get_db)):
query = db.query(NewsItem.keyword, func.count(NewsItem.id)).filter(NewsItem.keyword.isnot(None))
if fechaInicio and fechaFin:
query = query.filter(NewsItem.fecha >= fechaInicio, NewsItem.fecha <= fechaFin)
results = query.group_by(NewsItem.keyword).all()
return {keyword: count for keyword, count in results}
@router.get("/news/keywords/")
def get_all_keywords(db: Session = Depends(get_db)):
results = db.query(NewsItem.keyword).distinct().all()
# Extraer solo las keywords y filtrar valores nulos
keywords = [keyword[0] for keyword in results if keyword[0] is not None]
return {"keywords": keywords}
@router.get("/news/count/by-source/keyword/date-range")
def count_news_by_source_for_keyword_in_range(
keyword: str, fechaInicio: datetime, fechaFin: datetime, db: Session = Depends(get_db)
):
results = (
db.query(NewsItem.fuente, func.count(NewsItem.id))
.filter(
NewsItem.keyword == keyword,
NewsItem.fecha >= fechaInicio,
NewsItem.fecha <= fechaFin
)
.group_by(NewsItem.fuente)
.all()
)
formatted_results = {fuente: count for fuente, count in results}
return {"count_by_source_keyword": formatted_results}
@router.get("/news/titles/by-keyword/date-range")
def get_titles_by_keyword_in_range(
keyword: str, fecha_inicio: datetime, fecha_fin: datetime, db: Session = Depends(get_db)
):
results = (
db.query(NewsItem.titulo)
.filter(
NewsItem.keyword == keyword,
NewsItem.fecha >= fecha_inicio,
NewsItem.fecha <= fecha_fin
)
.all()
)
# Convertir resultados en una sola cadena separada por comas
titles = ", ".join([titulo[0] for titulo in results if titulo[0]])
return {"titles": titles}
# @router.get("/news-summary")
# def get_news_summary(
# keyword: str,
# fecha_inicio: datetime,
# fecha_fin: datetime,
# db: Session = Depends(get_db)
# ):
# results = get_titles_by_keyword_in_range(keyword,fecha_inicio, fecha_fin, db)
# data = {
# "model":"llama3",
# "prompt": f"A continuación tienes los titulares de muchas noticias, resume lo que encuentres más destacado. Noticias: {results}",
# }
# try:
# response = requests.post(
# "http://host.docker.internal:11434/api/generate", json=data
# )
# response.raise_for_status()
# except requests.RequestException as e:
# logging.error(f"Request error: {e}")
# return response
@router.get("/news/titles/")
def get_news_titles(
fechaInicio: datetime | None = None,
fechaFin: datetime | None = None,
db: Session = Depends(get_db),
):
query = db.query(NewsItem.titulo)
if fechaInicio and fechaFin:
query = query.filter(NewsItem.fecha >= fechaInicio, NewsItem.fecha <= fechaFin)
results = query.all()
return {"titles": [titulo[0] for titulo in results]}
@router.get("/news/")
def get_all_news(
fechaInicio: datetime | None = None,
fechaFin: datetime | None = None,
page:int = Query(1, alias="page", ge=1),
pageSize: int = Query(10, alias="pageSize", ge=1, le=100),
db: Session = Depends(get_db),
):
query = db.query(NewsItem.id, NewsItem.titulo, NewsItem.link, NewsItem.favorable, NewsItem.critico) # Solo seleccionamos id y titulo
if fechaInicio and fechaFin:
query = query.filter(NewsItem.fecha >= fechaInicio, NewsItem.fecha <= fechaFin)
totalCount = query.count()
results = query.offset((page - 1) * pageSize).limit(pageSize).all()
return {
"totalCount": totalCount,
"page": page,
"pageSize": pageSize,
"totalPages": (totalCount + pageSize - 1) // pageSize,
"news": [{"id": news_id, "titulo": titulo, "url":link, "critico":critico, "favorable": favorable} for
news_id, titulo, link, critico, favorable in results] # Devolvemos solo id y titulo
}