flet-cli 0.70.0.dev6232__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. flet_cli-0.70.0.dev6232/PKG-INFO +35 -0
  2. flet_cli-0.70.0.dev6232/README.md +17 -0
  3. flet_cli-0.70.0.dev6232/pyproject.toml +28 -0
  4. flet_cli-0.70.0.dev6232/setup.cfg +4 -0
  5. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/__init__.py +5 -0
  6. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/config.py +1 -0
  7. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/hook-flet.py +11 -0
  8. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/macos_utils.py +120 -0
  9. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/rthooks/pyi_rth_localhost_fletd.py +9 -0
  10. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/utils.py +25 -0
  11. flet_cli-0.70.0.dev6232/src/flet_cli/__pyinstaller/win_utils.py +109 -0
  12. flet_cli-0.70.0.dev6232/src/flet_cli/cli.py +100 -0
  13. flet_cli-0.70.0.dev6232/src/flet_cli/commands/base.py +57 -0
  14. flet_cli-0.70.0.dev6232/src/flet_cli/commands/build.py +2275 -0
  15. flet_cli-0.70.0.dev6232/src/flet_cli/commands/create.py +118 -0
  16. flet_cli-0.70.0.dev6232/src/flet_cli/commands/doctor.py +68 -0
  17. flet_cli-0.70.0.dev6232/src/flet_cli/commands/options.py +27 -0
  18. flet_cli-0.70.0.dev6232/src/flet_cli/commands/pack.py +312 -0
  19. flet_cli-0.70.0.dev6232/src/flet_cli/commands/publish.py +317 -0
  20. flet_cli-0.70.0.dev6232/src/flet_cli/commands/run.py +422 -0
  21. flet_cli-0.70.0.dev6232/src/flet_cli/commands/serve.py +72 -0
  22. flet_cli-0.70.0.dev6232/src/flet_cli/utils/android_sdk.py +243 -0
  23. flet_cli-0.70.0.dev6232/src/flet_cli/utils/distros.py +87 -0
  24. flet_cli-0.70.0.dev6232/src/flet_cli/utils/flutter.py +66 -0
  25. flet_cli-0.70.0.dev6232/src/flet_cli/utils/hash_stamp.py +22 -0
  26. flet_cli-0.70.0.dev6232/src/flet_cli/utils/jdk.py +134 -0
  27. flet_cli-0.70.0.dev6232/src/flet_cli/utils/merge.py +7 -0
  28. flet_cli-0.70.0.dev6232/src/flet_cli/utils/processes.py +70 -0
  29. flet_cli-0.70.0.dev6232/src/flet_cli/utils/project_dependencies.py +97 -0
  30. flet_cli-0.70.0.dev6232/src/flet_cli/utils/pyproject_toml.py +25 -0
  31. flet_cli-0.70.0.dev6232/src/flet_cli/version.py +1 -0
  32. flet_cli-0.70.0.dev6232/src/flet_cli.egg-info/PKG-INFO +35 -0
  33. flet_cli-0.70.0.dev6232/src/flet_cli.egg-info/SOURCES.txt +35 -0
  34. flet_cli-0.70.0.dev6232/src/flet_cli.egg-info/dependency_links.txt +1 -0
  35. flet_cli-0.70.0.dev6232/src/flet_cli.egg-info/entry_points.txt +2 -0
  36. flet_cli-0.70.0.dev6232/src/flet_cli.egg-info/requires.txt +6 -0
  37. flet_cli-0.70.0.dev6232/src/flet_cli.egg-info/top_level.txt +1 -0
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: flet-cli
3
+ Version: 0.70.0.dev6232
4
+ Summary: Flet CLI
5
+ Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://flet.dev
8
+ Project-URL: Repository, https://github.com/flet-dev/flet
9
+ Project-URL: Documentation, https://flet.dev/docs
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: flet
13
+ Requires-Dist: watchdog>=4.0.0
14
+ Requires-Dist: packaging>=25.0
15
+ Requires-Dist: qrcode>=7.4.2
16
+ Requires-Dist: toml>=0.10.2
17
+ Requires-Dist: cookiecutter>=2.6.0
18
+
19
+ # Flet CLI
20
+
21
+ Flet CLI is a command-line interface tool for Flet, a framework for building interactive multi-platform applications using Python.
22
+
23
+ ## Features
24
+
25
+ - Create new Flet projects
26
+ - Run Flet applications
27
+ - Package and deploy Flet apps
28
+
29
+ ## Basic Usage
30
+
31
+ To create a new Flet project:
32
+
33
+ ```
34
+ flet create myapp
35
+ ```
@@ -0,0 +1,17 @@
1
+ # Flet CLI
2
+
3
+ Flet CLI is a command-line interface tool for Flet, a framework for building interactive multi-platform applications using Python.
4
+
5
+ ## Features
6
+
7
+ - Create new Flet projects
8
+ - Run Flet applications
9
+ - Package and deploy Flet apps
10
+
11
+ ## Basic Usage
12
+
13
+ To create a new Flet project:
14
+
15
+ ```
16
+ flet create myapp
17
+ ```
@@ -0,0 +1,28 @@
1
+ [project]
2
+ name = "flet-cli"
3
+ version = "0.70.0.dev6232"
4
+ description = "Flet CLI"
5
+ authors = [{ name = "Appveyor Systems Inc.", email = "hello@flet.dev" }]
6
+ license = "Apache-2.0"
7
+ readme = "README.md"
8
+ requires-python = ">=3.10"
9
+ dependencies = [
10
+ "flet",
11
+ "watchdog >=4.0.0",
12
+ "packaging >=25.0",
13
+ "qrcode >=7.4.2",
14
+ "toml >=0.10.2",
15
+ "cookiecutter >=2.6.0"
16
+ ]
17
+
18
+ [project.urls]
19
+ Homepage = "https://flet.dev"
20
+ Repository = "https://github.com/flet-dev/flet"
21
+ Documentation = "https://flet.dev/docs"
22
+
23
+ [project.entry-points."pyinstaller40"]
24
+ hook-dirs = "flet_cli.__pyinstaller:get_hook_dirs"
25
+
26
+ [build-system]
27
+ requires = ["setuptools"]
28
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ import os
2
+
3
+
4
+ def get_hook_dirs():
5
+ return [os.path.dirname(__file__)]
@@ -0,0 +1 @@
1
+ temp_bin_dir = None
@@ -0,0 +1,11 @@
1
+ import os
2
+
3
+ import flet_cli.__pyinstaller.config as hook_config
4
+ from flet_cli.__pyinstaller.utils import get_flet_bin_path
5
+
6
+ bin_path = hook_config.temp_bin_dir
7
+ if not bin_path:
8
+ bin_path = get_flet_bin_path()
9
+
10
+ if bin_path:
11
+ datas = [(bin_path, "flet_desktop/app")]
@@ -0,0 +1,120 @@
1
+ import os
2
+ import plistlib
3
+ import shutil
4
+ import subprocess
5
+ import tarfile
6
+ from pathlib import Path
7
+
8
+ from flet.utils import safe_tar_extractall
9
+ from PyInstaller.building.icon import normalize_icon_type
10
+
11
+
12
+ def unpack_app_bundle(tar_path):
13
+ bin_dir = str(Path(tar_path).parent)
14
+
15
+ with tarfile.open(tar_path, "r:gz") as tar_arch:
16
+ safe_tar_extractall(tar_arch, bin_dir)
17
+ os.remove(tar_path)
18
+
19
+ return os.path.join(bin_dir, "Flet.app")
20
+
21
+
22
+ def update_flet_view_icon(app_path, icon_path):
23
+ print("Updating Flet View icon", app_path, icon_path)
24
+
25
+ icon_file = "AppIcon.icns"
26
+
27
+ # normalize icon
28
+ normalized_icon_path = normalize_icon_type(
29
+ icon_path, ("icns",), "icns", os.getcwd()
30
+ )
31
+
32
+ # patch icon
33
+ print("Copying icons from", normalized_icon_path)
34
+ shutil.copy(
35
+ normalized_icon_path,
36
+ os.path.join(app_path, "Contents", "Resources", icon_file),
37
+ )
38
+
39
+ # update icon file name
40
+ pl = __load_info_plist(app_path)
41
+ pl["CFBundleIconFile"] = icon_file
42
+ del pl["CFBundleIconName"]
43
+ __save_info_plist(app_path, pl)
44
+
45
+
46
+ def update_flet_view_version_info(
47
+ app_path,
48
+ bundle_id,
49
+ product_name,
50
+ product_version,
51
+ copyright,
52
+ ):
53
+ print("Updating Flet View plist", app_path)
54
+
55
+ pl = __load_info_plist(app_path)
56
+
57
+ if bundle_id:
58
+ pl["CFBundleIdentifier"] = bundle_id
59
+ if product_name:
60
+ pl["CFBundleName"] = product_name
61
+ pl["CFBundleDisplayName"] = product_name
62
+
63
+ # rename app bundle
64
+ new_app_path = os.path.join(Path(app_path).parent, f"{product_name}.app")
65
+ os.rename(app_path, new_app_path)
66
+ app_path = new_app_path
67
+ if product_version:
68
+ pl["CFBundleShortVersionString"] = product_version
69
+ if copyright:
70
+ pl["NSHumanReadableCopyright"] = copyright
71
+
72
+ __save_info_plist(app_path, pl)
73
+
74
+ return app_path
75
+
76
+
77
+ def assemble_app_bundle(app_path, tar_path):
78
+ # sign app bundle
79
+ print(f"Signing file {app_path}")
80
+ cmd_args = [
81
+ "codesign",
82
+ "-s",
83
+ "-",
84
+ "--force",
85
+ "--all-architectures",
86
+ "--timestamp",
87
+ "--deep",
88
+ app_path,
89
+ ]
90
+ p = subprocess.run(
91
+ cmd_args,
92
+ stdout=subprocess.PIPE,
93
+ stderr=subprocess.STDOUT,
94
+ universal_newlines=True,
95
+ )
96
+ if p.returncode:
97
+ raise SystemError(
98
+ f"codesign command ({cmd_args}) failed with error code {p.returncode}!\noutput: {p.stdout}"
99
+ )
100
+
101
+ # pack tar
102
+ with tarfile.open(tar_path, "w:gz") as tar:
103
+ tar.add(app_path, arcname=os.path.basename(app_path))
104
+
105
+ # cleanup
106
+ shutil.rmtree(app_path, ignore_errors=True)
107
+
108
+
109
+ def __load_info_plist(app_path):
110
+ with open(__get_plist_path(app_path), "rb") as fp:
111
+ return plistlib.load(fp)
112
+
113
+
114
+ def __save_info_plist(app_path, pl):
115
+ with open(__get_plist_path(app_path), "wb") as fp:
116
+ plistlib.dump(pl, fp)
117
+
118
+
119
+ def __get_plist_path(app_path):
120
+ return os.path.join(app_path, "Contents", "Info.plist")
@@ -0,0 +1,9 @@
1
+ import logging
2
+ import os
3
+
4
+ logger = logging.getLogger("flet")
5
+
6
+
7
+ logger.info("Running PyInstaller runtime hook for Flet...")
8
+
9
+ os.environ["FLET_SERVER_IP"] = "127.0.0.1"
@@ -0,0 +1,25 @@
1
+ import os
2
+ import tempfile
3
+ import uuid
4
+ from pathlib import Path
5
+
6
+ from flet.utils import copy_tree
7
+ from flet_desktop import get_package_bin_dir
8
+
9
+
10
+ def get_flet_bin_path():
11
+ bin_path = get_package_bin_dir()
12
+ if not os.path.exists(bin_path):
13
+ return None
14
+ return bin_path
15
+
16
+
17
+ def copy_flet_bin():
18
+ bin_path = get_flet_bin_path()
19
+ if not bin_path:
20
+ return None
21
+
22
+ # create temp bin dir
23
+ temp_bin_dir = Path(tempfile.gettempdir()).joinpath(str(uuid.uuid4()))
24
+ copy_tree(bin_path, str(temp_bin_dir))
25
+ return str(temp_bin_dir)
@@ -0,0 +1,109 @@
1
+ import os
2
+ import tempfile
3
+ import uuid
4
+ from pathlib import Path
5
+
6
+ import pefile
7
+ from packaging import version
8
+ from PyInstaller.building.icon import normalize_icon_type
9
+ from PyInstaller.compat import win32api
10
+ from PyInstaller.utils.win32 import versioninfo
11
+ from PyInstaller.utils.win32.icon import IconFile, normalize_icon_type
12
+
13
+
14
+ def update_flet_view_icon(exe_path, icon_path):
15
+ print("Updating Flet View icon", exe_path, icon_path)
16
+
17
+ RT_ICON = 3
18
+ RT_GROUP_ICON = 14
19
+
20
+ normalized_icon_path = normalize_icon_type(
21
+ icon_path, ("exe", "ico"), "ico", os.getcwd()
22
+ )
23
+ icon = IconFile(normalized_icon_path)
24
+ print("Copying icons from", normalized_icon_path)
25
+
26
+ hdst = win32api.BeginUpdateResource(exe_path, 0)
27
+
28
+ iconid = 1
29
+ # Each step in the following enumerate() will instantiate an IconFile object, as a result of deferred execution
30
+ # of the map() above.
31
+ i = 101
32
+ data = icon.grp_icon_dir()
33
+ data = data + icon.grp_icondir_entries(iconid)
34
+ win32api.UpdateResource(hdst, RT_GROUP_ICON, i, data, 1033)
35
+ print("Writing RT_GROUP_ICON %d resource with %d bytes", i, len(data))
36
+ for data in icon.images:
37
+ win32api.UpdateResource(hdst, RT_ICON, iconid, data, 1033)
38
+ print("Writing RT_ICON %d resource with %d bytes", iconid, len(data))
39
+ iconid = iconid + 1
40
+
41
+ win32api.EndUpdateResource(hdst, 0)
42
+
43
+
44
+ def update_flet_view_version_info(
45
+ exe_path,
46
+ product_name,
47
+ file_description,
48
+ product_version,
49
+ file_version,
50
+ company_name,
51
+ copyright,
52
+ ):
53
+ print("Updating Flet View version info", exe_path)
54
+
55
+ # load versioninfo from exe
56
+ if versioninfo.read_version_info_from_executable:
57
+ vs = versioninfo.read_version_info_from_executable(exe_path)
58
+ else:
59
+ vs = versioninfo.decode(exe_path)
60
+
61
+ # update file version
62
+ if file_version:
63
+ pv = version.parse(file_version)
64
+ filevers = (pv.major, pv.minor, pv.micro, 0)
65
+ vs.ffi.fileVersionMS = (filevers[0] << 16) | (filevers[1] & 0xFFFF)
66
+ vs.ffi.fileVersionLS = (filevers[2] << 16) | (filevers[3] & 0xFFFF)
67
+
68
+ # update string props
69
+ for k in vs.kids[0].kids[0].kids:
70
+ if k.name == "ProductName":
71
+ k.val = product_name if product_name else ""
72
+ elif k.name == "FileDescription":
73
+ k.val = file_description if file_description else ""
74
+ if k.name == "ProductVersion":
75
+ k.val = product_version if product_version else ""
76
+ if k.name == "FileVersion" and file_version:
77
+ k.val = file_version if file_version else ""
78
+ if k.name == "CompanyName":
79
+ k.val = company_name if company_name else ""
80
+ if k.name == "LegalCopyright":
81
+ k.val = copyright if copyright else ""
82
+
83
+ version_info_path = str(Path(tempfile.gettempdir()).joinpath(str(uuid.uuid4())))
84
+ with open(version_info_path, "w", encoding="utf-8") as f:
85
+ f.write(str(vs))
86
+
87
+ # Remember overlay
88
+ pe = pefile.PE(exe_path, fast_load=True)
89
+ overlay_before = pe.get_overlay()
90
+ pe.close()
91
+
92
+ hdst = win32api.BeginUpdateResource(exe_path, 0)
93
+ win32api.UpdateResource(
94
+ hdst, pefile.RESOURCE_TYPE["RT_VERSION"], 1, vs.toRaw(), 1033
95
+ )
96
+ win32api.EndUpdateResource(hdst, 0)
97
+
98
+ if overlay_before:
99
+ # Check if the overlay is still present
100
+ pe = pefile.PE(exe_path, fast_load=True)
101
+ overlay_after = pe.get_overlay()
102
+ pe.close()
103
+
104
+ # If the update removed the overlay data, re-append it
105
+ if not overlay_after:
106
+ with open(exe_path, "ab", encoding="utf-8") as exef:
107
+ exef.write(overlay_before)
108
+
109
+ return version_info_path
@@ -0,0 +1,100 @@
1
+ import argparse
2
+ import sys
3
+
4
+ import flet.version
5
+ import flet_cli.commands.build
6
+ import flet_cli.commands.create
7
+ import flet_cli.commands.doctor # Adding the doctor command
8
+ import flet_cli.commands.pack
9
+ import flet_cli.commands.publish
10
+ import flet_cli.commands.run
11
+ import flet_cli.commands.serve
12
+ from flet.version import update_version
13
+
14
+
15
+ # Source https://stackoverflow.com/a/26379693
16
+ def set_default_subparser(
17
+ parser: argparse.ArgumentParser, name: str, args: list = None, index: int = 0
18
+ ):
19
+ """
20
+ Set a default subparser when no subparser is provided.
21
+ This should be called after setting up the argument parser but before
22
+ `parse_args()`.
23
+
24
+ Args:
25
+ name: The name of the default subparser to use.
26
+ args: A list of arguments passed to `parse_args()`.
27
+ index: Position in `sys.argv` where the default subparser should be
28
+ inserted.
29
+ """
30
+
31
+ # exit if help or version flags are present
32
+ if any(flag in sys.argv[1:] for flag in {"-h", "--help", "-V", "--version"}):
33
+ return
34
+
35
+ # all subparser actions
36
+ subparser_actions = [
37
+ action
38
+ for action in parser._subparsers._actions
39
+ if isinstance(action, argparse._SubParsersAction)
40
+ ]
41
+
42
+ # all subparser names
43
+ subparser_names = [
44
+ sp_name for action in subparser_actions for sp_name in action._name_parser_map
45
+ ]
46
+
47
+ # if an existing subparser is provided, skip setting a default
48
+ if any(arg in subparser_names for arg in sys.argv[1:]):
49
+ return
50
+
51
+ # if the default subparser doesn't exist, register it in the first subparser action
52
+ if (name not in subparser_names) and subparser_actions:
53
+ subparser_actions[0].add_parser(name)
54
+
55
+ # insert the default subparser into the appropriate argument list
56
+ if args is None:
57
+ if len(sys.argv) > 1:
58
+ sys.argv.insert(index, name)
59
+ else:
60
+ args.insert(index, name)
61
+
62
+
63
+ def main():
64
+ parser = argparse.ArgumentParser()
65
+ parser.add_argument(
66
+ "--version",
67
+ "-V",
68
+ action="version",
69
+ version=flet.version.version if flet.version.version else update_version(),
70
+ )
71
+
72
+ sp = parser.add_subparsers(dest="command")
73
+
74
+ flet_cli.commands.create.Command.register_to(sp, "create")
75
+ flet_cli.commands.run.Command.register_to(sp, "run")
76
+ flet_cli.commands.build.Command.register_to(sp, "build")
77
+ flet_cli.commands.pack.Command.register_to(sp, "pack")
78
+ flet_cli.commands.publish.Command.register_to(sp, "publish")
79
+ flet_cli.commands.serve.Command.register_to(sp, "serve")
80
+ flet_cli.commands.doctor.Command.register_to(
81
+ sp, "doctor"
82
+ ) # Register the doctor command
83
+
84
+ # set "run" as the default subparser
85
+ set_default_subparser(parser, name="run", index=1)
86
+
87
+ # print usage/help if called without arguments
88
+ if len(sys.argv) == 1:
89
+ parser.print_help(sys.stdout)
90
+ sys.exit(1)
91
+
92
+ # parse arguments
93
+ args = parser.parse_args()
94
+
95
+ # execute command
96
+ args.handler(args)
97
+
98
+
99
+ if __name__ == "__main__":
100
+ main()
@@ -0,0 +1,57 @@
1
+ import argparse
2
+ from typing import Any, List, Optional
3
+
4
+ from flet_cli.commands.options import Option, verbose_option
5
+
6
+
7
+ class BaseCommand:
8
+ """A CLI subcommand"""
9
+
10
+ # The subcommand's name
11
+ name: Optional[str] = None
12
+ # The subcommand's help string, if not given, __doc__ will be used.
13
+ description: Optional[str] = None
14
+ # A list of pre-defined options which will be loaded on initializing
15
+ # Rewrite this if you don't want the default ones
16
+ arguments: List[Option] = [verbose_option]
17
+
18
+ def __init__(self, parser: argparse.ArgumentParser) -> None:
19
+ for arg in self.arguments:
20
+ arg.add_to_parser(parser)
21
+ self.add_arguments(parser)
22
+
23
+ @classmethod
24
+ def register_to(
25
+ cls,
26
+ subparsers: argparse._SubParsersAction,
27
+ name: Optional[str] = None,
28
+ **kwargs: Any
29
+ ) -> None:
30
+ """Register a subcommand to the subparsers,
31
+ with an optional name of the subcommand.
32
+ """
33
+ help_text = cls.description or cls.__doc__
34
+ name = name or cls.name or ""
35
+ # Remove the existing subparser as it will raises an error on Python 3.11+
36
+ subparsers._name_parser_map.pop(name, None)
37
+ subactions = subparsers._get_subactions()
38
+ subactions[:] = [action for action in subactions if action.dest != name]
39
+ parser = subparsers.add_parser(
40
+ name,
41
+ description=help_text,
42
+ help=help_text,
43
+ # formatter_class=PdmFormatter,
44
+ **kwargs,
45
+ )
46
+ command = cls(parser)
47
+ parser.set_defaults(handler=command.handle)
48
+
49
+ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
50
+ """Manipulate the argument parser to add more arguments"""
51
+ pass
52
+
53
+ def handle(self, options: argparse.Namespace) -> None:
54
+ """The command handler function.
55
+ :param options: the parsed Namespace object
56
+ """
57
+ raise NotImplementedError