The AR4T Paradigm: A Playbook for Self-Contained Python Applications

The AR4T Paradigm: A Playbook for Self-Contained Python Applications

The AR4T Paradigm: A Playbook for Self-Contained Python Applications

The "AR4T" (A Radically-reduced Text) paradigm reimagines Python development, advocating for the simplicity of single, self-contained script files. This post presents the argument for this approach and provides a technical playbook for its implementation.

The Argument for AR4T

Modern Python development often involves intricate project scaffolding, virtual environments, and multiple dependency files (requirements.txt, pyproject.toml). While essential for large-scale applications, this complexity can be burdensome for smaller projects, utilities, and rapid prototyping. The AR4T paradigm proposes a departure from this for the sake of portability, simplicity, and reduced cognitive overhead.

Core Principles:

  • One File to Rule: The entire application logic, including tests, resides in a single .py file.
  • Embedded Dependencies: Dependency information is declared directly within the script, leveraging modern tools that can read this metadata.
  • Explicit Execution Modes: The script can be run in different modes (e.g., application, test) controlled by command-line arguments.

Advantages:

  • Simplified Distribution: Sharing a single .py file is straightforward.
  • Atomic Changes: A change to a feature and its corresponding test exists in the same file, making commits and reviews more coherent.
  • Enhanced Portability: A script that manages its own dependencies and contains its own tests is easier to run and verify on different machines.
  • Lower Barrier to Entry: New contributors can get started immediately without complex setup procedures.

Technical Playbook: AR4T in Practice

This playbook demonstrates how to build and test a report-writing application in the AR4T style. The application will be a simple tool for writing reports with a GUI, a local database, and AI-powered text summarization, using PyQt6 and SQLite.

The Self-Contained Script: report_writer.py

The script is structured with a dedicated testing section that can be triggered from the command line. Note the PEP 723 compliant header for declaring dependencies.
# /// script
# requires-python = ">=3.9"
# dependencies = [
#   "pyqt6",
#   "requests",
# ]
# ///

import sys
import sqlite3
import requests
import unittest
import os
from unittest.mock import patch, MagicMock

# --- Part 1: Application Code ---

# Check if running in a GUI-less environment (like a CI server)
IS_HEADLESS = 'CI' in os.environ

# Only import PyQt6 if not in headless mode to avoid errors on servers
if not IS_HEADLESS:
    from PyQt6.QtWidgets import (
        QApplication, QMainWindow, QTextEdit, QLineEdit,
        QPushButton, QVBoxLayout, QWidget, QListWidget,
        QMessageBox, QDialog, QFormLayout,
    )
    from PyQt6.QtCore import Qt

# --- AI Integration ---
def summarize_text(text_to_summarize: str, api_key: str) -> str:
    # ... function implementation ...

# --- Database Management ---
DB_FILE = "reports.db"
TEST_DB_FILE = "test_reports.db"

def get_db_path(is_test=False):
    # ... function implementation ...

def init_db(is_test=False):
    # ... function implementation ...

def save_report(title: str, content: str, report_id: int = None, is_test=False):
    # ... function implementation ...

# --- User Interface (Loaded Conditionally) ---
if not IS_HEADLESS:
    class ApiKeyDialog(QDialog):
        # ... UI code ...
        pass

    class MainWindow(QMainWindow):
        # ... UI code ...
        pass

# --- Part 2: The AR4T Testing Paradigm ---

class TestReportWriter(unittest.TestCase):
    """
    Contains all tests for the report writer application.
    These tests run against a separate, temporary test database.
    """
    def setUp(self):
        # ... test setup ...

    def tearDown(self):
        # ... test teardown ...

    def test_save_and_retrieve_report(self):
        # ... test implementation ...

    @patch('__main__.requests.post')
    def test_summarize_api_call(self, mock_post):
        # ... test implementation ...

    def test_summarize_text_too_short(self):
        # ... test implementation ...

# --- Part 3: The Entry Point ---

def main_app():
    # ... app entry point ...

def main_test():
    # ... test entry point ...

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1].lower() == 'test':
        main_test()
    else:
        print("Starting AR4T Report Writer...")
        main_app()

AR4T and GitHub Flow Integration

The single-file nature of AR4T simplifies the standard GitHub Flow. The key is to automate the running of the embedded tests using a service like GitHub Actions.

The Workflow:

  1. Create a Branch: A developer creates a new feature branch from main.
  2. Develop and Commit: The developer modifies report_writer.py to add the new feature and a corresponding test for it in the TestReportWriter class within the same file.
  3. Local Testing: Before pushing, the developer runs the tests locally.
    # Using a tool like uv to handle dependencies
    uv run report_writer.py test
  4. Push and Create Pull Request: The developer pushes the branch and opens a Pull Request (PR) on GitHub.
  5. Automated Testing (CI): GitHub Actions automatically triggers on the PR. It checks out the code, installs dependencies using uv, and runs the tests in headless mode.

Sample GitHub Actions Workflow: .github/workflows/ci.yml

name: AR4T CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.10'

    - name: Install uv
      run: pip install uv

    - name: Run Tests
      # The CI=true environment variable activates headless mode in the script
      env:
        CI: true
      run: uv run report_writer.py test

This integrated approach ensures that the simplicity of a single file does not come at the cost of quality or collaboration. It maintains a high degree of confidence in the codebase while keeping the development process lightweight and accessible.

Comments

Popular posts from this blog

Code-Gurus Wanted: Bridging the gap - supporting the transition.

Using throw away app to help me get back into the vibe space post stack/structure/perfection enlightenment

Re-finding my coding muse: step 1