fastled 1.2.61__py3-none-any.whl → 1.2.63__py3-none-any.whl

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.
fastled/__init__.py CHANGED
@@ -13,7 +13,7 @@ from .types import BuildMode, CompileResult, CompileServerError
13
13
  # IMPORTANT! There's a bug in github which will REJECT any version update
14
14
  # that has any other change in the repo. Please bump the version as the
15
15
  # ONLY change in a commit, or else the pypi update and the release will fail.
16
- __version__ = "1.2.61"
16
+ __version__ = "1.2.63"
17
17
 
18
18
  DOCKER_FILE = (
19
19
  "https://raw.githubusercontent.com/zackees/fastled-wasm/refs/heads/main/Dockerfile"
fastled/open_browser.py CHANGED
@@ -26,7 +26,7 @@ def _open_http_server_subprocess(
26
26
  cmd = [
27
27
  PYTHON_EXE,
28
28
  "-m",
29
- "fastled.open_browser2",
29
+ "fastled.server_start",
30
30
  str(fastled_js),
31
31
  "--port",
32
32
  str(port),
@@ -32,7 +32,7 @@ def _run_fastapi_server(
32
32
  "fastled.server_fastapi:app",
33
33
  host="127.0.0.1",
34
34
  port=port,
35
- reload=True,
35
+ reload=False,
36
36
  # reload_includes=["index.html"],
37
37
  ssl_certfile=certfile,
38
38
  ssl_keyfile=keyfile,
@@ -0,0 +1,152 @@
1
+ import argparse
2
+ from multiprocessing import Process
3
+ from pathlib import Path
4
+
5
+ from livereload import Server
6
+
7
+
8
+ def _run_flask_server(
9
+ fastled_js: Path,
10
+ port: int,
11
+ certfile: Path | None = None,
12
+ keyfile: Path | None = None,
13
+ ) -> None:
14
+ """Run Flask server with live reload in a subprocess
15
+
16
+ Args:
17
+ fastled_js: Path to the fastled_js directory
18
+ port: Port to run the server on
19
+ certfile: Path to the SSL certificate file
20
+ keyfile: Path to the SSL key file
21
+ """
22
+ try:
23
+ from flask import Flask, send_from_directory
24
+
25
+ app = Flask(__name__)
26
+
27
+ # Must be a full path or flask will fail to find the file.
28
+ fastled_js = fastled_js.resolve()
29
+
30
+ @app.route("/")
31
+ def serve_index():
32
+ return send_from_directory(fastled_js, "index.html")
33
+
34
+ @app.route("/<path:path>")
35
+ def serve_files(path):
36
+ response = send_from_directory(fastled_js, path)
37
+ # Some servers don't set the Content-Type header for a bunch of files.
38
+ if path.endswith(".js"):
39
+ response.headers["Content-Type"] = "application/javascript"
40
+ if path.endswith(".css"):
41
+ response.headers["Content-Type"] = "text/css"
42
+ if path.endswith(".wasm"):
43
+ response.headers["Content-Type"] = "application/wasm"
44
+ if path.endswith(".json"):
45
+ response.headers["Content-Type"] = "application/json"
46
+ if path.endswith(".png"):
47
+ response.headers["Content-Type"] = "image/png"
48
+ if path.endswith(".jpg"):
49
+ response.headers["Content-Type"] = "image/jpeg"
50
+ if path.endswith(".jpeg"):
51
+ response.headers["Content-Type"] = "image/jpeg"
52
+ if path.endswith(".gif"):
53
+ response.headers["Content-Type"] = "image/gif"
54
+ if path.endswith(".svg"):
55
+ response.headers["Content-Type"] = "image/svg+xml"
56
+ if path.endswith(".ico"):
57
+ response.headers["Content-Type"] = "image/x-icon"
58
+ if path.endswith(".html"):
59
+ response.headers["Content-Type"] = "text/html"
60
+
61
+ # now also add headers to force no caching
62
+ response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
63
+ response.headers["Pragma"] = "no-cache"
64
+ response.headers["Expires"] = "0"
65
+ return response
66
+
67
+ server = Server(app.wsgi_app)
68
+ # Watch index.html for changes
69
+ server.watch(str(fastled_js / "index.html"))
70
+ # server.watch(str(fastled_js / "index.js"))
71
+ # server.watch(str(fastled_js / "index.css"))
72
+ # Start the server
73
+ server.serve(port=port, debug=True)
74
+ except KeyboardInterrupt:
75
+ import _thread
76
+
77
+ _thread.interrupt_main()
78
+ except Exception as e:
79
+ print(f"Failed to run Flask server: {e}")
80
+ import _thread
81
+
82
+ _thread.interrupt_main()
83
+
84
+
85
+ def run(
86
+ port: int, cwd: Path, certfile: Path | None = None, keyfile: Path | None = None
87
+ ) -> None:
88
+ """Run the Flask server."""
89
+ try:
90
+ _run_flask_server(cwd, port, certfile, keyfile)
91
+ import warnings
92
+
93
+ warnings.warn("Flask server has stopped")
94
+ except KeyboardInterrupt:
95
+ import _thread
96
+
97
+ _thread.interrupt_main()
98
+ pass
99
+
100
+
101
+ def parse_args() -> argparse.Namespace:
102
+ """Parse the command line arguments."""
103
+ parser = argparse.ArgumentParser(
104
+ description="Open a browser to the fastled_js directory"
105
+ )
106
+ parser.add_argument(
107
+ "fastled_js", type=Path, help="Path to the fastled_js directory"
108
+ )
109
+ parser.add_argument(
110
+ "--port",
111
+ "-p",
112
+ type=int,
113
+ required=True,
114
+ help="Port to run the server on (default: %(default)s)",
115
+ )
116
+ parser.add_argument(
117
+ "--certfile",
118
+ type=Path,
119
+ help="Path to the SSL certificate file for HTTPS",
120
+ )
121
+ parser.add_argument(
122
+ "--keyfile",
123
+ type=Path,
124
+ help="Path to the SSL key file for HTTPS",
125
+ )
126
+ return parser.parse_args()
127
+
128
+
129
+ def run_flask_server_process(
130
+ port: int,
131
+ cwd: Path | None = None,
132
+ certfile: Path | None = None,
133
+ keyfile: Path | None = None,
134
+ ) -> Process:
135
+ """Run the Flask server in a separate process."""
136
+ cwd = cwd or Path(".")
137
+ process = Process(
138
+ target=run,
139
+ args=(port, cwd, certfile, keyfile),
140
+ )
141
+ process.start()
142
+ return process
143
+
144
+
145
+ def main() -> None:
146
+ """Main function."""
147
+ args = parse_args()
148
+ run(args.port, args.fastled_js, args.certfile, args.keyfile)
149
+
150
+
151
+ if __name__ == "__main__":
152
+ main()
@@ -1,8 +1,34 @@
1
1
  import argparse
2
2
  import importlib.resources as pkg_resources
3
+ from dataclasses import dataclass
4
+ from multiprocessing import Process
3
5
  from pathlib import Path
4
6
 
5
7
  from fastled.server_fastapi_cli import run_fastapi_server_process
8
+ from fastled.server_flask import run_flask_server_process
9
+
10
+
11
+ def run_server_process(
12
+ port: int, cwd: Path, certfile: Path | None = None, keyfile: Path | None = None
13
+ ) -> Process:
14
+ """Run the server in a separate process."""
15
+ if True:
16
+ # Use Flask server
17
+ process = run_flask_server_process(
18
+ port=port,
19
+ cwd=cwd,
20
+ certfile=certfile,
21
+ keyfile=keyfile,
22
+ )
23
+ else:
24
+ # Use FastAPI server
25
+ process = run_fastapi_server_process(
26
+ port=port,
27
+ cwd=cwd,
28
+ certfile=certfile,
29
+ keyfile=keyfile,
30
+ )
31
+ return process
6
32
 
7
33
 
8
34
  def get_asset_path(filename: str) -> Path | None:
@@ -16,12 +42,12 @@ def get_asset_path(filename: str) -> Path | None:
16
42
  return None
17
43
 
18
44
 
19
- def run(
45
+ def start_process(
20
46
  path: Path,
21
47
  port: int,
22
48
  certfile: Path | None = None,
23
49
  keyfile: Path | None = None,
24
- ) -> None:
50
+ ) -> Process:
25
51
  """Run the server, using package assets if explicit paths are not provided"""
26
52
  # Use package resources if no explicit path
27
53
  if certfile is None:
@@ -31,16 +57,25 @@ def run(
31
57
 
32
58
  # _run_flask_server(path, port, certfile, keyfile)
33
59
  # run_fastapi_server_process(port=port, path=path, certfile=certfile, keyfile=keyfile)
34
- proc = run_fastapi_server_process(port=port, cwd=path)
35
- try:
36
- proc.join()
37
- except KeyboardInterrupt:
38
- import _thread
60
+ proc = run_server_process(port=port, cwd=path)
61
+ # try:
62
+ # proc.join()
63
+ # except KeyboardInterrupt:
64
+ # import _thread
65
+
66
+ # _thread.interrupt_main()
67
+ return proc
39
68
 
40
- _thread.interrupt_main()
41
69
 
70
+ @dataclass
71
+ class Args:
72
+ fastled_js: Path
73
+ port: int
74
+ cert: Path | None
75
+ key: Path | None
42
76
 
43
- def parse_args() -> argparse.Namespace:
77
+
78
+ def parse_args() -> Args:
44
79
  parser = argparse.ArgumentParser(
45
80
  description="Open a browser to the fastled_js directory"
46
81
  )
@@ -60,21 +95,37 @@ def parse_args() -> argparse.Namespace:
60
95
  parser.add_argument(
61
96
  "--key", type=Path, help="(Optional) Path to SSL private key (PEM format)"
62
97
  )
63
- return parser.parse_args()
98
+ args = parser.parse_args()
99
+ out: Args = Args(
100
+ fastled_js=args.fastled_js,
101
+ port=args.port,
102
+ cert=args.cert,
103
+ key=args.key,
104
+ )
105
+ if args.fastled_js is None:
106
+ raise ValueError("fastled_js directory is required")
107
+ return out
64
108
 
65
109
 
66
110
  def main() -> None:
67
- args = parse_args()
111
+ args: Args = parse_args()
68
112
  fastled_js: Path = args.fastled_js
69
113
  port: int = args.port
70
114
  cert: Path | None = args.cert
71
115
  key: Path | None = args.key
72
- run(
116
+ proc = start_process(
73
117
  path=fastled_js,
74
118
  port=port,
75
119
  certfile=cert,
76
120
  keyfile=key,
77
121
  )
122
+ try:
123
+ proc.join()
124
+ except KeyboardInterrupt:
125
+ import _thread
126
+
127
+ _thread.interrupt_main()
128
+ pass
78
129
 
79
130
 
80
131
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastled
3
- Version: 1.2.61
3
+ Version: 1.2.63
4
4
  Summary: FastLED Wasm Compiler
5
5
  Home-page: https://github.com/zackees/fastled-wasm
6
6
  Maintainer: Zachary Vorhies
@@ -23,6 +23,8 @@ Requires-Dist: fastapi>=0.115.12
23
23
  Requires-Dist: uvicorn>=0.34.2
24
24
  Requires-Dist: pywebview>=5.4
25
25
  Requires-Dist: watchfiles>=1.0.5
26
+ Requires-Dist: Flask>=3.0.0
27
+ Requires-Dist: livereload
26
28
  Dynamic: home-page
27
29
  Dynamic: license-file
28
30
  Dynamic: maintainer
@@ -1,4 +1,4 @@
1
- fastled/__init__.py,sha256=w_GKHlTrhiwiz_aQU4IZ08bHxQvhoyhd1oXEsz3gzYQ,6734
1
+ fastled/__init__.py,sha256=5aM7L5rPWOa6f56b-62Ta-VvK4OYGfZ0rAM9U06ffXY,6734
2
2
  fastled/app.py,sha256=Ozn7OJ0rz3CEHsJKMhFLxV7TisRKo4DuFpVhrf5FQNw,3944
3
3
  fastled/cli.py,sha256=FjVr31ht0UPlAcmX-84NwfAGMQHTkrCe4o744jCAxiw,375
4
4
  fastled/cli_test.py,sha256=qJB9yLRFR3OwOwdIWSQ0fQsWLnA37v5pDccufiP_hTs,512
@@ -11,14 +11,15 @@ fastled/interactive_srcs.py,sha256=F5nHdJc60xsnmOtnKhngE9JytqGn56PmYw_MVSIX1ac,1
11
11
  fastled/keyboard.py,sha256=UTAsqCn1UMYnB8YDzENiLTj4GeL45tYfEcO7_5fLFEg,3556
12
12
  fastled/keyz.py,sha256=WjfZHtZHEB8wNh1YYZGYwjx1jQV-6wwhCbYn4Zp7xs4,938
13
13
  fastled/live_client.py,sha256=MDauol0mxtXggV1Pv9ahC0Jjg_4wnnV6FjGEtdd9cxU,2763
14
- fastled/open_browser.py,sha256=YrjjCOALEStlrd-7gXGmzY0zSE5gJ6po__2u4M1orUk,4112
15
- fastled/open_browser2.py,sha256=xR8wLshpk3HPMtSzI48vUN9tvh0kMSR2eEs6LHpnpxM,2279
14
+ fastled/open_browser.py,sha256=HKiSFGtp182JdZvletrGrG_sit5MSjIpl7z54ceYzXU,4111
16
15
  fastled/parse_args.py,sha256=xgjxirQVX3FQxHZNVJtQQxTOeSJRQdGUNQ7W33Y880Y,8051
17
16
  fastled/paths.py,sha256=VsPmgu0lNSCFOoEC0BsTYzDygXqy15AHUfN-tTuzDZA,99
18
17
  fastled/project_init.py,sha256=bBt4DwmW5hZkm9ICt9Qk-0Nr_0JQM7icCgH5Iv-bCQs,3984
19
18
  fastled/select_sketch_directory.py,sha256=TZdCjl1D7YMKjodMTvDRurPcpAmN3x0TcJxffER2NfM,1314
20
19
  fastled/server_fastapi.py,sha256=ytsL4poO-yugDIhvYJq6nCNdLZ4fQJ1AFqXkF-uEkqo,1488
21
- fastled/server_fastapi_cli.py,sha256=Qha2Wvv4V1dQ_xstmF4rEtv0dc6dO-AF-nUDH8FlgWw,1391
20
+ fastled/server_fastapi_cli.py,sha256=fJGLvbJx5ertsZER_lgg0GfkYTX-V2rxzbNO1lEapU0,1392
21
+ fastled/server_flask.py,sha256=i0OtDdrjiF9hjKNnI2ebf6Ag-mxMmtUCxnuHMBOzx7I,4665
22
+ fastled/server_start.py,sha256=NfAV5pWdXn2HDvqiMrpHxuNqh2vnB4xVFltV5Pn16GM,3509
22
23
  fastled/settings.py,sha256=URgM6ZPlQYF-0ZTEhQCX8isLR6CbmYGwhDX4uXbh-ZI,468
23
24
  fastled/sketch.py,sha256=tHckjDj8P6BI_LWzUFM071a9qcqPs-r-qFWIe50P5Xw,3391
24
25
  fastled/spinner.py,sha256=VHxmvB92P0Z_zYxRajb5HiNmkHHvZ5dG7hKtZltzpcs,867
@@ -33,9 +34,9 @@ fastled/site/build.py,sha256=2YKU_UWKlJdGnjdbAbaL0co6kceFMSTVYwH1KCmgPZA,13987
33
34
  fastled/site/examples.py,sha256=s6vj2zJc6BfKlnbwXr1QWY1mzuDBMt6j5MEBOWjO_U8,155
34
35
  fastled/test/can_run_local_docker_tests.py,sha256=LEuUbHctRhNNFWcvnz2kEGmjDJeXO4c3kNpizm3yVJs,400
35
36
  fastled/test/examples.py,sha256=GfaHeY1E8izBl6ZqDVjz--RHLyVR4NRnQ5pBesCFJFY,1673
36
- fastled-1.2.61.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
37
- fastled-1.2.61.dist-info/METADATA,sha256=-ZksctwA-RHaJmKW0QkXp1ltfcQEPuPkzlG0sxBDHE8,22010
38
- fastled-1.2.61.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
39
- fastled-1.2.61.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
40
- fastled-1.2.61.dist-info/top_level.txt,sha256=Bbv5kpJpZhWNCvDF4K0VcvtBSDMa8B7PTOrZa9CezHY,8
41
- fastled-1.2.61.dist-info/RECORD,,
37
+ fastled-1.2.63.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
38
+ fastled-1.2.63.dist-info/METADATA,sha256=PlaQvKRqPQmKD0F2sDNNQBu2kGiGZCJwq_vYx-8YSOA,22064
39
+ fastled-1.2.63.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
40
+ fastled-1.2.63.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
41
+ fastled-1.2.63.dist-info/top_level.txt,sha256=Bbv5kpJpZhWNCvDF4K0VcvtBSDMa8B7PTOrZa9CezHY,8
42
+ fastled-1.2.63.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.0.0)
2
+ Generator: setuptools (80.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5