CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-coveralls

Python interface to coveralls.io API for uploading code coverage results

Pending
Overview
Eval results
Files

api-communication.mddocs/

API Communication

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.

Capabilities

HTTP POST Request

Sends coverage data to the coveralls.io API endpoint with proper authentication and formatting.

def post(url, repo_token, service_job_id, service_name, git, source_files, parallel, skip_ssl_verify=False):
    """
    Submit coverage data to coveralls.io API via HTTP POST.
    
    Args:
        url (str): coveralls.io API endpoint URL (typically 'https://coveralls.io/api/v1/jobs')
        repo_token (str): Repository authentication token from coveralls.io
        service_job_id (str): CI service job identifier (e.g., Travis job ID)
        service_name (str): CI service name (e.g., 'travis-ci', 'circle-ci')
        git (dict): Git repository information (commit, branch, remotes)
        source_files (list[dict]): Coverage data for source files
        parallel (bool): True if this is a parallel build
        skip_ssl_verify (bool): If True, skip SSL certificate verification
    
    Returns:
        requests.Response: HTTP response object from coveralls.io API
        
    Response Structure:
        - status_code: HTTP status (200 for success)
        - json(): Response data including success/error messages
        - text: Raw response content
    """

JSON Payload Construction

Builds the JSON payload structure required by the coveralls.io API format.

def build_file(repo_token, service_job_id, service_name, git, source_files, parallel):
    """
    Build JSON payload for coveralls.io API request.
    
    Args:
        repo_token (str): Repository authentication token  
        service_job_id (str): CI service job identifier
        service_name (str): CI service name
        git (dict): Git repository information
        source_files (list[dict]): Source files with coverage data
        parallel (bool): Parallel build flag
    
    Returns:
        StringIO: JSON data formatted as file-like object for HTTP upload
        
    Payload Structure:
        {
            "service_job_id": str,
            "service_name": str,
            "git": {...},
            "source_files": [...],
            "repo_token": str (optional - only if provided),
            "parallel": true (optional - only if true)
        }
    """

API Request Format

Required Payload Fields

# Core required fields
payload_structure = {
    "service_job_id": str,    # CI job identifier
    "service_name": str,      # CI service name
    "git": dict,              # Repository information
    "source_files": list,     # Coverage data
}

# Optional fields
optional_fields = {
    "repo_token": str,        # Authentication token (required for private repos)
    "parallel": bool,         # Parallel build indicator
}

Git Information Structure

git_info_structure = {
    "head": {
        "id": str,                    # Commit SHA
        "author_name": str,           # Commit author name
        "author_email": str,          # Commit author email
        "committer_name": str,        # Committer name
        "committer_email": str,       # Committer email
        "message": str,               # Commit message
    },
    "branch": str,                    # Current branch name
    "remotes": [
        {
            "name": str,              # Remote name (e.g., "origin")
            "url": str,               # Remote URL
        }
    ]
}

Source Files Structure

source_file_structure = {
    "name": str,                      # Relative file path
    "source": str,                    # Complete file content
    "coverage": list[int | None],     # Line-by-line coverage array
}

# Coverage array values:
# None: Non-executable line (comments, blank lines)
# 0: Executable line that was not hit (missed)
# 1: Executable line that was hit (covered)

Usage Examples

Basic API Submission

from coveralls.api import post, build_file

# Prepare data
repo_token = "your_repo_token"
service_job_id = "12345"
service_name = "travis-ci"
git_info = {...}  # From repository module
source_files = [...]  # From coverage processing

# Submit to coveralls.io
response = post(
    url="https://coveralls.io/api/v1/jobs",
    repo_token=repo_token,
    service_job_id=service_job_id,
    service_name=service_name,
    git=git_info,
    source_files=source_files,
    parallel=False,
    skip_ssl_verify=False
)

# Check response
if response.status_code == 200:
    result = response.json()
    if 'error' in result:
        print(f"API Error: {result}")
    else:
        print("Coverage uploaded successfully")
else:
    print(f"HTTP Error: {response.status_code}")

Payload Construction

