From 227c74294fe1287e9c4d64f4d3dbda014536c9bf Mon Sep 17 00:00:00 2001
From: HotSwapp <47397945+HotSwapp@users.noreply.github.com>
Date: Mon, 6 Oct 2025 18:27:44 -0500
Subject: [PATCH] feat: Set up SessionMiddleware and Jinja2 Template
Configuration
- Add SECRET_KEY environment variable and .env file for session management
- Configure SessionMiddleware with FastAPI for user session handling
- Set up Jinja2 template engine with template directory configuration
- Mount static files directory for CSS, JS, and image assets
- Create comprehensive base.html template with Bootstrap 5 CDN
- Add Bootstrap Icons and custom styling support
- Include responsive navigation with user authentication state
- Create placeholder CSS and JavaScript files for customization
- Add aiofiles dependency for static file serving
This establishes the web framework foundation with session management
and templating system ready for frontend development.
---
.env | 3 ++
app/main.py | 33 +++++++++++++++-
app/templates/base.html | 88 ++++++++++++++++++++++++++++++++++++++++-
requirements.txt | 1 +
static/css/custom.css | 51 ++++++++++++++++++++++++
static/js/custom.js | 82 ++++++++++++++++++++++++++++++++++++++
6 files changed, 256 insertions(+), 2 deletions(-)
create mode 100644 .env
create mode 100644 static/css/custom.css
create mode 100644 static/js/custom.js
diff --git a/.env b/.env
new file mode 100644
index 0000000..85236cb
--- /dev/null
+++ b/.env
@@ -0,0 +1,3 @@
+# Delphi Database Environment Configuration
+SECRET_KEY=your-secret-key-here-change-this-in-production
+DATABASE_URL=sqlite:///./delphi.db
diff --git a/app/main.py b/app/main.py
index 1551825..a92da2f 100644
--- a/app/main.py
+++ b/app/main.py
@@ -5,20 +5,36 @@ This module initializes the FastAPI application, sets up database connections,
and provides the main application instance.
"""
+import os
import logging
from contextlib import asynccontextmanager
-from fastapi import FastAPI, Depends
+from fastapi import FastAPI, Depends, Request
+from fastapi.middleware.sessions import SessionMiddleware
+from fastapi.middleware.cors import CORSMiddleware
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
+from dotenv import load_dotenv
from .database import create_tables, get_db, get_database_url
from .models import User
+# Load environment variables
+load_dotenv()
+
+# Get SECRET_KEY from environment variables
+SECRET_KEY = os.getenv("SECRET_KEY")
+if not SECRET_KEY:
+ raise ValueError("SECRET_KEY environment variable must be set")
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
+# Configure Jinja2 templates
+templates = Jinja2Templates(directory="app/templates")
+
@asynccontextmanager
async def lifespan(app: FastAPI):
@@ -54,6 +70,21 @@ app = FastAPI(
lifespan=lifespan
)
+# Add CORS middleware for cross-origin requests
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"], # In production, specify allowed origins
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+# Add SessionMiddleware for session management
+app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
+
+# Mount static files directory
+app.mount("/static", StaticFiles(directory="static"), name="static")
+
@app.get("/")
async def root():
diff --git a/app/templates/base.html b/app/templates/base.html
index ebe8c10..a16f733 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -1 +1,87 @@
-
+
+
+
+
+
+ {% block title %}Delphi Database{% endblock %}
+
+
+
+
+
+
+
+
+
+
+ {% block extra_head %}{% endblock %}
+
+
+
+
+
+
+
+ {% block content %}{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+ {% block extra_scripts %}{% endblock %}
+
+
diff --git a/requirements.txt b/requirements.txt
index 972ac95..02c7c88 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,3 +7,4 @@ passlib[bcrypt]==1.7.4
python-dotenv==1.0.0
uvicorn[standard]==0.24.0
jinja2==3.1.2
+aiofiles==23.2.1
diff --git a/static/css/custom.css b/static/css/custom.css
new file mode 100644
index 0000000..5850552
--- /dev/null
+++ b/static/css/custom.css
@@ -0,0 +1,51 @@
+/* Custom CSS for Delphi Database */
+
+/* Additional styles can be added here */
+body {
+ background-color: #f8f9fa;
+}
+
+/* Custom navbar styles */
+.navbar-brand {
+ font-weight: bold;
+}
+
+/* Custom card styles */
+.card {
+ box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+ border: 1px solid rgba(0, 0, 0, 0.125);
+}
+
+/* Custom button styles */
+.btn-primary {
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+
+.btn-primary:hover {
+ background-color: #0b5ed7;
+ border-color: #0a58ca;
+}
+
+/* Custom form styles */
+.form-control:focus {
+ border-color: #86b7fe;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+/* Custom table styles */
+.table th {
+ background-color: #f8f9fa;
+ border-bottom: 2px solid #dee2e6;
+}
+
+/* Custom alert styles */
+.alert {
+ border: none;
+ border-radius: 0.375rem;
+}
+
+/* Custom footer styles */
+footer {
+ margin-top: auto;
+}
diff --git a/static/js/custom.js b/static/js/custom.js
new file mode 100644
index 0000000..6dc4d33
--- /dev/null
+++ b/static/js/custom.js
@@ -0,0 +1,82 @@
+// Custom JavaScript for Delphi Database
+
+document.addEventListener('DOMContentLoaded', function() {
+ // Initialize tooltips if any
+ var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
+ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
+ return new bootstrap.Tooltip(tooltipTriggerEl);
+ });
+
+ // Auto-hide alerts after 5 seconds
+ var alerts = document.querySelectorAll('.alert:not(.alert-permanent)');
+ alerts.forEach(function(alert) {
+ setTimeout(function() {
+ var bsAlert = new bootstrap.Alert(alert);
+ bsAlert.close();
+ }, 5000);
+ });
+
+ // Confirm delete actions
+ var deleteButtons = document.querySelectorAll('[data-confirm-delete]');
+ deleteButtons.forEach(function(button) {
+ button.addEventListener('click', function(e) {
+ var message = this.getAttribute('data-confirm-delete') || 'Are you sure you want to delete this item?';
+ if (!confirm(message)) {
+ e.preventDefault();
+ }
+ });
+ });
+
+ // Form validation enhancement
+ var forms = document.querySelectorAll('.needs-validation');
+ Array.prototype.slice.call(forms).forEach(function(form) {
+ form.addEventListener('submit', function(event) {
+ if (!form.checkValidity()) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ form.classList.add('was-validated');
+ }, false);
+ });
+
+ // Dynamic form field enabling/disabling
+ var toggleFields = document.querySelectorAll('[data-toggle-field]');
+ toggleFields.forEach(function(element) {
+ element.addEventListener('change', function() {
+ var targetSelector = this.getAttribute('data-toggle-field');
+ var targetField = document.querySelector(targetSelector);
+ if (targetField) {
+ targetField.disabled = !this.checked;
+ }
+ });
+ });
+});
+
+// Utility functions
+function formatDate(dateString) {
+ if (!dateString) return '';
+ var date = new Date(dateString);
+ return date.toLocaleDateString();
+}
+
+function formatCurrency(amount) {
+ if (!amount) return '$0.00';
+ return new Intl.NumberFormat('en-US', {
+ style: 'currency',
+ currency: 'USD'
+ }).format(amount);
+}
+
+function showLoading(button) {
+ if (button) {
+ button.disabled = true;
+ button.innerHTML = 'Loading...';
+ }
+}
+
+function hideLoading(button, originalText) {
+ if (button) {
+ button.disabled = false;
+ button.innerHTML = originalText;
+ }
+}