pythonide-appui
/pythonide-appui
Build or modify PythonIDE AppUI MiniApps with native navigation, forms, lists, search, tabs, toolbars, presentation, storage, and AppUI media bridges. Use when the user wants an interactive iOS MiniApp, settings screen, list/detail app, or native UI that may also need photos, camera, location, maps, video, or share.
- Author
- Python-IDE ↗
- Repository
- pythonide-skills ↗
- Licence
- MIT
- Last repository change
- 13.07.2026
Assessment and security
- Files in this package
- 3
- Scripts
- 2
- HTML comments
- 2
- URLs in SKILL.md
- 14
No signals detected. Repository changed on 13.07.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
- 2 scripts in this package. Review them before installing, as Claude may execute them.
- SKILL.md zawiera komentarze HTML (2). Nie widać ich w podglądzie Markdown, a model je czyta.
Scripts: examples/counter/main.py, examples/photo_notes/main.py
What it does and when to use it
Build or modify PythonIDE AppUI MiniApps with native navigation, forms, lists, search, tabs, toolbars, presentation, storage, and AppUI media bridges. Use when the user wants an interactive iOS MiniApp, settings screen, list/detail app, or native UI that may also need photos, camera, location, maps, video, or share.
Original author description
Build or modify PythonIDE AppUI MiniApps with native navigation, forms, lists, search, tabs, toolbars, presentation, storage, and AppUI media bridges. Use when the user wants an interactive iOS MiniApp, settings screen, list/detail app, or native UI that may also need photos, camera, location, maps, video, or share.
How it works
- Read Before Coding
- Workflow
- Entry Pattern
- Presentation
- Structure Rules
- Layout And Styling
- Native Integration
- Callbacks And Runtime
- Hard Stops
- Common Mistakes
SKILL.md preview
---
name: pythonide-appui
description: Build or modify PythonIDE AppUI MiniApps with native navigation, forms, lists, search, tabs, toolbars, presentation, storage, and AppUI media bridges. Use when the user wants an interactive iOS MiniApp, settings screen, list/detail app, or native UI that may also need photos, camera, location, maps, video, or share.
license: MIT
version: "1.1.0"
last_updated: "2026-06-19"
user_invocable: true
---
# PythonIDE AppUI
Execution rulebook for native AppUI MiniApps. Pair with `pythonide-native` whenever the workflow touches iOS permissions, sensors, media capture, networking side effects, or secure storage.
## Read Before Coding
1. [appui quickstart](https://pythonide.xin/docs/pages/appui-quickstart/)
2. [AppUI module](https://pythonide.xin/docs/pages/appui-module/)
3. [UI patterns](https://pythonide.xin/docs/pages/miniapp-appui-ui-patterns/)
4. [AppUI schema](https://pythonide.xin/schemas/appui_api_schema.json) and [appui.pyi](https://pythonide.xin/stubs/appui.pyi) for signatures
5. [llms-full.txt](https://pythonide.xin/llms-full.txt) when unsure about exported symbols
6. Load `pythonide-native` before importing any `photos`, `location`, `permission`, `notification`, etc.
Chinese module pages on pythonide.xin are valid deep references for scenarios and examples.
## Workflow
1. Confirm AppUI is the right runtime (`pythonide` router). Do not use AppUI for widgets or frame-loop games.
2. Choose structure first: `Form`, `List`, `TabView`, `NavigationStack`, dashboard `ScrollView`.
3. Define module-level `appui.State` or `ReactiveState`.
4. Write named zero-argument callbacks; callbacks mutate state or call native APIs.
5. Keep `body()` pure: return a view tree only. No permissions, network, storage writes, notifications, timers started, or navigation side effects inside `body()`.
6. End with exactly one `appui.run(body, state=state, presentation=...)`.
7. For editable business data, use `storage.get_json(..., default)` only for small settings; use `database` for queryable records, caches, favorites, history, playlists, or large lists.
## Entry Pattern
```python
import appui
state = appui.State(count=0, status="Ready")
def increment():
state.count += 1
state.status = "Updated"
def body():
return appui.NavigationStack(
appui.Form([
appui.Section("Counter", [
appui.LabeledContent("Value", value=str(state.count)),
appui.Button("+1", action=increment).button_style("bordered_prominent"),
], footer=state.status),
]).navigation_title("Counter")
)
appui.run(body, state=state, presentation="fullscreen_with_close")
```
## Presentation
| Use case | `presentation` |
| --- | --- |
| Full app / tool with close affordance | `fullscreen_with_close` |
| Lightweight utility | `sheet` |
| Default when unsure for a real app | `fullscreen_with_close` |
## Structure Rules
- Settings, account, checkout, profile: `Form + Section`
- Dynamic rows: `List + ForEach` with stable `key`
- Master-detail: `NavigationStack + NavigationLink`
- Product areas: `TabView + Tab`, each tab owns a `NavigationStack`
- Continuing bottom tasks: `TabView + .tab_view_bottom_accessory(...) + .sheet(...)`
- Use `.tab_view_bottom_accessory` for the compact persistent row and `.sheet(detents=..., drag_indicator=...)` for the full panel. Do not invent an expandable bottom accessory API.
- Search: native `.searchable(...)`; do not hand-roll search bars
- Toolbar actions in fullscreen apps; `fullscreen_with_close` already provides close
- Stable item IDs; mutate by id, never by filtered index
- Do not nest `List` inside `ScrollView`, `Section`, or another scrolling container
## Layout And Styling
- Target iPhone width ~390 pt; avoid fixed widths above 360 pt
- Padding usually 8–20 pt
- Use semantic system colors: `systemBackground`, `label`, `secondaryLabel`, `systemBlue`, etc.
- Do not hard-code hex/RGB unless the API requires it
- Ordinary rows/settings/todos should stay `List`/`Form` native-first; reserve custom dashboard layouts for true dashboard/media surfaces
- Use `.tab_view_bottom_accessory` plus `.sheet` for persistent playback, podcast, recording, download, timer, or navigation state instead of making that ongoing task a dedicated tab
## Native Integration
**Also load `pythonide-native` for any capability below.**
### Hard Rules
- `nativeCallsStayOutOfAppUIBody`: permission prompts, GPS, capture, notifications, and network side effects belong in named callbacks, `.refreshable`, or `.task` — never in `body()`
- Prefer AppUI bridge components before imperative modules when the control is inline in the UI
- AppUI embedded video: `PlayerController` + `VideoPlayer`; do not use `import avplayer` unless the user explicitly wants script-level playback
- Secrets → `keychain`; small settings → `storage`; queryable records → `database`
- Do not import CPython `sqlite3` directly in MiniApps; use `database`
### AppUI Bridge Components
<!-- BEGIN GENERATED: appui-bridge-table -->
| Bridge | AppUI component | Related modules | Doc |
| --- | --- | --- | --- |
| `camera_picker` | `appui.CameraPicker` | `photos` | [camera-module](https://pythonide.xin/docs/pages/camera-module/#appui-camera-picker) |
| `file_importer` | `appui.FileImporter` | - | [file-picker-module](https://pythonide.xin/docs/pages/file-picker-module/#file-importer) |
| `map_view` | `appui.MapView` | `location`, `permission` | [location-module](https://pythonide.xin/docs/pages/location-module/#map-view) |
| `photo_picker` | `appui.PhotoPicker` | `photos` | [photos-module](https://pythonide.xin/docs/pages/photos-module/#appui-photo-picker) |
| `player_controller` | `appui.PlayerController` | `avplayer` | [appui-ref-media](https://pythonide.xin/docs/pages/appui-ref-media/#player-controller) |
| `share_link` | `appui.ShareLink` | - | [share-module](https://pythonide.xin/docs/pages/share-module/#share-link) |
| `video_player` | `appui.VideoPlayer` | `avplayer` | [appui-ref-media](https://pythonide.xin/docs/pages/appui-ref-media/#video-player) |
| `web_view` | `appui.WebView` | - | [appui-ref-media](https://pythonide.xin/docs/pages/appui-ref-media/#webview) |
<!-- END GENERATED: appui-bridge-table -->
### Bridge Vs Module
| Need | Prefer |
| --- | --- |
| Inline photo pick in a form | `appui.PhotoPicker` |
| Inline camera capture button | `appui.CameraPicker` |
| Map preview in a screen | `appui.MapView` + `pythonide-native` for `location` callbacks |
| Share a file or text | `appui.ShareLink` |
| Batch asset processing, save to library, background fetch | `import photos` in callback |
| GPS updates, geocoding, heading | `import location` in callback |
| Local notifications | `import notification` in callback |
## Callbacks And Runtime
- Prefer named zero-argument callbacks
- Wrong: `Button(action=open(item))` or `row.on_tap(save(i))` — runs during view construction
- Row callbacks should capture stable item IDs
- Timers at module scope with `action=` at construction; never `Timer(action=None)` then assign later
- High-frequency sensors, camera streams, waveforms → consider Aurora realtime docs; do not rebuild the whole tree every frame in a tight loop
## Hard Stops
- No HTML/WebView unless the user explicitly needs web content
- No `lambda` callbacks in deliverable code
- No `children=` for `VStack`/`HStack`; pass child lists positionally
- No `NavigationStack([...])`; one root view only
- No `ScrollView(VStack(...))` for ordinary lists → use `List(ForEach(...))`
- No dedicated playback/download/recording tab when the expected product pattern is a compact bottom bar that expands into a full panel
- No `Image(...).on_tap(...)` as a button → use `Button`
- No guessed SwiftUI-only APIs; verify against schema/stubs
- No tkinter, PyQt, Flask, Streamlit, or browser frameworks
## Common Mistakes
| Symptom | Fix |
| --- | --- |
| Dead button | Named zero-arg callback instead of eager invocation |
| Wrong row after search/filter | Stable ids + `ForEach(..., key=...)` |
| Permission dialog on launch | Move native call into button callback |
| Blank preview | Ensure `body()` returns a View and `appui.run(...)` is present |
| Shared search across tabs | Separate per-tab query state |
## Examples
- `examples/counter/` — minimal `Form` + persistence-ready structure
- `examples/photo_notes/` — AppUI shell + `PhotoPicker` + `storage`
## Validation
Done means: runnable AppUI code, documented APIs only, `appui.run(...)` present, named callbacks for side effects, and honest reporting if editor-side preview cannot be executed.
Files in this package (3)
- SKILL.md 8 KB
- examples/counter/main.py 1 KB
- examples/photo_notes/main.py 1 KB
Versions
The database has no other skills named pythonide-appui.
Database snapshot: 13.11.2026 · package version 2e45545452e3 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100pythonide-native
Choose and implement PythonIDE iOS native modules for permissions, device state, sensors, storage, keychain, photos, camera, location, notifications, networking, Bluetooth, health, speech, media, and system actions. Use with pythonide-appui when a MiniApp needs native capability… - 100pythonide
Route PythonIDE tasks to the correct runtime and companion skill (AppUI MiniApp, widget, scene, native modules, automation). Use when the user asks to build, fix, or choose a PythonIDE app, script, widget, game, or iOS capability workflow. - 100miniapp-dev
Generate, operate, and refine OpenBitFun MiniApps. Use when the user wants a new MiniApp, asks the Agent to inspect or operate a running MiniApp, or wants an existing MiniApp redesigned or extended. Typical triggers: "做一个小应用", "操作这个 MiniApp", "查看小应用当前状态", "改造 mini app". - 100argent-settings-permissions
Grant, deny, or reset an app's runtime permissions (camera, microphone, photos, contacts, notifications, calendar, location, location-always, media-library, motion, reminders) on an iOS simulator or Android device using the argent `settings-permissions` tool - without navigating…