or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Requests-Futures

1

2

Asynchronous Python HTTP requests using concurrent.futures for non-blocking operations. This library provides a small add-on for the popular requests HTTP library, enabling asynchronous HTTP requests by returning Future objects instead of immediate Response objects.

3

4

## Package Information

5

6

- **Package Name**: requests-futures

7

- **Package Type**: pypi

8

- **Language**: Python

9

- **Installation**: `pip install requests-futures`

10

11

## Core Imports

12

13

```python

14

from requests_futures.sessions import FuturesSession

15

```

16

17

Alternative import patterns:

18

19

```python

20

import requests_futures.sessions

21

# Access as: requests_futures.sessions.FuturesSession

22

23

from requests_futures import sessions

24

# Access as: sessions.FuturesSession

25

```

26

27

Package-level imports:

28

29

```python

30

import requests_futures

31

# Version info: requests_futures.__version__

32

# Package metadata: requests_futures.__title__, requests_futures.__author__

33

```

34

35

## Basic Usage

36

37

```python

38

from requests_futures.sessions import FuturesSession

39

40

# Create a session (default uses ThreadPoolExecutor with 8 workers)

41

session = FuturesSession()

42

43

# Start requests asynchronously

44

future_one = session.get('http://httpbin.org/get')

45

future_two = session.get('http://httpbin.org/get?foo=bar')

46

47

# Wait for results when needed

48

response_one = future_one.result()

49

response_two = future_two.result()

50

51

print(f'Response 1 status: {response_one.status_code}')

52

print(f'Response 2 status: {response_two.status_code}')

53

```

54

55

## Architecture

56

57

requests-futures extends the requests library's Session class to provide asynchronous functionality:

58

59

- **FuturesSession**: Core class that wraps requests.Session and executes HTTP requests asynchronously using concurrent.futures

60

- **Executor Support**: Works with both ThreadPoolExecutor (default) and ProcessPoolExecutor for different concurrency models

61

- **Future Objects**: All HTTP methods return concurrent.futures.Future objects instead of immediate Response objects

62

- **Context Management**: Supports context manager protocol for automatic resource cleanup and request cancellation

63

- **Background Processing**: Integrates with requests' hooks system for processing responses in background threads

64

65

## Capabilities

66

67

### FuturesSession Class

68

69

The main interface for asynchronous HTTP requests, extending requests.Session with concurrent.futures support.

70

71

```python { .api }

72

class FuturesSession(Session):

73

def __init__(

74

self,

75

executor=None,

76

max_workers=8,

77

session=None,

78

adapter_kwargs=None,

79

*args,

80

**kwargs

81

): ...

82

```

83

84

**Parameters:**

85

- `executor` (optional): Custom concurrent.futures executor instance (ThreadPoolExecutor or ProcessPoolExecutor)

86

- `max_workers` (int, default=8): Number of worker threads when no executor is provided

87

- `session` (optional): Existing requests.Session instance to wrap for asynchronous execution

88

- `adapter_kwargs` (dict, optional): Additional keyword arguments for HTTPAdapter configuration

89

- `*args, **kwargs`: Additional arguments passed to parent requests.Session class

90

91

**Usage Examples:**

92

93

Basic session creation:

94

```python

95

session = FuturesSession()

96

```

97

98

Custom thread pool size:

99

```python

100

session = FuturesSession(max_workers=16)

101

```

102

103

Custom executor:

104

```python

105

from concurrent.futures import ThreadPoolExecutor

106

executor = ThreadPoolExecutor(max_workers=10)

107

session = FuturesSession(executor=executor)

108

```

109

110

Using existing requests session:

111

```python

112

import requests

113

my_session = requests.Session()

114

my_session.headers.update({'User-Agent': 'MyApp/1.0'})

115

async_session = FuturesSession(session=my_session)

116

```

117

118

### HTTP Request Methods

119

120

All HTTP methods return concurrent.futures.Future objects that resolve to requests.Response objects.

121

122

```python { .api }

123

def request(self, *args, background_callback=None, **kwargs) -> Future[Response]: ...

124

def get(self, url, **kwargs) -> Future[Response]: ...

125

def post(self, url, data=None, json=None, **kwargs) -> Future[Response]: ...

126

def put(self, url, data=None, **kwargs) -> Future[Response]: ...

127

def patch(self, url, data=None, **kwargs) -> Future[Response]: ...

128

def delete(self, url, **kwargs) -> Future[Response]: ...

129

def head(self, url, **kwargs) -> Future[Response]: ...

130

def options(self, url, **kwargs) -> Future[Response]: ...

131

```

132

133

**Parameters:**

134

- `url` (str): Target URL for the HTTP request

135

- `data` (optional): Request body data for POST/PUT/PATCH requests

136

- `json` (optional): JSON data to send in request body (POST only)

137

- `background_callback` (callable, optional, **DEPRECATED**): Function called with (session, response) in background thread. **Deprecated in favor of hooks system - will be removed in version 1.0**

138

- `**kwargs`: All standard requests library parameters (headers, params, timeout, etc.)

139

140

**Returns:** `concurrent.futures.Future[requests.Response]` - Future object that resolves to a Response

141

142

**Usage Examples:**

143

144

```python

145

# GET request

146

future = session.get('https://api.example.com/users')

147

response = future.result()

148

149

# POST with JSON data

150

future = session.post('https://api.example.com/users', json={'name': 'John'})

151

response = future.result()

152

153

# Multiple concurrent requests

154

futures = [

155

session.get(f'https://api.example.com/users/{i}')

156

for i in range(5)

157

]

158

159

# Wait for all to complete

160

responses = [future.result() for future in futures]

161

```

