darabos commited on
Commit
becba58
·
1 Parent(s): f101ab5

Fix tests.

Browse files
lynxkite-app/src/lynxkite_app/config.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ """Some common configuration."""
2
+
3
+ import os
4
+ import pathlib
5
+
6
+
7
+ DATA_PATH = pathlib.Path(os.environ.get("LYNXKITE_DATA", "lynxkite_data"))
8
+ CRDT_PATH = pathlib.Path(os.environ.get("LYNXKITE_CRDT_DATA", "lynxkite_crdt_data"))
lynxkite-app/src/lynxkite_app/crdt.py CHANGED
@@ -12,10 +12,9 @@ import pycrdt_websocket.ystore
12
  import uvicorn
13
  import builtins
14
  from lynxkite.core import workspace, ops
 
15
 
16
  router = fastapi.APIRouter()
17
- DATA_PATH = pathlib.Path.cwd() / "data"
18
- CRDT_PATH = pathlib.Path.cwd() / "crdt_data"
19
 
20
 
21
  def ws_exception_handler(exception, log):
@@ -34,8 +33,8 @@ class WebsocketServer(pycrdt_websocket.WebsocketServer):
34
 
35
  The workspace is loaded from "crdt_data" if it exists there, or from "data", or a new workspace is created.
36
  """
37
- path = CRDT_PATH / f"{name}.crdt"
38
- assert path.is_relative_to(CRDT_PATH)
39
  ystore = pycrdt_websocket.ystore.FileYStore(path)
40
  ydoc = pycrdt.Doc()
41
  ydoc["workspace"] = ws = pycrdt.Map()
@@ -52,7 +51,7 @@ class WebsocketServer(pycrdt_websocket.WebsocketServer):
52
  if "edges" not in ws:
53
  ws["edges"] = pycrdt.Array()
54
  if "env" not in ws:
55
- ws["env"] = next(iter(ops.CATALOGS), 'unset')
56
  # We have two possible sources of truth for the workspaces, the YStore and the JSON files.
57
  # In case we didn't find the workspace in the YStore, we try to load it from the JSON files.
58
  try_to_load_workspace(ws, name)
@@ -222,8 +221,8 @@ async def execute(
222
  await asyncio.sleep(delay)
223
  except asyncio.CancelledError:
224
  return
225
- path = DATA_PATH / name
226
- assert path.is_relative_to(DATA_PATH),"Provided workspace path is invalid"
227
  # Save user changes before executing, in case the execution fails.
228
  workspace.save(ws_pyd, path)
229
  await workspace.execute(ws_pyd)
 
12
  import uvicorn
13
  import builtins
14
  from lynxkite.core import workspace, ops
15
+ from . import config
16
 
17
  router = fastapi.APIRouter()
 
 
18
 
19
 
20
  def ws_exception_handler(exception, log):
 
33
 
34
  The workspace is loaded from "crdt_data" if it exists there, or from "data", or a new workspace is created.
35
  """
36
+ path = config.CRDT_PATH / f"{name}.crdt"
37
+ assert path.is_relative_to(config.CRDT_PATH)
38
  ystore = pycrdt_websocket.ystore.FileYStore(path)
39
  ydoc = pycrdt.Doc()
40
  ydoc["workspace"] = ws = pycrdt.Map()
 
51
  if "edges" not in ws:
52
  ws["edges"] = pycrdt.Array()
53
  if "env" not in ws:
54
+ ws["env"] = next(iter(ops.CATALOGS), "unset")
55
  # We have two possible sources of truth for the workspaces, the YStore and the JSON files.
56
  # In case we didn't find the workspace in the YStore, we try to load it from the JSON files.
57
  try_to_load_workspace(ws, name)
 
221
  await asyncio.sleep(delay)
222
  except asyncio.CancelledError:
223
  return
