Praport

Version 1 – Backend

The backend of Praport V1 was developed in Python using the Flask micro-framework. This choice was made due to Flask’s simplicity, lightweight structure, and ease of learning — crucial as I had no prior backend experience. The app handled user authentication, data routing, communication with the SQLite database, and API calls to external tracking services.

Flask App Setup

The backend started with setting up Flask, sessions, and importing packages like werkzeug.security for password hashing:

from flask import Flask, render_template, request, redirect, url_for, session, jsonify
import sqlite3
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'your_secret_key'

Using generate_password_hash() and check_password_hash() meant passwords were stored securely — never as plain text.

User Registration

The registration logic took in email + password, hashed the password, and saved it to the SQLite database:

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        email = request.form['email']
        password = generate_password_hash(request.form['password'])

        conn = sqlite3.connect('database.db')
        c = conn.cursor()
        c.execute('INSERT INTO users (email, password) VALUES (?, ?)', (email, password))
        conn.commit()
        conn.close()

        return redirect(url_for('login'))
    return render_template('register.html')

SQLite made things very manageable during early testing. The database included basic tables: users, shipments, and logs.

Login & Sessions

When a user logged in, Flask used cookies to manage sessions and maintain login state:

@app.route('/login', methods=['POST'])
def login():
    email = request.form['email']
    password = request.form['password']

    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('SELECT password FROM users WHERE email = ?', (email,))
    user = c.fetchone()
    conn.close()

    if user and check_password_hash(user[0], password):
        session['user'] = email
        return redirect(url_for('dashboard'))
    else:
        return 'Invalid credentials'

Tracking Endpoint

The backend had a DHL API route that received tracking numbers from the frontend and returned real time tracking data.

@app.route('/api/track', methods=['POST'])
def track_shipment():
    tracking_id = request.json.get('tracking_id')

    if not tracking_id:
        return jsonify({'error': 'Missing tracking ID'}), 400

    return jsonify(data)

This was one of the most valuable learning points — how to send/receive JSON, validate requests, and connect frontend inputs to backend logic.

Dashboard Route

All stored shipments were retrieved from SQLite and passed into the dashboard view for rendering:

@app.route('/dashboard')
def dashboard():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('SELECT * FROM shipments')
    shipments = c.fetchall()
    conn.close()
    return render_template('dashboard.html', shipments=shipments)

On the frontend, JavaScript parsed this data and counted how many were marked as “Delivered” or “In Transit”.

Summary

Building this backend taught me core concepts of web development: how HTTP requests work, form processing, authentication, secure password storage, routing, JSON APIs, and persistence via SQL. While this wasn’t production-grade software, it was functional, clean, and a powerful foundation for everything that followed.