or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-extensions.mdhttp-client.mdindex.mdoauth-core.mdserver-verification.md

http-client.mddocs/

0

# HTTP Client

1

2

Automated OAuth-enabled HTTP client that extends httplib2 to handle request signing transparently. The Client class provides a simple interface for making OAuth-authenticated HTTP requests without manual signature handling.

3

4

## Capabilities

5

6

### OAuth HTTP Client

7

8

The Client class wraps httplib2.Http and automatically signs all requests using OAuth credentials. It supports all HTTP methods and handles both form-encoded and regular request bodies.

9

10

```python { .api }

11

class Client:

12

def __init__(self, consumer, token=None, **kwargs):

13

"""

14

Initialize OAuth HTTP client.

15

16

Args:

17

consumer: Consumer credentials (required)

18

token: Token credentials (optional, for authenticated requests)

19

**kwargs: Additional arguments passed to httplib2.Http

20

21

Raises:

22

ValueError: If consumer is invalid or token is invalid

23

"""

24

25

def set_signature_method(self, method):

26

"""

27

Set signature method for request signing.

28

29

Args:

30

method: SignatureMethod instance

31

32

Raises:

33

ValueError: If signature method is invalid

34

"""

35

36

def request(self, uri: str, method: str = "GET", body: bytes = b'', headers: dict = None, redirections: int = 5, connection_type=None) -> tuple:

37

"""

38

Make OAuth-signed HTTP request.

39

40

Args:

41

uri (str): Request URI

42

method (str): HTTP method (GET, POST, PUT, DELETE, etc.)

43

body (bytes): Request body

44

headers (dict): HTTP headers

45

redirections (int): Maximum number of redirects to follow

46

connection_type: Connection type for httplib2

47

48

Returns:

49

tuple: (response, content) where response contains status and headers,

50

content contains response body

51

"""

52

```

53

54

## Usage Examples

55

56

### Basic GET Request

57

58

```python

59

import oauth2

60

61

# Set up credentials

62

consumer = oauth2.Consumer('your_consumer_key', 'your_consumer_secret')

63

token = oauth2.Token('user_token_key', 'user_token_secret')

64

65

# Create client

66

client = oauth2.Client(consumer, token)

67

68

# Make authenticated GET request

69

response, content = client.request('https://api.example.com/user/profile')

70

71

print(f"Status: {response.status}")

72

print(f"Content: {content.decode('utf-8')}")

73

```

74

75

### POST Request with Form Data

76

77

```python

78

import oauth2

79

80

consumer = oauth2.Consumer('consumer_key', 'consumer_secret')

81

token = oauth2.Token('token_key', 'token_secret')

82

client = oauth2.Client(consumer, token)

83

84

# Form data

85

form_data = 'name=John&email=john@example.com'

86

headers = {'Content-Type': 'application/x-www-form-urlencoded'}

87

88

# Make POST request

89

response, content = client.request(

90

uri='https://api.example.com/users',

91

method='POST',

92

body=form_data.encode('utf-8'),

93

headers=headers

94

)

95

96

print(f"Response: {response.status}")

97

print(f"Location: {response.get('location', 'N/A')}")

98

```

99

100

### JSON POST Request

101

102

```python

103

import oauth2

104

import json

105

106

consumer = oauth2.Consumer('consumer_key', 'consumer_secret')

107

token = oauth2.Token('token_key', 'token_secret')

108

client = oauth2.Client(consumer, token)

109

110

# JSON data

111

data = {'name': 'John Doe', 'email': 'john@example.com'}

112

json_body = json.dumps(data).encode('utf-8')

113

headers = {'Content-Type': 'application/json'}

114

115

# Make JSON POST request

116

response, content = client.request(

117

uri='https://api.example.com/users',

118

method='POST',

119

body=json_body,

120

headers=headers

121

)

122

123

if response.status == 201:

124

result = json.loads(content.decode('utf-8'))

125

print(f"Created user: {result}")

126

```

