Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FastAPI instead of built-in Fletd server. Mixed async/sync apps. #2700

Merged
merged 34 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d20eac5
FastAPI to support sync event handlers
FeodorFitsner Feb 18, 2024
e35ba88
FastAPI to run sync handlers on a threadpool
FeodorFitsner Feb 18, 2024
29386bf
flet_fastapi package moved into flet
FeodorFitsner Feb 18, 2024
6a8dc5a
flet_fastapi renamed to flet.fastapi. Utils refactored.
FeodorFitsner Feb 18, 2024
9439ee3
Async server only - almost working. No threadpool shutdown.
FeodorFitsner Feb 19, 2024
d6eb907
Use FastAPI instead of built-in web server
FeodorFitsner Feb 19, 2024
fa9b0a5
Remove Fletd from builds
FeodorFitsner Feb 19, 2024
e961cce
Build Flet for web
FeodorFitsner Feb 20, 2024
3be7530
Remove async_lock, fix CI
FeodorFitsner Feb 20, 2024
b2bb463
Use url_host and host
FeodorFitsner Feb 20, 2024
5371003
Switch page between flet app instances
FeodorFitsner Feb 20, 2024
8a4fbf0
Fix getWebsocketEndpointPath() for desktop
FeodorFitsner Feb 20, 2024
3145e0a
Handle all flet run cases
FeodorFitsner Feb 21, 2024
223c7ca
FLET env vars re-worked
FeodorFitsner Feb 21, 2024
c85cb0f
Cleanup
FeodorFitsner Feb 21, 2024
a3b5f63
Running apps in external ASGI server
FeodorFitsner Feb 22, 2024
8692aa4
Correct handling of assets dir
FeodorFitsner Feb 22, 2024
c6b4cd5
Update poetry.lock
FeodorFitsner Feb 22, 2024
af696b1
FLET_UPLOAD_SECRET_KEY renamed back to FLET_SECRET_KEY
FeodorFitsner Feb 22, 2024
849fca5
opt_in_blocking, refactor flet_core.utils
FeodorFitsner Feb 22, 2024
759103b
Squashed commit of the following:
FeodorFitsner Feb 23, 2024
4e11559
Squashed commit of the following:
FeodorFitsner Feb 25, 2024
c5a1f93
`warn()` replaced with `@deprecated`
FeodorFitsner Feb 26, 2024
19b3b63
Make OAuth working in a new arch
FeodorFitsner Feb 27, 2024
5dd76ef
Fix deprecation
FeodorFitsner Feb 27, 2024
132bbf2
Customize web app endpoints via env vars
FeodorFitsner Feb 27, 2024
6270b9a
Renamed `PageMediaChangeEvent` to `PageMediaData`
FeodorFitsner Feb 27, 2024
dae0e24
Renamed `run_in_thread` to `run_thread`
FeodorFitsner Feb 27, 2024
931def2
Deprecate some Video methods
FeodorFitsner Feb 27, 2024
4314e22
Fix Video.__playlist
FeodorFitsner Feb 27, 2024
d2ba1c1
Small fixes with loops
FeodorFitsner Feb 27, 2024
e2f6e33
Cleanup
FeodorFitsner Feb 28, 2024
4e1fbdc
Switch to our own `@deprecated` decorator
FeodorFitsner Feb 28, 2024
f09d907
Update deprecated message.
FeodorFitsner Feb 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 8 additions & 34 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: ubuntu2004-arm
python_stack: ""

- job_name: Build Flet for web
job_group: build_flet
job_depends_on: build_flet_package
APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu

# - job_name: Build Flet for iOS
# job_group: build_flet
# job_depends_on: build_flet_package
# APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey

- job_name: Build Fletd
job_group: build_flet
job_depends_on: build_flet_package
APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu

- job_name: Test Python 3.8
job_group: python_tests
python_stack: python 3.8
Expand Down Expand Up @@ -349,23 +349,16 @@ for:
name: flet_ios

# ======================================
# Build Fletd
# Build Flet for web
# ======================================

- matrix:
only:
- job_name: Build Fletd
- job_name: Build Flet for web

install:
- flutter upgrade --force

# Go and GoReleaser
- gvm install go${GO_VERSION} -B
- gvm use go${GO_VERSION}
- go version
- bash ./ci/install_goreleaser.sh
- goreleaser --version

build_script:
# Flutter Web client
- cd client
Expand All @@ -375,19 +368,7 @@ for:
- cd ..
- tar -czvf client/build/flet-web.tar.gz -C client/build/web .

# Flet Server in Go
- cd server
- sh: |
if [[ "$APPVEYOR_REPO_TAG" == "true" ]]; then
goreleaser
else
goreleaser --snapshot --skip-publish
fi
- cd ..

