https://github.com/kscardinal/loto-report-generator
A python application for generating PDF reports related to lockout/tagout procedures with custom formatting, images, and fonts.
https://github.com/kscardinal/loto-report-generator
digitalocean fastapi html python reportlab-pdf server
Last synced: 4 months ago
JSON representation
A python application for generating PDF reports related to lockout/tagout procedures with custom formatting, images, and fonts.
- Host: GitHub
- URL: https://github.com/kscardinal/loto-report-generator
- Owner: kscardinal
- License: mit
- Created: 2025-05-02T20:52:27.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-05T18:27:34.000Z (7 months ago)
- Last Synced: 2025-12-09T01:13:19.835Z (7 months ago)
- Topics: digitalocean, fastapi, html, python, reportlab-pdf, server
- Language: Python
- Homepage:
- Size: 8.99 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
π loto-report-generator
loto-report-generator is a Python web application for generating, managing, and downloading LOTO (Lockout/Tagout) reports. It supports PDF generation, JSON/photo uploads, audit logging, and role-based access, all configurable via environment variables and Docker.
---
---
## Table of Contents
- [Overview](#overview)
- [Features](#features)
- [Tech Stack](#tech-stack)
- [Project Structure](#project-structure)
- [Setup](#setup)
- [Docker](#docker)
- [PDF Generation](#pdf-generation)
- [Database Management](#database-management)
- [PyTest](#pytest)
- [Web Interface](#web-interface)
- [SSH](#ssh)
- [Misc](#misc)
- [Customization](#customization)
- [API Endpoints](#api-endpoints)
- [License](#license)
---
## Overview
`loto-report-generation` is a full-stack Python application designed to automate the creation, management, and retrieval of LOTO reports. It features:
- Custom PDF generation with templates, fonts, and images
- Dynamic JSON/photo uploads for report creation
- Web interface and API endpoints for interactive management
- Role-based authentication and audit logging for security and compliance
- Dockerized deployment for easy setup across environments
This makes it ideal for industrial safety documentation, operational reporting, and automated compliance workflows.
---
## Features
- **Secure Authentication & Roles**: Supports login, account creation, and owner/admin/user roles. Sensitive actions are restricted based on role.
- **Audit Logging**: Tracks user actions like logins, report creation, uploads, deletions, and status changes with timestamps and IP addresses.
- **Automated PDF Generation**: Generates professional LOTO reports using templates, fonts, and embedded images.
- **JSON & Photo Uploads**: Accepts structured data and image files for flexible report creation.
- **Web Interface**: Interactive frontend for managing users, reports, and logs with visual status indicators and responsive design.
- **RESTful API Endpoints**: Full set of API routes for programmatic access to users, reports, files, and audit logs.
- **Environment Config via `.env`**: Supports local and production deployment using environment variables.
- **Modular & Extensible**: Components like auth, PDF generation, API, and database are self-contained and easily extendable.
- **Docker & Nginx Integration**: Full containerized setup for consistent deployments.
---
## Tech Stack
- **Frontend**: HTML, CSS, JavaScript, TypeScript, Markdown
- **Backend**: Python, FastAPI, Jinja2
- **Database**: MongoDB with GridFS for file storage
- **Authentication & Security**: JWT, role-based access
- **Other Tools**: Docker, Nginx, UV, Pytest, ReportLab, GitHub Actions
---
## Project Structure
```
loto-report-generator/
ββ .env # Environment variables
ββ .env.dev # Local/test environment variables
ββ Dockerfile # Python image for the app
ββ docker-compose.yml # Docker setup: FastAPI, MongoDB, Nginx
ββ includes/ # Images, fonts, and other static assets
ββ logs/ # Application and server logs
ββ mongod.conf # MongoDB configuration
ββ nginx.conf # Nginx reverse proxy config
ββ src/
β βββ api/ # Backend FastAPI endpoints and utilities
β β βββ main.py # FastAPI entry point
β β βββ auth_utils.py # Authentication helpers
β β βββ logging_config.py # Central logging config
β βββ database/ # MongoDB helper scripts
β βββ pdf/ # PDF generation scripts
β βββ tests/ # Pytest test cases
β βββ web/ # Frontend web interface
β βββ main.html # Entry HTML page
β βββ static/ # CSS, JS, and assets
β βββ templates/ # Jinja2 HTML templates
ββ temp/ # Temporary files
```
---
## Setup
1. **Install uv**
Download and install [uv](https://github.com/astral-sh/uv) from the official repository or use:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
uv self update
uv python install 3.13.2
```
2. **Create a virtual environment**
```bash
uv venv
source .venv/bin/activate
# --- OR ---
source .venv/Scripts/activate
```
3. **Confirm virtual environment**
```bash
# --- MacOS ---
where python
# --- Windows ---
which python
```
3. **Install dependencies**
```bash
# --- Might need to clear cache if it is an issue ---
uv cache clean # Optional
uv sync
uv pip install -e .
```
4. **Add a `.env` file**
- Create a file named `.env` in the project root directory.
- Add the following line (replace with your server IP, no quotes):
```bash
SERVER_IP = your.server.ip.address
```
- Should start with http:// (ex. SERVER_IP=http://127.0.0.1:8000)
---
### Docker
1. Clone the repo
```bash
git clone
cd loto-report-generator
```
2. Create the `.env` file
```bash
vi .env
```
- add the following
```text
# Mongo Credentials
MONGO_USER=...
MONGO_PASSWORD=...
MONGO_HOST=...
MONGO_PORT=...
MONGO_DB=...
# App Config
APP_ENV=dev
# Server IP
SERVER_IP=http://{SERVER_IP_ADDRESS}:8000
TEST_SERVER_IP=http://localhost:8000
# JWT
SECRET_KEY=...
ADMIN_JWT=...
# email
SENDER_EMAIL=...
SENDER_PASSWORD=...
SENDGRID_API_KEY=...
DEFAULT_EMAIL=...
# Cleanup URL
CLEANUP_URL=http://lotogenerator.app/cleanup_orphan_photos
```
3. Start Docker
```bash
docker-compose up -d --build
```
- remove `-d` if you want to see everything behind the covers
4. Test Connection
```bash
docker logs -f fastapi_app
docker logs -f mongo_db
curl http:///api/docs
```
- The first 2 should open logs for both `uvicron` and `mongo`
- The last should return the FastAPI docs page if Nginx is configured correctly
5. Run a test docker container locally
```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml --env-file .env.dev up --build
```
---
## PDF Generation
1. Start server
``` bash
uvicorn src.api.main:app --reload --host 127.0.0.1 --port 8000
```
2. Add temp assets to the `temp/` folder for usage in the scripts
3. Run the automate_pdf script:
```python
python automate_pdf.py $JSON_FILE
```
-- or --
```python
python generate_pdf.py $JSON_FILE
```
---
## Database Management
1. Configure and start MongoDB (Mac example)
``` bash
# one-time
brew tap mongodb/brew
brew install mongodb-community@7.0
# run on login (recommended)
brew services start mongodb-community@7.0
# verify itβs listening
lsof -nP -iTCP:27017 -sTCP:LISTEN
```
2. Double check mongosh
```bash
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --eval "db.adminCommand({ ping: 1 })"
```
3. Look at the current database on the web
``` txt
http://localhost:8000/pdf_list
```
---
### PyTest
1. Install `poppler`
``` bash
# Windows
https://github.com/oschwartz10612/poppler-windows/releases/
```
- Download latest ZIP release on GitHub
- Extract the zip somewhere, e.g. `C:\tools\poppler-23.12.0\`
- or latest release number
- if folder doesn't exist, add it
- Add the `bin` folder to your`PATH` environment variable:
- `C:\tools\poppler-23.12.0\Library\bin`
- System variables
``` bash
# MacOS
brew install poppler
```
2. Check `poppler` installation
``` bash
pdfinfo -v
pdftoppm -v
```
3. Double check `pre-commit` and `pre-push` hooks are updated
``` bash
uv add pre-commit # if not already added
pre-commit install --hook-type pre-commit --hook-type pre-push
pre-commit autoupdate
pre-commit run --all-files
```
4. Run the tests
``` bash
pytest -v -s --no-summary src/tests/test_pdf_scripts.py
```
- `-q` is optional to reduce more of the unnecessary text in the test
5. Check the results
============= ___ passed in ___s =============
- You are looking out for all of them to say `PASSED`
---
### Server CRON jobs
1. **Python Interpreter Path:** Find where your Python executable is located.
```bash
which python3
```
2. **Script Path:** Find the full path to your Python file
```bash
pwd {SCRIPT_FILE}
```
3. **Open the Crontab Editor:** This command opens your user-specific cron schedule file.
```bash
crontab -e
```
4. Set up task (server is in UTC time +5)
```bash
0 8 * * * {PYTHON_PATH} {SCRIPT_PATH} >> {LOG_PATH} 2>&1
```
---
## Web Interface
1. Get TypeScript running
```bash
npm install -D typescript
npx tsc --init
```
2. Compile TypeScript to JavaScript
```bash
npx tsc src/web/scripts/input_form_3.ts --outDir src/web/scripts
```
---
### SSH
1. Start agent
``` bash
eval "$(ssh-agent -s -t 8h)"
```
2. Add key to agent
```bash
ssh-add ~/.ssh/id_ed25519
```
- Enter passphrase and it should stop bugging you
3. Add this to the `.bashrc` or `.zshrc` file
```bashrc
SSH_ENV="$HOME/.ssh/agent-environment"
function start_agent {
echo "Starting ssh-agent..."
ssh-agent -s > "$SSH_ENV"
source "$SSH_ENV" > /dev/null
ssh-add -t 8h ~/.ssh/id_ed25519
}
# Source ssh-agent environment file if exists
if [ -f "$SSH_ENV" ]; then
source "$SSH_ENV" > /dev/null
# Check if agent is still running
ps -p $SSH_AGENT_PID > /dev/null || {
start_agent;
}
else
start_agent;
fi
```
---
### Misc
1. Count lines of code
```bash
git ls-files src | xargs wc -l | sort -n
find . -type f -print0 | xargs -0 wc -l
```
2. Counts the number of times a file has been committed
```bash
git log --diff-filter=AM --name-only --pretty=format: | grep -v '^$' | sort | uniq -c | sort -n
```
3. Git file endings
```bash
git config --global core.autocrlf
```
---
## Customization
- Upload `.json` file with your own data
- Modify `generate_pdf.py` for custom report layouts
- Place additional images or fonts in the `inlcudes/` folder as needed
---
## API Endpoints
```
http://localhost:8000/docs
```
- For more info on each endpoint
| Endpoint | Methods | Category | Description |
|----------------------------------------|-----------|-------------------|-------------------------------------------------------------------------------------|
| `/health` | GET | π©Ί Health | Simple public health-check endpoint returning a JSON status payload. |
| `/login` | GET, POST | π Auth Page | Displays the login page and processes user authentication. |
| `/logout` | POST | π Auth API | Logs out the current user by clearing the authentication cookie/token. |
| `/create_account` | GET, POST | π Auth Page | Displays the create-account page and creates a new (inactive) user. |
| `/check-username-email` | GET | π Auth API | Checks whether a username or email is already in use during signup. |
| `/forgot_password` | GET | π Auth Page | Displays the forgot-password page where users can request a backup code. |
| `/send_backup_code` | POST | π Auth API | Sends the current backup code to the specified email and rotates the code. |
| `/verify_backup_code` | POST | π Auth API | Verifies a submitted backup code for an email and rotates to a new code. |
| `/update-verification-attempts` | POST | βοΈ Auth API | Updates the verification-attempt counter for a given email address. |
| `/reset_password` | POST | π Auth API | Resets a userβs password and sends a confirmation email. |
| `/jwt_test` | GET | βοΈ Auth API | Verifies the current JWT and returns a success JSON response. |
| `/users` | GET | π₯οΈ Admin Page | Displays the HTML user management page (owner only). |
| `/users_json` | GET | βοΈ Admin API | Returns JSON data for all users (owner only). |
| `/change_status` | POST | βοΈ Admin API | Activates or deactivates a user account (owner only). |
| `/update_role` | POST | βοΈ Admin API | Updates a userβs role (owner only). |
| `/delete_user` | POST | βοΈ Admin API | Deletes a user account and sends a notification email (owner only). |
| `/update-login-attempts` | POST | βοΈ Admin API | Updates the stored login-attempt counter for a specified user (JWT-protected). |
| `/audit_logs` | GET | π₯οΈ Admin Page | Displays the audit log viewer page (owner only). |
| `/audit_logs_json` | GET | βοΈ Admin API | Returns recent audit logs as JSON (owner only). |
| `/create_report` | GET | π₯οΈ Reports Page | Displays the HTML form for creating a new report. |
| `/upload/` | POST | βοΈ Reports API | Uploads JSON report data and photos to create or update a report in MongoDB/GridFS. |
| `/pdf_list` | GET | π₯οΈ Reports Page | Displays the HTML page listing all available reports. |
| `/pdf_list_json` | GET | βοΈ Reports API | Returns a paginated JSON list of reports and their metadata. |
| `/view_report/{report_name}` | GET | π₯οΈ Reports Page | Displays detailed metadata and photos for a single report as an HTML page. |
| `/metadata/{report_name}` | GET | βοΈ Reports API | Returns stored metadata for a specific report (without JSON payload or photos). |
| `/download_report_files/{report_name}` | GET | βοΈ Reports API | Returns JSON containing download URLs for a reportβs JSON and photos. |
| `/download_json/{report_name}` | GET | βοΈ Reports API | Downloads the raw JSON data for the specified report. |
| `/download_pdf/{report_name}` | GET | βοΈ Reports API | Downloads or streams the generated PDF file for the specified report. |
| `/download_photo/{photo_id}` | GET | βοΈ Reports API | Downloads an individual photo file from GridFS by its ID. |
| `/photo/{photo_id}` | GET | βοΈ Reports API | Returns a photo image from GridFS by its ID for inline display. |
| `/remove_report/{report_name}` | GET, POST | βοΈ Reports API | Deletes a report document from the database (shared photos are retained). |
| `/cleanup_orphan_photos` | GET, POST | π§Ή Maintenance | Deletes photos in GridFS that are not referenced by any report. |
| `/clear/` | POST | π§Ή Maintenance | Clears all temporary files in the serverβs temp directory. |
| `/db_status` | GET | π§© Maintenance | Checks the database connection and returns a status message. |
---
## License
This project is licensed under the MIT License, which means you are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, as long as you include the original copyright and license notice in any copy of the software. The software is provided "as is," without warranty of any kind.