Skip to main content

A CLI tool to generate full-stack web projects from SQLModel

Project description

OneSite

OneSite is a powerful model-driven CLI tool that automatically generates a full-stack web application (FastAPI + React/Vite) from simple Python SQLModel definitions.

It automates the repetitive work of building CRUD APIs, database schemas, and frontend management pages, allowing you to focus on business logic.

Features

  • Full-Stack Generation: Generates Backend (FastAPI, SQLModel, Pydantic) and Frontend (React, Tailwind, Zustand, Lucide Icons).
  • Model-Driven: Define your data models in standard Python code, and let OneSite handle the rest.
  • Auto CRUD: Automatically generates Create, Read, Update, Delete APIs and UI.
  • Smart UI Components:
    • bool -> Switch / Badge
    • Enum -> Select / Badge
    • datetime -> Text
    • Image Upload: Detects image fields (e.g. avatar, _image) and generates file upload and preview components.
    • File Attachment: Detects file fields (e.g. report_file, _file suffix) and generates file upload components with built-in preview.
      • Preview Support: PDF, Word (docx), Excel (xlsx, csv), Markdown, Code/Text, Video, Audio, Images.
    • Foreign Key: Auto-detects foreign keys and generates searchable select dropdowns (SearchableSelect).
    • Many-to-Many: Supports M2M relationships via link tables, generating multi-select components.
  • Pagination: Built-in standard pagination support for all list views.
  • Auto Refresh: Configurable auto-refresh for real-time data monitoring.
  • Authentication & Security:
    • Built-in Login: Modern login page with JWT authentication.
    • Protected Routes: Automatic auth guards for frontend pages.
    • Secure APIs: CRUD endpoints default to authenticated access; static files are public.
    • User Management: Secure password hashing and role-based field access.
  • Containerization: Built-in support for Docker/Podman build and Compose.

Installation

# Clone the repository
git clone https://github.com/IronSpiderMan/OneSite.git
cd OneSite

# Install the tool in editable mode
pip install -e .

Quick Start

1. Create a New Project

site create myproject
cd myproject

This creates a new directory structure:

myproject/
├── backend/    # FastAPI Backend
├── frontend/   # React Frontend
└── models/     # Your Data Models (Source of Truth)

2. Define Your Models

Add your models to the models/ directory.

Basic Model

models/product.py:

from typing import Optional
from sqlmodel import Field, SQLModel
from enum import Enum

class Category(str, Enum):
    ELECTRONICS = "electronics"
    CLOTHING = "clothing"

