YoBatM commited on
Commit
743deb5
·
verified ·
1 Parent(s): 4b2a922

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +153 -0
app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MAX_API_RETRIES=3
2
+ from pydantic import BaseModel
3
+ import pydantic_core._pydantic_core as pydantic_core
4
+ from fastapi import FastAPI
5
+ from functools import partial
6
+ import json,requests
7
+ app = FastAPI()
8
+ def morph(valor,tipo):
9
+ if isinstance(valor,dict):
10
+ return tipo(valor)
11
+ elif isinstance(valor,list):
12
+ return list(map(lambda v:morph(v,tipo),valor))
13
+ else:
14
+ return valor
15
+ class ResponseData(BaseModel):
16
+ error:bool
17
+ message:str
18
+ class Diccionario:
19
+ def __init__(self,diccionario:dict):
20
+ self.d = diccionario
21
+ def __str__(self):
22
+ return json.dumps(self.d)
23
+ def __repr__(self):
24
+ return self.__str__()
25
+ def __getattr__(self,data:str):
26
+ attr = self.d.get(data,None)
27
+ return morph(attr,Diccionario)
28
+ class Mensaje(BaseModel):
29
+ content:str = ""
30
+ role:str = "user"
31
+ class persona(BaseModel):
32
+ nombres:str
33
+ apellidos:str
34
+ edad:int
35
+ personalidad:str
36
+ biografia:str
37
+ pais:str
38
+ sexo:str
39
+ hobbies:list[str]
40
+ class personaje(BaseModel):
41
+ interpretador:persona
42
+ nombre:str
43
+ personalidad:str
44
+ apariencia:str
45
+ papel:str
46
+ edad:int
47
+ class pelicula(BaseModel):
48
+ personajes: list[personaje]
49
+ titulo:str
50
+ traduccion:dict[str,str]
51
+ sinopsis:str
52
+ duracion:int
53
+ detailed_image_token_prompt_english:list[str]
54
+
55
+ class trabajador(BaseModel):
56
+ identidad:persona
57
+ trabajo:str
58
+ sueldo:int
59
+ remoto:bool=False
60
+ historial_sueldo:list[str]
61
+ class comentario(BaseModel):
62
+ mensaje:str
63
+ autor:persona
64
+ likes:int
65
+ dislikes:int
66
+ class publicacion(BaseModel):
67
+ mensaje:str
68
+ likes:int
69
+ dislikes:int
70
+ visitas:int
71
+ comentarios:list[comentario]
72
+ class perfil(BaseModel):
73
+ data:persona
74
+ amigos:list[persona]
75
+ publicaciones:list[publicacion]
76
+ class steamgame(BaseModel):
77
+ nombre:str
78
+ descripcion_corta:str
79
+ descripcion_larga:str
80
+ reviews:list[comentario]
81
+ calificacion:int
82
+ descargas:int
83
+
84
+ class episodio(BaseModel):
85
+ personajes_involucrados:list[personaje]
86
+ dialogos:list[dict[int,dict[str,str]]]
87
+ descripcion:str
88
+ class serie(BaseModel):
89
+ nombre:str
90
+ personajes:list[personaje]
91
+ clasificacion:str
92
+ rating:int
93
+ episodios:int
94
+ lista_episodios:list[episodio]
95
+ def ask(query:str,system_prompt:str)->ResponseData:
96
+ msgs:list[dict[str,str]] = [
97
+ Mensaje(role="system",content=system_prompt).model_dump(),
98
+ Mensaje(content=query).model_dump()
99
+ ]
100
+ response = requests.post("https://text.pollinations.ai/openai",json={
101
+ "messages":msgs,
102
+ "private":True,
103
+ "jsonMode":True,
104
+ "model":"openai",
105
+ "seed":__import__("random").randint(10000,999999)
106
+ })
107
+ data=response.json()
108
+
109
+ error_msg = Diccionario(data).error
110
+ structured_data = ResponseData(error=True if error_msg else False,message=error_msg or Diccionario(data).choices[0].message.content)
111
+ return structured_data
112
+
113
+ def generate_model(model:BaseModel,gived_data:BaseModel=None,retries=0)->BaseModel | None:
114
+ 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"""
115
+ if gived_data:
116
+ system+=f"\n Ademas tengo esta informacion: {gived_data.model_dump_json()}"
117
+ resultado = ask(json.dumps(model.model_json_schema()),system)
118
+ if resultado.error==True:
119
+ return {"error":resultado.message}
120
+ try:
121
+ data = list(json.loads(resultado.message).values())[0]
122
+ if retries>MAX_API_RETRIES: return {"error":"Se ha intentado, pero no hubo caso, prueba nuevamente","failed_data":data}
123
+ if isinstance(data,str):
124
+ retries+=1
125
+ return generate_model(model,gived_data,retries)
126
+
127
+
128
+ return model(**(data))
129
+ except (pydantic_core.ValidationError, json.JSONDecodeError) as e:
130
+ retries+=1
131
+ return generate_model(model,gived_data,retries)
132
+
133
+ models:BaseModel= [
134
+ persona,
135
+ pelicula,
136
+ trabajador,
137
+ publicacion,
138
+ perfil,
139
+ steamgame,
140
+ serie
141
+ ]
142
+ def create_handler(model_class: BaseModel):
143
+ def handler() -> dict:
144
+ generated=generate_model(model_class)
145
+
146
+ return generated if isinstance(generated,dict) else json.loads(generated.model_dump_json())
147
+ handler.__name__=f"Crear {model_class.__name__}"
148
+ return handler
149
+ for model in models:
150
+ app.add_api_route(f"/{model.__name__}",create_handler(model))
151
+ @app.post("/generate_movie")
152
+ def gen_movie(user:persona):
153
+ return generate_model(pelicula,user)