162

163

### Session Management

164

165

```python { .api }

166

def close(self) -> None: ...

167

```

168

169

Closes the session and shuts down the owned executor. Called automatically when using the session as a context manager.

170

171

**Usage Examples:**

172

173

Manual cleanup:

174

```python

175

session = FuturesSession()

176

# ... use session

177

session.close()

178

```

179

180

Context manager (recommended):

181

```python

182

with FuturesSession() as session:

183

future = session.get('https://api.example.com/data')

184

response = future.result()

185

# Session automatically closed

186

```

187

188

### Background Processing with Hooks

189

190

requests-futures integrates with the requests library's hooks system for background response processing:

191

192

```python

193

def response_hook(resp, *args, **kwargs):

194

# Parse JSON in background thread

195

resp.data = resp.json()

196

197

session = FuturesSession()

198

future = session.get('https://api.example.com/data',

199

hooks={'response': response_hook})

200

response = future.result()

201

# response.data is already parsed

202

```

203

204

Session-level hooks:

205

```python

206

session = FuturesSession()

207

session.hooks['response'] = response_hook

208

209

future = session.get('https://api.example.com/data')

210

response = future.result()

211

# Hook applied to all requests

212

```

213

214

### ProcessPoolExecutor Support

215

216

For CPU-intensive processing or memory isolation, use ProcessPoolExecutor:

217

218

```python

219

from concurrent.futures import ProcessPoolExecutor

220

221

# Python 3.5+ (full support)

222

session = FuturesSession(executor=ProcessPoolExecutor(max_workers=4))

223

224

# Python 3.4 (requires existing session)

225

import requests

226

base_session = requests.Session()

227

session = FuturesSession(

228

executor=ProcessPoolExecutor(max_workers=4),

229

session=base_session

230

)

231

```

232

233

**Requirements:**

234

- Python >= 3.4 required

235

- Python < 3.5 requires providing a `session` parameter

236

- All functions must be picklable (module-level functions only)

237

238

### Working with Multiple Requests

239

240

Using `concurrent.futures.as_completed()` for processing responses as they arrive:

241

242

```python

243

from concurrent.futures import as_completed

244

245

session = FuturesSession()

246

futures = [

247

session.get(f'https://api.example.com/item/{i}')

248

for i in range(10)

249

]

250

251

for future in as_completed(futures):

252

response = future.result()

253

print(f'Status: {response.status_code}, URL: {response.url}')

254

```

255

256

Attaching metadata to futures:

257

```python

258

session = FuturesSession()

259

futures = []

260

261

for i in range(3):

262

future = session.get('https://api.example.com/data')

263

future.request_id = i # Attach custom metadata

264

futures.append(future)

265

266

for future in as_completed(futures):

267

response = future.result()

268

print(f'Request {future.request_id}: {response.status_code}')

269

```

270

271

### Error Handling

272

273

Exceptions are deferred to the `Future.result()` call:

274

275

```python

276

session = FuturesSession()

277

future = session.get('https://invalid-url-example.com')

278

279

try:

280

response = future.result()

281

except requests.exceptions.ConnectionError as e:

282

print(f'Connection failed: {e}')

283

except requests.exceptions.Timeout as e:

284

print(f'Request timed out: {e}')

285

```

286

287

### Compatibility Notes

288

289

**Threading Support:**

290

- Python 2.7+ supported for ThreadPoolExecutor

291

- Default executor uses 8 worker threads

292

- Connection pool automatically sized to match worker count when max_workers > 10

293

294

**Process Pool Support:**

295

- Python >= 3.4 required

296

- Python 3.4: Must provide existing `session` parameter

297

- Python >= 3.5: Full support without restrictions

298

- Functions must be picklable (no lambda functions or instance methods)

299

300

**RuntimeError Exceptions:**

301

- Raised when using ProcessPoolExecutor with non-picklable functions

302

- Error message includes link to documentation for troubleshooting

303

304

## Package Metadata

305

306

The package exposes version and metadata information:

307

308

```python { .api }

309

# Module-level constants (from requests_futures.__init__)

310

__title__ = 'requests-futures'

311

__version__ = '1.0.2'

312

__author__ = 'Ross McFarland'

313

__license__ = 'Apache 2.0'

314

__copyright__ = 'Copyright 2013 Ross McFarland'

315

```

316

317

**Usage:**

318

```python

319

import requests_futures

320

print(f"Version: {requests_futures.__version__}")

321

print(f"Author: {requests_futures.__author__}")

322

```

323

324

## Types

325

326

```python { .api }

327

# From concurrent.futures

328

class Future:

329

def result(self, timeout=None) -> Response: ...

330

def cancel(self) -> bool: ...

331

def cancelled(self) -> bool: ...

332

def done(self) -> bool: ...

333

def add_done_callback(self, fn) -> None: ...

334

335

# From requests

336

class Response:

337

status_code: int

338

headers: dict

339

text: str

340

content: bytes

341

url: str

342

request: Request

343

def json(self, **kwargs) -> dict: ...

344

def raise_for_status(self) -> None: ...

345

346

class Session:

347

headers: dict

348

cookies: dict

349

hooks: dict

350

def request(self, method: str, url: str, **kwargs) -> Response: ...

351

def get(self, url: str, **kwargs) -> Response: ...

352

def post(self, url: str, **kwargs) -> Response: ...

353

# ... other HTTP methods

354

```