Skip to content

Amsh23/Python-MVC-Forum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python MVC Forum Application

A lightweight, custom-built forum application using pure Python (no external dependencies) with an MVC architecture, custom template engine, and SQLite database.


🚀 Quick Start

# Start the server
python main.py

# Open in browser
http://127.0.0.1:8000

👤 User Management

Sign Up

  1. Navigate to: http://127.0.0.1:8000/signup
  2. Enter username and password
  3. Click Sign Up
  4. Automatically logged in

Login

  1. Navigate to: http://127.0.0.1:8000/login
  2. Enter credentials
  3. Session stored in memory

🔐 Admin Dashboard — quick & simple

Want to make a user an admin? Follow one of these two easy methods.

Important: stop the server before editing the database to avoid in-memory state mismatch; restart the server after changes.

Method A — Quick (SQLite CLI)

  1. Stop the server (Ctrl+C).
  2. Open a terminal in the project folder and run:
sqlite3 forum.db
  1. Inside sqlite prompt run:
SELECT id, username, is_admin FROM users WHERE username = 'YOUR_USERNAME';
UPDATE users SET is_admin = 1 WHERE username = 'YOUR_USERNAME';
  1. Exit sqlite:
.exit
  1. Restart the server and log in as that user, then visit http://127.0.0.1:8000/admin to verify.

Method B — Safe (one-line Python, recommended)

  1. Stop the server.
  2. Run this from the project root (PowerShell / bash):
python - <<'PY'
from app.repository.base_repo import get_conn
u = 'YOUR_USERNAME'
conn = get_conn()
cur = conn.cursor()
cur.execute('SELECT id, username, is_admin FROM users WHERE username = ?', (u,))
print('Before ->', cur.fetchone())
cur.execute('UPDATE users SET is_admin = 1 WHERE username = ?', (u,))
conn.commit()
cur.execute('SELECT id, username, is_admin FROM users WHERE username = ?', (u,))
print('After  ->', cur.fetchone())
conn.close()
PY
  1. Restart the server and check http://127.0.0.1:8000/admin.

Revoke admin access

sqlite3 forum.db
UPDATE users SET is_admin = 0 WHERE username = 'YOUR_USERNAME';
.exit

Quick troubleshooting

  • If the SELECT returns no rows, create the user first via /signup.
  • If the admin page still doesn't load, restart the server and clear browser cookies.

That's it — two safe, simple options to set (or remove) admin status.


📋 Features

User System

  • Registration with password hashing (SHA256)
  • Session-based authentication
  • CSRF token protection
  • Role-based access (User, Admin)

Posts & Comments

  • Create, read, update, delete posts
  • Comment on posts
  • Vote on posts and comments

Social Features

  • Follow/unfollow users
  • Personalized feed
  • Reputation system
  • Badge awarding
  • Notifications

Security

  • Password hashing with random salts
  • CSRF tokens on all forms
  • Rate limiting (60 req/min default)
  • Authorization checks (401, 403)

Zero Dependencies

  • Pure Python standard library
  • sqlite3 for database
  • wsgiref for WSGI server
  • No external packages needed

🛠 Technology Stack

Component Technology
Language Python 3.10+
Server wsgiref.simple_server (WSGI)
Database SQLite
Template Engine Custom Python parser/renderer
Security SHA256 hashing, CSRF tokens, rate limiting

📁 Project Structure

Python-MVC-Forum/
├── main.py                      # Server entry point
├── config.py                    # Configuration
├── forum.db                     # SQLite database
├── README.md                    # Documentation
├── LICENSE                      # Proprietary license
│
├── core/                        # Framework core
│   ├── router.py              # URL routing
│   ├── dispatcher.py          # WSGI application
│   ├── request.py             # Request parsing
│   ├── response.py            # Response building
│   ├── session.py             # Session management
│   └── security.py            # Hashing, CSRF, rate limiting
│
├── app/
│   ├── models/                # Data models
│   ├── repository/            # Data access (CRUD)
│   ├── services/              # Business logic
│   ├── controllers/           # Route handlers
│   ├── templates/             # HTML templates
│   └── templates_engine/      # Custom template engine
│
├── static/css/style.css       # Stylesheet
├── tests/                     # Unit tests
└── requirements.txt           # Dependencies (empty)

