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 shortcutsapp.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 setText, 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.

Download files

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

Source Distribution

artemis_ui-0.97.0.tar.gz (93.9 kB view details)

Uploaded Source

Built Distribution

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

artemis_ui-0.97.0-py3-none-any.whl (90.9 kB view details)

Uploaded Python 3

File details

Details for the file artemis_ui-0.97.0.tar.gz.

File metadata

  • Download URL: artemis_ui-0.97.0.tar.gz
  • Upload date:
  • Size: 93.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for artemis_ui-0.97.0.tar.gz
Algorithm Hash digest
SHA256 e7fd299d5b274c8d805d9b091774853a2d0cb8a8481f81aa23a9ce1dc216ef8a
MD5 febe7a4030c39420e82f8fdd0e96330b
BLAKE2b-256 61a7fa2496f850a0b6523ed4f2287505bf9aef42e1019b929e07ef62a588c306

See more details on using hashes here.

File details

Details for the file artemis_ui-0.97.0-py3-none-any.whl.

File metadata

  • Download URL: artemis_ui-0.97.0-py3-none-any.whl
  • Upload date:
  • Size: 90.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for artemis_ui-0.97.0-py3-none-any.whl
Algorithm Hash digest
SHA256 44e399d2e22cad4f0aa6401544271696b192d580547782b51b61e25d46d5e492
MD5 24a009028bae742a05b5d02c85ddba34
BLAKE2b-256 5d2c7e6f3acf483cd37eb6ab7a0fee6129cdd7bed5f140bfa1ddc449989f5f0b

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 Sentry Error logging StatusPage Status page