Skip to main content

Overview

CoroNet provides seamless data export functionality, allowing users to download the complete vehicle registration database as a CSV file. This enables data analysis in spreadsheet applications, integration with third-party systems, and backup creation.

Export Endpoint

The export functionality is implemented through a single, straightforward endpoint:
@app.route("/descargar")
def descargar():
    ensure_csv()
    return send_file(DATA_PATH, as_attachment=True, download_name="registros.csv")
Implementation details:
  • Route: /descargar (Spanish for “download”) (app.py:154)
  • Method: GET request
  • File validation: Calls ensure_csv() to guarantee file exists (app.py:155)
  • Response: Streams the CSV file directly to the browser (app.py:156)
  • Download name: File is saved as registros.csv on the user’s device
The export endpoint uses Flask’s send_file() function with as_attachment=True, which triggers a browser download dialog instead of displaying the file inline.

CSV File Structure

The exported CSV follows a consistent seven-column format:
id,fecha_hora,matricula,propietario,tipo_vehiculo,observacion,imagen
1,2024-03-15 14:30:22,ABC123,Juan Pérez,Automóvil,Vehículo oficial,matricula_20240315_143022.jpg
2,2024-03-15 14:35:10,XYZ789,María García,Camioneta,Visitante,matricula_20240315_143510.jpg
3,2024-03-15 15:20:45,DEF456,Carlos López,Motocicleta,,matricula_20240315_152045.jpg

Column Specifications

  • Type: String (numeric)
  • Format: Auto-incremented integer starting at 1
  • Purpose: Unique identifier for each registration
  • Usage: Can be used for record lookup, deletion, or updates
  • Type: String (datetime)
  • Format: YYYY-MM-DD HH:MM:SS (ISO-like format)
  • Example: 2024-03-15 14:30:22
  • Purpose: Records exact date and time of vehicle entry
  • Usage: Chronological sorting, time-based filtering, audit trails
  • Type: String (alphanumeric)
  • Format: Uppercase, alphanumeric + hyphens only, max 10 characters
  • Example: ABC-123, XYZ789
  • Source: Automatically detected via GPT-4o or Tesseract OCR
  • Special value: NO_DETECTADA when detection fails
  • Normalization: Spaces removed, uppercase conversion applied (app.py:74-75)
  • Type: String (free text)
  • Format: User-provided, supports UTF-8 characters
  • Example: Juan Pérez, María García
  • Purpose: Identifies the vehicle owner or driver
  • Usage: Owner lookup, access control, contact information
  • Type: String (free text)
  • Format: User-provided category
  • Examples: Automóvil, Camioneta, Motocicleta, Camión
  • Purpose: Categorizes vehicles for reporting and analysis
  • Usage: Vehicle type statistics, parking allocation, access rules
  • Type: String (free text, optional)
  • Format: User-provided notes
  • Examples: Vehículo oficial, Visitante, Entrega de paquetes
  • Purpose: Additional context or special conditions
  • Usage: Security notes, visitor tracking, special permissions
  • Type: String (filename)
  • Format: matricula_YYYYMMDD_HHMMSS.jpg
  • Example: matricula_20240315_143022.jpg
  • Purpose: References the uploaded vehicle image
  • Location: Physical file stored in uploads/ directory
  • Usage: Visual verification, evidence, manual plate verification

How the Export Works

Step-by-Step Process

  1. User clicks the download/export button in the web interface
  2. Browser sends GET request to /descargar
  3. Server processes request and initiates file download
  4. Browser saves registros.csv to the user’s download folder

File Validation

Before export, the system ensures data integrity:
def ensure_csv():
    if not os.path.exists(DATA_PATH):
        with open(DATA_PATH, "w", newline="", encoding="utf-8") as f:
            csv.writer(f).writerow(CSV_HEADER)
This guarantees that:
  • The CSV file exists (creates it if missing)
  • The file has proper headers
  • Export never fails due to missing file
  • Empty database exports as header-only CSV
If no registrations exist, the exported CSV will contain only the header row. This is valid CSV format and can be imported into spreadsheet applications.

Use Cases

Data Analysis

The exported CSV can be imported into analysis tools: Excel/Google Sheets:
  • Create pivot tables for vehicle type distribution
  • Generate charts showing entries by date/time
  • Calculate peak traffic hours
  • Identify frequent visitors by license plate
Python/Pandas:
import pandas as pd

# Load exported data
df = pd.read_csv('registros.csv')

# Convert timestamps
df['fecha_hora'] = pd.to_datetime(df['fecha_hora'])

# Analyze entries by hour
hourly = df.groupby(df['fecha_hora'].dt.hour).size()

# Find most common vehicle types
type_counts = df['tipo_vehiculo'].value_counts()

# Detect repeated plates
repeated = df['matricula'].value_counts()[df['matricula'].value_counts() > 1]

Backup and Archive

Regular CSV exports provide a simple backup mechanism. The file includes all registration metadata but not the actual images (which remain in uploads/).
Backup strategy:
  1. Schedule regular exports (daily/weekly)
  2. Store CSV files with dated filenames
  3. Copy uploads/ directory for complete backup
  4. Archive old records to reduce active database size

Integration with External Systems

