or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcontent-processing.mdcookies.mdhttp-client.mdhttp-requests.mdindex.mdtesting.md

authentication.mddocs/

0

# Authentication Support

1

2

HTTP authentication mechanisms including Basic Auth with integration into the Agent architecture for secure credential handling. treq provides both high-level parameter support and low-level agent wrapping for authentication.

3

4

## Capabilities

5

6

### Basic Authentication Agent

7

8

Creates an agent wrapper that automatically adds HTTP Basic Authentication headers to all requests.

9

10

```python { .api }

11

def add_basic_auth(agent, username, password):

12

"""

13

Add HTTP Basic Authentication to an agent.

14

15

Creates a wrapper agent that automatically includes Basic Auth

16

headers for all requests made through it.

17

18

Parameters:

19

- agent: IAgent - Twisted agent to wrap

20

- username: str or bytes - Username for authentication

21

- password: str or bytes - Password for authentication

22

23

Returns:

24

IAgent - Wrapped agent with Basic Auth support

25

"""

26

```

27

28

### Generic Authentication Configuration

29

30

Adds authentication to an agent based on configuration tuple, currently supporting HTTP Basic Auth.

31

32

```python { .api }

33

def add_auth(agent, auth_config):

34

"""

35

Add authentication to an agent based on configuration.

36

37

Currently supports HTTP Basic Authentication via tuple format.

38

39

Parameters:

40

- agent: IAgent - Twisted agent to wrap

41

- auth_config: tuple - Authentication configuration (username, password)

42

43

Returns:

44

IAgent - Agent with authentication configured

45

46

Raises:

47

UnknownAuthConfig - If auth_config format is not recognized

48

"""

49

```

50

51

### Request Header Setting Agent

52

53

Internal utility class for wrapping agents to set custom headers on all requests.

54

55

```python { .api }

56

class _RequestHeaderSetterAgent:

57

"""

58

Wrap an agent to set request headers on all requests.

59

60

This is used internally by authentication functions but can be

61

used directly for custom header requirements.

62

"""

63

64

def __init__(self, agent, headers):

65

"""

66

Initialize header-setting agent wrapper.

67

68

Parameters:

69

- agent: IAgent - Agent to wrap

70

- headers: Headers - Headers to add to each request

71

"""

72

73

def request(self, method, uri, headers=None, bodyProducer=None):

74

"""

75

Make request with automatic header injection.

76

77

Merges the configured headers with any headers provided

78

in the request, with request headers taking precedence.

79

"""

80

```

81

82

### Authentication Exceptions

83

84

```python { .api }

85

class UnknownAuthConfig(Exception):

86

"""

87

Exception raised when authentication config cannot be interpreted.

88

89

Raised by add_auth() when the auth_config parameter is not

90

in a recognized format.

91

"""

92

```

93

94

## Usage Examples

95

96

### Basic Authentication with Request Parameters

97

98

The simplest way to use authentication is through the `auth` parameter:

99

100

```python

101

import treq

102

from twisted.internet import defer

103

104

@defer.inlineCallbacks

105

def basic_auth_requests():

106

# Using auth parameter (recommended for simple cases)

107

response = yield treq.get(

108

'https://httpbin.org/basic-auth/user/pass',

109

auth=('user', 'pass')

110

)

111

112

# Verify authentication worked

113

data = yield response.json()

114

print("Authenticated user:", data['user'])

115

116

# POST with authentication

117

response = yield treq.post(

118

'https://httpbin.org/basic-auth/api/key',

119

auth=('api', 'key'),

120

json={'data': 'sensitive information'}

121

)

122

```

123

124

### Custom Agent with Authentication

125

126

For applications needing persistent authentication across many requests:

127

128

```python

129

from twisted.web.client import Agent

130

from treq.auth import add_basic_auth

131

from treq.client import HTTPClient

132

from twisted.internet import reactor

133

134

@defer.inlineCallbacks

135

def persistent_auth():

136

# Create base agent

137

base_agent = Agent(reactor)

138

139

# Wrap with authentication

140

auth_agent = add_basic_auth(base_agent, 'username', 'password')

141

142

# Create client using authenticated agent

143

client = HTTPClient(auth_agent)

144

145

# All requests through this client will be authenticated

146

response1 = yield client.get('https://api.example.com/profile')

147

response2 = yield client.post('https://api.example.com/data', json={'key': 'value'})

148

response3 = yield client.put('https://api.example.com/resource/123')

149

150

# No need to specify auth for each request

151

```

152

153

### Multiple Authentication Schemes

154

155

Handling different authentication requirements:

156

157

```python

158

from treq.auth import add_basic_auth, add_auth

159

from twisted.web.client import Agent

160

161

@defer.inlineCallbacks

162

def multiple_auth_schemes():

163

base_agent = Agent(reactor)

164

165

# API with Basic Auth

166

api_agent = add_basic_auth(base_agent, 'api_user', 'api_key')

167

api_client = HTTPClient(api_agent)

168

169

# Admin interface with different credentials

170

admin_agent = add_auth(base_agent, ('admin', 'admin_password'))

171

admin_client = HTTPClient(admin_agent)

172

173

# Use appropriate client for each service

174

api_data = yield api_client.get('https://api.service.com/data')

175

admin_data = yield admin_client.get('https://admin.service.com/users')

176

```

177

178

### Custom Header Authentication

179

180

