File size: 4,847 Bytes
743deb5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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)