The CSV format enables integration with:
  • Access control systems: Import plates into gate controllers
  • Billing systems: Calculate parking fees based on entry times
  • Security databases: Cross-reference with authorized vehicle lists
  • Reporting tools: Generate compliance and audit reports
  • Database systems: Bulk import into PostgreSQL, MySQL, etc.
Example: Import to PostgreSQL
CREATE TABLE registros (
    id SERIAL PRIMARY KEY,
    fecha_hora TIMESTAMP,
    matricula VARCHAR(10),
    propietario VARCHAR(255),
    tipo_vehiculo VARCHAR(100),
    observacion TEXT,
    imagen VARCHAR(255)
);

COPY registros(id, fecha_hora, matricula, propietario, tipo_vehiculo, observacion, imagen)
FROM '/path/to/registros.csv'
DELIMITER ','
CSV HEADER;

Technical Implementation

Flask send_file() Function

CoroNet uses Flask’s built-in send_file() for optimal file delivery:
return send_file(
    DATA_PATH,              # Path to the CSV file
    as_attachment=True,     # Trigger download dialog
    download_name="registros.csv"  # Custom filename
)
Key advantages:
  • Streaming: Large files are streamed without loading into memory
  • Automatic headers: Sets correct Content-Type and Content-Disposition
  • Cross-browser support: Works with all modern browsers
  • Error handling: Handles missing files gracefully

Content-Type Header

Flask automatically sets the appropriate MIME type:
Content-Type: text/csv
Content-Disposition: attachment; filename="registros.csv"
This ensures browsers:
  • Recognize the file as CSV
  • Trigger download instead of display
  • Use the correct filename

Character Encoding

The CSV file uses UTF-8 encoding throughout:
# Writing (creation/update)
with open(DATA_PATH, "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=CSV_HEADER)
    writer.writeheader()
    writer.writerows(rows)
This ensures:
  • International characters (Spanish accents, etc.) are preserved
  • Compatibility with modern spreadsheet applications
  • Data integrity during import/export cycles
Why UTF-8?
  • Supports all Unicode characters (accents, emojis, Asian characters)
  • Standard encoding for modern applications
  • Compatible with Excel, Google Sheets, LibreOffice
Potential issues with Excel:
  • Older Excel versions may not auto-detect UTF-8
  • Solution: Import via “Data > From Text/CSV” instead of double-clicking
  • Or save as UTF-8 with BOM for better Excel compatibility

Export Limitations

Images Not Included

The CSV export contains only metadata about registrations:
  • ✅ License plate numbers
  • ✅ Owner names
  • ✅ Vehicle types
  • ✅ Timestamps
  • Image filenames
  • Actual image data
The physical image files remain in the uploads/ directory. To create a complete backup, you must:
  1. Export the CSV using /descargar
  2. Copy the entire uploads/ directory separately
  3. Maintain the directory structure for image references to work

File Size Considerations

The CSV file size grows linearly with the number of registrations (approximately 100-200 bytes per record). A database with 10,000 entries would produce a ~1-2 MB CSV file.
Performance characteristics:
  • Small datasets (< 1,000 records): Instant download
  • Medium datasets (1,000-10,000 records): Few seconds
  • Large datasets (> 10,000 records): May take 10-30 seconds
  • Very large datasets (> 100,000 records): Consider pagination or database migration

No Incremental Export

The current implementation exports the entire database every time:
def descargar():
    ensure_csv()
    return send_file(DATA_PATH, as_attachment=True, download_name="registros.csv")
There is no built-in support for:
  • Date range filtering
  • Exporting only new records since last export
  • Partial exports by vehicle type or owner
Workaround for filtered exports: You could implement custom export endpoints:
@app.route("/descargar/rango")
def descargar_rango():
    fecha_inicio = request.args.get('inicio')
    fecha_fin = request.args.get('fin')
    
    rows = read_csv()
    filtered = [
        r for r in rows 
        if fecha_inicio <= r['fecha_hora'] <= fecha_fin
    ]
    
    # Write to temporary file and send
    temp_path = os.path.join(BASE_DIR, "temp_export.csv")
    write_csv_to_path(filtered, temp_path)
    return send_file(temp_path, as_attachment=True, download_name="registros_filtrado.csv")

Security Considerations

Authentication Required

The current implementation does not include authentication. The /descargar endpoint is publicly accessible. For production deployments, add authentication using Flask-Login or similar.
Recommended security additions:
from flask_login import login_required

@app.route("/descargar")
@login_required
def descargar():
    ensure_csv()
    return send_file(DATA_PATH, as_attachment=True, download_name="registros.csv")

Data Privacy

The exported CSV contains personally identifiable information (PII):
  • Vehicle owner names
  • License plate numbers
  • Entry timestamps
Ensure compliance with data protection regulations (GDPR, CCPA) by:
  • Restricting export access to authorized personnel
  • Encrypting exported files for transmission
  • Implementing audit logging for export operations
  • Providing data retention policies

Future Enhancements

Potential improvements to the export system:
  1. Multiple formats: Add JSON, Excel, PDF export options
  2. Filtered exports: Date ranges, vehicle types, owner names
  3. Scheduled exports: Automatic daily/weekly exports via email
  4. Compressed archives: ZIP files containing CSV + all images
  5. API endpoint: RESTful API for programmatic data access
  6. Pagination: Export in chunks for very large datasets
  7. Custom column selection: Allow users to choose which fields to export

Build docs developers (and LLMs) love