For APIs using custom authentication headers:

181

182

```python

183

from treq.auth import _RequestHeaderSetterAgent

184

from twisted.web.http_headers import Headers

185

from twisted.web.client import Agent

186

187

@defer.inlineCallbacks

188

def custom_header_auth():

189

# Create headers for API key authentication

190

auth_headers = Headers({

191

'Authorization': ['Bearer your-api-token'],

192

'X-API-Key': ['your-api-key']

193

})

194

195

# Wrap agent with custom headers

196

base_agent = Agent(reactor)

197

auth_agent = _RequestHeaderSetterAgent(base_agent, auth_headers)

198

199

# Create client

200

client = HTTPClient(auth_agent)

201

202

# All requests include authentication headers

203

response = yield client.get('https://api.example.com/protected-resource')

204

```

205

206

### Error Handling

207

208

```python

209

from treq.auth import UnknownAuthConfig

210

211

@defer.inlineCallbacks

212

def handle_auth_errors():

213

try:

214

# This will raise UnknownAuthConfig

215

agent = add_auth(base_agent, "invalid-config")

216

except UnknownAuthConfig as e:

217

print(f"Authentication configuration error: {e}")

218

# Fall back to no authentication or different config

219

agent = base_agent

220

221

# Handle authentication failures

222

try:

223

response = yield treq.get(

224

'https://httpbin.org/basic-auth/user/pass',

225

auth=('wrong', 'credentials')

226

)

227

if response.code == 401:

228

print("Authentication failed - invalid credentials")

229

elif response.code == 403:

230

print("Authentication succeeded but access forbidden")

231

except Exception as e:

232

print(f"Request failed: {e}")

233

```

234

235

### Session-Based Authentication

236

237

Combining authentication with cookie-based sessions:

238

239

```python

240

from http.cookiejar import CookieJar

241

242

@defer.inlineCallbacks

243

def session_auth():

244

# Client with cookie support

245

cookiejar = CookieJar()

246

client = HTTPClient(Agent(reactor), cookiejar=cookiejar)

247

248

# Login with credentials

249

login_response = yield client.post(

250

'https://example.com/login',

251

data={'username': 'user', 'password': 'pass'}

252

)

253

254

if login_response.code == 200:

255

# Session cookie automatically stored

256

print("Login successful")

257

258

# Subsequent requests use session cookie

259

profile = yield client.get('https://example.com/profile')

260

data = yield profile.json()

261

262

# Logout

263

yield client.post('https://example.com/logout')

264

else:

265

print("Login failed")

266

```

267

268

### Advanced Authentication Patterns

269

270

```python

271

@defer.inlineCallbacks

272

def advanced_auth_patterns():

273

# Token refresh pattern

274

class TokenRefreshAgent:

275

def __init__(self, base_agent, get_token_func):

276

self.base_agent = base_agent

277

self.get_token = get_token_func

278

self.current_token = None

279

280

@defer.inlineCallbacks

281

def request(self, method, uri, headers=None, bodyProducer=None):

282

# Refresh token if needed

283

if not self.current_token:

284

self.current_token = yield self.get_token()

285

286

# Add token to headers

287

if headers is None:

288

headers = Headers()

289

else:

290

headers = headers.copy()

291

292

headers.addRawHeader('Authorization', f'Bearer {self.current_token}')

293

294

response = yield self.base_agent.request(method, uri, headers, bodyProducer)

295

296

# Handle token expiration

297

if response.code == 401:

298

self.current_token = yield self.get_token()

299

headers.setRawHeaders('Authorization', [f'Bearer {self.current_token}'])

300

response = yield self.base_agent.request(method, uri, headers, bodyProducer)

301

302

defer.returnValue(response)

303

```

304

305

## Types

306

307

Authentication-related types:

308

309

```python { .api }

310

# Basic auth configuration

311

AuthConfig = Tuple[Union[str, bytes], Union[str, bytes]]

312

313

# Agent interface

314

from twisted.web.iweb import IAgent

315

316

# Headers type

317

from twisted.web.http_headers import Headers

318

319

# Username/password types

320

Username = Union[str, bytes]

321

Password = Union[str, bytes]

322

```

323

324

## Security Best Practices

325

326

### Credential Handling

327

328

- **Environment variables**: Store credentials in environment variables, not code

329

- **Secure transmission**: Always use HTTPS for authenticated requests

330

- **Password rotation**: Implement credential rotation for long-running applications

331

- **Least privilege**: Use credentials with minimal required permissions

332

333

### SSL/TLS Configuration

334

335

- **Certificate validation**: Ensure proper SSL certificate validation

336

- **Strong ciphers**: Configure agents to use strong cipher suites

337

- **TLS versions**: Use modern TLS versions (1.2+)

338

- **HSTS**: Respect HTTP Strict Transport Security headers

339

340

### Error Handling

341

342

- **Status codes**: Check response status codes for authentication failures

343

- **Retry logic**: Implement appropriate retry logic for temporary failures

344

- **Logging**: Log authentication events while protecting sensitive data

345

- **Rate limiting**: Respect API rate limits to avoid account lockouts

346

347

### Token Management

348

349

- **Expiration**: Handle token expiration gracefully

350

- **Refresh**: Implement automatic token refresh when possible

351

- **Storage**: Securely store tokens (avoid plain text files)

352

- **Scope**: Use appropriately scoped tokens for different operations