Skip to content

Commit 011fde9

Browse files
Merge pull request #5 from flet-dev/diag
Add diagnostics
2 parents 9498148 + e5a55e9 commit 011fde9

14 files changed

Lines changed: 1730 additions & 64 deletions

File tree

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.venv/
2+
__pycache__/
3+
*.pyc
4+
*.pyo
5+
*.pyd
6+
.Python
7+
.pytest_cache/
8+
.mypy_cache/
9+
.ruff_cache/
10+
.git/
11+
.gitignore

.github/workflows/fly-deploy.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Deploy to Fly.io
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: fly-deploy-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
deploy:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Compute app version
22+
id: app_version
23+
run: |
24+
APP_VERSION=$(python - <<'PY'
25+
import tomllib
26+
import os
27+
28+
with open("pyproject.toml", "rb") as f:
29+
data = tomllib.load(f)
30+
base = data["project"]["version"]
31+
parts = base.split(".")
32+
if len(parts) != 3:
33+
raise SystemExit(f"Expected semantic version 'X.Y.Z', got: {base}")
34+
print(f"{parts[0]}.{parts[1]}.{os.environ['GITHUB_RUN_NUMBER']}")
35+
PY
36+
)
37+
echo "value=${APP_VERSION}" >> "$GITHUB_OUTPUT"
38+
39+
- name: Setup flyctl
40+
uses: superfly/flyctl-actions/setup-flyctl@master
41+
42+
- name: Deploy to Fly.io
43+
run: flyctl deploy --remote-only --config fly.toml --build-arg APP_VERSION=${{ steps.app_version.outputs.value }}
44+
env:
45+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

.gitignore

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,6 @@ ipython_config.py
9494
# install all needed dependencies.
9595
#Pipfile.lock
9696

97-
# poetry
98-
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99-
# This is especially recommended for binary packages to ensure reproducibility, and is more
100-
# commonly ignored for libraries.
101-
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102-
*.lock
103-
10497
# pdm
10598
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
10699
#pdm.lock

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.10
1+
3.14

Dockerfile

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
FROM python:3-alpine
1+
FROM python:3.14-slim
22

33
WORKDIR /app
44

5+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
6+
7+
ENV UV_PYTHON_DOWNLOADS=never
8+
ENV UV_LINK_MODE=copy
9+
10+
COPY pyproject.toml uv.lock ./
11+
RUN uv sync --frozen --no-dev --no-install-project
12+
513
COPY . .
14+
RUN uv sync --frozen --no-dev
615

7-
RUN pip install --no-cache-dir .
16+
ARG APP_VERSION=dev
17+
ENV APP_VERSION=${APP_VERSION}
818

9-
EXPOSE 8000
19+
EXPOSE 8080
1020

11-
CMD ["python", "src/main.py"]
21+
CMD ["/app/.venv/bin/python", "src/main.py"]

fly.toml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ app = "flet-controls-gallery"
66
[env]
77
FLET_SERVER_PORT = "8080"
88
FLET_FORCE_WEB_SERVER = "true"
9+
FLET_SESSION_TIMEOUT = "600"
10+
MEM_DIAG = "0"
11+
MEM_DIAG_INTERVAL_SEC = "60"
12+
MEM_DIAG_TRACE_INTERVAL_SEC = "300"
13+
MEM_DIAG_TRACE_FRAMES = "10"
14+
MEM_DIAG_TRACE_TOP = "10"
15+
MEM_DIAG_CONTROL_SCAN_MAX_NODES = "15000"
16+
MEM_DIAG_COLLECT_ON_SAMPLE = "1"
17+
MEM_DIAG_CONTROL_SCAN = "1"
18+
MEM_DIAG_GC_OBJECTS = "0"
19+
MEM_DIAG_COLLECT_GEN2_ON_SAMPLE = "1"
20+
MEM_DIAG_TYPE_HIST = "0"
21+
MEM_DIAG_TYPE_HIST_INTERVAL_SEC = "300"
22+
MEM_DIAG_TYPE_HIST_TOP = "30"
23+
MALLOC_ARENA_MAX = "2"
24+
MALLOC_TRIM_THRESHOLD_ = "131072"
925

1026
[experimental]
1127
allowed_public_ports = []
@@ -36,4 +52,4 @@ app = "flet-controls-gallery"
3652
grace_period = "1s"
3753
interval = "15s"
3854
restart_limit = 0
39-
timeout = "2s"
55+
timeout = "2s"

pyproject.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "gallery"
33
version = "0.1.0"
44
description = ""
55
readme = "README.md"
6-
requires-python = ">=3.10"
6+
requires-python = ">=3.14"
77
authors = [
88
{ name = "Flet developer", email = "you@example.com" }
99
]
@@ -12,6 +12,7 @@ dependencies = [
1212
"flet-audio",
1313
"flet-video",
1414
"flet",
15+
"flet-web",
1516
"objgraph"
1617
]
1718

@@ -27,6 +28,6 @@ path = "src"
2728

2829
[dependency-groups]
2930
dev = [
30-
"flet[all]",
31+
"flet-cli",
32+
"flet-desktop",
3133
]
32-

src/components/app.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import flet as ft
22

33
from components.app_bar import AppBar
4+
from components.diagnostics_view import DiagnosticsView
45
from components.gallery_view import GalleryView
56
from contexts.route import RouteContext, RouteContextValue
67
from contexts.theme import ThemeContext, ThemeContextValue
@@ -74,7 +75,11 @@ def update_theme():
7475
lambda: ft.View(
7576
route="/",
7677
appbar=AppBar(),
77-
controls=[GalleryView(gallery)],
78+
controls=[
79+
DiagnosticsView(key="diagnostics-view")
80+
if app.route == "/__diag"
81+
else GalleryView(gallery, key="gallery-view")
82+
],
7883
),
7984
),
8085
)

src/components/app_bar.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,34 @@
1+
import platform
2+
13
import flet as ft
24
import flet.version
35

6+
from utils.app_version import get_app_version
7+
48

59
@ft.component
610
def AppBar():
11+
def show_about_dialog():
12+
ft.context.page.show_dialog(
13+
ft.AlertDialog(
14+
title=ft.Text("About Gallery"),
15+
content=ft.Column(
16+
tight=True,
17+
controls=[
18+
ft.Text(f"Gallery version: {get_app_version()}"),
19+
ft.Text(f"Flet version: {flet.version.flet_version}"),
20+
ft.Text(f"Flutter version: {flet.version.flutter_version}"),
21+
ft.Text(f"Python version: {platform.python_version()}"),
22+
],
23+
),
24+
actions=[
25+
ft.TextButton(
26+
"Close", on_click=lambda _: ft.context.page.pop_dialog()
27+
)
28+
],
29+
)
30+
)
31+
732
return ft.AppBar(
833
title=ft.Row(
934
[
@@ -14,8 +39,15 @@ def AppBar():
1439
center_title=True,
1540
# bgcolor=ft.Colors.INVERSE_PRIMARY,
1641
actions=[
17-
ft.Container(
18-
padding=10, content=ft.Text(f"Version: {flet.version.flet_version}")
42+
ft.PopupMenuButton(
43+
icon=ft.Icons.MORE_VERT,
44+
tooltip="Menu",
45+
items=[
46+
ft.PopupMenuItem(
47+
content="About",
48+
on_click=show_about_dialog,
49+
)
50+
],
1951
),
2052
],
2153
)

src/components/diagnostics_view.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import json
2+
3+
import flet as ft
4+
5+
from diagnostics import diagnostics
6+
7+
8+
@ft.component
9+
def DiagnosticsView() -> ft.Control:
10+
last_dump, set_last_dump = ft.use_state("No diagnostics dump requested yet.")
11+
12+
print("Rendering DiagnosticsView")
13+
14+
def dump_now(_):
15+
payload = diagnostics.dump_now(reason="hidden_route_button")
16+
set_last_dump(json.dumps(payload, indent=2, default=str))
17+
18+
return ft.Column(
19+
expand=True,
20+
controls=[
21+
ft.Text("Memory Diagnostics"),
22+
ft.Text(
23+
"Hidden route for on-demand mem diagnostics. Triggering a dump logs JSON via memdiag logger.",
24+
color=ft.Colors.ON_SURFACE_VARIANT,
25+
),
26+
ft.Row(
27+
controls=[
28+
ft.Button(
29+
"Dump diagnostics now",
30+
icon=ft.Icons.BUG_REPORT,
31+
on_click=dump_now,
32+
),
33+
ft.OutlinedButton(
34+
"Back to gallery",
35+
icon=ft.Icons.ARROW_BACK,
36+
on_click=lambda _: ft.context.page.go("/"),
37+
),
38+
]
39+
),
40+
ft.TextField(
41+
value=last_dump,
42+
multiline=True,
43+
min_lines=14,
44+
max_lines=24,
45+
read_only=True,
46+
expand=True,
47+
text_style=ft.TextStyle(font_family="Roboto Mono", size=12),
48+
),
49+
],
50+
)

0 commit comments

Comments
 (0)