224
+ path = config.DATA_PATH / name
225
+ assert path.is_relative_to(config.DATA_PATH), "Provided workspace path is invalid"
226
  # Save user changes before executing, in case the execution fails.
227
  workspace.save(ws_pyd, path)
228
  await workspace.execute(ws_pyd)
lynxkite-app/src/lynxkite_app/main.py CHANGED
@@ -16,7 +16,7 @@ from fastapi.staticfiles import StaticFiles
16
  import starlette
17
  from lynxkite.core import ops
18
  from lynxkite.core import workspace
19
- from . import crdt
20
 
21
 
22
  def detect_plugins():
@@ -50,8 +50,8 @@ class SaveRequest(workspace.BaseConfig):
50
 
51
 
52
  def save(req: SaveRequest):
53
- path = DATA_PATH / req.path
54
- assert path.is_relative_to(DATA_PATH)
55
  workspace.save(req.ws, path)
56
 
57
 
@@ -65,27 +65,23 @@ async def save_and_execute(req: SaveRequest):
65
 
66
  @app.post("/api/delete")
67
  async def delete_workspace(req: dict):
68
- json_path: pathlib.Path = DATA_PATH / req["path"]
69
- crdt_path: pathlib.Path = CRDT_PATH / f"{req['path']}.crdt"
70
- assert json_path.is_relative_to(DATA_PATH)
71
- assert crdt_path.is_relative_to(CRDT_PATH)
72
  json_path.unlink()
73
  crdt_path.unlink()
74
 
75
 
76
  @app.get("/api/load")
77
  def load(path: str):
78
- path = DATA_PATH / path
79
- assert path.is_relative_to(DATA_PATH)
80
  if not path.exists():
81
  return workspace.Workspace()
82
  return workspace.load(path)
83
 
84
 
85
- DATA_PATH = pathlib.Path(os.environ.get("LYNXKITE_DATA", "lynxkite_data"))
86
- CRDT_PATH = pathlib.Path(os.environ.get("LYNXKITE_CRDT_DATA", "lynxkite_crdt_data"))
87
-
88
-
89
  @dataclasses.dataclass(order=True)
90
  class DirectoryEntry:
91
  name: str
@@ -94,12 +90,13 @@ class DirectoryEntry:
94
 
95
  @app.get("/api/dir/list")
96
  def list_dir(path: str):
