Skip to content

Synchronous HTTP request in DeviceCodeFlow.poll_for_token blocks the event loop #452

Description

@Nievesjyl

Description

DeviceCodeFlow.poll_for_token() is asynchronous, but performs token polling with the synchronous requests.post() API.

While the HTTP request is in progress, control is not returned to the event loop. As a result, unrelated asynchronous tasks running on the same loop cannot make progress until the request completes or times out.

I reproduced this behavior using a local HTTP server that delays its token response for approximately one second.

Observed behavior:

Synchronous HTTP duration: ~1.004 seconds
Expected heartbeat opportunities during the request: 20
Heartbeats executed during the request: 0
External service contacted: No

This means a slow token endpoint can block other asynchronous work sharing the event loop for the duration of each polling request.

Affected Version

Confirmed on:

authsome==0.7.2
Python 3.13.14
src/authsome/auth/flows/device_code.py, DeviceCodeFlow.poll_for_token()

The current main branch also contains the same synchronous requests.post() pattern. The reproduction itself was performed against version 0.7.2.

Reproduction

The attached PoC executes the released DeviceCodeFlow.poll_for_token() implementation against a local HTTP server.

The server deliberately waits one second before returning a successful token response. At the same time, an asynchronous heartbeat task is scheduled to run every 50 ms.

Observed result:

synchronous HTTP interval: 1.004s
expected heartbeat opportunities: 20
heartbeats during requests.post: 0
event loop starved: yes

The heartbeat does not execute while requests.post() is blocked and resumes only after the synchronous request returns.

The reproduction uses only a local loopback HTTP server and does not contact any external service.

Expected behavior

Network I/O performed by an asynchronous authentication flow should not block the event loop.

The token request could use an asynchronous HTTP client, or the synchronous request could be moved off the event-loop thread.

Attachment

run.py

oauth_poll.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions