Skip to content

A lightweight Python HTTP server built with http.server and Jinja2, featuring static file serving, dynamic templates, and form submission with local JSON-based data persistence.

License

Notifications You must be signed in to change notification settings

oleksandr-romashko/goit-pythonweb-hw-03

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Fullstack Web Development with Python

project thumbnail

The Basics of the Web. Simple HTTP Server Build.

This project showcases a minimalist HTTP server implemented in pure Python, using the standard http.server module. The server serves static pages and assets, renders dynamic templates via Jinja2, and handles form submissions with data persistence.

Project display image

It supports GET and POST requests and features:

  • Basic routing and clean URL handling (/message instead of /message.html)
  • Static file serving with MIME type detection (images, css, js, etc.) and path traversal protection
  • Dynamic page rendering with message data (using templates and Jinja2)
  • Message storage using a local JSON file
  • Simple error and redirect handling
  • Logging for server activity
  • Docker- and Compose-ready

All functionality runs in a single, self-contained Python environment β€” without any external web frameworks or databases.

⚠️ Important note
This setup is intended for local development and educational purposes only.
It is not production-ready and lacks critical features such as input sanitization, HTTPS, concurrency, and robust error handling.
While some basic safeguards are included, significant hardening would be required for real-world deployment.

Table of Contents

Task Requirements

Your goal is to implement a basic web application. As a starting point, use the following repository: https://github.com/GoIT-Python-Web/FullStack-Web-Development-hw3.

The application should use Python's built-in HTTP server and follow the structure demonstrated in the course materials. It must serve multiple HTML pages, handle static assets, process a form submission, and store messages persistently in a JSON file.

This task is intended to reinforce your understanding of basic routing, HTTP handling, and file-based persistence.

Technical Description

You are required to build a simple web application with routing for two HTML pages:

  • index.html
  • message.html

Additionally, your app must:

  • Serve static resources: style.css, logo.png
  • Process a form on the message.html page
  • Return a custom error page (error.html) in case of a 404 Not Found error
  • Listen on port 3000

Form Processing and Data Storage

When the form on message.html is submitted, the application must:

  1. Convert the received byte-string into a Python dictionary
  2. Save the resulting data into a JSON file data.json located inside storage directory

The JSON format should follow this structure:

{
  "2022-10-29 20:20:58.020261": {
    "username": "krabaton",
    "message": "First message"
  },
  "2022-10-29 20:21:11.812177": {
    "username": "Krabat",
    "message": "Second message"
  }
}

Each key is the timestamp of the message, generated using datetime.now().

Additional Route: /read

Create a new route /read, which renders a Jinja2 template that displays all stored messages from data.json.

Optional Enhancements (Not Required)

  • Create a Dockerfile to run the application in a Docker container
  • Use Docker volumes to store the storage/data.json file outside the container

Acceptance Criteria

Main Acceptance Criteria

  1. Routing and Pages
    • The application includes two HTML pages: index.html and message.html
    • Static files (style.css, logo.png) are served correctly
    • The server runs on port 3000
  2. Form Handling
    • The form on message.html page collects username and message.
    • Submitted form data is converted into a dictionary. The data is stored in storage/data.json using timestamp keys.
    {
      "%timestamp%": {
        "username": "example",
        "message": "example message"
      }
    }
  3. Message Display
    • A GET request to /read returns a Jinja2-based page
    • The page renders all saved messages from the JSON file data.json
  4. Error Handling A 404 Not Found triggers to serve error.html page
  5. Data Storage
    • Messages are saved in storage/data.json as valid JSON
    • Each key represents the exact time the message was received

Additional (Optional) Requirements

  • A Dockerfile is created that allows running the app as a Docker container
  • A volume is used to persist data.json outside the container

Task Solution

A lightweight Python HTTP server built with http.server and Jinja2, featuring static file serving, dynamic templates, and form submission with local JSON-based persistence.

Features

  • Routes: /, /message, /read
  • Static assets (images, HTML, JS, CSS)
  • Form submission with data saved to JSON file
  • Custom error page based on Jinja2 template
  • Docker support
  • Compose support

Project Files Structure

