Bug Report: Timeout parameters are accepted but not used
Summary
The RESTClient constructor accepts connect_timeout and read_timeout parameters, creates a urllib3.Timeout object, but never passes it to the PoolManager or uses it in HTTP requests. This means requests can hang indefinitely.
Environment
- Package: massive==2.0.3
- Python: 3.13
- OS: macOS
Steps to Reproduce
from massive import RESTClient
# Create client with explicit timeouts
client = RESTClient(
api_key="your_api_key",
connect_timeout=5.0,
read_timeout=5.0
)
# Check if timeout is actually used
print("Timeout object:", client.timeout)
print("PoolManager kwargs:", client.client.connection_pool_kw)
Expected Behavior
The timeout should be passed to either:
urllib3.PoolManager(timeout=...) at construction, or
self.client.request(..., timeout=self.timeout) on each request
Actual Behavior
Timeout object: Timeout(connect=5.0, read=5.0, total=None)
PoolManager kwargs: {'ca_certs': '...', 'cert_reqs': 'CERT_REQUIRED', 'retries': Retry(...)}
The timeout object is created but never used. The connection_pool_kw does not contain a timeout, and the _get method in base.py does not pass timeout to requests.
Root Cause
In massive/rest/base.py:
# Line 81: Timeout is created
self.timeout = urllib3.Timeout(connect=connect_timeout, read=read_timeout)
# Line 73-79: PoolManager is created WITHOUT timeout
self.client = urllib3.PoolManager(
num_pools=num_pools,
headers=self.headers,
ca_certs=certifi.where(),
cert_reqs="CERT_REQUIRED",
retries=retry_strategy,
# timeout=self.timeout ← MISSING
)
# Line 119-124: Request is made WITHOUT timeout
resp = self.client.request(
"GET",
self.BASE + path,
fields=params,
headers=headers,
# timeout=self.timeout ← MISSING
)
Suggested Fix
Either pass timeout to PoolManager (applies to all requests):
self.client = urllib3.PoolManager(
num_pools=num_pools,
headers=self.headers,
ca_certs=certifi.where(),
cert_reqs="CERT_REQUIRED",
retries=retry_strategy,
timeout=self.timeout, # Add this
)
Or pass timeout on each request (more flexible):
resp = self.client.request(
"GET",
self.BASE + path,
fields=params,
headers=headers,
timeout=self.timeout, # Add this
)
Impact
Without a working timeout, any network issue (slow server, DNS hang, etc.) can cause the SDK to hang indefinitely, blocking the calling thread.
Workaround
For async code, wrap SDK calls with asyncio.timeout():
import asyncio
async def get_data_with_timeout():
async with asyncio.timeout(15):
return await asyncio.to_thread(client.get_snapshot_ticker, ...)
Bug Report: Timeout parameters are accepted but not used
Summary
The
RESTClientconstructor acceptsconnect_timeoutandread_timeoutparameters, creates aurllib3.Timeoutobject, but never passes it to thePoolManageror uses it in HTTP requests. This means requests can hang indefinitely.Environment
Steps to Reproduce
Expected Behavior
The timeout should be passed to either:
urllib3.PoolManager(timeout=...)at construction, orself.client.request(..., timeout=self.timeout)on each requestActual Behavior
The timeout object is created but never used. The
connection_pool_kwdoes not contain a timeout, and the_getmethod inbase.pydoes not pass timeout to requests.Root Cause
In
massive/rest/base.py:Suggested Fix
Either pass timeout to PoolManager (applies to all requests):
Or pass timeout on each request (more flexible):
Impact
Without a working timeout, any network issue (slow server, DNS hang, etc.) can cause the SDK to hang indefinitely, blocking the calling thread.
Workaround
For async code, wrap SDK calls with
asyncio.timeout():