The codebase has been organized into a modular structure for better maintainability, testing, and understanding.
src/
├── terminal_chat.py ← Original monolithic version (WORKING)
├── lib/ ← Reusable library modules
│ ├── __init__.py - Library exports
│ ├── utils.py - Utilities & constants
│ ├── encryption.py - Encryption/decryption
│ ├── server.py - ChatServer class (TODO)
│ └── client.py - ChatClient class (TODO)
└── modular/ ← Modular version
├── terminal_chat_modular.py - Entry point using lib/
└── MODULAR_STRUCTURE.md - This file
- Purpose: Common utilities and constants
- Contents:
- ANSI color codes (BLUE, GREEN, YELLOW, RED, CYAN, MAGENTA, RESET)
timestamp()function
- Size: 20 lines
- Dependencies: datetime
- Purpose: Encryption/decryption functionality
- Contents:
Encryptionclassencrypt(text)methoddecrypt(encrypted_text)method
- Size: 76 lines
- Dependencies: subprocess, sys, utils
- Purpose: Server-side functionality
- Contents:
ChatServerclass (~330 lines)- Client handling
- Message broadcasting
- File transfer handling
- Command processing
- Logging
- Dependencies: socket, threading, os, shutil, logging, utils, encryption
- Purpose: Client-side functionality
- Contents:
ChatClientclass (~230 lines)- Message sending/receiving
- File transfer
- Color-coded display
- Command processing
- Dependencies: socket, threading, os, base64, utils, encryption
- Purpose: Main entry point using modular components
- Contents:
- Import from lib/
main()function- Command-line argument parsing
- Size: ~50 lines
- Dependencies: lib.server, lib.client, sys
- Each module has a single responsibility
- Easier to locate and fix bugs
- Changes isolated to specific modules
- Individual components can be tested separately
- Mock dependencies easily
- Better test coverage
- Smaller, focused files
- Clear module boundaries
- Better documentation possibilities
- Encryption module can be used elsewhere
- Server/Client classes as libraries
- Utils shared across project
- Multiple developers can work on different modules
- Less merge conflicts
- Clear ownership boundaries
┌─────────────────────────────────────────────┐
│ terminal_chat_modular.py │
│ (Entry Point) │
│ - Parse arguments │
│ - Initialize server/client │
└──────────────┬──────────────┬───────────────┘
│ │
┌──────▼──────┐ ┌───▼──────┐
│ Server │ │ Client │
│ │ │ │
│ - Listen │ │ - Connect│
│ - Broadcast │ │ - Send │
│ - Handle │ │ - Receive│
└──────┬──────┘ └────┬─────┘
│ │
└──────┬───────┘
│
┌─────────▼──────────┐
│ Encryption │
│ │
│ - encrypt() │
│ - decrypt() │
└─────────┬──────────┘
│
┌─────────▼──────────┐
│ Utils │
│ │
│ - Colors │
│ - timestamp() │
└────────────────────┘
python3 src/terminal_chat.py listen 4444 pass123 Admin
python3 src/terminal_chat.py connect localhost 4444 pass123 Alicepython3 src/modular/terminal_chat_modular.py listen 4444 pass123 Admin
python3 src/modular/terminal_chat_modular.py connect localhost 4444 pass123 Alicefrom lib import ChatServer, ChatClient, Encryption
# Create server
server = ChatServer(4444, "password", "Admin")
server.run()
# Or create client
client = ChatClient("localhost", 4444, "password", "Alice")
client.run()- ✅ Phase 1: Extract utils and encryption (DONE)
- 🚧 Phase 2: Extract server class
- 🚧 Phase 3: Extract client class
- 🚧 Phase 4: Create modular entry point
- 🚧 Phase 5: Update tests to test modules
- 🚧 Phase 6: Update documentation
# tests/test_encryption.py
from lib.encryption import Encryption
def test_encrypt_decrypt():
enc = Encryption("password")
encrypted = enc.encrypt("hello")
decrypted = enc.decrypt(encrypted)
assert decrypted == "hello"
# tests/test_utils.py
from lib.utils import timestamp
def test_timestamp_format():
ts = timestamp()
assert len(ts) == 8
assert ts[2] == ':'# tests/test_integration.py
from lib import ChatServer, ChatClient
def test_server_client_communication():
# Test server-client message exchange
pass- Original file preserved:
src/terminal_chat.pyremains unchanged - Gradual migration: Can be done incrementally
- Backwards compatible: Old code continues to work
- Future proof: Easy to add new features as modules
To complete the modularization:
- Extract
ChatServerclass tolib/server.py - Extract
ChatClientclass tolib/client.py - Create
modular/terminal_chat_modular.pyentry point - Update tests to import from lib/
- Update documentation
Each step can be done independently without breaking the original version!