artifacts:
- path: server/dist/fletd-*
- path: server/dist/fletd_*/*
- path: client/build/flet-web.tar.gz
name: flet_web

Expand Down Expand Up @@ -444,7 +425,6 @@ for:
- python3 patch_toml.py packages/flet-runtime/pyproject.toml $PYPI_VER
- python3 patch_toml.py packages/flet-core/pyproject.toml $PYPI_VER
- python3 patch_toml.py packages/flet-pyodide/pyproject.toml $PYPI_VER
- python3 patch_toml.py packages/flet-fastapi/pyproject.toml $PYPI_VER

# build "flet-core" package
- pushd packages/flet-core
Expand Down Expand Up @@ -473,15 +453,10 @@ for:
- poetry build
- popd

# build "flet-fastapi" package
- pushd packages/flet-fastapi
- poetry build
- popd

# publish package
- sh: |
if [[ ("$APPVEYOR_REPO_BRANCH" == "main" || "$APPVEYOR_REPO_TAG_NAME" != "") && "$APPVEYOR_PULL_REQUEST_NUMBER" == "" ]]; then
twine upload packages/flet-core/dist/* packages/flet-runtime/dist/* packages/flet-embed/dist/* packages/flet/dist/* packages/flet-pyodide/dist/* packages/flet-fastapi/dist/*
twine upload packages/flet-core/dist/* packages/flet-runtime/dist/* packages/flet-embed/dist/* packages/flet/dist/* packages/flet-pyodide/dist/*
fi

artifacts:
Expand All @@ -490,4 +465,3 @@ for:
- path: sdk/python/packages/flet/dist/*
- path: sdk/python/packages/flet-embed/dist/*
- path: sdk/python/packages/flet-pyodide/dist/*
- path: sdk/python/packages/flet-fastapi/dist/*
6 changes: 3 additions & 3 deletions packages/flet/lib/src/flet_server_protocol_web_socket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ class FletWebSocketServerProtocol implements FletServerProtocol {

String getWebSocketEndpoint(Uri uri) {
final wsScheme = uri.scheme == "https" ? "wss" : "ws";
final path = getWebsocketEndpointPath();
if (path == "") {
final wsPath = getWebsocketEndpointPath(uri.path);
if (wsPath == "") {
throw Exception("WebSocket endpoint path cannot be empty.");
}
return "$wsScheme://${uri.authority}/$path";
return "$wsScheme://${uri.authority}/$wsPath";
}
}
10 changes: 8 additions & 2 deletions packages/flet/lib/src/utils/platform_utils_non_web.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import 'strings.dart';

bool isProgressiveWebApp() {
return false;
}

String getWebsocketEndpointPath() {
return "ws";
String getWebsocketEndpointPath(String uriPath) {
var pagePath = trim(uriPath, "/");
if (pagePath != "") {
pagePath = "$pagePath/";
}
return "${pagePath}ws";
}

String getFletRouteUrlStrategy() {
Expand Down
2 changes: 1 addition & 1 deletion packages/flet/lib/src/utils/platform_utils_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ bool isProgressiveWebApp() {
html.window.matchMedia('(display-mode: minimal-ui)').matches;
}

String getWebsocketEndpointPath() {
String getWebsocketEndpointPath(String uriPath) {
var meta = html.document.head
?.querySelector("meta[name='flet-websocket-endpoint-path']");
return trim(meta?.attributes["content"] ?? "ws", "/");
Expand Down
1 change: 0 additions & 1 deletion sdk/python/clean-pypi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ pypi-cleanup -u flet -p flet -y -r $VER --do-it
pypi-cleanup -u flet -p flet-core -y -r $VER --do-it
pypi-cleanup -u flet -p flet-runtime -y -r $VER --do-it
pypi-cleanup -u flet -p flet-embed -y -r $VER --do-it
pypi-cleanup -u flet -p flet-fastapi -y -r $VER --do-it
pypi-cleanup -u flet -p flet-pyodide -y -r $VER --do-it
4 changes: 3 additions & 1 deletion sdk/python/packages/flet-core/src/flet_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@
KeyboardEvent,
LoginEvent,
Page,
PageMediaChangeEvent,
PageDisconnectedException,
PageMediaData,
RouteChangeEvent,
ViewPopEvent,
)
Expand All @@ -176,6 +177,7 @@
from flet_core.popup_menu_button import PopupMenuButton, PopupMenuItem
from flet_core.progress_bar import ProgressBar
from flet_core.progress_ring import ProgressRing
from flet_core.pubsub import PubSub, PubSubHub
from flet_core.querystring import QueryString
from flet_core.radio import Radio
from flet_core.radio_group import RadioGroup
Expand Down
4 changes: 2 additions & 2 deletions sdk/python/packages/flet-core/src/flet_core/alert_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ def __init__(
def _get_control_name(self):
return "alertdialog"

def _before_build_command(self):
super()._before_build_command()
def before_update(self):
super().before_update()
self._set_attr_json("actionsPadding", self.__actions_padding)
self._set_attr_json("contentPadding", self.__content_padding)
self._set_attr_json("titlePadding", self.__title_padding)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ def __init__(
def _get_control_name(self):
return "animatedswitcher"

def _before_build_command(self):
super()._before_build_command()
def before_update(self):
super().before_update()

def _get_children(self):
children = []
Expand Down
66 changes: 43 additions & 23 deletions sdk/python/packages/flet-core/src/flet_core/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from flet_core.control import Control, OptionalNumber
from flet_core.ref import Ref
from flet_core.utils import deprecated


class ReleaseMode(Enum):
Expand Down Expand Up @@ -80,43 +81,63 @@ def _get_control_name(self):
return "audio"

def play(self):
self.page.invoke_method("play", control_id=self.uid)
self.invoke_method("play")

@deprecated(
reason="Use play() method instead.",
version="0.21.0",
delete_version="1.0",
)
async def play_async(self):
await self.page.invoke_method_async("play", control_id=self.uid)
self.play()

def pause(self):
self.page.invoke_method("pause", control_id=self.uid)
self.invoke_method("pause")

@deprecated(
reason="Use pause() method instead.",
version="0.21.0",
delete_version="1.0",
)
async def pause_async(self):
await self.page.invoke_method_async("pause", control_id=self.uid)
self.pause()

def resume(self):
self.page.invoke_method("resume", control_id=self.uid)
self.invoke_method("resume")

@deprecated(
reason="Use resume() method instead.",
version="0.21.0",
delete_version="1.0",
)
async def resume_async(self):
await self.page.invoke_method_async("resume", control_id=self.uid)
self.resume()

def release(self):
self.page.invoke_method("release", control_id=self.uid)
self.invoke_method("release")

@deprecated(
reason="Use release() method instead.",
version="0.21.0",
delete_version="1.0",
)
async def release_async(self):
await self.page.invoke_method_async("release", control_id=self.uid)
self.release()

def seek(self, position_milliseconds: int):
self.page.invoke_method(
"seek", {"position": str(position_milliseconds)}, control_id=self.uid
)
self.invoke_method("seek", {"position": str(position_milliseconds)})

@deprecated(
reason="Use seek() method instead.",
version="0.21.0",
delete_version="1.0",
)
async def seek_async(self, position_milliseconds: int):
await self.page.invoke_method_async(
"seek", {"position": str(position_milliseconds)}, control_id=self.uid
)
self.seek(position_milliseconds)

def get_duration(self, wait_timeout: Optional[float] = 5) -> Optional[int]:
sr = self.page.invoke_method(
sr = self.invoke_method(
"get_duration",
control_id=self.uid,
wait_for_result=True,
wait_timeout=wait_timeout,
)
Expand All @@ -125,18 +146,16 @@ def get_duration(self, wait_timeout: Optional[float] = 5) -> Optional[int]:
async def get_duration_async(
self, wait_timeout: Optional[float] = 5
) -> Optional[int]:
sr = await self.page.invoke_method_async(
sr = await self.invoke_method_async(
"get_duration",
control_id=self.uid,
wait_for_result=True,
wait_timeout=wait_timeout,
)
return int(sr) if sr else None

def get_current_position(self, wait_timeout: Optional[float] = 5) -> Optional[int]:
sr = self.page.invoke_method(
sr = self.invoke_method(
"get_current_position",
control_id=self.uid,
wait_for_result=True,
wait_timeout=wait_timeout,
)
Expand All @@ -145,9 +164,8 @@ def get_current_position(self, wait_timeout: Optional[float] = 5) -> Optional[in
async def get_current_position_async(
self, wait_timeout: Optional[float] = 5
) -> Optional[int]:
sr = await self.page.invoke_method_async(
sr = await self.invoke_method_async(
"get_current_position",
control_id=self.uid,
wait_for_result=True,
wait_timeout=wait_timeout,
)
Expand Down Expand Up @@ -217,7 +235,9 @@ def release_mode(self):

@release_mode.setter
def release_mode(self, value: Optional[ReleaseMode]):
self._set_attr("releaseMode", value.value if isinstance(value, ReleaseMode) else value)
self._set_attr(
"releaseMode", value.value if isinstance(value, ReleaseMode) else value
)

# on_loaded
@property
Expand Down
Loading