Skip to main content

Artemis

Build Android, iOS, desktop, and web apps in Python — with almost none of the boilerplate.

Artemis is a batteries-included layer on top of Flet (Flutter, for Python). Flet gives you the raw building blocks; Artemis gives you the everyday app-shell parts — theming, navigation, forms, state, dialogs, testing — as a small set of plain functions instead of something you assemble by hand in every new project.

import artemis as art

app = art.App("Hello", theme="ocean")

@app.page("/")
def home(page):
    return art.Column([
        art.Title("Hello, Artemis"),
        art.Button("Say hi", on_click=lambda e: app.toast("Hi!")),
    ], center=True)

app.run()

Run that and you get a real, native-feeling window (not a webview) with a proper Material 3 color scheme, correct fonts, and modern rounded controls — from eleven lines. Build the same file for Android and it's a real Android app, because underneath, it's Flet and Flutter the whole way down. Artemis doesn't fork Flet or invent a new rendering engine — it removes repetition.

Install

pip install artemis-ui
import artemis as art

Want charts, or automatic conversion of a custom logo into a Windows icon? Those are optional extras:

pip install "artemis-ui[charts]"    # for art.LineChart / BarChart / PieChart
pip install "artemis-ui[icons]"     # for converting a custom logo.png into a Windows .ico

Scaffold a new project

pip install artemis-ui
artemis new "My App"
cd "My App"
pip install -e .
python main.py

artemis new sets up a working starter app, and a GitHub Actions workflow that builds your app for Android, iOS, Windows, macOS, Linux, and Web the moment you push — so producing a real install-able app on every platform never requires setting up Flutter, the Android SDK, or Xcode on your own machine. See Building & CI/CD.

What you get

Theming. 31 named color palettes, or full manual control over background/surface/text/accent colors — each one Material 3-correct in both light and dark mode automatically.

art.App("My App", theme="sunset")
art.App("My App", background="#0B1220", surface="#161F32", text="#E5E7EB", primary="#818CF8")

Navigation that behaves like a real app. A genuine back-stack (not a page swap) with automatic back arrows, working hardware/browser back buttons, route parameters, route guards, a bottom tab bar, and a side drawer.

@app.page("/user/:id", guard=lambda: logged_in.value, redirect="/login")
def profile(page, params):
    return art.Text(f"User #{params['id']}")

app.go("/user/42")
app.back()

State that just works, with a persistent and an async variant when you need them.

count = art.State(0)
theme_pref = art.PersistentState("theme", default="indigo")   # survives an app restart
products = art.AsyncData(lambda: art.fetch_json(url))          # loads once, not on every re-render

Forms with real validation.

email = art.Field("", art.validators.required(), art.validators.email())
form = art.Form(email=email)
art.Input(label="Email", field=email)
art.Button("Submit", on_click=form.submit(handle_submit))

Dialogs, toasts, pickers, and shortcuts — app.alert(...), app.confirm(...), app.toast(..., action="Undo"), app.pick_date(...), app.on_key("ctrl+s", ...), clipboard access, and more, each a one-line call instead of manual control wiring.

A wide widget set — Text, Button (with an automatic loading spinner), Input, Switch, Slider, Dropdown, Column/Row/Grid, Tabs, Card, ListTile, Avatar, charts, and more — every one a plain Flet control under the hood, so anything Artemis doesn't wrap is one import flet away.

Automatic branding. A default app icon on first run, replaced instantly if you drop your own logo.png in assets/ — and a dev-only splash screen for web apps that appears on localhost and disappears the moment the same code is actually deployed, with nothing to remember to turn off.

A testing toolkit. Test your app's logic — clicks, typed input, navigation, dialogs — without opening a window:

from artemis.testing import TestApp

t = TestApp(app).build()
t.click(t.find_button("+"))
assert t.has_text("1")

Documentation

The README above is the tour. The full reference — every widget, every parameter, every subsystem, with runnable examples — lives in docs/:

Full index: docs/00-index.md.

The mental model, briefly

A page is a plain function that returns a control tree:

@app.page("/")
def home(page):
    return art.Text("hello")

When a button is clicked, Artemis re-runs the current screen's function and redraws it — you don't call page.update() yourself. Text inputs are the one exception, so typing doesn't lose focus or cursor position; bind them to a State instead. This is the one idea worth understanding properly before diving in further — Core Concepts covers it in full.

Examples

The examples/ folder has a complete, runnable app for nearly every feature above — a counter, a todo list, a themed dashboard with live charts, a login form, drawer navigation, keyboard shortcuts, and more:

python examples/counter.py
python examples/dashboard.py

Good to know before you start

  • Screens re-render on every interaction, not just the one that changed. This keeps the mental model simple (your page function is always a fresh, correct description of the screen) at a small performance cost. Fine for typical app sizes; if you're rendering thousands of rows at once, consider pagination.
  • There is no file picker. Flet's underlying FilePicker control has a real, unresolved upstream registration bug that made it unreliable across machines and Python versions — rather than ship something that silently works for some people and not others, Artemis doesn't wrap it. See Troubleshooting if you need file access anyway.
  • Charts need an extra install (pip install artemis-ui[charts]) — kept optional so it's not forced on projects that don't need it.
  • Python 3.14 has some rough edges with Flet right now. Python 3.12 or 3.13 are the most stable targets. See Troubleshooting.
  • Packaging for Android/iOS/desktop genuinely requires Flutter. That's how Flet works, not something Artemis can avoid — but it auto-installs itself, and the CI workflow every artemis new project ships with means your own machine may never need it at all. See Building & CI/CD.

License

MIT — see LICENSE.

Metadata

Release files for artemis-ui 0.97.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for artemis-ui 0.97.0
File Size Uploaded
artemis_ui-0.97.0.tar.gz 93.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for artemis-ui 0.97.0
File Interpreter ABI Platform
artemis_ui-0.97.0-py3-none-any.whl Python 3 none any Details

Total release size: 184.7 kB

Release files / artemis_ui-0.97.0.tar.gz

Download URL artemis_ui-0.97.0.tar.gz
Size 93.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e7fd299d5b274c8d805d9b091774853a2d0cb8a8481f81aa23a9ce1dc216ef8a
BLAKE2b-256 checksum
How to use checksums
61a7fa2496f850a0b6523ed4f2287505bf9aef42e1019b929e07ef62a588c306
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release files / artemis_ui-0.97.0-py3-none-any.whl

Download URL artemis_ui-0.97.0-py3-none-any.whl
Size 90.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44e399d2e22cad4f0aa6401544271696b192d580547782b51b61e25d46d5e492
BLAKE2b-256 checksum
How to use checksums
5d2c7e6f3acf483cd37eb6ab7a0fee6129cdd7bed5f140bfa1ddc449989f5f0b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release history Release notifications | RSS feed

This release

0.97.0 This release

2 release files

0.96.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page