es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Realización de solicitudes de API asíncronas concurrentes en Python.

Tengo este código:

import requests
import json
import psycopg2
import time
import csv

epics = []
with open('cmd.csv', newline='') as inputfile:
    for row in csv.reader(inputfile):
        epics.append(row[0])

# print(epics)

for epic in epics:
    url = 'https://demo-api.ig.com/gateway/deal/positions/otc'
    params = {
        "epic": epic,
        "expiry": "DFB",
        "direction": "BUY",
        "size": "1",
        "orderType": "MARKET",
        # "timeInForce":'null',
        # "level":'null',
        "guaranteedStop": "false",
        # "stopLevel": 'null',
        # "stopDistance":'null',
        # "trailingStop":'null',
        # "trailingStopIncrement":'null',
        "forceOpen": "true",
        # "limitLevel": 'null',
        # "limitDistance":'null',
        # "quoteId":'null',
        "currencyCode": "GBP"
    }

    # Envío de la solicitud
    time.sleep(1.5)
    resp = requests.post(url, headers=headers, json=params)
    print(url)
    result = resp.json()
    print(result)

epics es simplemente una lista csv de valores que el bucle itera y envía una solicitud “post” para cada epic. Sin embargo, como estoy utilizando requests, tarda demasiado tiempo en iterar a través de la lista de epics. Me gustaría enviar 100 solicitudes “post” concurrentes por segundo, ya que este es el nivel de servicio acordado por el sitio web. Cada solicitud debe ser para un epic único.

¿Podría alguien brindar amablemente orientación sobre cómo hacer esto?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para enviar múltiples solicitudes concurrentes en Python, se puede utilizar la biblioteca multiprocessing para crear procesos separados para cada solicitud. Aquí hay un ejemplo de cómo se puede modificar el código existente para enviar 100 solicitudes por segundo:

    import requests
    import json
    import multiprocessing
    import csv
    
    epics = []
    with open('cmd.csv', newline='') as inputfile:
        for row in csv.reader(inputfile):
            epics.append(row[0])
    
    def send_request(epic):
        url = 'https://demo-api.ig.com/gateway/deal/positions/otc'
        params = {
            "epic": epic,
            "expiry": "DFB",
            "direction": "BUY",
            "size": "1",
            "orderType": "MARKET",
            "guaranteedStop": "false",
            "forceOpen": "true",
            "currencyCode": "GBP"
        }
        resp = requests.post(url, headers=headers, json=params)
        result = resp.json()
        print(result)
    
    if __name__ == '__main__':
        pool = multiprocessing.Pool(processes=100)
        start_time = time.time()
        for epic in epics:
            pool.apply_async(send_request, args=(epic,))
            time.sleep(0.01) # Sleep for 10 milliseconds between requests
        pool.close()
        pool.join()
        end_time = time.time()
        print(f"Tiempo requerido: {end_time - start_time:.2f} segundos")
    

    En este código modificado, definimos una función send_request que envía una sola solicitud con el epic dado. Luego, utilizamos la clase multiprocessing.Pool para crear un grupo de 100 procesos trabajadores. Para cada epic en la lista epics, usamos el método pool.apply_async para enviar de manera asíncrona una solicitud en un proceso de trabajo separado. También agregamos una demora de 10 milisegundos entre cada solicitud para limitar la tasa de solicitudes a 100 por segundo.

    Una vez que se hayan enviado todas las solicitudes, cerramos el grupo y esperamos a que todos los procesos trabajadores finalicen con los métodos pool.close() y pool.join(). Finalmente, imprimimos el tiempo total requerido para enviar todas las solicitudes.

    Tenga en cuenta que es posible que deba modificar el código para incluir la variable headers y cualquier otro detalle de autenticación necesario para la API.

Comments are closed.