How MobileAudit Generates and Exports PDF Scan Reports: A Technical Deep Dive

MobileAudit generates PDF scan reports by rendering Django templates with scan data, converting the resulting HTML to PDF using pdfkit and wkhtmltopdf, and streaming the binary file back to the client as a downloadable attachment.

MobileAudit is an open-source mobile application security testing framework built with Django. When users complete a security scan, the platform provides a PDF export feature that packages all findings, certificates, permissions, and metadata into a polished, printable report. This article examines the complete technical pipeline—from URL routing to PDF delivery—based on the actual implementation in the mpast/mobileaudit repository.

The PDF Generation Pipeline

The export process follows a clear five-step pipeline: request handling, data aggregation, template rendering, PDF conversion, and HTTP response streaming. Each stage is implemented in specific modules within the Django application structure.

Request Routing and URL Handling

When a user clicks the Export button for a specific scan, Django routes the request through the URL configuration defined in app/config/urls.py. The system maps the /export/<int:id> endpoint to the views.export function:


# app/config/urls.py

path('export/<int:id>', views.export, name="export")

This pattern captures the scan ID from the URL and passes it as an integer parameter to the view function, ensuring that each PDF export corresponds to a specific, existing scan record in the database.

Data Collection and Context Building

The export function in app/views.py serves as the orchestration layer for PDF generation. Located at lines 418-456, this view performs several critical operations:

  1. Retrieves the scan object using the provided ID
  2. Queries related entities including certificates, permissions, activities, and findings
  3. Constructs a context dictionary that mirrors the data structure used in the standard scan detail page

# app/views.py

@login_required
def export(request, id):
    scan = Scan.objects.get(pk=id)
    
    # Gather all related objects

    certificates = Certificate.objects.filter(scan=id)
    permissions = Permission.objects.filter(scan=id)
    activities = Activity.objects.filter(scan=id)
    # Additional queries for findings, etc.

    
    # Build context for template rendering

    c = {
        'scan': scan,
        'certificates': certificates,
        'permissions': permissions,
        'activities': activities,
        # Remaining context data

    }
    
    # Rendering and PDF conversion follows...

This approach ensures that the PDF contains the same comprehensive security analysis data available in the web interface, maintaining consistency across different output formats.

HTML Template Rendering and Conversion

Once the data context is prepared, MobileAudit transitions from data aggregation to document generation through Django's templating system and external PDF conversion tools.

The Export Template Structure

The system loads the export.html template from app/templates/ using Django's get_template function. This template implements a compact, table-based HTML layout specifically designed for PDF output:


# Inside views.export function

t = get_template('export.html')
html = t.render(c)

The template structure (visible in the first part of app/templates/export.html) organizes the scan metadata, permission lists, security findings, certificate details, and statistical summaries into a printable format. Unlike the interactive web interface, this template uses static tables and simplified styling to ensure consistent rendering across different PDF viewers.

PDF Conversion with pdfkit and wkhtmltopdf

MobileAudit utilizes pdfkit as a Python wrapper around wkhtmltopdf, a command-line tool that converts HTML to PDF using the WebKit rendering engine. The conversion happens in-memory without writing temporary files to disk:

options = {
    'page-size': 'Letter',
    'encoding': "UTF-8",
}
pdf = pdfkit.from_string(html, False, options)

The False parameter instructs pdfkit to return the PDF as a byte string rather than saving to a file. The options dictionary specifies standard Letter page sizing and UTF-8 encoding to support international characters in security findings.

Dependency Management:

The wkhtmltopdf binary is installed at the system level in the Docker image via apt-get:


# Dockerfile

RUN apt-get install -y wkhtmltopdf

The Python wrapper is pinned to version 0.6.1 in requirements.txt:


# requirements.txt

pdfkit==0.6.1

This separation ensures the rendering engine is available at the OS level while the Python application maintains a stable API interface through the pdfkit library.

Delivering the PDF to the Client

The final stage involves configuring the HTTP response to trigger a file download in the user's browser while properly handling the binary PDF data.

HTTP Response Configuration

The export view constructs an HttpResponse object with the appropriate content type and disposition headers:

response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = "attachment; filename = scan.pdf"
return response

Setting content_type='application/pdf' informs the browser that the response contains PDF data rather than HTML. The Content-Disposition header with the attachment value forces the browser to download the file as scan.pdf rather than attempting to display it inline.

When a user accesses the export endpoint (e.g., /export/12), the complete flow executes in real-time: the scan data is retrieved, the template is rendered, HTML is converted to PDF, and the binary stream is returned to the client as a downloadable document containing the complete security analysis.

Summary

MobileAudit's PDF export functionality demonstrates a practical implementation of HTML-to-PDF conversion within a Django web application:

  • URL Routing: The /export/<int:id> endpoint in app/config/urls.py maps to the views.export function
  • Data Aggregation: The view collects scan metadata, certificates, permissions, activities, and findings into a unified context dictionary
  • Template Rendering: The export.html template in app/templates/ provides a print-optimized HTML layout
  • PDF Conversion: The system uses pdfkit (version 0.6.1) as a Python wrapper around the wkhtmltopdf binary to convert HTML to PDF
  • File Delivery: The view returns an HttpResponse with content_type='application/pdf' and a Content-Disposition header set to attachment; filename=scan.pdf

Frequently Asked Questions

What library does MobileAudit use to convert HTML to PDF?

MobileAudit uses pdfkit version 0.6.1, a Python wrapper library that interfaces with the wkhtmltopdf command-line tool. The wrapper is defined in requirements.txt, while the actual binary is installed at the system level via the Dockerfile using apt-get install wkhtmltopdf.

How is the wkhtmltopdf binary installed in MobileAudit?

The wkhtmltopdf binary is installed in the Docker container at build time. The Dockerfile contains a RUN apt-get install -y wkhtmltopdf command that installs the binary from the Ubuntu package repositories. This ensures the HTML-to-PDF conversion engine is available when the Django application calls pdfkit functions.

Can I customize the PDF report template in MobileAudit?

Yes, the PDF layout is controlled by the export.html template located in app/templates/. This Django template uses standard HTML and CSS with table-based layouts optimized for print output. You can modify this template to change the report branding, reorganize sections, or adjust styling, and the changes will reflect in subsequent PDF exports.

What file name does MobileAudit use for downloaded PDF reports?

MobileAudit uses the static filename scan.pdf for all downloaded reports. This is set in the Content-Disposition header within the export view in app/views.py: response['Content-Disposition'] = "attachment; filename = scan.pdf". Users can rename the file after download, or developers can modify this line to generate dynamic filenames based on scan ID or date.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →