0
# API Communication
1
2
The API communication module handles HTTP interaction with the coveralls.io API, including request formatting, authentication, payload construction, and response processing. It provides functions for building JSON payloads and submitting coverage data via HTTP POST requests.
3
4
## Capabilities
5
6
### HTTP POST Request
7
8
Sends coverage data to the coveralls.io API endpoint with proper authentication and formatting.
9
10
```python { .api }
11
def post(url, repo_token, service_job_id, service_name, git, source_files, parallel, skip_ssl_verify=False):
12
"""
13
Submit coverage data to coveralls.io API via HTTP POST.
14
15
Args:
16
url (str): coveralls.io API endpoint URL (typically 'https://coveralls.io/api/v1/jobs')
17
repo_token (str): Repository authentication token from coveralls.io
18
service_job_id (str): CI service job identifier (e.g., Travis job ID)
19
service_name (str): CI service name (e.g., 'travis-ci', 'circle-ci')
20
git (dict): Git repository information (commit, branch, remotes)
21
source_files (list[dict]): Coverage data for source files
22
parallel (bool): True if this is a parallel build
23
skip_ssl_verify (bool): If True, skip SSL certificate verification
24
25
Returns:
26
requests.Response: HTTP response object from coveralls.io API
27
28
Response Structure:
29
- status_code: HTTP status (200 for success)
30
- json(): Response data including success/error messages
31
- text: Raw response content
32
"""
33
```
34
35
### JSON Payload Construction
36
37
Builds the JSON payload structure required by the coveralls.io API format.
38
39
```python { .api }
40
def build_file(repo_token, service_job_id, service_name, git, source_files, parallel):
41
"""
42
Build JSON payload for coveralls.io API request.
43
44
Args:
45
repo_token (str): Repository authentication token
46
service_job_id (str): CI service job identifier
47
service_name (str): CI service name
48
git (dict): Git repository information
49
source_files (list[dict]): Source files with coverage data
50
parallel (bool): Parallel build flag
51
52
Returns:
53
StringIO: JSON data formatted as file-like object for HTTP upload
54
55
Payload Structure:
56
{
57
"service_job_id": str,
58
"service_name": str,
59
"git": {...},
60
"source_files": [...],
61
"repo_token": str (optional - only if provided),
62
"parallel": true (optional - only if true)
63
}
64
"""
65
```
66
67
## API Request Format
68
69
### Required Payload Fields
70
71
```python { .api }
72
# Core required fields
73
payload_structure = {
74
"service_job_id": str, # CI job identifier
75
"service_name": str, # CI service name
76
"git": dict, # Repository information
77
"source_files": list, # Coverage data
78
}
79
80
# Optional fields
81
optional_fields = {
82
"repo_token": str, # Authentication token (required for private repos)
83
"parallel": bool, # Parallel build indicator
84
}
85
```
86
87
### Git Information Structure
88
89
```python { .api }
90
git_info_structure = {
91
"head": {
92
"id": str, # Commit SHA
93
"author_name": str, # Commit author name
94
"author_email": str, # Commit author email
95
"committer_name": str, # Committer name
96
"committer_email": str, # Committer email
97
"message": str, # Commit message
98
},
99
"branch": str, # Current branch name
100
"remotes": [
101
{
102
"name": str, # Remote name (e.g., "origin")
103
"url": str, # Remote URL
104
}
105
]
106
}
107
```
108
109
### Source Files Structure
110
111
```python { .api }
112
source_file_structure = {
113
"name": str, # Relative file path
114
"source": str, # Complete file content
115
"coverage": list[int | None], # Line-by-line coverage array
116
}
117
118
# Coverage array values:
119
# None: Non-executable line (comments, blank lines)
120
# 0: Executable line that was not hit (missed)
121
# 1: Executable line that was hit (covered)
122
```
123
124
## Usage Examples
125
126
### Basic API Submission
127
128
```python
129
from coveralls.api import post, build_file
130
131
# Prepare data
132
repo_token = "your_repo_token"
133
service_job_id = "12345"
134
service_name = "travis-ci"
135
git_info = {...} # From repository module
136
source_files = [...] # From coverage processing
137
138
# Submit to coveralls.io
139
response = post(
140
url="https://coveralls.io/api/v1/jobs",
141
repo_token=repo_token,
142
service_job_id=service_job_id,
143
service_name=service_name,
144
git=git_info,
145
source_files=source_files,
146
parallel=False,
147
skip_ssl_verify=False
148
)
149
150
# Check response
151
if response.status_code == 200:
152
result = response.json()
153
if 'error' in result:
154
print(f"API Error: {result}")
155
else:
156
print("Coverage uploaded successfully")
157
else:
158
print(f"HTTP Error: {response.status_code}")
159
```
160
161
### Payload Construction
162
163
```python
164
from coveralls.api import build_file
165
import json
166
167
# Build payload file object
168
json_file = build_file(
169
repo_token="repo_token_here",
170
service_job_id="travis_job_123",
171
service_name="travis-ci",
172
git={
173
"head": {
174
"id": "abc123",
175
"author_name": "Developer",
176
"author_email": "dev@example.com",
177
"committer_name": "Developer",
178
"committer_email": "dev@example.com",
179
"message": "Add new feature"
180
},
181
"branch": "main",
182
"remotes": [{"name": "origin", "url": "https://github.com/user/repo.git"}]
183
},
184
source_files=[
185
{
186
"name": "src/module.py",
187
"source": "def hello():\n return 'world'",
188
"coverage": [1, 1]
189
}
190
],
191
parallel=True
192
)
193
194
# Access JSON content
195
json_content = json_file.getvalue()
196
data = json.loads(json_content)
197
```
198
199
### Error Handling and Debugging
200
201
```python
202
from coveralls.api import post
203
import logging
204
205
# Enable request logging for debugging
206
logging.basicConfig(level=logging.DEBUG)
207
208
try:
209
response = post(
210
url="https://coveralls.io/api/v1/jobs",
211
repo_token=repo_token,
212
service_job_id=service_job_id,
213
service_name=service_name,
214
git=git_info,
215
source_files=source_files,
216
parallel=parallel,
217
skip_ssl_verify=skip_ssl_verify
218
)
219
220
# Log response details
221
print(f"Status Code: {response.status_code}")
222
print(f"Response Headers: {response.headers}")
223
print(f"Response Content: {response.text}")
224
225
# Parse JSON response
226
if response.headers.get('content-type', '').startswith('application/json'):
227
result = response.json()
228
229
if 'error' in result:
230
print(f"Coveralls API Error: {result['error']}")
231
if 'message' in result:
232
print(f"Error Message: {result['message']}")
233
else:
234
print("Upload successful!")
235
if 'url' in result:
236
print(f"Coverage Report URL: {result['url']}")
237
238
except requests.exceptions.RequestException as e:
239
print(f"HTTP Request Error: {e}")
240
except json.JSONDecodeError as e:
241
print(f"JSON Parse Error: {e}")
242
except Exception as e:
243
print(f"Unexpected Error: {e}")
244
```
245
246
### SSL and Network Configuration
247
248
```python
249
# Skip SSL verification for corporate environments
250
response = post(
251
url="https://coveralls.io/api/v1/jobs",
252
repo_token=repo_token,
253
service_job_id=service_job_id,
254
service_name=service_name,
255
git=git_info,
256
source_files=source_files,
257
parallel=False,
258
skip_ssl_verify=True # Skip SSL verification
259
)
260
261
# Custom API endpoint (for enterprise installations)
262
response = post(
263
url="https://coveralls.company.com/api/v1/jobs",
264
repo_token=repo_token,
265
service_job_id=service_job_id,
266
service_name=service_name,
267
git=git_info,
268
source_files=source_files,
269
parallel=False
270
)
271
```
272
273
## Authentication Methods
274
275
### Repository Token
276
277
```python
278
# For private repositories or when not using supported CI services
279
repo_token = "your_coveralls_repo_token"
280
281
# Token is included in payload automatically
282
response = post(
283
url="https://coveralls.io/api/v1/jobs",
284
repo_token=repo_token, # Included in JSON payload
285
service_job_id=service_job_id,
286
service_name=service_name,
287
git=git_info,
288
source_files=source_files,
289
parallel=False
290
)
291
```
292
293
### CI Service Integration
294
295
```python
296
# For supported CI services (Travis, Circle, etc.)
297
# No repo_token needed if properly configured
298
response = post(
299
url="https://coveralls.io/api/v1/jobs",
300
repo_token="", # Empty for public repos with CI integration
301
service_job_id=os.environ.get('TRAVIS_JOB_ID'),
302
service_name="travis-ci",
303
git=git_info,
304
source_files=source_files,
305
parallel=False
306
)
307
```
308
309
## Response Handling
310
311
### Success Response
312
313
```python
314
# Successful upload response
315
success_response = {
316
"message": "Job #123.1",
317
"url": "https://coveralls.io/jobs/12345"
318
}
319
```
320
321
### Error Response
322
323
```python
324
# Error response examples
325
error_responses = [
326
{"error": "Couldn't find a repository matching this job."},
327
{"error": "Build processing error.", "message": "Details about the error"},
328
{"error": "Invalid repo token."}
329
]
330
```