erdewit / ib_insync

Python sync/async framework for Interactive Brokers API
BSD 2-Clause "Simplified" License
2.8k stars 743 forks source link

FastAPI + ib_insync #557

Closed elyssial closed 1 year ago

elyssial commented 1 year ago

I am trying to make fastapi work concurrently with ib insync. The first request is processed fine, but following requests are hanging and get timed out. I assume because something is wrong with the code regarding connections or events.

@app.get("/get_pnl")
async def get_pnl(account: str):
    ib = IB()
    with await ib.connectAsync('localhost', 4001, clientId=randrange(5, 1000)):
        summary = ib.reqPnL(account)
        await ib.pnlEvent
        print(summary)
        resp = json.dumps(util.tree(summary))
    return resp

How do I properly implement ib-insync with FastAPI so that requests get processed concurrently?

EDIT: The issue only seems to happen if I am querying multiple accounts simultaneously. If I use the same account ID and call requests concurrently - it works without issues.

erdewit commented 1 year ago

How do I properly implement ib-insync with FastAPI so that requests get processed concurrently?

For one, I would suggest to use a long-lived IB connection instead of connecting per end-point request.

elyssial commented 1 year ago

For one, I would suggest to use a long-lived IB connection instead of connecting per end-point request.

That example I have already tried and it still gives me the same outcome. See the code below:

@app.on_event("startup")
async def startup_tasks():
    global ib
    ib = IB()
    await ib.connectAsync('localhost', 4001, clientId=randrange(5, 1000))

@app.get("/get_pnl")
async def get_pnl(account: str):
    summary = ib.reqPnL(account)
    await ib.pnlEvent
    resp = json.dumps(util.tree(summary))
    ib.cancelPnL(account)
    return resp
elyssial commented 1 year ago

@erdewit any follow-up? Thank you.