📌 Core Features

Posts

  • Create: /posts/create (logged in only)
  • View: /posts (all posts) or /posts/{id} (single post)
  • Vote: Upvote/downvote to increase/decrease author reputation
  • Delete: Post author only

Comments

  • Add comments to posts
  • Vote on comments
  • Voting updates author's reputation

Voting System

  • Upvote (+1): Increases author reputation
  • Downvote (-1): Decreases reputation
  • One vote per user per post/comment

Badges & Reputation

Auto-awarded badges:

  • Newcomer: First post
  • Popular: 10+ votes on a post
  • Expert: 100+ reputation points
  • Moderator: Admin-awarded

View Badges: User profile page

Notifications

Sent for:

  • Comments on your posts
  • Votes on your posts
  • Follows from other users

View: Navigate to /notifications when logged in

Follow System

  • Follow users to see their posts in your feed
  • Unfollow anytime
  • Generates notifications

🔗 API Endpoints

Public Routes (No Login)

Method Endpoint Description
GET / Home (all posts)
GET /posts Posts list
GET /posts/{id} Single post view
GET /users/{username} User profile
GET /signup Signup form
POST /signup Register user
GET /login Login form
POST /login Authenticate

Protected Routes (Login Required)

Method Endpoint Description
GET /posts/create Create form
POST /posts/create Submit post
POST /posts/{id}/vote Vote on post
POST /posts/{id}/comment Add comment
GET /feed User feed
GET /notifications Notifications
GET /logout Logout

Admin Routes

Method Endpoint Required
GET /admin is_admin=1

🔒 Security

Password Hashing

Algorithm: SHA256 with random salt

Format: salt$hash
Stored: sha256(salt + password)

CSRF Protection

  1. Token generated on form GET
  2. Token stored in session
  3. Form includes hidden csrf input
  4. Token validated on POST
  5. Invalid token returns 400

Sessions

  • Stored in-memory (expires on restart)
  • HTTP-Only cookies
  • 24-hour max age
  • Contains: user, csrf token

Rate Limiting

  • 60 requests per IP per minute (default)
  • Configured in config.py
  • Sliding window per IP address

📝 Custom Template Engine

Syntax

Variables:

<h1>{{ title }}</h1>
<p>Author: {{ post.author }}</p>

Conditionals:

{% if user %}
  <p>Welcome, {{ user }}!</p>
{% else %}
  <p><a href="/login">Please sign in</a></p>
{% endif %}

Loops:

<ul>
  {% for post in posts %}
    <li>{{ post.title }} by {{ post.author }}</li>
  {% endfor %}
</ul>

Implementation

  • Parser (app/templates_engine/parser.py): Tokenizes and builds AST
  • Renderer (app/templates_engine/renderer.py): Evaluates with context

💾 Database Schema

users

id | username | password_hash | reputation | is_admin | badges | created_at

posts

id | title | content | author | votes | created_at | updated_at

comments

id | post_id | author | content | votes | created_at

votes

id | voter | voteable_id | voteable_type | value | created_at

follows

id | follower | following | created_at

notifications

id | user_id | message | is_read | created_at

badges

id | name | criteria | created_at

✅ Testing

Run All Tests

python -m unittest discover tests -v

Test Coverage

  • tests/test_router.py: URL routing and parameters
  • tests/test_template_engine.py: Variable/for/if rendering
  • tests/test_repo.py: User/post CRUD operations
  • tests/test_auth.py: Registration and authentication

Expected Result

Ran 7 tests in 0.XXXs
OK

⚙️ Configuration

Edit config.py:

HOST = '127.0.0.1'              # Server address
PORT = 8000                     # Server port
DB_PATH = 'forum.db'            # Database file
RATE_LIMIT_PER_MINUTE = 60      # Rate limit per IP

Common Changes:

Network access:

HOST = '0.0.0.0'  # Instead of 127.0.0.1

Different port:

PORT = 8001

Different database:

DB_PATH = '/var/lib/forum/forum.db'

🐛 Troubleshooting

Server won't start: "Address already in use"

Solution:

  • Change PORT in config.py
  • Or kill process: taskkill /PID <PID> /F (Windows)

CSRF token validation fails

Error: Invalid CSRF token

Solution:

  • Clear browser cookies
  • Restart server (resets sessions)
  • Ensure cookies are enabled

Template rendering error

Error: Unknown tag else

Solution:

  • Check syntax: {% endif %} closes {% if %}
  • Verify variable names: {{ post.title }} not {{ post['title'] }}
  • Use valid Python expressions

Database locked

Error: database is locked

Solution:

  • Close SQLite CLI if open
  • Restart server

Port already in use (Windows)

netstat -ano | findstr :8000
taskkill /PID <PID> /F

🏗 Architecture

Request Flow

HTTP Request
    ↓
Dispatcher (core/dispatcher.py)
    ↓
Router (core/router.py) - URL matching
    ↓
Controller (app/controllers/*) - Handler
    ↓
Service (app/services/*) - Business logic
    ↓
Repository (app/repository/*) - Data access
    ↓
Database (forum.db)
    ↓
Template (app/templates/*) - Render HTML
    ↓
Response (core/response.py)
    ↓
HTTP Response (HTML)

MVC Pattern

  • Models: Data structures
  • Views: HTML templates
  • Controllers: Route handlers
  • Repository: Data layer
  • Services: Business logic

📦 Requirements

  • Python 3.10+
  • Windows, macOS, or Linux
  • No external dependencies (pure stdlib)

🚀 Deployment Notes

For Development

python main.py

For Production

  • Use production WSGI server (Gunicorn, uWSGI)
  • Set HOST = '0.0.0.0' for network access
  • Use environment variables for config
  • Enable HTTPS/SSL
  • Use persistent session storage
  • Add database backups

📋 Checklist for New Users

  • Python 3.10+ installed
  • Repository cloned
  • Run: python main.py
  • Open: http://127.0.0.1:8000
  • Sign up for account
  • Create a post
  • Vote on posts
  • Follow users
  • View notifications
  • For admin access, see Admin Dashboard

📄 License

PROPRIETARY LICENSE - ALL RIGHTS RESERVED

© 2025 Arian (Amsh23)

You Can ✅

  • Use personally
  • Modify for personal use

You Cannot ❌

  • Copy the code
  • Distribute the code
  • Use commercially without permission
  • Reverse engineer
  • Sell the software
  • Create derivatives

Disclaimer

This software is provided "as is" without warranty. Author is not responsible for damages or data loss.

Commercial Licensing

Contact the author for commercial licensing options.


📞 Support

  • Check Troubleshooting section
  • Review test files for usage examples
  • Check inline code comments
  • Report issues via GitHub

📊 Project Stats

  • Language: Python
  • Framework: Custom MVC
  • Database: SQLite
  • Lines of Code: ~2000+
  • Test Coverage: 7 unit tests
  • Version: 1.0.0
  • Status: Production Ready

🎯 Future Enhancements

  • Persistent session storage
  • Email notifications
  • User messaging
  • Advanced search
  • Tagging system
  • Content moderation tools
  • REST API
  • Frontend JavaScript
  • Docker support
  • Deployment guides

Last Updated: November 30, 2025 Author: Amir (Amsh23) Repository: https://github.com/Amsh23/Python-MVC-Forum

About

A lightweight, zero-dependency forum built with pure Python, custom MVC architecture, and SQLite. Features user authentication, posts, comments, voting, social following, badges, notifications, and admin dashboard.

Topics

Resources

Stars

Watchers

Forks

Contributors