97
- path = DATA_PATH / path
98
- assert path.is_relative_to(DATA_PATH)
99
  return sorted(
100
  [
101
  DirectoryEntry(
102
- p.relative_to(DATA_PATH), "directory" if p.is_dir() else "workspace"
 
103
  )
104
  for p in path.iterdir()
105
  ]
@@ -108,17 +105,16 @@ def list_dir(path: str):
108
 
109
  @app.post("/api/dir/mkdir")
110
  def make_dir(req: dict):
111
- path = DATA_PATH / req["path"]
112
- assert path.is_relative_to(DATA_PATH)
113
  assert not path.exists()
114
  path.mkdir()
115
- return list_dir(path.parent)
116
 
117
 
118
  @app.post("/api/dir/delete")
119
  def delete_dir(req: dict):
120
- path: pathlib.Path = DATA_PATH / req["path"]
121
- assert all([path.is_relative_to(DATA_PATH), path.exists(), path.is_dir()])
122
  shutil.rmtree(path)
123
  return list_dir(path.parent)
124
 
 
16
  import starlette
17
  from lynxkite.core import ops
18
  from lynxkite.core import workspace
19
+ from . import crdt, config
20
 
21
 
22
  def detect_plugins():
 
50
 
51
 
52
  def save(req: SaveRequest):
53
+ path = config.DATA_PATH / req.path
54
+ assert path.is_relative_to(config.DATA_PATH)
55
  workspace.save(req.ws, path)
56
 
57
 
 
65
 
66
  @app.post("/api/delete")
67
  async def delete_workspace(req: dict):
68
+ json_path: pathlib.Path = config.DATA_PATH / req["path"]
69
+ crdt_path: pathlib.Path = config.CRDT_PATH / f"{req['path']}.crdt"
70
+ assert json_path.is_relative_to(config.DATA_PATH)
71
+ assert crdt_path.is_relative_to(config.CRDT_PATH)
72
  json_path.unlink()
73
  crdt_path.unlink()
74
 
75
 
76
  @app.get("/api/load")
77
  def load(path: str):
78
+ path = config.DATA_PATH / path
79
+ assert path.is_relative_to(config.DATA_PATH)
80
  if not path.exists():
81
  return workspace.Workspace()
82
  return workspace.load(path)
83
 
84
 
 
 
 
 
85
  @dataclasses.dataclass(order=True)
86
  class DirectoryEntry:
87
  name: str
 
90
 
91
  @app.get("/api/dir/list")
92
  def list_dir(path: str):
93
+ path = config.DATA_PATH / path
94
+ assert path.is_relative_to(config.DATA_PATH)
95
  return sorted(
96
  [
97
  DirectoryEntry(
98
+ p.relative_to(config.DATA_PATH),
99
+ "directory" if p.is_dir() else "workspace",
100
  )
101
  for p in path.iterdir()
102
  ]
 
105
 
106
  @app.post("/api/dir/mkdir")
107
  def make_dir(req: dict):
108
+ path = config.DATA_PATH / req["path"]
109
+ assert path.is_relative_to(config.DATA_PATH)
110
  assert not path.exists()
111
  path.mkdir()
 
112
 
113
 
114
  @app.post("/api/dir/delete")
115
  def delete_dir(req: dict):
116
+ path: pathlib.Path = config.DATA_PATH / req["path"]
117
+ assert all([path.is_relative_to(config.DATA_PATH), path.exists(), path.is_dir()])
118
  shutil.rmtree(path)
119
  return list_dir(path.parent)
120
 
lynxkite-app/tests/test_main.py CHANGED
@@ -1,6 +1,7 @@
1
  import uuid
2
  from fastapi.testclient import TestClient
3
- from lynxkite_app.main import app, detect_plugins, DATA_PATH
 
4
  import os
5
 
6
 
@@ -13,9 +14,9 @@ def test_detect_plugins_with_plugins():
13
  assert all(
14
  plugin in plugins.keys()
15
  for plugin in [
16
- "lynxkite_plugins.graph_analytics",
17
- "lynxkite_plugins.lynxscribe",
18
- "lynxkite_plugins.pillow_example",
19
  ]
20
  )
21
 
@@ -57,7 +58,7 @@ def test_save_and_load():
57
  def test_list_dir():
58
  test_dir = str(uuid.uuid4())
59
  test_dir_full_path = DATA_PATH / test_dir
60
- test_dir_full_path.mkdir(exist_ok=True)
61
  test_file = test_dir_full_path / "test_file.txt"
62
  test_file.touch()
63
  response = client.get(f"/api/dir/list?path={str(test_dir)}")
 
1
  import uuid
2
  from fastapi.testclient import TestClient
3
+ from lynxkite_app.main import app, detect_plugins
4
+ from lynxkite_app.config import DATA_PATH
5
  import os
6
 
7
 
 
14
  assert all(
15
  plugin in plugins.keys()
16
  for plugin in [
17
+ "lynxkite_graph_analytics",
18
+ "lynxkite_lynxscribe",
19
+ "lynxkite_pillow_example",
20
  ]
21
  )
22
 
 
58
  def test_list_dir():
59
  test_dir = str(uuid.uuid4())
60
  test_dir_full_path = DATA_PATH / test_dir
61
+ test_dir_full_path.mkdir(parents=True, exist_ok=True)
62
  test_file = test_dir_full_path / "test_file.txt"
63
  test_file.touch()
64
  response = client.get(f"/api/dir/list?path={str(test_dir)}")