aiverify-moonshot 0.4.4__py3-none-any.whl → 0.4.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aiverify-moonshot
3
- Version: 0.4.4
3
+ Version: 0.4.5
4
4
  Summary: AI Verify advances Gen AI testing with Project Moonshot.
5
5
  Project-URL: Repository, https://github.com/aiverify-foundation/moonshot
6
6
  Project-URL: Documentation, https://aiverify-foundation.github.io/moonshot/
@@ -45,7 +45,7 @@ Description-Content-Type: text/markdown
45
45
 
46
46
  ![Moonshot Logo](https://github.com/aiverify-foundation/moonshot/raw/main/misc/aiverify-moonshot-logo.png)
47
47
 
48
- **Version 0.4.4**
48
+ **Version 0.4.5**
49
49
 
50
50
  A simple and modular tool to evaluate any LLM application.
51
51
 
@@ -1,5 +1,5 @@
1
1
  moonshot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- moonshot/__main__.py,sha256=NB_sWjPRcwr8BbFXtih2y3fbVYPZ1YS5dI_bNNaTD3U,7551
2
+ moonshot/__main__.py,sha256=owir7ug4VzfPwG7hSYTrN03SRpHMiLUifoEe_-IaeYw,9908
3
3
  moonshot/api.py,sha256=f7vIMlpC-1ZQsbqipe2cTlP5dwgoVujQKYNxzEKcWlg,4822
4
4
  moonshot/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  moonshot/integrations/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -33,7 +33,7 @@ moonshot/integrations/cli/utils/process_data.py,sha256=QVL5vp2_8ZgGicmCAdeYEHkeb
33
33
  moonshot/integrations/web_api/.env.dev,sha256=0z5_Ut8rF-UqFZtgjkH2qoqORhD5_nSs2w_OeX2SteI,182
34
34
  moonshot/integrations/web_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  moonshot/integrations/web_api/__main__.py,sha256=MdnLi_ZF-olAAEJwTPU1iGYFYwo-fNWNT2qfchkH3y4,2050
36
- moonshot/integrations/web_api/app.py,sha256=rrL-N4cVO1qBQ5v6y039jfMqUdSC9jyqsgCudmyfZx0,3651
36
+ moonshot/integrations/web_api/app.py,sha256=4EzGEwvFh6any62ZJNGH2GCXUOPjqNYURL0Toe2rTNI,3651
37
37
  moonshot/integrations/web_api/container.py,sha256=DVkJG_qm7ItcG6tgMYOqIj07wpKhPWOOfy6-bEv72y4,5915
38
38
  moonshot/integrations/web_api/logging_conf.py,sha256=t3EGRV6tZhV732KXe8_Tiy0fiwVAWxZX5Tt8VTgrrfg,3388
39
39
  moonshot/integrations/web_api/log/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -41,7 +41,7 @@ moonshot/integrations/web_api/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
41
41
  moonshot/integrations/web_api/routes/attack_modules.py,sha256=m0mGGTEHyaVld8WYHXxQ5Gm0sKdTqy_rJUrNVFcgVgw,2413
42
42
  moonshot/integrations/web_api/routes/benchmark.py,sha256=RRzouKcoVNYXm7o1LadsZTgzfmUsaYdQTC0AfsLdiC4,4163
43
43
  moonshot/integrations/web_api/routes/benchmark_result.py,sha256=WZ_dI8qT4dli9hKPNkhSwhdfz2VfW5BshirpEVEUci4,6351
44
- moonshot/integrations/web_api/routes/bookmark.py,sha256=K-1jL0IwOYvmYpgJvU65-lRfQlQhMzJk_n-Zf92IeR0,6135
44
+ moonshot/integrations/web_api/routes/bookmark.py,sha256=aHUT86Llbzqo1CT3Dy7ciIhxVEzu1YgZk_VkxVeOZ3s,6304
45
45
  moonshot/integrations/web_api/routes/context_strategy.py,sha256=kJTpjrwxfYGyBLY_hAgpHOMZMtjV5Z6vpu7RIdHDylg,4828
46
46
  moonshot/integrations/web_api/routes/cookbook.py,sha256=oddmcdfhgH3qZb4_ThfUk8SBKmHOt51dFlAHubQh2fQ,8648
47
47
  moonshot/integrations/web_api/routes/dataset.py,sha256=qtxflHRDr31W3u6voOFE5iRHsCVr0MQ35H94Pw5M1YU,6114
@@ -114,7 +114,7 @@ moonshot/src/api/api_session.py,sha256=OGH05ZxAwo_hKI-RNaJ-jCp_v-zcTm-9bHUclpq2z
114
114
  moonshot/src/bookmark/bookmark.py,sha256=KZoKOyJseW02IS5KqfCIMusFiNwESBxOAvOZTwO7YUw,8867
115
115
  moonshot/src/bookmark/bookmark_arguments.py,sha256=rwgUPMXmDLNaHfJvRTR4GaZ8vwRilchzOg9bZJQoe_8,1130
116
116
  moonshot/src/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
- moonshot/src/configs/env_variables.py,sha256=leemw8TNM6GI_6iaajFb49zv1K3hWB0EpZfO0p9CWZQ,7100
117
+ moonshot/src/configs/env_variables.py,sha256=eF__UJN37LCzIB4pv_T7G-kQHlOa657QA7IpL1d_0MM,7150
118
118
  moonshot/src/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
119
  moonshot/src/connectors/connector.py,sha256=e0ZCX9m83ezjMiY5H8gbWE64IStsNQqxzVwGtMwShPY,13396
120
120
  moonshot/src/connectors/connector_prompt_arguments.py,sha256=cIlAgbFk2g_XUZ0stVM904Ng2g4GYP2LyiAjktmhEQM,470
@@ -155,7 +155,7 @@ moonshot/src/runners/runner.py,sha256=Wsvdzcw4KOa-ppgGVRGSK2YxLfXK-daHDw3k5jETv-
155
155
  moonshot/src/runners/runner_arguments.py,sha256=Bg4OPSmgr9jZKNAwPH0T3epEHw-6qGrflszFc6oMyEU,1640
156
156
  moonshot/src/runners/runner_type.py,sha256=jOfnAnaCYp-rPTRJXhM8hin_dinlR0sMwmimQXvLcJ0,100
157
157
  moonshot/src/runs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
- moonshot/src/runs/run.py,sha256=QFdvWwCnqSjLrsTk3jJ1ccs3R1ZAZNvz5ls9Q_iRxO0,14132
158
+ moonshot/src/runs/run.py,sha256=3Y_256IfOv5zpeujVPsA5YdX7uZjGMRvg0VencUwgLw,14339
159
159
  moonshot/src/runs/run_arguments.py,sha256=G043ERvHIU_dd0JghboZgxDWCcjYOaDwue1ieDunDKA,6443
160
160
  moonshot/src/runs/run_progress.py,sha256=d1BcNo6Kp4vA165TDx_xebl8JDo92aV-YutPxsgCOxE,6495
161
161
  moonshot/src/runs/run_status.py,sha256=TRtizcDzPxf6aQ2c3OovM6IQKJ0VCBhqDWvn7UBw5Zg,251
@@ -169,9 +169,9 @@ moonshot/src/utils/import_modules.py,sha256=T9zTN59PFnvY2rjyWhSV9KSIAHxWV1pyBemF
169
169
  moonshot/src/utils/log.py,sha256=YNgD7Eh2OT36XlmVBKCGUTAh9TRp4Akfe4kDdvHASgs,2502
170
170
  moonshot/src/utils/pagination.py,sha256=5seymyRoqyENIhKllAatr1T91kMCGFslcvRnJHyMSvc,814
171
171
  moonshot/src/utils/timeit.py,sha256=TvuF0w8KWhp0oZFY0cUU3UY0xlGKjchb0OkfYfgVTlc,866
172
- aiverify_moonshot-0.4.4.dist-info/METADATA,sha256=zQ4rKRFVE_p6uB6dgGBcKhIB4KXRn8ZzdBymh3d2y6g,12368
173
- aiverify_moonshot-0.4.4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
174
- aiverify_moonshot-0.4.4.dist-info/licenses/AUTHORS.md,sha256=mmAbe3i3sT8JZHJMBhxp3i1xRehV0g7WB4T_eyIBuBs,59
175
- aiverify_moonshot-0.4.4.dist-info/licenses/LICENSE.md,sha256=mDOKOkWFbJmUORaAchXByEVGC1jw37QRn-zS14wY_wM,11347
176
- aiverify_moonshot-0.4.4.dist-info/licenses/NOTICES.md,sha256=0Ikx6IBGGQEOJeNb2MkRoXxTXwrtlMz6EDgLBFIz6v0,179593
177
- aiverify_moonshot-0.4.4.dist-info/RECORD,,
172
+ aiverify_moonshot-0.4.5.dist-info/METADATA,sha256=d8sIDGy6Ywuov6QnMj62fa6Qu5Uvbekv4_rBGeLObWM,12368
173
+ aiverify_moonshot-0.4.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
174
+ aiverify_moonshot-0.4.5.dist-info/licenses/AUTHORS.md,sha256=mmAbe3i3sT8JZHJMBhxp3i1xRehV0g7WB4T_eyIBuBs,59
175
+ aiverify_moonshot-0.4.5.dist-info/licenses/LICENSE.md,sha256=mDOKOkWFbJmUORaAchXByEVGC1jw37QRn-zS14wY_wM,11347
176
+ aiverify_moonshot-0.4.5.dist-info/licenses/NOTICES.md,sha256=0Ikx6IBGGQEOJeNb2MkRoXxTXwrtlMz6EDgLBFIz6v0,179593
177
+ aiverify_moonshot-0.4.5.dist-info/RECORD,,
moonshot/__main__.py CHANGED
@@ -1,10 +1,12 @@
1
1
  import argparse
2
2
  import os
3
3
  import platform
4
+ import shutil
4
5
  import subprocess
5
6
  import sys
6
7
  import threading
7
8
  import warnings
9
+ from typing import Any
8
10
 
9
11
  from dotenv import dotenv_values
10
12
 
@@ -19,7 +21,7 @@ Run the Moonshot application
19
21
  """
20
22
 
21
23
 
22
- def run_subprocess(*args, **kwargs):
24
+ def run_subprocess(*args: Any, **kwargs: Any) -> subprocess.CompletedProcess:
23
25
  """
24
26
  Run a subprocess with the option to use shell=True on Windows.
25
27
  """
@@ -28,7 +30,7 @@ def run_subprocess(*args, **kwargs):
28
30
  return subprocess.run(*args, **kwargs)
29
31
 
30
32
 
31
- def ms_lib_env_file(data_repo_name):
33
+ def ms_lib_env_file(data_repo_name: str) -> None:
32
34
  """
33
35
  Writes the env file to be used for moonshot library
34
36
  """
@@ -70,7 +72,7 @@ def ms_lib_env_file(data_repo_name):
70
72
  env_file.write(combined_content.strip())
71
73
 
72
74
 
73
- def ms_ui_env_file(ui_repo):
75
+ def ms_ui_env_file(ui_repo: str) -> None:
74
76
  """
75
77
  Write the env file to be used with moonshot ui
76
78
  """
@@ -84,90 +86,160 @@ def ms_ui_env_file(ui_repo):
84
86
  env_file.write(env_content.strip())
85
87
 
86
88
 
87
- def moonshot_data_installation():
89
+ def download_nltk_resources() -> None:
90
+ """
91
+ Download and verify necessary NLTK resources.
92
+
93
+ This function downloads a predefined list of NLTK resources and verifies their availability.
94
+ If a resource fails to download or verify, a warning is logged and an exception is raised.
95
+ """
96
+ import nltk
97
+
98
+ resources = [
99
+ "punkt",
100
+ "stopwords",
101
+ ]
102
+
103
+ for resource in resources:
104
+ try:
105
+ nltk.download(resource)
106
+ # Check if the resource is available
107
+ nltk.data.find(
108
+ f"tokenizers/{resource}"
109
+ ) if resource == "punkt" else nltk.data.find(f"corpora/{resource}")
110
+ logger.info(f"Successfully downloaded and verified {resource}")
111
+ except LookupError:
112
+ logger.warning(f"Failed to download {resource}")
113
+ raise
114
+ except Exception as e:
115
+ logger.warning(f"An error occurred while downloading {resource}: {e}")
116
+ raise
117
+
118
+
119
+ def moonshot_data_installation() -> None:
88
120
  # Code for moonshot-data installation
89
121
  logger.info("Installing Moonshot Data from GitHub")
90
122
  repo = "https://github.com/aiverify-foundation/moonshot-data.git"
91
123
  folder_name = repo.split("/")[-1].replace(".git", "")
92
124
 
93
125
  # Check if the directory already exists
94
- if not os.path.exists(folder_name):
95
- logger.info(f"Cloning {repo}")
96
- # Clone the repository
97
- run_subprocess(["git", "clone", repo], check=True)
126
+ if os.path.exists(folder_name):
127
+ logger.warning(f"Directory {folder_name} already exists.")
128
+ user_input = (
129
+ input(
130
+ f"Directory {folder_name} already exists. Do you want to remove it and reinstall? (Y/n): "
131
+ )
132
+ .strip()
133
+ .lower()
134
+ )
135
+ if user_input == "y":
136
+ logger.info(f"Removing directory {folder_name}.")
137
+ # Remove the existing directory
138
+ shutil.rmtree(folder_name)
139
+ else:
140
+ logger.info("Exiting function without removing the directory.")
141
+ return
98
142
 
99
- # Create .env to point to installed folder
100
- ms_lib_env_file(folder_name)
143
+ logger.info(f"Cloning {repo}")
144
+ # Clone the repository
145
+ run_subprocess(["git", "clone", repo], check=True)
101
146
 
102
- # Change directory to the folder
103
- os.chdir(folder_name)
147
+ # Create .env to point to installed folder
148
+ ms_lib_env_file(folder_name)
104
149
 
105
- logger.info(f"Installing requirements for {folder_name}")
106
- # Install the requirements if they exist
107
- if os.path.exists("requirements.txt"):
108
- run_subprocess(["pip", "install", "-r", "requirements.txt"], check=True)
109
- import nltk
150
+ # Change directory to the folder
151
+ os.chdir(folder_name)
110
152
 
111
- nltk.download("punkt")
112
- nltk.download("stopwords")
113
- nltk.download("averaged_perceptron_tagger")
114
- nltk.download("universal_tagset")
153
+ logger.info(f"Installing requirements for {folder_name}")
154
+ # Install the requirements if they exist
155
+ if os.path.exists("requirements.txt"):
156
+ run_subprocess(["pip", "install", "-r", "requirements.txt"], check=True)
157
+ download_nltk_resources()
115
158
 
116
- # Change back to the base directory
117
- os.chdir("..")
159
+ # Change back to the base directory
160
+ os.chdir("..")
118
161
 
119
- else:
120
- logger.warning(f"Directory {folder_name} already exists, skipping clone.")
162
+
163
+ def check_node() -> bool:
164
+ """
165
+ Check if Node.js is installed on the user's machine.
166
+ """
167
+ try:
168
+ result = subprocess.run(
169
+ ["node", "--version"], capture_output=True, text=True, check=True
170
+ )
171
+ node_version = result.stdout.strip()
172
+ logger.info(f"Node.js is installed. Version: {node_version}")
173
+ return True
174
+ except (subprocess.CalledProcessError, FileNotFoundError):
175
+ logger.error("Node.js is not installed. Please install Node.js to proceed.")
176
+ return False
121
177
 
122
178
 
123
- def moonshot_ui_installation():
179
+ def moonshot_ui_installation() -> None:
180
+ if not check_node():
181
+ logger.error("Node.js is not installed. Please install Node.js to proceed.")
182
+ return
183
+
124
184
  # Code for moonshot-ui installation
125
185
  repo = "https://github.com/aiverify-foundation/moonshot-ui.git"
126
186
  folder_name = repo.split("/")[-1].replace(".git", "")
127
187
 
128
188
  # Check if the directory already exists
129
- if not os.path.exists(folder_name):
130
- logger.info(f"Cloning {repo}")
131
- # Clone the repository
132
- run_subprocess(["git", "clone", repo], check=True)
189
+ if os.path.exists(folder_name):
190
+ logger.warning(f"Directory {folder_name} already exists.")
191
+ user_input = (
192
+ input(
193
+ f"Directory {folder_name} already exists. Do you want to remove it and reinstall? (Y/n): "
194
+ )
195
+ .strip()
196
+ .lower()
197
+ )
198
+ if user_input == "y":
199
+ logger.info(f"Removing directory {folder_name}.")
200
+ # Remove the existing directory
201
+ shutil.rmtree(folder_name)
202
+ else:
203
+ logger.info("Exiting function without removing the directory.")
204
+ return
133
205
 
134
- # Change directory to the folder
135
- os.chdir(folder_name)
206
+ logger.info(f"Cloning {repo}")
207
+ # Clone the repository
208
+ run_subprocess(["git", "clone", repo], check=True)
136
209
 
137
- logger.info(f"Installing requirements for {folder_name}")
138
- # Install the requirements if they exist
139
- if os.path.exists("package.json"):
140
- run_subprocess(["npm", "install"], check=True)
141
- run_subprocess(["npm", "run", "build"], check=True)
210
+ # Change directory to the folder
211
+ os.chdir(folder_name)
142
212
 
143
- # Change back to the base directory
144
- os.chdir("..")
213
+ logger.info(f"Installing requirements for {folder_name}")
214
+ # Install the requirements if they exist
215
+ if os.path.exists("package.json"):
216
+ run_subprocess(["npm", "install"], check=True)
217
+ run_subprocess(["npm", "run", "build"], check=True)
145
218
 
146
- # Create .env for ui
147
- ms_ui_env_file(folder_name)
148
- else:
149
- logger.warning(
150
- f"Directory {folder_name} already exists, skipping installation."
151
- )
219
+ # Change back to the base directory
220
+ os.chdir("..")
152
221
 
222
+ # Create .env for ui
223
+ ms_ui_env_file(folder_name)
153
224
 
154
- def run_moonshot_ui_dev():
225
+
226
+ def run_moonshot_ui() -> None:
155
227
  """
156
228
  To start a thread to run the Moonshot UI
157
229
  """
158
230
  base_directory = os.getcwd()
159
- ui_dev_dir = os.path.join(base_directory, "moonshot-ui")
231
+ ui_dir = os.path.join(base_directory, "moonshot-ui")
160
232
 
161
- if not os.path.exists(ui_dev_dir):
233
+ if not os.path.exists(ui_dir):
162
234
  logger.error(
163
235
  "moonshot-ui does not exist. Please run with '-i moonshot-ui' to install moonshot-ui first."
164
236
  )
165
237
  sys.exit(1)
166
238
  # ms_ui_env_file(ui_dev_dir)
167
- run_subprocess(["npm", "start"], cwd=ui_dev_dir)
239
+ run_subprocess(["npm", "start"], cwd=ui_dir)
168
240
 
169
241
 
170
- def main():
242
+ def main() -> None:
171
243
  parser = argparse.ArgumentParser(description="Run the Moonshot application")
172
244
  parser.add_argument(
173
245
  "mode",
@@ -206,7 +278,7 @@ def main():
206
278
 
207
279
  if args.mode == "help":
208
280
  parser.print_help()
209
- sys.exit(1)
281
+ sys.exit(0)
210
282
 
211
283
  api_set_environment_variables(dotenv_values(args.env))
212
284
 
@@ -216,7 +288,7 @@ def main():
216
288
  web_api.start_app()
217
289
  elif args.mode == "web":
218
290
  # Create and start the UI dev server thread
219
- ui_thread = threading.Thread(target=run_moonshot_ui_dev)
291
+ ui_thread = threading.Thread(target=run_moonshot_ui)
220
292
  ui_thread.start()
221
293
  ui_thread.join(timeout=0.1) # Wait briefly for the thread to become alive
222
294
  if not ui_thread.is_alive():
@@ -232,8 +304,7 @@ def main():
232
304
  # Handle CLI mode here, possibly also with additional arguments
233
305
  pass
234
306
  else:
235
- parser.print_help()
236
- sys.exit(1)
307
+ sys.exit(0)
237
308
 
238
309
 
239
310
  if __name__ == "__main__":
@@ -71,7 +71,7 @@ def create_app(cfg: providers.Configuration) -> CustomFastAPI:
71
71
  }
72
72
 
73
73
  app: CustomFastAPI = CustomFastAPI(
74
- title="Project Moonshot", version="0.4.4", **app_kwargs
74
+ title="Project Moonshot", version="0.4.5", **app_kwargs
75
75
  )
76
76
 
77
77
  if cfg.cors.enabled():
@@ -1,7 +1,9 @@
1
+ import os
1
2
  from typing import Optional
2
3
 
3
4
  from dependency_injector.wiring import Provide, inject
4
5
  from fastapi import APIRouter, Depends, HTTPException, Query
6
+ from fastapi.responses import FileResponse
5
7
 
6
8
  from ..container import Container
7
9
  from ..schemas.bookmark_create_dto import BookmarkCreateDTO, BookmarkPydanticModel
@@ -136,7 +138,7 @@ def delete_bookmark(
136
138
  raise HTTPException(
137
139
  status_code=500, detail=f"Failed to delete bookmark: {e.msg}"
138
140
  )
139
- @router.post(
141
+ @router.get(
140
142
  "/api/v1/bookmarks/export", response_description="Exporting Bookmark to JSON file"
141
143
  )
142
144
  @inject
@@ -145,7 +147,7 @@ def export_bookbookmarks(
145
147
  "bookmarks", description="Name of the exported file"
146
148
  ),
147
149
  bookmark_service: BookmarkService = Depends(Provide[Container.bookmark_service]),
148
- ) -> str:
150
+ ) -> FileResponse:
149
151
  """
150
152
  Export bookmarks to a JSON file with a given file name.
151
153
 
@@ -154,10 +156,11 @@ def export_bookbookmarks(
154
156
  bookmark_service: The service responsible for bookmark operations.
155
157
 
156
158
  Returns:
157
- A string with the path to the exported file or an error message.
159
+ A FileResponse with the path to the exported file or an error message.
158
160
  """
159
161
  try:
160
- return bookmark_service.export_bookmarks(export_file_name)
162
+ file_path = bookmark_service.export_bookmarks(export_file_name)
163
+ return FileResponse(file_path, media_type="application/json", filename=export_file_name)
161
164
  except ServiceException as e:
162
165
  if e.error_code == "FileNotFound":
163
166
  raise HTTPException(
@@ -39,7 +39,11 @@ class EnvironmentVars:
39
39
  ]
40
40
  BOOKMARKS = [
41
41
  env_vars.get(EnvVariables.BOOKMARKS.value),
42
- str(importlib.resources.files(__app_name__).joinpath("data/generated-outputs/bookmarks")),
42
+ str(
43
+ importlib.resources.files(__app_name__).joinpath(
44
+ "data/generated-outputs/bookmarks"
45
+ )
46
+ ),
43
47
  ]
44
48
  CONNECTORS = [
45
49
  env_vars.get(EnvVariables.CONNECTORS.value),
@@ -144,8 +148,8 @@ class EnvironmentVars:
144
148
  EnvironmentVars.__dict__[key][0] = str(given_path)
145
149
  else:
146
150
  logger.warning(
147
- f"Unable to set {key}. The provided path {given_path} does not exist. ",
148
- "The stock set will be used.",
151
+ f"Unable to set {key}. The provided path {given_path} does not exist. "
152
+ "The stock set will be used."
149
153
  )
150
154
  else:
151
155
  unset_keys.append(key)
moonshot/src/runs/run.py CHANGED
@@ -20,6 +20,7 @@ logger = configure_logger(__name__)
20
20
 
21
21
 
22
22
  class Run:
23
+ sql_table_name = "run_table"
23
24
  sql_create_run_table = """
24
25
  CREATE TABLE IF NOT EXISTS run_table (
25
26
  run_id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -147,6 +148,12 @@ class Run:
147
148
  if not database_instance:
148
149
  raise RuntimeError("[Run] Database instance not provided.")
149
150
 
151
+ # Check that the table exists
152
+ if not Storage.check_database_table_exists(
153
+ database_instance, Run.sql_table_name
154
+ ):
155
+ return []
156
+
150
157
  all_run_arguments_info = Storage.read_database_records(
151
158
  database_instance,
152
159
  Run.sql_read_all_run_records,