FastAPI3 / app.py
YoBatM's picture
Update app.py
b77d7b6 verified
raw
history blame
4.85 kB
MAX_API_RETRIES=3
from pydantic import BaseModel
import pydantic_core._pydantic_core as pydantic_core
from fastapi import FastAPI
import json,requests
app = FastAPI()
def morph(valor,tipo):
if isinstance(valor,dict):
return tipo(valor)
elif isinstance(valor,list):
return list(map(lambda v:morph(v,tipo),valor))
else:
return valor
class ResponseData(BaseModel):
error:bool
message:str
class Diccionario:
def __init__(self,diccionario:dict):
self.d = diccionario
def __str__(self):
return json.dumps(self.d)
def __repr__(self):
return self.__str__()
def __getattr__(self,data:str):
attr = self.d.get(data,None)
return morph(attr,Diccionario)
class Mensaje(BaseModel):
content:str = ""
role:str = "user"
class persona(BaseModel):
nombres:str
apellidos:str
edad:int
personalidad:str
biografia:str
pais:str
sexo:str
hobbies:list[str]
class personaje(BaseModel):
interpretador:persona
nombre:str
personalidad:str
apariencia:str
papel:str
edad:int
class pelicula(BaseModel):
personajes: list[personaje]
titulo:str
traduccion:dict[str,str]
sinopsis:str
duracion:int
detailed_image_token_prompt_english:list[str]
class trabajador(BaseModel):
identidad:persona
trabajo:str
sueldo:int
remoto:bool=False
historial_sueldo:list[str]
class comentario(BaseModel):
mensaje:str
autor:persona
likes:int
dislikes:int
class publicacion(BaseModel):
mensaje:str
likes:int
dislikes:int
visitas:int
comentarios:list[comentario]
class perfil(BaseModel):
data:persona
amigos:list[persona]
publicaciones:list[publicacion]
class steamgame(BaseModel):
nombre:str
descripcion_corta:str
descripcion_larga:str
reviews:list[comentario]
calificacion:int
descargas:int
class episodio(BaseModel):
personajes_involucrados:list[personaje]
dialogos:list[dict[int,dict[str,str]]]
descripcion:str
class serie(BaseModel):
nombre:str
personajes:list[personaje]
clasificacion:str
rating:int
episodios:int
lista_episodios:list[episodio]
def ask(query:str,system_prompt:str)->ResponseData:
msgs:list[dict[str,str]] = [
Mensaje(role="system",content=system_prompt).model_dump(),
Mensaje(content=query).model_dump()
]
response = requests.post("https://text.pollinations.ai/openai",json={
"messages":msgs,
"private":True,
"jsonMode":True,
"model":"openai",
"seed":__import__("random").randint(10000,999999)
})
data=response.json()
error_msg = Diccionario(data).error
structured_data = ResponseData(error=True if error_msg else False,message=error_msg or Diccionario(data).choices[0].message.content)
return structured_data
def generate_model(model:BaseModel,gived_data:BaseModel=None,retries=0)->BaseModel | None:
system = f"""Eres un generador de contenido avanzado(evita contenido repetido) capaz de comprender cualquier contexto, debes generar un json valido con estas propiedades, las claves son los valores de title y los valores deben ser del mismo tipo que el valor de type, el title que esta por fuera de propierties debe ser el tipo general, tipo el que contiene todas las propiedades,no realices ningun comentario o acotacion,otorga un json valido,las claves deben estar en minuscula pero los valores no necesariamente"""
if gived_data:
system+=f"\n Ademas tengo esta informacion: {gived_data.model_dump_json()}"
resultado = ask(json.dumps(model.model_json_schema()),system)
if resultado.error==True:
return {"error":resultado.message}
try:
data = list(json.loads(resultado.message).values())[0]
if retries>MAX_API_RETRIES: return {"error":"Se ha intentado, pero no hubo caso, prueba nuevamente","failed_data":data}
if isinstance(data,str):
retries+=1
return generate_model(model,gived_data,retries)
return model(**(data))
except (pydantic_core.ValidationError, json.JSONDecodeError) as e:
retries+=1
return generate_model(model,gived_data,retries)
models:BaseModel= [
persona,
pelicula,
trabajador,
publicacion,
perfil,
steamgame,
serie
]
def create_handler(model_class: BaseModel):
def handler() -> dict:
generated=generate_model(model_class)
return generated if isinstance(generated,dict) else json.loads(generated.model_dump_json())
handler.__name__=f"Crear {model_class.__name__}"
return handler
for model in models:
app.add_api_route(f"/{model.__name__}",create_handler(model))
@app.post("/generate_movie")
def gen_movie(user:persona):
return generate_model(pelicula,user)