Metadata-Version: 2.4
Name: monoframe
Version: 0.0.1
Summary: A lightweight, single-tenant web framework extracted from Frappe
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: babel~=2.16.0
Requires-Dist: beautifulsoup4~=4.13.5
Requires-Dist: bleach-allowlist~=1.0.3
Requires-Dist: bleach~=6.3.0
Requires-Dist: chardet~=5.2.0
Requires-Dist: click<8.2,>=8.0
Requires-Dist: croniter~=6.0.0
Requires-Dist: cryptography~=46.0.3
Requires-Dist: cssutils~=2.11.1
Requires-Dist: email-reply-parser~=0.5.12
Requires-Dist: filelock~=3.20.1
Requires-Dist: filetype~=1.2.0
Requires-Dist: hiredis~=3.3.0
Requires-Dist: html5lib~=1.1
Requires-Dist: ipython~=8.37.0
Requires-Dist: jinja2~=3.1.6
Requires-Dist: ldap3~=2.9.1
Requires-Dist: markdown2~=2.5.4
Requires-Dist: markdownify~=1.2.2
Requires-Dist: markupsafe~=3.0.3
Requires-Dist: mysqlclient==2.2.7
Requires-Dist: nh3~=0.3.2
Requires-Dist: num2words~=0.5.14
Requires-Dist: oauthlib~=3.3.1
Requires-Dist: openpyxl~=3.1.5
Requires-Dist: orjson~=3.11.5
Requires-Dist: passlib~=1.7.4
Requires-Dist: phonenumbers~=9.0.21
Requires-Dist: pillow~=12.0.0
Requires-Dist: premailer~=3.10.0
Requires-Dist: psutil~=7.0.0
Requires-Dist: psycopg2-binary~=2.9.11
Requires-Dist: pycountry~=24.6.1
Requires-Dist: pydantic~=2.12.5
Requires-Dist: pyjwt~=2.10.1
Requires-Dist: pymysql==1.1.2
Requires-Dist: pyopenssl~=25.3.0
Requires-Dist: pyotp~=2.9.0
Requires-Dist: pypdf==6.6.2
Requires-Dist: pypika~=0.48.9
Requires-Dist: pyqrcode~=1.2.1
Requires-Dist: python-dateutil~=2.9.0.post0
Requires-Dist: python-dotenv
Requires-Dist: pytz==2025.2
Requires-Dist: pyyaml~=6.0.3
Requires-Dist: rauth~=0.7.3
Requires-Dist: redis~=7.1.0
Requires-Dist: requests-oauthlib~=2.0.0
Requires-Dist: requests~=2.32.5
Requires-Dist: restrictedpython~=8.1
Requires-Dist: rich
Requires-Dist: rq==2.6.1
Requires-Dist: rsa~=4.9.1
Requires-Dist: semantic-version~=2.10.0
Requires-Dist: sql-metadata~=2.19.0
Requires-Dist: sqlparse~=0.5.5
Requires-Dist: tenacity~=9.1.2
Requires-Dist: terminaltables~=3.1.10
Requires-Dist: traceback-with-variables~=2.2.1
Requires-Dist: typer
Requires-Dist: typing-extensions<5,>=4.15.0
Requires-Dist: vobject~=0.9.9
Requires-Dist: websockets~=15.0.1
Requires-Dist: werkzeug==3.1.5
Requires-Dist: whoosh~=2.7.4
Requires-Dist: xlrd~=2.0.2
Requires-Dist: zxcvbn~=4.5.0
Provides-Extra: dev
Requires-Dist: gitpython~=3.1.45; extra == 'dev'
Requires-Dist: pyngrok~=7.5.0; extra == 'dev'
Requires-Dist: watchdog~=6.0.0; extra == 'dev'
Provides-Extra: google
Requires-Dist: google-api-python-client~=2.188.0; extra == 'google'
Requires-Dist: google-auth-oauthlib~=1.2.4; extra == 'google'
Requires-Dist: google-auth~=2.48.0; extra == 'google'
Provides-Extra: pdf
Requires-Dist: pdfkit~=1.0.0; extra == 'pdf'
Requires-Dist: pydyf==0.12.1; extra == 'pdf'
Requires-Dist: weasyprint==68.0; extra == 'pdf'
Provides-Extra: telemetry
Requires-Dist: posthog~=5.0.0; extra == 'telemetry'
Requires-Dist: sentry-sdk~=1.45.1; extra == 'telemetry'
Description-Content-Type: text/markdown

