Skip to main content

Transform any Python function into a web interface automatically

Project description

Func To Web 1.0.0

PyPI version Python License

Type hints → Web UI. Minimal-boilerplate web apps from Python functions.

func-to-web Demo

Quick start

pip install func-to-web
from func_to_web import run

def divide(a: float, b: float):
    return a / b

run(divide)

Open http://127.0.0.1:8000.

demo

Inputs

Type Widget
int, float Number input with step buttons and optional slider docs
str, Email Text input, textarea, password, or email docs
bool Toggle switch docs
date, time Date and time pickers docs
Color Hex color picker docs
File, ImageFile, VideoFile, AudioFile, DataFile, TextFile, DocumentFile File upload with extension filter docs
Literal, Enum, Dropdown(func) Select / dropdown docs
list[T] Dynamic list with add/remove buttons docs
T | None Any input with enable/disable toggle docs
Params Reusable parameter groups docs
Annotated[T, ...] Compose constraints, labels, sliders, placeholders docs

Outputs

Return type Rendered as
str, int, float, None Text with copy button docs
PIL Image, Matplotlib Figure Inline image with expand button docs
FileResponse, list[FileResponse] Download button(s) docs
list[dict], list[tuple], DataFrame, ndarray Sortable, paginated table with CSV export docs
ActionTable Clickable table → next function with prefill docs
tuple / list Multiple outputs combined docs
print() Streamed to browser in real time docs

Features

  • Multiple functions with index page or collapsible groups — docs
  • URL prefill — forms open prefilled from query params — docs
  • Real-time print() output in the browser — docs
  • Username/password authentication — docs
  • Dark mode — docs
  • Configurable host, port and path — docs

Full documentation with examples and screenshots for every feature: offerrall.github.io/FuncToWeb

ActionTable and Params

Params groups typed parameters into a reusable class. Add a field once, it appears in every function that uses it.

ActionTable turns a table into navigation — click a row and the next function opens with its form prefilled from that row's data. No routing, no state.

The example below is a full CRUD user database in 70 lines:

import json
from pathlib import Path
from typing import Annotated
from pydantic import Field
from func_to_web import run, ActionTable, HiddenFunction, Params, Email

DB_FILE = Path("users.json")

class UserData(Params):
    name: Annotated[str, Field(min_length=2, max_length=50)]
    email: Email
    phone: Annotated[str, Field(pattern=r'^\+?[0-9]{9,15}$')]

def _load() -> dict:
    if not DB_FILE.exists():
        return {}
    return {int(k): v for k, v in json.loads(DB_FILE.read_text()).items()}

def _save(db: dict):
    DB_FILE.write_text(json.dumps(db, indent=2))

def _check(db: dict, id: int):
    if id not in db:
        raise ValueError(f"User {id} not found")

def _user_dict(uid: int, data: UserData) -> dict:
    return {"id": uid, **vars(data)}

def edit_users():
    """Edit users"""
    return ActionTable(data=_load, action=edit_user)

def delete_users():
    """Delete users"""
    return ActionTable(data=_load, action=delete_user)

def create_user(data: UserData):
    """Create a new user"""
    db = _load()
    uid = max(db) + 1 if db else 1
    db[uid] = _user_dict(uid, data)
    _save(db)
    return f"User {uid} created"

def edit_user(id: int, data: UserData):
    """Edit an existing user"""
    db = _load()
    _check(db, id)
    db[id] = _user_dict(id, data)
    _save(db)
    return f"User {id} updated"

def delete_user(id: int):
    """Delete a user"""
    db = _load()
    _check(db, id)
    del db[id]
    _save(db)
    return f"User {id} deleted"

run([edit_users, delete_users, create_user, HiddenFunction(delete_user), HiddenFunction(edit_user)])

Demo

UserData is the single source of truth. Swap the JSON file for SQLAlchemy and you have a production-ready CRUD in a few more lines.

ActionTable is experimental. Simple types (str, int, float) work well. Files are not yet supported via row navigation.

Using Func To Web alongside your frontend

Every function has its own URL with query param prefill.
That means any existing web app can embed a Func To Web function in an iframe — open a modal, pass the data via URL, let Func To Web handle the form and validation, close.

This works best for self-contained operations: editing a record, uploading and processing files, generating a report, running a bulk action...

Examples

File transfer

from func_to_web import run, File
import shutil, os

downloads = os.path.expanduser("~/Downloads")

def upload_files(files: list[File]):
    for f in files:
        shutil.move(f, downloads)
    return "Done."

run(upload_files)

Protected admin panel

import subprocess
from typing import Literal
from func_to_web import run

def restart_service(service: Literal['nginx', 'gunicorn', 'celery']):
    subprocess.run(["sudo", "supervisorctl", "restart", service], check=True)
    return f"{service} restarted."

run(restart_service, auth={"admin": "your_password"})
# Use HTTPS in production.

QR code generator

import qrcode
from func_to_web import run

def make_qr(text: str):
    return qrcode.make(text).get_image()

run(make_qr)

PDF merger

from io import BytesIO
from pypdf import PdfWriter
from func_to_web import run
from func_to_web.types import DocumentFile, FileResponse

def merge_pdfs(files: list[DocumentFile]):
    merger = PdfWriter()
    for pdf in files:
        merger.append(pdf)
    output = BytesIO()
    merger.write(output)
    return FileResponse(data=output.getvalue(), filename="merged.pdf")

run(merge_pdfs)

More in examples/ and examples/apps/.


Requirements

External:

  • Python 3.10+
  • FastAPI, Uvicorn, Jinja2, python-multipart, itsdangerous, aiofiles, starlette

Internal:

  • pytypeinput — type analysis engine (2030+ tests). Powers Func To Web's type system and can be used standalone to build other interfaces — a CLI, a Qt app, or anything else.
  • pytypeinputweb — JS/CSS form renderer built on pytypeinput.

Optional (for specific features):

  • Pillow, Matplotlib, Pandas, NumPy, Polars

400 stars and Awesome Python — didn't see that coming at all. Built this to scratch my own itch, so genuinely thanks.

I want to keep making it better and I'd love to hear how you actually use it, what's missing, what's annoying. If there's demand I'll open a Discord, otherwise issues work fine. Any help — code, docs, bug reports — is very welcome.

MIT License · Made by Beltrán Offerrall · Contributions welcome

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

func_to_web-1.0.0.tar.gz (44.2 kB view details)

Uploaded Source

Built Distribution

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

func_to_web-1.0.0-py3-none-any.whl (56.4 kB view details)

Uploaded Python 3

File details

Details for the file func_to_web-1.0.0.tar.gz.

File metadata

  • Download URL: func_to_web-1.0.0.tar.gz
  • Upload date:
  • Size: 44.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for func_to_web-1.0.0.tar.gz
Algorithm Hash digest
SHA256 d364c472ea4c9702b2f26a7c71e22acbbba5a1611985ed4c9ea4a64088a3d52f
MD5 36d5afb4417a2de4252b031b7183542a
BLAKE2b-256 8f91ecf40e91fa42d43f734a363ac60fb074666bea633e3339856c0105404450

See more details on using hashes here.

File details

Details for the file func_to_web-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: func_to_web-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 56.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for func_to_web-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 22c1dda564840f6588993b45e29648940ece5bd000ccbfd1e13383f594b419b5
MD5 59f7ce8de397c49cdca782119529e82e
BLAKE2b-256 3ab8c80aefb03eda567908a458ddde7711d7906904a1649cdf7aab7898fe4638

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