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¶m2=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