# Monoframe

### The Frappe Framework, Distilled.

**Monoframe** is a lightweight, single-tenant web framework for Python. It takes the powerful metadata-driven engine of [Frappe](https://frappe.io) and strips away the multi-tenancy, the "Bench" tool, and the complex deployment architecture.

It is Frappe for developers who want to build **one** solid application, not manage a hosting platform.

---

## Why Monoframe?

The original Frappe Framework is an engineering marvel, but it was built to run an ERP ecosystem (ERPNext) with hundreds of sites on a single server. This architectural decision brings massive complexity:

* **Bloat:** A standard install can weigh over 1.8GB.
* **Complexity:** Requires a custom CLI tool (`bench`) just to manage processes.
* **Obscurity:** Database connections rely on HTTP host headers and folder lookups.

**Monoframe changes the philosophy:**

1. **No Bench:** We use standard Python tooling (`pip`, `venv`, `pyproject.toml`).
2. **Single Tenant:** One application = One Database. Configuration happens in `.env`, not in a `common_site_config.json` buried three folders deep.
3. **Lightweight:** We stripped the "platform" code to focus on the "application" code.

## Comparison

| Feature | Original Frappe | Monoframe |
| --- | --- | --- |
| **Architecture** | Multi-Tenant (Sites) | Monolithic (Single App) |
| **Process Manager** | `bench` (Custom) | Standard Python / ASGI |
| **Config** | JSON files in `/sites` | `.env` file |
| **Dependency Mgmt** | `apps.txt` + `bench get-app` | `requirements.txt` / `poetry` |
| **Footprint** | Heavy (~1.8GB) | Light (Goal: <200MB) |
| **DX** | "The Frappe Way" | Standard Python Way |

---

## Quick Start

*(Note: Monoframe is currently in active development. These commands are the target DX.)*

### 1. Installation

Monoframe is a standard Python package. You don't need to install a system-wide CLI tool first.

```bash
pip install monoframe

```

### 2. Create a Project

Generate a clean, flat project structure. No `apps` folder, no `sites` folder.

```bash
monoframe new my_cool_app
cd my_cool_app

```

### 3. Run Development Server

Connects to the DB specified in your `.env` and starts the server.

```bash
monoframe start
# Server running at http://localhost:8000

```

---

## 📂 Project Structure

Monoframe simplifies the directory hierarchy significantly.

**Before (Frappe Bench):**

```text
frappe-bench/
├── apps/
│   ├── frappe/
│   └── my_app/
├── sites/
│   ├── assets/
│   ├── site1.local/
│   └── common_site_config.json
└── config/

```

**After (Monoframe):**

```text
my_cool_app/
├── .env                # Database credentials
├── main.py             # Entry point
├── pyproject.toml      # Dependencies
└── src/
    └── doctypes/       # Your data models
    └── api/            # Your API endpoints

```

---

## 🛠 Roadmap

* [ ] **Phase 1: Extraction.** Successfully run the Frappe ORM and Desk without `bench`.
* [ ] **Phase 2: Cleanup.** Remove multi-tenancy code (`frappe.init(site=...)`) and site-based routing.
* [ ] **Phase 3: Typing.** Add Type Hints to core functions for better VS Code autocompletion.
* [ ] **Phase 4: Diet.** Remove heavy dependencies (PDF generation, Pandas) and make them optional extras.

## ❤️ Credits

Monoframe is a hard fork of [Frappe](https://github.com/frappe/frappe). We owe everything to the genius of the Frappe team. We aren't trying to replace them; we are offering an alternative path for specific use cases.

## License

MIT