name: create-flet-example-projects description: Use when asked to create Flet example projects from flat .py files with main.py and pyproject.toml metadata for Gallery/MCP indexing.
When to use
Use this skill when a user asks to:
- create one control/example folder (for example
examples/controls/chip) in the project-per-example format - migrate existing flat examples to the project-per-example format
- normalize a partially converted folder so all examples follow the same structure
Goal
Ensure each runnable example is a standalone project containing:
main.pypyproject.tomlwith Gallery/MCP metadataassets/(if the example uses local assets)
Workflow
- Inspect source folder.
- Detect current state per example:
- flat file:
foo.py - project folder:
foo/main.py - mixed/partial conversion: both styles present or missing metadata files
- flat file:
- Find candidate flat modules:
*.pyin the target folder (exclude helper files such as__init__.py). - Keep existing
media/unless an example needs local assets copied into its ownassets/.
- Convert or normalize examples.
- For
foo.py, createfoo/and move file tofoo/main.py. - If
foo/main.pyalready exists, keep it and do not recreate/move files. - If folder exists but
main.pyis missing, repair structure only when there is a clear source file. - Do not create
foo/__init__.py; import example modules directly in tests/docs (for exampleimport examples.controls.foo.bar.main as barorimport examples.controls.foo.bar as barwhen using namespace-package imports). - When a control folder has been fully converted to project-per-example layout, delete the control-level
examples/controls/<control>/__init__.pytoo. The converted folders should behave like namespace packages, matching prior migrations such as commit7e65ad566.
- Add
pyproject.tomlfor each example project.
- Infer from path and code.
- Create missing
pyproject.tomlfiles for existing project folders. - Update obviously stale metadata when migrating existing examples (for example wrong title/description/categories).
- Verify platform support before adding or omitting
[tool.flet].platforms:- Check the local implementation and docs for explicit platform guards, support tables, or platform-specific exceptions.
- If support is limited, add
[tool.flet].platformswith only the supported platforms. - If support is broad/all-platform, omit
[tool.flet].platforms.
- Required fields:
[project]:name,version,description,requires-python,keywords,authors,dependencies[dependency-groups].dev: includeflet-cli,flet-desktop,flet-web[tool.flet.gallery].categories[tool.flet.metadata]:title,controls,layout_pattern,complexity,features[tool.flet]:org,company,copyright
- Add
[tool.flet].platformsonly when the example is platform-limited. - Add permissions blocks only when code actually needs them.
- Infer metadata.
- Title: readable version of file/folder intent.
- Short description: one line of what the example demonstrates.
[project].descriptionmust be meaningful and example-specific; avoid generic placeholders like "Example N" or "example for ". - Description should mention the concrete behavior or interaction shown (for example: hover highlight, live updates, custom axes, event handling).
- Categories: typically control-based, e.g.
Input/Chip, plus optionalApps/Basic controls. - Tags: from control/topic/behavior words.
- Controls used: list key controls from code.
- Layout pattern: choose closest practical value (e.g.
filter-bar,inline-actions,dashboard,list-detail). - Complexity:
basicunless logic/state/architecture is non-trivial. - Features: notable behaviors only (click handling, selection, async loading, drag-and-drop, etc.).
- If an example supports exporting or downloading output, include
"save to file"in[tool.flet.metadata].features. - If an example module contains
async defhandlers or async control flow, append"async"tokeywords.
- Infer dependencies from imports.
- Always include
fletfor standard examples. - Include extra packages if imported (for example extension packages).
- Do not add unused dependencies.
- Make examples mobile-safe.
If
ft.context.disable_auto_update()is not used, do not add explicitpage.update()unless strictly necessary.Apply this
page.update()rule to all examples in the touched folder (new, migrated, and already converted).Wrap app content in
ft.SafeAreaso example renders correctly on mobile.Add
expand=Truetoft.SafeAreaonly when needed for correct layout/sizing (for example to avoid Infinity/NaN sizing issues), and avoid adding it when not necessary.When converting legacy
page.add(a, b, ...)style examples, wrap the controls inft.Column(controls=[...])insideft.SafeArea(content=...)rather thanft.Row, unless the original code explicitly used a row layout.Apply this to all examples in the touched folder (new, migrated, and already converted), not only files changed by moves.
During validation, confirm every
<example>/main.pyin scope includes a top-levelft.SafeAreaaround rendered content.For declarative examples using
@ft.component, do not pass component instances as regular control children (for exampleSafeArea(content=App())) because this can raise runtime attribute errors.In declarative examples, ensure the component itself returns regular controls (including
SafeAreawhen needed) and render it at page level withpage.render(App)inmain().
- Prefer
@ft.controlfor custom controls in examples.
- If an example defines a custom control class inheriting from a Flet control (for example
class MyThing(ft.Column)), prefer@ft.controlstyle. - Move constructor-style setup to declarative fields +
init()where practical. - Keep behavior unchanged and avoid refactors that alter public usage unless needed for compatibility.
- Remove deprecated Material 3 toggle usage.
- If
use_material3appears in example code, remove it and simplify the example to current API usage. - Remove related Material 3 toggle logic/UI that exists only to switch
use_material3. - Update example metadata (
pyproject.toml) to remove stale Material 3 references when code is changed.
- Ensure runnable entrypoint.
- Every example
main.pyshould end with:if __name__ == "__main__":ft.run(main)
- Apply this to all examples in the touched folder (new, migrated, and already converted).
- Update references.
- Docs code includes: change from
.../example.pyto.../example/main.py. - Inspect the relevant docs pages for each touched control/service/example area (for example
sdk/python/packages/flet/docs/controls/<control>.md) and update any--8<--includes or direct file-path references to the newmain.pypath. - Tests/imports: use direct module imports and avoid relying on package-level
__init__.pyre-exports. - For already-converted examples, only update references that are stale; avoid unnecessary churn.
- If removing a control-level
__init__.py, confirm no remaining imports rely onfrom examples.controls.<control> import ....
- Validate.
- Run
python -m compileallon changedmain.pyfiles. - Run
uv run ruff checkon changed example files and fix violations until it passes (respecting repositorypyproject.tomlunder[tool.ruff]). - Search for stale paths to old flat files.
- Search docs and package sources for stale references to the migrated flat example paths and fix any hits in scope.
- Check
git statusto confirm expected moves and edits. - When integration tests exist for the touched control, run the targeted test file(s).
- Confirm all in-scope
main.pyfiles include both top-levelft.SafeAreawrapping and theif __name__ == "__main__": ft.run(main)entrypoint. - Confirm in-scope
ft.SafeAreawrappers useexpand=Trueonly where needed for correct behavior and sizing; avoid forcing it by default. - Confirm there are no unnecessary
page.update()calls in in-scope examples (unless explicitly required by isolated-control or non-auto-update behavior). - Confirm no in-scope examples use
use_material3. - Confirm each in-scope
pyproject.tomlhas a meaningful, example-specific[project].description(not generic or templated text). - Confirm metadata features include
"save to file"when the example code supports file export/save behavior. - Confirm there is no stale control-level
__init__.pyleft behind once a touched control folder has been fully converted. - Confirm the relevant docs pages were updated to reference
main.pyand that no stale doc includes remain for the touched examples.
Code style
- When writing wrapped controls (
SafeArea,Column,Row,Container, etc.), keepcontent=orcontrols=as the last named argument in that control call. - Apply this ordering consistently when creating or refactoring examples.
- Follow code style and linting rules defined in the repository
pyproject.tomlunder[tool.ruff]for all edits.
Command checklist
- Discover files:
rg --files <target_dir> - Find docs links/imports:
rg -n "<old_path_or_module>" packages examples - Syntax check:
python -m compileall <changed_main_files> - Ruff check:
uv run ruff check <changed_example_files>
Output expectations
Report:
- created example projects
- metadata added
- docs/tests updates
- validation results