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.
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.
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.
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 a404 Not Found
error - Listen on port
3000
When the form on message.html
is submitted, the application must:
- Convert the received byte-string into a Python dictionary
- Save the resulting data into a JSON file
data.json
located insidestorage
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()
.
Create a new route /read
, which renders a Jinja2 template that displays all stored messages from data.json
.
- Create a
Dockerfile
to run the application in a Docker container - Use Docker
volumes
to store thestorage/data.json
file outside the container
- Routing and Pages
- The application includes two HTML pages:
index.html
andmessage.html
- Static files (
style.css
,logo.png
) are served correctly - The server runs on port
3000
- The application includes two HTML pages:
- 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" } }
- The form on
- Message Display
- A
GET
request to/read
returns a Jinja2-based page - The page renders all saved messages from the JSON file
data.json
- A
- Error Handling
A
404 Not Found
triggers to serveerror.html
page - Data Storage
- Messages are saved in
storage/data.json
as valid JSON - Each key represents the exact time the message was received
- Messages are saved in
- A
Dockerfile
is created that allows running the app as a Docker container - A volume is used to persist
data.json
outside the container
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.
- 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
.
βββ 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
This project is also published to Docker Hub.
You can pull and run it directly:
docker pull rmsh/goit-pythonweb-hw-03
Messages shown on the rendered /read
page:
Empty messages state at rendered /read
page:
Rendered 404 Not Found error page:
Rendered 500 Internal Server error page:
Served static resources:
This guide will help you set up the environment and run the project.
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.
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.
You can either run the project in a fully containerized development environment (recommended) or set it up locally using a virtual environment.
This method runs app using Docker Compose
docker compose up --build
This will:
- Build the FastAPI application image.
- Create and run the container with necessary ports.
- Use a volume for data persistence.
The app will be available at: http://localhost:3000
To stop:
docker compose down
For those who want a bit more control using
docker run
.
-
Build the Docker image:
docker build -t goit-pythonweb-hw-03 .
-
(Optional) Create a named volume for persistent data:
Only needed once before first run:
docker volume create storage_data
-
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
For local development without Docker.
-
Install dependencies:
poetry install
-
Run the app:
poetry run python src/main.py
App will be available at: http://localhost:3000
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.