pyEscoAPI 0.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.1
2
+ Name: pyEscoAPI
3
+ Version: 0.0.4
4
+ Summary: Python client for Esco API (Esco bolsa)
5
+ Author-email: Codetria <hola@codetria.com>
6
+ License: MIT License
7
+ Keywords: Esco,API,bolsa,client,market,provider
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests==2.31.0
14
+
15
+ # Python client for Esco API (Esco bolsa)
@@ -0,0 +1 @@
1
+ # Python client for Esco API (Esco bolsa)
@@ -0,0 +1,6 @@
1
+ from .esco_api import EscoAPI
2
+ from .esco_api import APIVersion
3
+ __all__ = [
4
+ "EscoAPI",
5
+ "APIVersion"
6
+ ]
@@ -0,0 +1,566 @@
1
+ import logging
2
+ from datetime import datetime, timedelta
3
+ from enum import Enum
4
+ from http import HTTPMethod
5
+
6
+ import requests
7
+ from requests import Response
8
+
9
+ logger = logging.getLogger(f"{__name__}")
10
+
11
+
12
+ class APIVersion(Enum):
13
+ VERSION_9 = 9
14
+
15
+
16
+ class EscoAPI:
17
+ base_url: str
18
+ username: str
19
+ password: str
20
+ client_id: str = ""
21
+ version: APIVersion = APIVersion.VERSION_9
22
+
23
+ __token: str = ""
24
+ __expire_datetime: datetime
25
+
26
+ def __make_request(
27
+ self,
28
+ request_endpoint: str,
29
+ request_method: HTTPMethod,
30
+ request_body: dict,
31
+ error_message: str = ""
32
+ ):
33
+ req_call = getattr(requests, request_method.lower())
34
+ headers = {
35
+ "api-version": str(self.version.value)
36
+ }
37
+ if self.__token:
38
+ headers["Authorization"] = f"Bearer {self.__token}"
39
+ params = {
40
+ "url": f"{self.base_url}{request_endpoint}",
41
+ "json": request_body,
42
+ "headers": headers
43
+ }
44
+ result: Response = req_call(**params)
45
+ if 200 <= result.status_code <= 299:
46
+ return result.json()
47
+ else:
48
+ if not error_message:
49
+ error_message = f"Error during endpoint call: {request_endpoint}. Code: {result.status_code}"
50
+ raise ConnectionRefusedError(error_message)
51
+
52
+ def __esco_login(self):
53
+ req_body = {
54
+ "userName": self.username,
55
+ "password": self.password,
56
+ "clientId": self.client_id
57
+ }
58
+
59
+ result_data = self.__make_request(
60
+ request_endpoint="/login",
61
+ request_body=req_body,
62
+ request_method=HTTPMethod.POST,
63
+ error_message="Login to ESCO API failed."
64
+ )
65
+
66
+ self.__token = result_data["access_token"]
67
+ expires_in_minutes = result_data["expires_in"] - 1
68
+ self.__expire_datetime = datetime.now() + timedelta(minutes=expires_in_minutes)
69
+
70
+ def __pre_connection(self):
71
+ if datetime.now() > self.__expire_datetime:
72
+ self.__esco_login()
73
+
74
+ def __new__(cls, base_url: str, username: str, password: str, client_id: str, version: APIVersion):
75
+ if not hasattr(cls, 'instance'):
76
+ cls.instance = super(EscoAPI, cls).__new__(cls)
77
+ # noinspection PyUnresolvedReferences
78
+ return cls.instance
79
+
80
+ def __init__(
81
+ self,
82
+ base_url: str,
83
+ username: str,
84
+ password: str,
85
+ client_id: str = "",
86
+ version: APIVersion = APIVersion.VERSION_9
87
+ ):
88
+ """
89
+ Initializes the EscoAPI client, starting a login to the platform.
90
+ Instantiating a new EscoAPI client will not result in a new login (Singleton).
91
+ Login runs automatically when the last token expires.
92
+ :param base_url: The URL of your EscoAPI implementation. Include the protocol without slash at the end.
93
+ :param username: The username of your EscoAPI client.
94
+ :param password: The password of your EscoAPI client.
95
+ :param client_id: Optional. Include if you want to specify a client_id.
96
+ :param version: Optional. The EscoAPI version that you want to use. Default: Version 9.
97
+ """
98
+ self.base_url = f"{base_url}/api/v{version.value}"
99
+ self.username = username
100
+ self.password = password
101
+ self.client_id = client_id
102
+ self.version = version
103
+
104
+ self.__esco_login()
105
+
106
+ def get_posiciones(
107
+ self,
108
+ cuenta: str,
109
+ por_concertacion: bool = True,
110
+ es_consolidado: bool = False,
111
+ incluir_monedas: bool = True,
112
+ incluir_titulos: bool = False,
113
+ incluir_opciones: bool = False,
114
+ incluir_futuros: bool = False,
115
+ incluir_fondos: bool = False,
116
+ solo_saldos_iniciales: bool = True
117
+ ):
118
+ """
119
+ Esta consulta devuelve las tenencias de instrumentos de una cuenta o una lista de cuentas a una fecha
120
+ indicada y discrimina vencimientos de 24, 48hs y futuro. Las tenencias no se valúan generando una
121
+ respuesta mas rapida de la consulta.
122
+ :param cuenta: Cuenta comitente a consultar.
123
+ :param por_concertacion: Indica si las tenencias se buscan por Fecha de Concertación o no.
124
+ :param es_consolidado: Indica si se muestran todas las cuentas del usuario consolidadas o solo la cuenta seleccionada
125
+ :param incluir_monedas: Indica si se incluyen tenencias de Monedas
126
+ :param incluir_titulos: Indica si se incluyen tenencias de Titulos
127
+ :param incluir_opciones: Indica si se incluyen tenencias de Opciones
128
+ :param incluir_futuros: Indica si se incluyen tenencias de Futuros
129
+ :param incluir_fondos: Indica si se incluyen tenencias de Fondos
130
+ :param solo_saldos_iniciales: Indica si solo se muestran saldos al inicio del día o se impactan movimientos realizados en en el dia
131
+ """
132
+ req_body = {
133
+ "cuentas": cuenta,
134
+ "porConcertacion": por_concertacion,
135
+ "esConsolidado": es_consolidado,
136
+ "incluirMonedas": incluir_monedas,
137
+ "incluirTitulos": incluir_titulos,
138
+ "incluirOpciones": incluir_opciones,
139
+ "incluirFuturos": incluir_futuros,
140
+ "incluirFondos": incluir_fondos,
141
+ "soloSaldosIniciales": solo_saldos_iniciales
142
+ }
143
+ self.__pre_connection()
144
+ return self.__make_request(
145
+ request_endpoint="/get-posiciones",
146
+ request_body=req_body,
147
+ request_method=HTTPMethod.POST
148
+ )
149
+
150
+ def get_disponible_mon(
151
+ self,
152
+ cuenta: str,
153
+ fecha_disponible: datetime = datetime.now(),
154
+ moneda: str = "ARS",
155
+ dias_rescates_pendientes: int = 0,
156
+ dias_suscripciones_pendientes: int = 0,
157
+ plazo: int = 0,
158
+ incluye_creditos: bool = True,
159
+ fecha_colocacion_hasta: datetime = datetime.now(),
160
+ es_bloqueado_bcra: bool = False
161
+ ):
162
+ """
163
+ Esta consulta informa el disponible de moneda para una cuenta comitente a una fecha determinada.
164
+ La respuesta discrimina cómo se compone el saldo disponible.
165
+
166
+ :param cuenta: Código de Comitente
167
+ :param fecha_disponible: Fecha en que se pide la consulta
168
+ :param moneda: Código ISO de la moneda
169
+ :param dias_rescates_pendientes: Cantidad de días de antiguedad máximo para considerar Rescates pendientes de liquidación
170
+ :param dias_suscripciones_pendientes: Cantidad de días de antiguedad máximo para considerar Suscripciones pendientes de liquidación.
171
+ :param plazo: Plazo de liquidación del movimiento que se está cargando. Se suma al campo Fecha el plazo en días hábiles para calcular la fecha a la que se debe mostrar el disponible.
172
+ :param incluye_creditos: Indica si se deben considerar en el disponible los créditos para operar asignados en Back Office.
173
+ :param fecha_colocacion_hasta: Se usa en licitaciones, es la fecha de liquidación del proceso de licitación.
174
+ :param es_bloqueado_bcra: Indica si se discriminan los USD que no se pueden utilizar para compras según BCRA 7340
175
+ """
176
+ req_body = {
177
+ "cuenta": cuenta,
178
+ "fechaDisponible": fecha_disponible.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
179
+ "moneda": moneda,
180
+ "diasRescatesPendientes": dias_rescates_pendientes,
181
+ "diasSuscripcionesPendientes": dias_suscripciones_pendientes,
182
+ "plazo": plazo,
183
+ "incluyeCreditos": incluye_creditos,
184
+ "fechaColocacionHasta": fecha_colocacion_hasta.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
185
+ "esBloqueadoBcra": es_bloqueado_bcra
186
+ }
187
+ self.__pre_connection()
188
+ return self.__make_request(
189
+ request_endpoint="/get-disponible-mon",
190
+ request_body=req_body,
191
+ request_method=HTTPMethod.POST
192
+ )
193
+
194
+ def get_tenencia_val(
195
+ self,
196
+ cuenta: str,
197
+ fecha: datetime = datetime.now(),
198
+ por_concertacion: bool = True,
199
+ es_consolidado: bool = False,
200
+ agrupar_por_moneda: bool = True,
201
+ moneda_valuacion: str = "ARS",
202
+ incluir_ppp: bool = False,
203
+ incluir_monedas: bool = True,
204
+ incluir_titulos: bool = False,
205
+ incluir_opciones: bool = False,
206
+ incluir_futuros: bool = False,
207
+ incluir_fondos: bool = False,
208
+ valuar_posicion: bool = True,
209
+ utiliza_cotizaciones_online: bool = True
210
+ ):
211
+ """
212
+ Esta consulta devuelve la tenencia valorizada de una cuenta a una determinada fecha.
213
+ :param cuenta: Código de Comitente
214
+ :param fecha: Fecha a la que se consultan las tenencias
215
+ :param por_concertacion: Indica si las tenencias se buscan por Fecha de Concertación o no.
216
+ :param es_consolidado: Indica si se muestran todas las cuentas del usuario consolidadas o solo la cuenta seleccionada.
217
+ :param agrupar_por_moneda: Indica si agrupa los instrumentos por moneda de emisión.
218
+ :param moneda_valuacion: Indica la moneda que se utiliza para valuar todos los instrumentos.
219
+ :param incluir_ppp: Indica si se incluye PPP
220
+ :param incluir_monedas: Indica si se incluyen tenencias de Monedas
221
+ :param incluir_titulos: Indica si se incluyen tenencias de Titulos
222
+ :param incluir_opciones: Indica si se incluyen tenencias de Opciones
223
+ :param incluir_futuros: Indica si se incluyen tenencias de Futuros
224
+ :param incluir_fondos: Indica si se incluyen tenencias de Fondos
225
+ :param valuar_posicion: Indica si se debe valuar la posición o no
226
+ :param utiliza_cotizaciones_online: Indica si utiliza cotizaciones online o busca directamente cotizaciones de VBolsa
227
+ """
228
+ req_body = {
229
+ "cuentas": cuenta,
230
+ "fecha": fecha.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
231
+ "porConcertacion": por_concertacion,
232
+ "esConsolidado": es_consolidado,
233
+ "agruparPorMoneda": agrupar_por_moneda,
234
+ "monedaValuacion": moneda_valuacion,
235
+ "incluirPPP": incluir_ppp,
236
+ "incluirMonedas": incluir_monedas,
237
+ "incluirTitulos": incluir_titulos,
238
+ "incluirOpciones": incluir_opciones,
239
+ "incluirFuturos": incluir_futuros,
240
+ "incluirFondos": incluir_fondos,
241
+ "valuarPosicion": valuar_posicion,
242
+ "utilizaCotizacionesOnLine": utiliza_cotizaciones_online
243
+ }
244
+ self.__pre_connection()
245
+ return self.__make_request(
246
+ request_endpoint="/get-tenenciaval",
247
+ request_body=req_body,
248
+ request_method=HTTPMethod.POST
249
+ )
250
+
251
+ def get_tenencia_val_vencimientos(
252
+ self,
253
+ cuenta: str,
254
+ fecha: datetime = datetime.now(),
255
+ incluir_ppp: bool = True
256
+ ):
257
+ """
258
+ Esta consulta devuelve la valuación de una cuenta a una determinada fecha (por liquidación) y los
259
+ vencimientos posteriores a esa fecha.
260
+ :param cuenta: Código de Comitente
261
+ :param fecha: Fecha a la que se deben recuperar los movimientos que conforman los saldos. En esta consulta los movimientos se recuperan siempre por fecha de liquidación.
262
+ :param incluir_ppp: Indica si se incluye ppp en la consulta. PPP se genera en un proceso de Vbolsa.
263
+ """
264
+ req_body = {
265
+ "cuentas": cuenta,
266
+ "fecha": fecha.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
267
+ "incluirPPP": incluir_ppp
268
+ }
269
+ self.__pre_connection()
270
+ return self.__make_request(
271
+ request_endpoint="/get-tenenciaval-vencimientos",
272
+ request_body=req_body,
273
+ request_method=HTTPMethod.POST
274
+ )
275
+
276
+ def get_rendimiento_cartera(
277
+ self,
278
+ cuenta: str,
279
+ fecha_desde: datetime = datetime.now() - timedelta(days=15),
280
+ fecha_hasta: datetime = datetime.now(),
281
+ por_concertacion: bool = True
282
+ ):
283
+ """
284
+
285
+ :param cuenta: Número de Cuenta Comitente
286
+ :param fecha_desde: Fecha inicial del período de Rendimientos consultado.
287
+ :param fecha_hasta: Fecha final del período de Rendimientos consultado.
288
+ :param por_concertacion: Indica si saldos y movimientos involucrados en esta consulta se buscan por Fecha de Concertación o Liquidación.
289
+ """
290
+ req_body = {
291
+ "cuenta": cuenta,
292
+ "fechaDesde": fecha_desde.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
293
+ "fechaHasta": fecha_hasta.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
294
+ "porConcertacion": por_concertacion
295
+ }
296
+ self.__pre_connection()
297
+ return self.__make_request(
298
+ request_endpoint="/get-rendimiento-cartera",
299
+ request_body=req_body,
300
+ request_method=HTTPMethod.POST
301
+ )
302
+
303
+ def get_instrumentos(
304
+ self,
305
+ cod_tp_especie: int,
306
+ page_number: int = 1,
307
+ page_size: int = 200,
308
+ solo_byma: bool = True
309
+ ):
310
+ """
311
+ Es una consulta de Instrumentos que se pueden operar. Se toman de la tabla que registra todos los
312
+ instrumentos para operar WEB. La respuesta es paginada.
313
+ :param cod_tp_especie: Codigo interno del tipo de especie.
314
+ :param page_number: Número de página a mostrar.
315
+ :param page_size: Cantidad de registros por página.
316
+ :param solo_byma:Indica si solo se recuperan los Instrumentos con Abreviaturas Byma. Por defecto informa solo Byma.
317
+ """
318
+ req_body = {
319
+ "codTpEspecie": cod_tp_especie,
320
+ "soloByMA": solo_byma,
321
+ "paramPagination": {
322
+ "pageNumber": page_number,
323
+ "pageSize": page_size
324
+ }
325
+ }
326
+ self.__pre_connection()
327
+ return self.__make_request(
328
+ request_endpoint="/get-instrumentos-paginada",
329
+ request_body=req_body,
330
+ request_method=HTTPMethod.POST
331
+ )
332
+
333
+ def get_cotizaciones(self, instrumento: str, exact_match: bool = True):
334
+ """
335
+ Es una consulta de cotizaciones de instrumentos, se busca en la información en la tabla de cotizaciones
336
+ online que registra cotizaciones para un mismo instrumento en distintas monedas y plazos
337
+ :param instrumento: Abreviatura o descripción del instrumento. Se puede ingresar total o parcial dependiendo del siguiente parámetro.
338
+ :param exact_match: Este parámetro indica si se debe busca exacto el texto ingresado o no.
339
+ """
340
+ req_body = {
341
+ "instrumento": instrumento,
342
+ "exactMatch": exact_match
343
+ }
344
+ self.__pre_connection()
345
+ return self.__make_request(
346
+ request_endpoint="/get-cotizaciones",
347
+ request_body=req_body,
348
+ request_method=HTTPMethod.POST
349
+ )
350
+
351
+ def get_cotizaciones_fondos(self):
352
+ """
353
+ Es una consulta de cotizaciones y datos de Fondos Comunes de Inversión. Se informan las cotizaciones
354
+ cargadas en VBolsa.
355
+ :return:
356
+ """
357
+ self.__pre_connection()
358
+ return self.__make_request(
359
+ request_endpoint="/get-cotizaciones-fondos",
360
+ request_body={},
361
+ request_method=HTTPMethod.POST
362
+ )
363
+
364
+ def get_cotizaciones_historicas(
365
+ self,
366
+ instrumento: str,
367
+ fecha_desde: datetime = datetime.now() - timedelta(days=7),
368
+ fecha_hasta: datetime = datetime.now()
369
+ ):
370
+ """
371
+ Es una consulta de cotizaciones históricas de un instrumento. Se informan las cotizaciones cargadas en VBolsa.
372
+ :param instrumento: Abreviatura del instrumento, se puede ingresar cualquier abreviatura vinculada. Se recupera la cotización de cierre que está cargada en VBolsa, la abreviatura se usa para ubicar el instrumento.
373
+ :param fecha_desde: Fecha inicial de la consulta.
374
+ :param fecha_hasta: Fecha final de la consulta.
375
+ """
376
+ req_body = {
377
+ "instrumento": instrumento,
378
+ "fechaDesde": fecha_desde.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
379
+ "fechaHasta": fecha_hasta.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
380
+ }
381
+ self.__pre_connection()
382
+ return self.__make_request(
383
+ request_endpoint="/get-cotizaciones-historicas",
384
+ request_body=req_body,
385
+ request_method=HTTPMethod.POST
386
+ )
387
+
388
+ def get_cotizaciones_historicas_fci(
389
+ self,
390
+ instrumento: str,
391
+ fecha_desde: datetime = datetime.now() - timedelta(days=7),
392
+ fecha_hasta: datetime = datetime.now()
393
+ ):
394
+ """
395
+ Es una consulta de cotizaciones históricas de un FCI. Se informan las cotizaciones cargadas en VBolsa.
396
+ :param instrumento: Código de Interfaz Bloomberg del Fondo.
397
+ :param fecha_desde: Fecha inicial de la consulta.
398
+ :param fecha_hasta: Fecha final de la consulta.
399
+ """
400
+ req_body = {
401
+ "instrumento": instrumento,
402
+ "fechaDesde": fecha_desde.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
403
+ "fechaHasta": fecha_hasta.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
404
+ }
405
+ self.__pre_connection()
406
+ return self.__make_request(
407
+ request_endpoint="/get-cotizaciones-historicas-fci",
408
+ request_body=req_body,
409
+ request_method=HTTPMethod.POST
410
+ )
411
+
412
+ def get_instrumento(self, abreviatura: str):
413
+ """
414
+ Devuelve los instrumentos filtrados por su abreviatura.
415
+ :param abreviatura: Abreviatura del instrumento, se puede ingresar cualquier abreviatura vinculada.
416
+ """
417
+ req_body = {
418
+ "abreviatura": abreviatura
419
+ }
420
+ self.__pre_connection()
421
+ return self.__make_request(
422
+ request_endpoint="/get-instrumento",
423
+ request_body=req_body,
424
+ request_method=HTTPMethod.POST
425
+ )
426
+
427
+ def get_cotizaciones_cierre_search(self, instrumento: str, mercado: str = "ME"):
428
+ """
429
+ Es una consulta de cotizaciones de cierre de instrumentos
430
+ :param instrumento: Abreviatura del instrumento, se puede ingresar cualquier abreviatura vinculada. Se recupera la cotización de cierre que esta cargada en VBolsa, la abreviatura se usa para ubicar el instrumento.
431
+ :param mercado: Mercado al cual corresponde la abreviatura ingresada. Default: ME (ByMA)
432
+ :return:
433
+ """
434
+ req_body = {
435
+ "instrumento": instrumento,
436
+ "mercado": mercado
437
+ }
438
+ self.__pre_connection()
439
+ return self.__make_request(
440
+ request_endpoint="/get-cotizaciones-cierre-search",
441
+ request_body=req_body,
442
+ request_method=HTTPMethod.POST
443
+ )
444
+
445
+ def get_monedas(self):
446
+ """
447
+ Devuelve la lista de Monedas habilitadas.
448
+ """
449
+ self.__pre_connection()
450
+ return self.__make_request(
451
+ request_endpoint="/get-monedas",
452
+ request_body={},
453
+ request_method=HTTPMethod.GET
454
+ )
455
+
456
+ def get_feriados(self):
457
+ """
458
+ Devuelve la lista de Feriados habilitados.
459
+ """
460
+ self.__pre_connection()
461
+ return self.__make_request(
462
+ request_endpoint="/get-feriados",
463
+ request_body={},
464
+ request_method=HTTPMethod.GET
465
+ )
466
+
467
+ def get_provincias(self):
468
+ """
469
+ Devuelve la lista de Provincias habilitadas.
470
+ """
471
+ self.__pre_connection()
472
+ return self.__make_request(
473
+ request_endpoint="/get-provincias",
474
+ request_body={},
475
+ request_method=HTTPMethod.GET
476
+ )
477
+
478
+ def get_paises(self):
479
+ """
480
+ Devuelve la lista de Paises habilitados.
481
+ """
482
+ self.__pre_connection()
483
+ return self.__make_request(
484
+ request_endpoint="/get-paises",
485
+ request_body={},
486
+ request_method=HTTPMethod.GET
487
+ )
488
+
489
+ def get_tipos_especies(self):
490
+ """
491
+ Devuelve la lista de tipos de especies.
492
+ """
493
+ self.__pre_connection()
494
+ return self.__make_request(
495
+ request_endpoint="/get-tipos-especies",
496
+ request_body={},
497
+ request_method=HTTPMethod.GET
498
+ )
499
+
500
+ def get_tipos_fondos(self):
501
+ """
502
+ Devuelve la lista de tipos de especies.
503
+ """
504
+ self.__pre_connection()
505
+ return self.__make_request(
506
+ request_endpoint="/get-tipos-fondos",
507
+ request_body={},
508
+ request_method=HTTPMethod.GET
509
+ )
510
+
511
+ def get_tipos_riesgo_comitente(self):
512
+ """
513
+ Devuelve la lista de tipos de riesgo de Comitente.
514
+ """
515
+ self.__pre_connection()
516
+ return self.__make_request(
517
+ request_endpoint="/get-tipos-riesgo-comitente",
518
+ request_body={},
519
+ request_method=HTTPMethod.GET
520
+ )
521
+
522
+ def get_detalle_cuenta(self, cuenta: str):
523
+ """
524
+ Esta consulta muestra el detalle de datos de la cuenta
525
+ :param cuenta: Número de Comitente.
526
+ """
527
+ req_body = {
528
+ "cuenta": cuenta,
529
+ "timeStamp": 13128022,
530
+ "paramPagination": {
531
+ "pageNumber": 1,
532
+ "pageSize": 1
533
+ }
534
+ }
535
+ self.__pre_connection()
536
+ return self.__make_request(
537
+ request_endpoint="/get-detalle-cuenta",
538
+ request_body=req_body,
539
+ request_method=HTTPMethod.POST
540
+ )
541
+
542
+ def get_cuentas_por_cuit(self, cuit: str):
543
+ """
544
+ Es una consulta que informa las cuentas comitente que corresponden al CUIT ingresado. El cuit puede
545
+ ser del comitente o de los condóminos.
546
+ :param cuit: Nro de CUIT a buscar. Se deben ingresar solo numeros.
547
+ """
548
+ self.__pre_connection()
549
+ return self.__make_request(
550
+ request_endpoint=f"/get-cuentas-por-cuit?CUIT={cuit}",
551
+ request_body={},
552
+ request_method=HTTPMethod.GET
553
+ )
554
+
555
+ def get_persona(self, num_doc: int, tipo_doc: int = 1):
556
+ """
557
+ Retorna datos de una persona filtrando por tipo y número de documento.
558
+ :param num_doc: Número de documento de la Persona a buscar.
559
+ :param tipo_doc: Código del Tipo de Documento. 1: DNI, 2: Pasaporte, 3: Otros.
560
+ """
561
+ self.__pre_connection()
562
+ return self.__make_request(
563
+ request_endpoint=f"/get-persona?tipoDoc={tipo_doc}&numDoc={num_doc}",
564
+ request_body={},
565
+ request_method=HTTPMethod.GET
566
+ )
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.1
2
+ Name: pyEscoAPI
3
+ Version: 0.0.4
4
+ Summary: Python client for Esco API (Esco bolsa)
5
+ Author-email: Codetria <hola@codetria.com>
6
+ License: MIT License
7
+ Keywords: Esco,API,bolsa,client,market,provider
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests==2.31.0
14
+
15
+ # Python client for Esco API (Esco bolsa)
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ pyEscoAPI/__init__.py
4
+ pyEscoAPI/esco_api.py
5
+ pyEscoAPI.egg-info/PKG-INFO
6
+ pyEscoAPI.egg-info/SOURCES.txt
7
+ pyEscoAPI.egg-info/dependency_links.txt
8
+ pyEscoAPI.egg-info/requires.txt
9
+ pyEscoAPI.egg-info/top_level.txt
10
+ tests/test_client.py
@@ -0,0 +1 @@
1
+ requests==2.31.0
@@ -0,0 +1 @@
1
+ pyEscoAPI
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = 'pyEscoAPI'
7
+ version = "0.0.4"
8
+ license = {text = "MIT License"}
9
+ authors = [
10
+ { name="Codetria", email="hola@codetria.com" },
11
+ ]
12
+ dependencies = [
13
+ "requests==2.31.0"
14
+ ]
15
+ keywords = ["Esco", "API", "bolsa", "client", "market", "provider"]
16
+ description = 'Python client for Esco API (Esco bolsa)'
17
+ readme = "README.md"
18
+ requires-python = ">=3.11"
19
+ classifiers = [
20
+ "Programming Language :: Python :: 3",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Operating System :: OS Independent",
23
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,155 @@
1
+ import os
2
+ from datetime import datetime, timedelta
3
+
4
+ import pytest
5
+
6
+ from pyEscoAPI import EscoAPI
7
+ from pyEscoAPI.esco_api import APIVersion
8
+
9
+
10
+ @pytest.fixture
11
+ def api_client():
12
+ return EscoAPI(
13
+ base_url=os.getenv("base_url"),
14
+ username=os.getenv("user_name"),
15
+ password=os.getenv("password"),
16
+ client_id=os.getenv("client_id"),
17
+ version=APIVersion.VERSION_9
18
+ )
19
+
20
+
21
+ def test_get_posiciones(api_client):
22
+ cuenta = "351008539"
23
+ result = api_client.get_posiciones(cuenta=cuenta)
24
+ assert result[0]["cuenta"] == int(cuenta)
25
+ assert result[0]["abreviatura"] == "ARS"
26
+
27
+
28
+ def test_get_disponible_mon(api_client):
29
+ cuenta = "351008539"
30
+ result = api_client.get_disponible_mon(cuenta=cuenta)
31
+ assert result[0]["orden"] == 0
32
+ assert result[0]["simbolo"] == "ARS"
33
+
34
+
35
+ def test_get_tenencia_val(api_client):
36
+ cuenta = "351008539"
37
+ result = api_client.get_tenencia_val(cuenta=cuenta)
38
+ assert result[0]["grupo"] == "MON"
39
+ assert result[0]["abreviatura"] == "ARS"
40
+
41
+
42
+ def test_get_tenencia_val_vencimientos(api_client):
43
+ cuenta = "351008539"
44
+ result = api_client.get_tenencia_val_vencimientos(cuenta=cuenta)
45
+ assert result[0]["grupo"] == "MON"
46
+ assert result[0]["abreviatura"] == "ARS"
47
+
48
+
49
+ def test_get_rendimiento_cartera(api_client):
50
+ cuenta = "351008539"
51
+ result = api_client.get_rendimiento_cartera(cuenta=cuenta)
52
+ assert "resultados1" in result
53
+ assert "resultados2" in result
54
+
55
+
56
+ def test_get_instrumentos(api_client):
57
+ cod_tp_especie = 2 # Bonos (Titulos Publicos)
58
+ result = api_client.get_instrumentos(cod_tp_especie=cod_tp_especie)
59
+ assert result["data"][0]["tpEspecie"] == "Titulo Publicos"
60
+
61
+
62
+ def test_get_cotizaciones(api_client):
63
+ instrumento = "AL30"
64
+ result = api_client.get_cotizaciones(instrumento=instrumento)
65
+ assert result[0]["abreviatura"] == "AL30"
66
+
67
+
68
+ def test_get_cotizaciones_fondos(api_client):
69
+ result = api_client.get_cotizaciones_fondos()
70
+ assert len(result) > 0
71
+
72
+
73
+ def test_get_cotizaciones_historicas(api_client):
74
+ instrumento = "AL30"
75
+ result = api_client.get_cotizaciones_historicas(
76
+ instrumento=instrumento,
77
+ fecha_desde=datetime.now() - timedelta(days=30)
78
+ )
79
+ assert result[0]["moneda"] == "ARS"
80
+
81
+
82
+ def test_get_cotizaciones_historicas_fci(api_client):
83
+ instrumento = "CPYMESA AR"
84
+ result = api_client.get_cotizaciones_historicas_fci(
85
+ instrumento=instrumento,
86
+ fecha_desde=datetime.now() - timedelta(days=30)
87
+ )
88
+ assert result[0]["moneda"] == "ARS"
89
+
90
+
91
+ def test_get_cotizaciones_cierre_search(api_client):
92
+ instrumento = "AL30"
93
+ result = api_client.get_cotizaciones_cierre_search(
94
+ instrumento=instrumento
95
+ )
96
+ assert result[0]["monedaAbreviatura"] == "ARS"
97
+
98
+
99
+ def test_get_instrumento(api_client):
100
+ instrumento = "COME"
101
+ result = api_client.get_instrumento(abreviatura=instrumento)
102
+ assert result[0]["moneda"] == "ARS"
103
+
104
+
105
+ def test_get_monedas(api_client):
106
+ result = api_client.get_monedas()
107
+ assert result[0]["simbolo"] == "ARS"
108
+
109
+
110
+ def test_get_feriados(api_client):
111
+ result = api_client.get_feriados()
112
+ assert len(result) > 0
113
+
114
+
115
+ def test_get_provincias(api_client):
116
+ result = api_client.get_provincias()
117
+ assert len(result) > 0
118
+
119
+
120
+ def test_get_paises(api_client):
121
+ result = api_client.get_paises()
122
+ assert len(result) > 0
123
+
124
+
125
+ def test_get_tipos_especies(api_client):
126
+ result = api_client.get_tipos_especies()
127
+ assert len(result) > 0
128
+
129
+
130
+ def test_get_tipos_fondos(api_client):
131
+ result = api_client.get_tipos_fondos()
132
+ assert len(result) >= 0 # Returns no result in dev for some reason
133
+
134
+
135
+ def test_get_tipos_riesgo_comitente(api_client):
136
+ result = api_client.get_tipos_riesgo_comitente()
137
+ assert len(result) > 0
138
+
139
+
140
+ def test_get_detalle_cuenta(api_client):
141
+ cuenta = "351008539"
142
+ result = api_client.get_detalle_cuenta(cuenta=cuenta)
143
+ assert result["data"][0]["cuentaDetalle"]["numComitente"] == int(cuenta)
144
+
145
+
146
+ def test_get_cuentas_por_cuit(api_client):
147
+ cuit = "20076387878"
148
+ result = api_client.get_cuentas_por_cuit(cuit)
149
+ assert len(result) > 0
150
+
151
+
152
+ def test_get_persona(api_client):
153
+ dni = 7638787
154
+ result = api_client.get_persona(num_doc=dni)
155
+ assert int(result["numDoc"]) == dni