Skip to content

Commit 6aebbfd

Browse files
authored
Add env var: MESOP_APP_BASE_PATH (#1057)
1 parent 4ea0053 commit 6aebbfd

File tree

13 files changed

+83
-4
lines changed

13 files changed

+83
-4
lines changed

.github/workflows/ci.yml

+8
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ jobs:
9696
name: playwright-report-with-static-folder
9797
path: playwright-report-with-static-folder/
9898
retention-days: 30
99+
- name: Run playwright test with app base
100+
run: MESOP_APP_BASE_PATH=$PWD/mesop/examples/app_base MESOP_STATIC_FOLDER=static PLAYWRIGHT_HTML_OUTPUT_DIR=playwright-report-with-static-folder yarn playwright test mesop/tests/e2e/app_base_test.ts
101+
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
102+
if: always()
103+
with:
104+
name: playwright-report-with-static-folder
105+
path: playwright-report-with-static-folder/
106+
retention-days: 30
99107
# Deploy docs
100108
deploy-docs:
101109
# Only deploy docs if we're pushing to main (see on.push.branches)

docs/api/config.md

+4
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ By default, this is not enabled. You can enable this by setting it to `true`.
252252

253253
This uses WebSockets instead of HTTP Server-Sent Events (SSE) as the transport protocol for UI updates. If you set this environment variable to `true`, then [`MESOP_CONCURRENT_UPDATES_ENABLED`](#MESOP_CONCURRENT_UPDATES_ENABLED) will automatically be enabled as well.
254254

255+
### MESOP_APP_BASE_PATH
256+
257+
This is the base path used to resolve other paths, particularly for serving static files. Must be an absolute path. This is rarely needed because the default of using the current working directory is usually sufficient.
258+
255259
## Usage Examples
256260

257261
### One-liner

mesop/env/env.py

+21
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
import os
22

3+
from mesop.exceptions import MesopDeveloperException
4+
35
AI_SERVICE_BASE_URL = os.environ.get(
46
"MESOP_AI_SERVICE_BASE_URL", "http://localhost:43234"
57
)
68

9+
MESOP_APP_BASE_PATH = os.environ.get("MESOP_APP_BASE_PATH", "")
10+
if MESOP_APP_BASE_PATH:
11+
if not os.path.isabs(MESOP_APP_BASE_PATH):
12+
raise MesopDeveloperException(
13+
f"MESOP_APP_BASE_PATH must be an absolute path, but got {MESOP_APP_BASE_PATH} instead."
14+
)
15+
if not os.path.isdir(MESOP_APP_BASE_PATH):
16+
raise MesopDeveloperException(
17+
f"MESOP_APP_BASE_PATH is not a valid directory: {MESOP_APP_BASE_PATH}"
18+
)
19+
print(f"MESOP_APP_BASE_PATH set to {MESOP_APP_BASE_PATH}")
20+
21+
22+
def get_app_base_path() -> str:
23+
if not MESOP_APP_BASE_PATH:
24+
return os.getcwd()
25+
return MESOP_APP_BASE_PATH
26+
27+
728
MESOP_WEBSOCKETS_ENABLED = (
829
os.environ.get("MESOP_WEBSOCKETS_ENABLED", "false").lower() == "true"
930
)

mesop/examples/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ py_library(
4747
"//mesop/components/text/e2e",
4848
"//mesop/examples/web_component",
4949
"//mesop/examples/docs",
50+
"//mesop/examples/app_base",
5051
"//mesop/examples/integrations",
5152
"//mesop/examples/shared",
5253
"//mesop/examples/starter_kit",

mesop/examples/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from mesop.examples import (
33
allowed_iframe_parents as allowed_iframe_parents,
44
)
5+
from mesop.examples import app_base as app_base
56
from mesop.examples import async_await as async_await
67
from mesop.examples import (
78
boilerplate_free_event_handlers as boilerplate_free_event_handlers,

mesop/examples/app_base/BUILD

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
load("//build_defs:defaults.bzl", "py_library")
2+
3+
package(
4+
default_visibility = ["//build_defs:mesop_examples"],
5+
)
6+
7+
py_library(
8+
name = "app_base",
9+
srcs = glob(["*.py"]),
10+
data = glob([
11+
"static/**/*",
12+
]),
13+
deps = [
14+
"//mesop",
15+
],
16+
)

mesop/examples/app_base/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from mesop.examples.app_base import main as main

mesop/examples/app_base/main.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import os
2+
3+
import mesop as me
4+
5+
6+
@me.page(path="/examples/app_base")
7+
def page():
8+
me.text(
9+
"Testing: MESOP_APP_BASE_PATH="
10+
+ os.getenv("MESOP_APP_BASE_PATH", "<not set>")
11+
)
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test MESOP_APP_BASE_PATH works

mesop/labs/web_component.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from functools import wraps
44
from typing import Any, Callable, TypeVar, cast
55

6+
from mesop.env.env import get_app_base_path
67
from mesop.runtime import runtime
78
from mesop.utils.validate import validate
89

@@ -54,4 +55,4 @@ def format_filename(filename: str) -> str:
5455
return filename.split(".runfiles", 1)[1]
5556
else:
5657
# Handle pip CLI case
57-
return os.path.relpath(filename, os.getcwd())
58+
return os.path.relpath(filename, get_app_base_path())

mesop/server/server_utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from werkzeug.security import safe_join
1111

1212
import mesop.protos.ui_pb2 as pb
13-
from mesop.env.env import EXPERIMENTAL_EDITOR_TOOLBAR_ENABLED
13+
from mesop.env.env import EXPERIMENTAL_EDITOR_TOOLBAR_ENABLED, get_app_base_path
1414
from mesop.exceptions import MesopDeveloperException
1515
from mesop.runtime import runtime
1616
from mesop.server.config import app_config
@@ -148,7 +148,7 @@ def get_static_folder() -> str | None:
148148
"Static folder cannot be an absolute path: static_folder_name}"
149149
)
150150

151-
static_folder_path = safe_join(os.getcwd(), static_folder_name)
151+
static_folder_path = safe_join(get_app_base_path(), static_folder_name)
152152

153153
if not static_folder_path:
154154
raise MesopDeveloperException(

mesop/server/static_file_serving.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from flask import Flask, Response, g, make_response, request, send_file
1313
from werkzeug.security import safe_join
1414

15+
from mesop.env.env import get_app_base_path
1516
from mesop.exceptions import MesopException
1617
from mesop.runtime import runtime
1718
from mesop.server.constants import WEB_COMPONENTS_PATH_SEGMENT
@@ -100,7 +101,7 @@ def serve_web_components(path: str):
100101
serving_path = (
101102
get_runfile_location(path)
102103
if has_runfiles()
103-
else safe_join(os.getcwd(), path)
104+
else safe_join(get_app_base_path(), path)
104105
)
105106

106107
file_name = os.path.basename(path)

mesop/tests/e2e/app_base_test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {test, expect} from '@playwright/test';
2+
3+
test.describe('MESOP_APP_BASE_PATH', () => {
4+
if (process.env['MESOP_APP_BASE_PATH'] === undefined) {
5+
test.skip('Test skipped because MESOP_APP_BASE_PATH is not set.');
6+
}
7+
test('serves static file relative to MESOP_APP_BASE_PATH', async ({page}) => {
8+
const response = await page.goto('/static/test.txt');
9+
expect(response!.status()).toBe(200);
10+
const text = await response!.text();
11+
expect(text).toContain('test MESOP_APP_BASE_PATH works');
12+
});
13+
});

0 commit comments

Comments
 (0)