Skip to content

Commit d29724c

Browse files
committed
Expose WSGI application interface via main Mesop module
1 parent 863ddd0 commit d29724c

File tree

4 files changed

+62
-78
lines changed

4 files changed

+62
-78
lines changed

mesop/__init__.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from typing import Any, TypeVar, cast
1+
import sys
2+
import types
3+
from typing import Any, Callable, TypeVar, cast
24

35
from mesop.commands.navigate import navigate as navigate
46
from mesop.component_helpers import (
@@ -112,7 +114,17 @@
112114
from mesop.key import Key as Key
113115
from mesop.runtime import runtime
114116
from mesop.server.colab_run import colab_run as colab_run
115-
from mesop.server.create_app import create_app as create_app
117+
from mesop.server.wsgi_app import wsgi_app
118+
119+
120+
class _WsgiAppModule(types.ModuleType):
121+
def __call__(
122+
self, environ: dict[Any, Any], start_response: Callable[..., Any]
123+
):
124+
return wsgi_app(environ, start_response)
125+
126+
127+
sys.modules[__name__].__class__ = _WsgiAppModule
116128

117129
_T = TypeVar("_T")
118130

mesop/bin/bin.py

+31-65
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,50 @@
11
import os
22
import sys
3-
from typing import Any, Callable, Sequence
3+
from typing import Sequence
44

55
from absl import app, flags
6-
from flask import Flask
76

87
import mesop.protos.ui_pb2 as pb
98
from mesop.cli.execute_module import execute_module, get_module_name_from_path
109
from mesop.exceptions import format_traceback
11-
from mesop.runtime import enable_debug_mode, runtime
12-
from mesop.server.constants import EDITOR_PACKAGE_PATH, PROD_PACKAGE_PATH
13-
from mesop.server.flags import port
14-
from mesop.server.logging import log_startup
15-
from mesop.server.server import configure_flask_app
16-
from mesop.server.static_file_serving import configure_static_file_serving
10+
from mesop.runtime import runtime
11+
from mesop.server.wsgi_app import create_app
1712

1813
FLAGS = flags.FLAGS
1914

2015
flags.DEFINE_bool(
2116
"prod", False, "set to true for prod mode; otherwise editor mode."
2217
)
23-
flags.DEFINE_bool("verbose", False, "set to true for verbose logging.")
2418

2519

26-
class App:
27-
_flask_app: Flask
28-
29-
def __init__(self, flask_app: Flask):
30-
self._flask_app = flask_app
31-
32-
def run(self):
33-
log_startup(port=port())
34-
self._flask_app.run(host="0.0.0.0", port=port(), use_reloader=False)
20+
def main(argv: Sequence[str]):
21+
if len(argv) < 2:
22+
print(
23+
"""\u001b[31mERROR: missing command-line argument to Mesop application.\u001b[0m
3524
36-
def __call__(
37-
self, environ: dict[Any, Any], start_response: Callable[..., Any]
38-
) -> Any:
39-
"""Wrapper around Flask API so that a WGSI server can call this application."""
40-
return self._flask_app.wsgi_app(environ, start_response) # type: ignore
25+
Example command:
26+
$\u001b[35m mesop file.py\u001b[0m"""
27+
)
28+
sys.exit(1)
4129

30+
if len(argv) > 2:
31+
print(
32+
f"""\u001b[31mERROR: Too many command-line arguments.\u001b[0m
4233
43-
def make_path_absolute(file_path: str):
44-
if os.path.isabs(file_path):
45-
return file_path
46-
# Otherwise, make the relative path absolute by joining
47-
# with current working dir.
48-
absolute_path = os.path.join(os.getcwd(), file_path)
49-
return absolute_path
34+
Actual:
35+
$\u001b[35m mesop {" ".join(argv[1:])}\u001b[0m
5036
37+
Re-run with:
38+
$\u001b[35m mesop {argv[1]}\u001b[0m"""
39+
)
40+
sys.exit(1)
5141

52-
def create_app(path_arg: str) -> App:
53-
flask_app = configure_flask_app()
42+
create_app(
43+
prod_mode=FLAGS.prod, run_block=lambda: execute_main_module(argv[1])
44+
).run()
5445

55-
if FLAGS.prod:
56-
enable_debug_mode()
5746

47+
def execute_main_module(path_arg: str):
5848
try:
5949
absolute_path = make_path_absolute(path_arg)
6050
execute_module(
@@ -69,38 +59,14 @@ def create_app(path_arg: str) -> App:
6959
# Always raise an error to make it easy to debug
7060
raise e
7161

72-
configure_static_file_serving(
73-
flask_app,
74-
static_file_runfiles_base=PROD_PACKAGE_PATH
75-
if FLAGS.prod
76-
else EDITOR_PACKAGE_PATH,
77-
)
78-
79-
return App(flask_app=flask_app)
80-
8162

82-
def main(argv: Sequence[str]):
83-
if len(argv) < 2:
84-
print(
85-
"""\u001b[31mERROR: missing command-line argument to Mesop application.\u001b[0m
86-
87-
Example command:
88-
$\u001b[35m mesop file.py\u001b[0m"""
89-
)
90-
sys.exit(1)
91-
92-
if len(argv) > 2:
93-
print(
94-
f"""\u001b[31mERROR: Too many command-line arguments.\u001b[0m
95-
96-
Actual:
97-
$\u001b[35m mesop {" ".join(argv[1:])}\u001b[0m
98-
99-
Re-run with:
100-
$\u001b[35m mesop {argv[1]}\u001b[0m"""
101-
)
102-
sys.exit(1)
103-
create_app(argv[1]).run()
63+
def make_path_absolute(file_path: str):
64+
if os.path.isabs(file_path):
65+
return file_path
66+
# Otherwise, make the relative path absolute by joining
67+
# with current working dir.
68+
absolute_path = os.path.join(os.getcwd(), file_path)
69+
return absolute_path
10470

10571

10672
def run_main():

mesop/server/create_app.py mesop/server/wsgi_app.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from mesop.runtime import enable_debug_mode
66
from mesop.server.constants import EDITOR_PACKAGE_PATH, PROD_PACKAGE_PATH
7+
from mesop.server.flags import port
78
from mesop.server.logging import log_startup
89
from mesop.server.server import configure_flask_app
910
from mesop.server.static_file_serving import configure_static_file_serving
@@ -15,23 +16,23 @@ class App:
1516
def __init__(self, flask_app: Flask):
1617
self._flask_app = flask_app
1718

18-
def run(self, port: int = 32123):
19-
log_startup(port=port)
20-
self._flask_app.run(host="0.0.0.0", port=port, use_reloader=False)
19+
def run(self):
20+
log_startup(port=port())
21+
self._flask_app.run(host="0.0.0.0", port=port(), use_reloader=False)
2122

22-
def __call__(
23-
self, environ: dict[Any, Any], start_response: Callable[..., Any]
24-
) -> Any:
25-
"""Wrapper around Flask API so that a WGSI server can call this application."""
26-
return self._flask_app.wsgi_app(environ, start_response) # type: ignore
2723

28-
29-
def create_app(*, prod_mode: bool = True) -> App:
24+
def create_app(
25+
prod_mode: bool,
26+
run_block: Callable[..., None] | None = None,
27+
) -> App:
3028
flask_app = configure_flask_app()
3129

3230
if prod_mode:
3331
enable_debug_mode()
3432

33+
if run_block is not None:
34+
run_block()
35+
3536
configure_static_file_serving(
3637
flask_app,
3738
static_file_runfiles_base=PROD_PACKAGE_PATH
@@ -40,3 +41,8 @@ def create_app(*, prod_mode: bool = True) -> App:
4041
)
4142

4243
return App(flask_app=flask_app)
44+
45+
46+
def wsgi_app(environ: dict[Any, Any], start_response: Callable[..., Any]):
47+
app = create_app(prod_mode=True)
48+
return app._flask_app.wsgi_app(environ, start_response) # type: ignore

scripts/pip.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ cp -r ./scripts/smoketest_app /tmp/mesoprelease-test && \
3232
cd /tmp/mesoprelease-test/ && \
3333
tar -xzf mesop.tar.gz && \
3434
pip install --upgrade /tmp/mesoprelease-test/mesop*.whl && \
35-
cd smoketest_app && mesop --path main.py
35+
cd smoketest_app && mesop main.py

0 commit comments

Comments
 (0)