class Product(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    price: float
    is_active: bool = True
    category: Category = Category.ELECTRONICS
    # Image field (auto-detected by name 'image', 'avatar', or '_image' suffix)
    image: Optional[str] = Field(default=None, sa_column_kwargs={"info": {"site_props": {"component": "image"}}})

File Attachments

models/document.py:

from typing import Optional
from sqlmodel import Field, SQLModel

class Document(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str
    
    # Method 1: Auto-detection via '_file' suffix
    report_file: Optional[str] = Field(default=None)
    
    # Method 2: Explicit component definition
    attachment: Optional[str] = Field(default=None, sa_column_kwargs={"info": {"site_props": {"component": "file"}}})
    
    # Method 3: Disable download (preview only)
    preview_only: Optional[str] = Field(default=None, sa_column_kwargs={"info": {"site_props": {"component": "file", "allow_download": False}}})

Foreign Key Relationship

models/post.py:

from typing import Optional
from sqlmodel import Field, SQLModel

class Post(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str
    content: str
    # Foreign Key to User (naming convention: target_model_lower + _id)
    user_id: Optional[int] = Field(default=None, foreign_key="user.id")

Many-to-Many Relationship

To define a Many-to-Many relationship (e.g., Posts have many Tags), create a link table model with specific metadata.

models/tag.py:

from typing import Optional
from sqlmodel import Field, SQLModel

class Tag(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(unique=True)

models/post_tag_link.py:

from typing import Optional
from sqlmodel import Field, SQLModel

class PostTagLink(SQLModel, table=True):
    # Required metadata to identify this as a M2M link table
    __table_args__ = {"info": {"site_props": {"is_link_table": True}}}
    
    post_id: Optional[int] = Field(default=None, foreign_key="post.id", primary_key=True)
    tag_id: Optional[int] = Field(default=None, foreign_key="tag.id", primary_key=True)

OneSite will automatically inject a tag_ids field into the Post form, allowing you to select multiple Tags.

3. Advanced Configuration

You can customize field behavior using site_props in sa_column_kwargs.

Field Permissions & Validation

Control field visibility and validation requirements for Create/Update operations.

class User(SQLModel, table=True):
    # ...
    password: str = Field(sa_column_kwargs={"info": {"site_props": {
        "permissions": "cu",          # 'c'=Create, 'u'=Update. 'r'=Read (omitted here, so password is never sent to frontend)
        "create_optional": False,     # Required when creating a user
        "update_optional": True       # Optional when updating (leave blank to keep current password)
    }}})
  • permissions: String with r (read), c (create), u (update). Default is rcu.
  • create_optional: If True, field is not required in Create form.
  • update_optional: If True, field is not required in Update form.

Auto Refresh

Enable automatic data refreshing for list and detail views. This is useful for monitoring dashboards or real-time data.

class DashboardMetric(SQLModel, table=True):
    # Enable auto-refresh every 5 seconds (5000ms)
    __table_args__ = {"info": {"site_props": {
        "auto_refresh": True, 
        "refresh_interval": 5000
    }}}
    
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    value: float
  • auto_refresh: bool. If True, adds an "Auto Refresh" toggle to the UI.
  • refresh_interval: int (milliseconds). The default refresh interval (default: 5000ms). Users can change this in the UI.

4. Sync and Generate Code

Run the sync command to generate backend and frontend code based on your models. Use --install flag for the first run to install dependencies.

site sync --install

5. Run the Application (Local Development)

Start both backend and frontend servers with one command:

site run

Default Admin Credentials:

  • Email: admin@example.com
  • Password: admin

6. Containerization & Deployment

OneSite makes it easy to build and run your application using Docker/Podman.

Build Images & Generate Configuration

This command builds the container images and generates a docker-compose.yml configured to use them.

# Build with default settings (Docker, tag: latest, port: 3000)
site build

# Or customize settings
site build --engine podman --tag v1.0 --port 8080

Run with Compose

Start the services using the generated configuration.

site compose up -d

Project Structure

myproject/
├── models/             # Define your SQLModel classes here
├── backend/
│   ├── app/
│   │   ├── api/        # Generated API endpoints
│   │   ├── cruds/      # Generated CRUD logic
│   │   ├── models/     # Synced models
│   │   ├── schemas/    # Generated Pydantic schemas
│   │   ├── services/   # Business logic
│   │   ├── core/       # Config, Security, DB
│   │   │   └── security.py # Password hashing & Auth
│   │   └── initial_data.py # Data seeding (Admin user)
│   ├── uploads/        # User uploaded files
│   └── ...
└── frontend/
    ├── src/
        ├── components/ # UI Components (Button, Input, Modal, ImageUpload, etc.)
        ├── pages/      # Generated List/Edit Pages
        ├── services/   # Generated API Clients
        ├── stores/     # Generated State Management
        └── ...

Commands Reference

  • site create <name>: Create a new project scaffold.
  • site sync [--install/-i]: Sync models and generate code. Use -i to install Python and Node dependencies.
  • site run [component]: Run the project locally. component can be backend, frontend, or all (default).
  • site build [--component/-c] [--engine/-e] [--tag/-t] [--port/-p]: Build container images and generate docker-compose.yml.
    • --component: backend, frontend, or all (default).
    • --engine: docker (default) or podman.
    • --tag: Image tag (default: latest).
    • --port: Frontend exposed port (default: 3000).
  • site compose <command> [args]...: Run docker-compose commands using the generated file.
    • Examples: site compose up -d, site compose down, site compose logs -f.

Requirements

  • Python 3.10+
  • Node.js & npm (for frontend)
  • Docker or Podman (optional, for containerization)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

onesite-0.1.5.tar.gz (54.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

onesite-0.1.5-py3-none-any.whl (86.1 kB view details)

Uploaded Python 3

File details

Details for the file onesite-0.1.5.tar.gz.

File metadata

  • Download URL: onesite-0.1.5.tar.gz
  • Upload date:
  • Size: 54.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for onesite-0.1.5.tar.gz
Algorithm Hash digest
SHA256 da17880a54cf681cac8f16b412b0cdaa43ac5b56afd98ba7e61e8a7792f6a4b8
MD5 badfa631e5d205a0a9216b03e845fd5d
BLAKE2b-256 dd2527481a3bcf5f8f42536119d1b11661165717029c7b6dbcfbf019bfea47a4

See more details on using hashes here.

File details

Details for the file onesite-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: onesite-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 86.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for onesite-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 dd777a5ca9588b770b2e619ef1acec50353aa132ab6e05dd04f7d4aae5bb377f
MD5 ffa88c4e8e0f3342ea95ba0ce45dc54b
BLAKE2b-256 edf52fe964868488c207fe4c7a3b47f1a792e48925800da28bf9b5df5ab8601b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page