from coveralls.api import build_file
import json

# Build payload file object
json_file = build_file(
    repo_token="repo_token_here",
    service_job_id="travis_job_123",
    service_name="travis-ci",
    git={
        "head": {
            "id": "abc123",
            "author_name": "Developer",
            "author_email": "dev@example.com",
            "committer_name": "Developer", 
            "committer_email": "dev@example.com",
            "message": "Add new feature"
        },
        "branch": "main",
        "remotes": [{"name": "origin", "url": "https://github.com/user/repo.git"}]
    },
    source_files=[
        {
            "name": "src/module.py",
            "source": "def hello():\n    return 'world'",
            "coverage": [1, 1]
        }
    ],
    parallel=True
)

# Access JSON content
json_content = json_file.getvalue()
data = json.loads(json_content)

Error Handling and Debugging

from coveralls.api import post
import logging

# Enable request logging for debugging
logging.basicConfig(level=logging.DEBUG)

try:
    response = post(
        url="https://coveralls.io/api/v1/jobs",
        repo_token=repo_token,
        service_job_id=service_job_id,
        service_name=service_name,
        git=git_info,
        source_files=source_files,
        parallel=parallel,
        skip_ssl_verify=skip_ssl_verify
    )
    
    # Log response details
    print(f"Status Code: {response.status_code}")
    print(f"Response Headers: {response.headers}")
    print(f"Response Content: {response.text}")
    
    # Parse JSON response
    if response.headers.get('content-type', '').startswith('application/json'):
        result = response.json()
        
        if 'error' in result:
            print(f"Coveralls API Error: {result['error']}")
            if 'message' in result:
                print(f"Error Message: {result['message']}")
        else:
            print("Upload successful!")
            if 'url' in result:
                print(f"Coverage Report URL: {result['url']}")
    
except requests.exceptions.RequestException as e:
    print(f"HTTP Request Error: {e}")
except json.JSONDecodeError as e:
    print(f"JSON Parse Error: {e}")
except Exception as e:
    print(f"Unexpected Error: {e}")

SSL and Network Configuration

# Skip SSL verification for corporate environments
response = post(
    url="https://coveralls.io/api/v1/jobs",
    repo_token=repo_token,
    service_job_id=service_job_id,
    service_name=service_name,  
    git=git_info,
    source_files=source_files,
    parallel=False,
    skip_ssl_verify=True  # Skip SSL verification
)

# Custom API endpoint (for enterprise installations)
response = post(
    url="https://coveralls.company.com/api/v1/jobs",
    repo_token=repo_token,
    service_job_id=service_job_id,
    service_name=service_name,
    git=git_info,
    source_files=source_files,
    parallel=False
)

Authentication Methods

Repository Token

# For private repositories or when not using supported CI services
repo_token = "your_coveralls_repo_token"

# Token is included in payload automatically
response = post(
    url="https://coveralls.io/api/v1/jobs",
    repo_token=repo_token,  # Included in JSON payload
    service_job_id=service_job_id,
    service_name=service_name,
    git=git_info,
    source_files=source_files,
    parallel=False
)

CI Service Integration

# For supported CI services (Travis, Circle, etc.)
# No repo_token needed if properly configured
response = post(
    url="https://coveralls.io/api/v1/jobs",
    repo_token="",  # Empty for public repos with CI integration
    service_job_id=os.environ.get('TRAVIS_JOB_ID'),
    service_name="travis-ci",
    git=git_info,
    source_files=source_files,
    parallel=False
)

Response Handling

Success Response

# Successful upload response
success_response = {
    "message": "Job #123.1",
    "url": "https://coveralls.io/jobs/12345"
}

Error Response

# Error response examples  
error_responses = [
    {"error": "Couldn't find a repository matching this job."},
    {"error": "Build processing error.", "message": "Details about the error"},
    {"error": "Invalid repo token."}
]

Install with Tessl CLI

npx tessl i tessl/pypi-python-coveralls

docs

api-communication.md

coverage-processing.md

index.md

main-workflow.md

repository-integration.md

tile.json