-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
221 lines (184 loc) · 7.18 KB
/
main.py
File metadata and controls
221 lines (184 loc) · 7.18 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
from fastapi import Depends, FastAPI, HTTPException, Request, Response
from fastapi.responses import HTMLResponse, PlainTextResponse
from sqlalchemy.orm import Session
from database import SessionLocal, engine
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address, get_ipaddr
from slowapi.errors import RateLimitExceeded
from enum import Enum
import crud
import json
import funcionesIOL
import models
import schemas
import redis
from starlette import status
def crear_database():
return models.Base.metadata.create_all(bind=engine)
def limitar_con_redis(client,key, limit):
req = client.incr(key)
if req == 1:
client.expire(key, 60)
ttl = 60
else:
ttl = client.ttl(key)
if req > limit:
return {
"call": False,
"ttl": ttl
}
else:
return {
"call": True,
"ttl": ttl
}
crear_database()
limiter = Limiter(key_func=get_ipaddr, default_limits=['5minute'])
app = FastAPI(title="API-IOL")
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
creditos_disponibles = {}
def limitar_porcreditos(ip_cliente, creditos_endpoint):
try:
req=creditos_disponibles[ip_cliente]
if req==0:
return {
"call": False,
"creditos": req
}
else:
creditos_disponibles[ip_cliente]=creditos_disponibles[ip_cliente]-1
return {
"call": True,
"creditos": creditos_disponibles
}
except KeyError:
creditos_disponibles[ip_cliente]=creditos_endpoint
return {
"call": True,
"creditos": creditos_endpoint
}
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def get_redis():
# Verificar que esta corriendo localmente en consola
redis_conn = redis.Redis(host='localhost', port=6379, db=0)
try:
yield redis_conn
finally:
redis_conn.close()
@app.get("/")
@limiter.exempt
def home(request: Request):
""" Endpoint para dar la bienvenida
"""
response_data = {"messagge":"Bienvenidos a la API",
}
return response_data
@app.get("/DatosPerfil",
summary="Consulta Datos del Perfil",
description="Consulta los datos del perfil seleccionado",
tags=['Consulta de datos del Perfil'])
@limiter.exempt
def datos_perfil(request: Request):
"""Solcitar datos del pefil de IOL
"""
response_data = funcionesIOL.datos_perfil()
return response_data
@app.get("/EstadoCuenta",
summary="Consulta El estado de cuenta",
description="Consulta el estado de cuenta del cliente",
tags=['Estado de Cuenta'])
@limiter.exempt
def EstadoCuenta(request: Request):
"""Solcitar datos del pefil de IOL
"""
response_data = funcionesIOL.estado_cuenta()
if response_data=="API Caida":
raise HTTPException (status_code=503, detail="API Caida, Servicio No Disponible")
else:
return response_data
@app.get("/Portafolio/{pais}",
summary="Consulta El Portafolio",
description="Consulta el portafolio del cliente",
tags=['Composicion del Portafolio'])
@limiter.exempt
def portafolio(pais:schemas.PortafolioPais, request: Request):
"""Solcitar datos del pefil de IOL
"""
response_data = funcionesIOL.portafolio(pais)
return response_data
@app.post("/operaciones",tags=['Consulta Operaciones'])
@limiter.limit("20/minute",
error_message="Superado el máximo de consultas permitido por minuto")
def operaciones(item: schemas.Operacion, request: Request):
"""Solcitar datos del pefil de IOL
"""
response_data = funcionesIOL.consulta_operaciones(item.estado, item.desde, item.hasta, item.pais)
#response_data.headers["X-Cat-Dog"] = "alone in the world" Primero se debe instanciar la clase Response
return response_data
@app.post("/mep",
tags=['Cotizacion Mep'],
description="Obtiene los valores del MEP del ticker asignado en caso de existir")
@limiter.limit("20/minute",
error_message="Superado el máximo de consultas permitido por minuto")
def mep(simbolo: schemas.ConsultaMep, request:Request):
response_data = funcionesIOL.mep(simbolo.simbolo)
if response_data is None:
raise HTTPException(status_code=422, detail="Ticker Nulo")
elif isinstance(response_data, dict) | isinstance(response_data, float) :
return Response(content=json.dumps(response_data), media_type="application/json")
else:
raise HTTPException(status_code=400, detail="Ticker sin mep")
@app.post("/consultas/", response_model=schemas.Consulta, tags=['Nueva alta en tabla Consultas'])
@limiter.limit("1/minute",
error_message="Superado el máximo de consultas permitido por minuto")
def crear_consulta(request : Request, consulta: schemas.Consulta, db: Session = Depends(get_db)):
"""Este enpoint permite agregar un nuevo registro a la tabla Consultas
"""
db_proveedor = crud.consulta_precio(stock = consulta.Stock, db=db)
return db_proveedor
@app.post("/Trade/", response_model=schemas.Orden, tags=['Comprar Stock'])
@limiter.limit("10/minute",
error_message="Superado el máximo de consultas permitido por minuto")
def trade_long(request: Request, orden: schemas.Orden, db: Session = Depends(get_db)):
operacion = funcionesIOL.comprar_stock(simbolo=orden.simbolo,
cantidad=orden.cantidad,
precio=orden.precio,
plazo = orden.plazo,
validez=orden.validez)
return Response(content=operacion, media_type="application/json")
@app.get("/redis")
def test(request: Request, redis=Depends(get_redis)):
clientIp = request.client.host
res = limitar_con_redis(redis,clientIp, 2)
if res["call"]:
redis.hset('disponible', mapping={
"message": "Bienvenido",
"ttl": res["ttl"]})
return redis.hgetall('disponible')
else:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail={
"message": "Limite alcanzado",
"ttl": res["ttl"]
}
)
@app.get("/Creditos")
def creditos(request: Request):
#envia IP del dispositivo, maximos creditos para este endpoint
tengo_creditos=limitar_porcreditos(get_remote_address,2)
if tengo_creditos['call']==True:
return PlainTextResponse("Bienvenidos!")
else:
return HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail={
"message": "Te quedaste sin créditos",
}
)