127

128

### Request Without Token (2-legged OAuth)

129

130

```python

131

import oauth2

132

133

# Consumer-only authentication (no user token)

134

consumer = oauth2.Consumer('consumer_key', 'consumer_secret')

135

client = oauth2.Client(consumer) # No token provided

136

137

# Make request signed only with consumer credentials

138

response, content = client.request('https://api.example.com/public_data')

139

140

print(f"Public data: {content.decode('utf-8')}")

141

```

142

143

### Custom Signature Method

144

145

```python

146

import oauth2

147

148

consumer = oauth2.Consumer('consumer_key', 'consumer_secret')

149

token = oauth2.Token('token_key', 'token_secret')

150

client = oauth2.Client(consumer, token)

151

152

# Use PLAINTEXT signature method instead of default HMAC-SHA1

153

plaintext_method = oauth2.SignatureMethod_PLAINTEXT()

154

client.set_signature_method(plaintext_method)

155

156

response, content = client.request('https://api.example.com/data')

157

```

158

159

### Error Handling

160

161

```python

162

import oauth2

163

import httplib2

164

165

consumer = oauth2.Consumer('consumer_key', 'consumer_secret')

166

token = oauth2.Token('token_key', 'token_secret')

167

client = oauth2.Client(consumer, token)

168

169

try:

170

response, content = client.request('https://api.example.com/protected')

171

172

if response.status == 401:

173

print("Authentication failed - check credentials")

174

elif response.status == 403:

175

print("Access forbidden - insufficient permissions")

176

elif response.status >= 400:

177

print(f"Client error: {response.status}")

178

elif response.status >= 500:

179

print(f"Server error: {response.status}")

180

else:

181

print(f"Success: {content.decode('utf-8')}")

182

183

except httplib2.HttpLib2Error as e:

184

print(f"HTTP error: {e}")

185

except oauth2.Error as e:

186

print(f"OAuth error: {e}")

187

```

188

189

### Advanced Configuration

190

191

```python

192

import oauth2

193

import httplib2

194

195

# Configure httplib2 options

196

consumer = oauth2.Consumer('consumer_key', 'consumer_secret')

197

token = oauth2.Token('token_key', 'token_secret')

198

199

# Pass httplib2 configuration

200

client = oauth2.Client(

201

consumer,

202

token,

203

timeout=30,

204

disable_ssl_certificate_validation=False,

205

ca_certs='/path/to/cacerts.txt'

206

)

207

208

# Make request with custom headers and redirects

209

headers = {

210

'User-Agent': 'MyApp/1.0',

211

'Accept': 'application/json'

212

}

213

214

response, content = client.request(

215

uri='https://api.example.com/data',

216

method='GET',

217

headers=headers,

218

redirections=3 # Limit redirects

219

)

220

```

221

222

## Integration Notes

223

224

### Working with Different Content Types

225

226

The Client automatically detects form-encoded content and handles parameter extraction for signing:

227

228

```python

229

# Form data is automatically parsed for OAuth signing

230

form_body = 'param1=value1&param2=value2'

231

headers = {'Content-Type': 'application/x-www-form-urlencoded'}

232

233

# Client extracts form parameters for signature base string

234

response, content = client.request(

235

uri='https://api.example.com/endpoint',

236

method='POST',

237

body=form_body.encode('utf-8'),

238

headers=headers

239

)

240

```

241

242

### Request Signing Process

243

244

The Client automatically:

245

1. Extracts parameters from form-encoded bodies

246

2. Adds OAuth parameters (timestamp, nonce, signature method)

247

3. Calculates signature base string

248

4. Generates signature using configured method

249

5. Adds Authorization header or modifies request URL/body as appropriate

250

251

### Compatibility

252

253

The Client extends httplib2.Http, so it supports all httplib2 features including:

254

- SSL certificate validation

255

- HTTP authentication

256

- Proxy support

257

- Connection pooling

258

- Custom socket options