-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMonetizacion.py
More file actions
186 lines (156 loc) · 7.49 KB
/
Copy pathMonetizacion.py
File metadata and controls
186 lines (156 loc) · 7.49 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
import http.server
import json
import os
import urllib.parse
import urllib.request
import urllib.error
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP, getcontext
API_BASE_URL = "https://openexchangerates.org/api/latest.json"
API_APP_ID_ENV = "OPENEXCHANGERATES_APP_ID"
class CurrencyConverter(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/" or self.path == "/index.html":
self.serve_file("static/index.html", "text/html; charset=utf-8")
return
if self.path.startswith("/static/"):
file_path = self.path.lstrip("/")
if file_path.endswith(".css"):
content_type = "text/css; charset=utf-8"
elif file_path.endswith(".js"):
content_type = "application/javascript; charset=utf-8"
else:
content_type = "application/octet-stream"
self.serve_file(file_path, content_type)
return
self.send_error(404, "Recurso no encontrado")
def do_POST(self):
if self.path != "/convert":
self.send_error(404, "Recurso no encontrado")
return
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
try:
data = json.loads(post_data)
except json.JSONDecodeError:
self.send_response(400)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({"error": "JSON inválido"}).encode())
return
amount = data.get("amount")
from_currency = data.get("from_currency")
to_currency = data.get("to_currency")
if amount is None or from_currency is None or to_currency is None:
self.send_response(400)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({"error": "Faltan parámetros en la solicitud"}).encode())
return
try:
amount_decimal = Decimal(str(amount))
except (InvalidOperation, TypeError):
self.send_response(400)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({"error": "El monto debe ser un número válido"}).encode())
return
if amount_decimal <= 0:
self.send_response(400)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({"error": "El monto debe ser mayor a cero"}).encode())
return
converted_amount, exchange_rate, error_message = self.convert_currency(
amount_decimal,
from_currency,
to_currency
)
if converted_amount is None:
self.send_response(500)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({
"error": error_message or "No se pudo realizar la conversión de moneda"
}).encode())
return
quantized_amount = converted_amount.quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
quantized_rate = exchange_rate.quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
response_data = {
"converted_amount": str(quantized_amount),
"from_currency": from_currency,
"to_currency": to_currency,
"exchange_rate": str(quantized_rate)
}
self.wfile.write(json.dumps(response_data).encode())
def convert_currency(self, amount, from_currency, to_currency):
getcontext().prec = 28
from_currency = from_currency.upper()
to_currency = to_currency.upper()
if from_currency == to_currency:
return amount, Decimal("1"), None
app_id = os.environ.get(API_APP_ID_ENV)
if not app_id:
return None, None, (
f"Falta configurar la variable de entorno {API_APP_ID_ENV} "
"con tu API key de Open Exchange Rates."
)
url = f"{API_BASE_URL}?app_id={app_id}&symbols={from_currency},{to_currency}"
try:
with urllib.request.urlopen(url) as response:
if response.getcode() != 200:
print(f"Error al obtener tasas de cambio. Código de estado: {response.getcode()}")
return None, None, "Error al obtener tasas de cambio."
data = json.loads(response.read().decode())
if "error" in data:
print(f"Error en la respuesta de la API: {data['error']['message']}")
return None, None, data["error"]["message"]
if "rates" not in data or to_currency not in data["rates"]:
print("No se encontraron tasas de cambio en la respuesta.")
return None, None, "No se encontraron tasas de cambio en la respuesta."
rates = data["rates"]
if from_currency not in rates or to_currency not in rates:
print("No se encontraron todas las tasas solicitadas.")
return None, None, "No se encontraron todas las tasas solicitadas."
from_rate = Decimal(str(rates[from_currency]))
to_rate = Decimal(str(rates[to_currency]))
if from_currency == "USD":
exchange_rate = to_rate
elif to_currency == "USD":
exchange_rate = Decimal("1") / from_rate
else:
exchange_rate = to_rate / from_rate
converted_amount = amount * exchange_rate
return converted_amount, exchange_rate, None
except urllib.error.HTTPError as e:
print(f"Error HTTP al acceder a la API: {e}")
return None, None, "Error HTTP al acceder a la API."
except urllib.error.URLError as e:
print(f"Error de URL al acceder a la API: {e}")
return None, None, "Error de URL al acceder a la API."
except Exception as e:
print(f"Error inesperado: {e}")
return None, None, "Error inesperado al procesar la conversión."
return None, None, "No se pudo realizar la conversión."
def serve_file(self, file_path, content_type):
base_dir = os.path.dirname(os.path.abspath(__file__))
full_path = os.path.join(base_dir, file_path)
if not os.path.isfile(full_path):
self.send_error(404, "Recurso no encontrado")
return
with open(full_path, "rb") as file_handle:
content = file_handle.read()
self.send_response(200)
self.send_header("Content-type", content_type)
self.send_header("Content-Length", str(len(content)))
self.end_headers()
self.wfile.write(content)
def run(server_class=http.server.HTTPServer, handler_class=CurrencyConverter, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print(f'Starting server on port {port}...')
httpd.serve_forever()
if __name__ == "__main__":
run()