0
# HTTP Implementations
1
2
Ready-to-use implementations of the GitHubAPI abstract base class for popular asynchronous HTTP libraries. These implementations handle the low-level HTTP details while providing the same high-level GitHub API interface.
3
4
## Capabilities
5
6
### aiohttp Implementation
7
8
Implementation using the aiohttp library for HTTP requests.
9
10
```python { .api }
11
import aiohttp
12
from gidgethub.abc import GitHubAPI as GitHubAPIBase
13
14
class GitHubAPI(GitHubAPIBase):
15
"""aiohttp-based GitHub API client."""
16
17
def __init__(
18
self,
19
session: aiohttp.ClientSession,
20
*args: Any,
21
**kwargs: Any
22
) -> None:
23
"""
24
Initialize GitHub API client with aiohttp session.
25
26
Parameters:
27
- session: aiohttp ClientSession for making HTTP requests
28
- *args: Additional arguments passed to GitHubAPIBase
29
- **kwargs: Additional keyword arguments passed to GitHubAPIBase
30
"""
31
32
async def _request(
33
self,
34
method: str,
35
url: str,
36
headers: Mapping[str, str],
37
body: bytes = b""
38
) -> Tuple[int, Mapping[str, str], bytes]:
39
"""Make an HTTP request using aiohttp."""
40
41
async def sleep(self, seconds: float) -> None:
42
"""Sleep for the specified number of seconds."""
43
```
44
45
### httpx Implementation
46
47
Implementation using the httpx library for HTTP requests.
48
49
```python { .api }
50
import httpx
51
from gidgethub.abc import GitHubAPI as GitHubAPIBase
52
53
class GitHubAPI(GitHubAPIBase):
54
"""httpx-based GitHub API client."""
55
56
def __init__(
57
self,
58
client: httpx.AsyncClient,
59
*args: Any,
60
**kwargs: Any
61
) -> None:
62
"""
63
Initialize GitHub API client with httpx client.
64
65
Parameters:
66
- client: httpx AsyncClient for making HTTP requests
67
- *args: Additional arguments passed to GitHubAPIBase
68
- **kwargs: Additional keyword arguments passed to GitHubAPIBase
69
"""
70
71
async def _request(
72
self,
73
method: str,
74
url: str,
75
headers: Mapping[str, str],
76
body: bytes = b""
77
) -> Tuple[int, Mapping[str, str], bytes]:
78
"""Make an HTTP request using httpx."""
79
80
async def sleep(self, seconds: float) -> None:
81
"""Sleep for the specified number of seconds."""
82
```
83
84
### Tornado Implementation
85
86
Implementation using the Tornado HTTP client.
87
88
```python { .api }
89
from tornado import httpclient
90
from gidgethub.abc import GitHubAPI as GitHubAPIBase
91
92
class GitHubAPI(GitHubAPIBase):
93
"""Tornado-based GitHub API client."""
94
95
def __init__(self, *args: Any, **kwargs: Any) -> None:
96
"""
97
Initialize GitHub API client for Tornado.
98
99
Parameters:
100
- *args: Arguments passed to GitHubAPIBase
101
- **kwargs: Keyword arguments passed to GitHubAPIBase
102
103
Note: Uses Tornado's singleton AsyncHTTPClient internally
104
"""
105
106
async def _request(
107
self,
108
method: str,
109
url: str,
110
headers: Mapping[str, str],
111
body: bytes = b""
112
) -> Tuple[int, Mapping[str, str], bytes]:
113
"""Make an HTTP request using Tornado."""
114
115
async def sleep(self, seconds: float) -> None:
116
"""Sleep for the specified number of seconds."""
117
```
118
119
## Usage Examples
120
121
### Using aiohttp Implementation
122
123
```python
124
import asyncio
125
import aiohttp
126
from gidgethub.aiohttp import GitHubAPI
127
128
async def aiohttp_example():
129
async with aiohttp.ClientSession() as session:
130
gh = GitHubAPI(session, "my-app/1.0", oauth_token="your_token")
131
132
# Use any GitHubAPI method
133
repo = await gh.getitem("/repos/octocat/Hello-World")
134
print(f"Repository: {repo['name']}")
135
136
# Create an issue
137
issue = await gh.post(
138
"/repos/owner/repo/issues",
139
data={"title": "Test issue", "body": "Issue description"}
140
)
141
print(f"Created issue #{issue['number']}")
142
143
asyncio.run(aiohttp_example())
144
```
145
146
### Using httpx Implementation
147
148
```python
149
import asyncio
150
import httpx
151
from gidgethub.httpx import GitHubAPI
152
153
async def httpx_example():
154
async with httpx.AsyncClient() as client:
155
gh = GitHubAPI(client, "my-app/1.0", oauth_token="your_token")
156
157
# Same interface as other implementations
158
user = await gh.getitem("/user")
159
print(f"Authenticated as: {user['login']}")
160
161
# Iterate through repositories
162
async for repo in gh.getiter("/user/repos"):
163
print(f"Repository: {repo['name']}")
164
165
# GraphQL query
166
query = """
167
query {
168
viewer {
169
login
170
repositories(first: 5) {
171
nodes {
172
name
173
stargazerCount
174
}
175
}
176
}
177
}
178
"""
179
result = await gh.graphql(query)
180
print(f"GraphQL result: {result['viewer']['login']}")
181
182
asyncio.run(httpx_example())
183
```
184
185
### Using Tornado Implementation
186
187
```python
188
import asyncio
189
from tornado import httpclient
190
from gidgethub.tornado import GitHubAPI
191
192
async def tornado_example():
193
# Tornado implementation doesn't require external session/client
194
gh = GitHubAPI("my-app/1.0", oauth_token="your_token")
195
196
try:
197
# Check rate limit
198
rate_limit = await gh.getitem("/rate_limit")
199
print(f"Rate limit: {rate_limit['rate']['remaining']}/{rate_limit['rate']['limit']}")
200
201
# Get organization info
202
org = await gh.getitem("/orgs/github")
203
print(f"Organization: {org['name']}")
204
205
finally:
206
# Clean up Tornado's HTTP client
207
httpclient.AsyncHTTPClient().close()
208
209
asyncio.run(tornado_example())
210
```
211
212
### Custom HTTP Timeout Configuration
213
214
```python
215
import asyncio
216
import aiohttp
217
from gidgethub.aiohttp import GitHubAPI
218
219
async def custom_timeout_example():
220
# Configure custom timeouts
221
timeout = aiohttp.ClientTimeout(total=30, connect=10)
222
223
async with aiohttp.ClientSession(timeout=timeout) as session:
224
gh = GitHubAPI(session, "my-app/1.0")
225
226
try:
227
repo = await gh.getitem("/repos/octocat/Hello-World")
228
print(f"Repository loaded: {repo['name']}")
229
except asyncio.TimeoutError:
230
print("Request timed out")
231
232
asyncio.run(custom_timeout_example())
233
```
234
235
### Error Handling with Different Implementations
236
237
```python
238
import asyncio
239
import httpx
240
from gidgethub.httpx import GitHubAPI
241
from gidgethub import HTTPException, RateLimitExceeded
242
243
async def error_handling_example():
244
async with httpx.AsyncClient() as client:
245
gh = GitHubAPI(client, "my-app/1.0", oauth_token="your_token")
246
247
try:
248
# Attempt to access a private repository
249
repo = await gh.getitem("/repos/private-org/private-repo")
250
except HTTPException as exc:
251
if exc.status_code == 404:
252
print("Repository not found or access denied")
253
else:
254
print(f"HTTP error: {exc.status_code}")
255
except RateLimitExceeded as exc:
256
print(f"Rate limit exceeded. Resets at: {exc.rate_limit.reset_datetime}")
257
258
asyncio.run(error_handling_example())
259
```
260
261
### Using with Different Base URLs (GitHub Enterprise)
262
263
```python
264
import asyncio
265
import aiohttp
266
from gidgethub.aiohttp import GitHubAPI
267
268
async def enterprise_example():
269
async with aiohttp.ClientSession() as session:
270
# Use GitHub Enterprise Server
271
gh = GitHubAPI(
272
session,
273
"my-app/1.0",
274
oauth_token="your_token",
275
base_url="https://github.company.com/api/v3"
276
)
277
278
# Same API, different server
279
user = await gh.getitem("/user")
280
print(f"Enterprise user: {user['login']}")
281
282
asyncio.run(enterprise_example())
283
```
284
285
### Comparison of HTTP Libraries
286
287
| Feature | aiohttp | httpx | Tornado |
288
|---------|---------|-------|---------|
289
| Session Management | Required | Required | Built-in |
290
| HTTP/2 Support | No | Yes | No |
291
| Timeout Configuration | Flexible | Flexible | Limited |
292
| Connection Pooling | Yes | Yes | Yes |
293
| Proxy Support | Yes | Yes | Yes |
294
| SSL/TLS Configuration | Advanced | Advanced | Basic |
295
| Community Support | Large | Growing | Mature |
296
297
### Choosing an Implementation
298
299
- **aiohttp**: Mature, widely used, extensive ecosystem
300
- **httpx**: Modern, HTTP/2 support, familiar requests-like API
301
- **Tornado**: Integrated with Tornado web framework, singleton pattern
302
303
All implementations provide identical GitHub API functionality through the same interface.
304
305
## Types
306
307
```python { .api }
308
from typing import Any, Mapping, Tuple
309
import aiohttp
310
import httpx
311
from tornado import httpclient
312
313
# Implementation-specific session/client types
314
AiohttpSession = aiohttp.ClientSession
315
HttpxClient = httpx.AsyncClient
316
TornadoClient = httpclient.AsyncHTTPClient # Used internally
317
```