.
β”œβ”€β”€ compose.yaml                # Docker Compose file
β”œβ”€β”€ Dockerfile                  # Docker image definition
β”œβ”€β”€ .dockerignore               # Files/folders to exclude from Docker context
β”œβ”€β”€ pyproject.toml              # Project dependencies and config (Poetry)
└── src/
    β”œβ”€β”€ main.py                 # Entry point for the application
    β”œβ”€β”€ decorators/
    β”‚   └── handle_server_errors.py   # Decorator to catch and handle server errors
    β”œβ”€β”€ storage/
    β”‚   β”œβ”€β”€ data/
    β”‚   β”‚   └── data.json       # App's message data (created on first write)
    β”‚   └── storage.py          # Functions to read/write saved in storage data
    β”œβ”€β”€ utils/
    β”‚   β”œβ”€β”€ constants.py        # Constants used across the app
    β”‚   └── validations.py      # Input validation helpers
    └── web/
        β”œβ”€β”€ static/
        β”‚   β”œβ”€β”€ images/         # Logos, icons, etc.
        β”‚   β”œβ”€β”€ pages/          # Pure static HTML pages
        β”‚   β”œβ”€β”€ scripts/        # JavaScript files
        β”‚   └── styles/         # CSS or SCSS stylesheets
        └── templates/
            β”œβ”€β”€ error.html      # Template for error pages
            └── read.html       # Template to display submitted messages

Docker Hub

This project is also published to Docker Hub.

You can pull and run it directly:

docker pull rmsh/goit-pythonweb-hw-03

Solution Screenshots

Messages shown on the rendered /read page:

Read page with submitted messages

Empty messages state at rendered /read page:

Read page with no messages

Rendered 404 Not Found error page:

404 error page example

Rendered 500 Internal Server error page:

500 error page example

Served static resources:

Example of serving static content using dev tools

Project Setup & Run Instructions

This guide will help you set up the environment and run the project.

Prerequisites

Before you begin, make sure you have the following installed:

  • Python 3.10.* (tested with 3.10.18) β€” Required to run the application locally (outside Docker, if needed).
  • (Optional - for local development) Poetry - To manage dependencies in virtual environment.
  • Docker β€” Used to containerize the application in a unified environment using Docker or Docker Compose.
  • (Optional - for local development) Git β€” To clone the repository, version control and development.
  • (Optional - for local development) VS Code or another IDE β€” Recommended for browsing and editing the project source code and overall development.

Setting Up the Development Environment

1. Clone the Repository

git clone https://github.com/oleksandr-romashko/goit-pythonweb-hw-03
cd goit-pythonweb-hw-03-main

or download the ZIP archive from GitHub Repository and extract it.

2. Choose Setup Method

You can either run the project in a fully containerized development environment (recommended) or set it up locally using a virtual environment.

🐳 Option 1: Using Docker Compose (Recommended, easiest way to run the app with minimal setup)

This method runs app using Docker Compose

docker compose up --build

This will:

  1. Build the FastAPI application image.
  2. Create and run the container with necessary ports.
  3. Use a volume for data persistence.

The app will be available at: http://localhost:3000

To stop:

docker compose down
🐳 Option 2: Run with Docker (Alternative Method)

For those who want a bit more control using docker run.

  1. Build the Docker image:

    docker build -t goit-pythonweb-hw-03 .
  2. (Optional) Create a named volume for persistent data:

    Only needed once before first run:

    docker volume create storage_data
  3. Run the Docker container:

    docker run -p 3000:3000 \
    -v storage_data:/app/storage/data \
    --rm -ti \
    --name goit-pythonweb-hw-03 \
    goit-pythonweb-hw-03

    App will be available at: http://localhost:3000

🐍 Option 3: Local Development (Poetry)

For local development without Docker.

  1. Install dependencies:

    poetry install
  2. Run the app:

    poetry run python src/main.py

    App will be available at: http://localhost:3000

License

This project is licensed under the MIT License. You are free to use, modify, and distribute this software in accordance with the terms of the license.

About

A lightweight Python HTTP server built with http.server and Jinja2, featuring static file serving, dynamic templates, and form submission with local JSON-based data persistence.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published