setta 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (265) hide show
  1. setta/__init__.py +1 -1
  2. setta/cli/__init__.py +1 -0
  3. setta/cli/connect.py +43 -0
  4. setta/cli/logger.py +225 -0
  5. setta/code_gen/__init__.py +0 -0
  6. setta/code_gen/create_runnable_scripts.py +466 -0
  7. setta/code_gen/export_selected.py +776 -0
  8. setta/code_gen/find_placeholders.py +13 -0
  9. setta/code_gen/python/__init__.py +0 -0
  10. setta/code_gen/python/ast_utils.py +183 -0
  11. setta/code_gen/python/check_scope.py +187 -0
  12. setta/code_gen/python/generate_code.py +280 -0
  13. setta/code_gen/python/make_parseable.py +97 -0
  14. setta/code_gen/python/position_line_col.py +33 -0
  15. setta/code_gen/python/validate_imports.py +87 -0
  16. setta/code_gen/utils.py +120 -0
  17. setta/code_gen/yaml/__init__.py +0 -0
  18. setta/code_gen/yaml/generate_yaml.py +23 -0
  19. setta/code_gen/yaml/section_dict.py +93 -0
  20. setta/database/__init__.py +0 -0
  21. setta/database/backup.py +80 -0
  22. setta/database/db/__init__.py +0 -0
  23. setta/database/db/artifacts/__init__.py +0 -0
  24. setta/database/db/artifacts/load.py +93 -0
  25. setta/database/db/artifacts/save.py +85 -0
  26. setta/database/db/artifacts/save_or_create.py +68 -0
  27. setta/database/db/artifacts/utils.py +13 -0
  28. setta/database/db/codeInfo/__init__.py +0 -0
  29. setta/database/db/codeInfo/copy.py +26 -0
  30. setta/database/db/codeInfo/load.py +65 -0
  31. setta/database/db/codeInfo/save.py +75 -0
  32. setta/database/db/codeInfo/utils.py +33 -0
  33. setta/database/db/evRefs/__init__.py +0 -0
  34. setta/database/db/evRefs/load.py +45 -0
  35. setta/database/db/evRefs/save.py +95 -0
  36. setta/database/db/projects/__init__.py +0 -0
  37. setta/database/db/projects/copy.py +36 -0
  38. setta/database/db/projects/delete.py +7 -0
  39. setta/database/db/projects/load.py +184 -0
  40. setta/database/db/projects/save.py +267 -0
  41. setta/database/db/projects/saveAs.py +40 -0
  42. setta/database/db/projects/utils.py +135 -0
  43. setta/database/db/sectionVariants/__init__.py +0 -0
  44. setta/database/db/sectionVariants/copy.py +28 -0
  45. setta/database/db/sectionVariants/load.py +139 -0
  46. setta/database/db/sectionVariants/save.py +140 -0
  47. setta/database/db/sectionVariants/utils.py +44 -0
  48. setta/database/db/sections/__init__.py +0 -0
  49. setta/database/db/sections/copy.py +70 -0
  50. setta/database/db/sections/jsonSource.py +119 -0
  51. setta/database/db/sections/load.py +350 -0
  52. setta/database/db/sections/save.py +204 -0
  53. setta/database/db/sections/utils.py +13 -0
  54. setta/database/db/uiTypes/__init__.py +0 -0
  55. setta/database/db/uiTypes/copy.py +33 -0
  56. setta/database/db/uiTypes/load.py +51 -0
  57. setta/database/db/uiTypes/save.py +99 -0
  58. setta/database/db/uiTypes/utils.py +27 -0
  59. setta/database/db_init.py +36 -0
  60. setta/database/db_objs.py +102 -0
  61. setta/database/db_path.py +8 -0
  62. setta/database/export_db/__init__.py +0 -0
  63. setta/database/export_db/export_db.py +43 -0
  64. setta/database/export_db/export_raw.py +53 -0
  65. setta/database/export_db/export_readable.py +242 -0
  66. setta/database/export_db/utils.py +16 -0
  67. setta/database/import_db.py +28 -0
  68. setta/database/seed.py +41 -0
  69. setta/database/settings_file.py +118 -0
  70. setta/database/utils.py +32 -0
  71. setta/lsp/__init__.py +0 -0
  72. setta/lsp/file_watcher.py +113 -0
  73. setta/lsp/reader.py +184 -0
  74. setta/lsp/reader_fns/__init__.py +0 -0
  75. setta/lsp/reader_fns/completion.py +84 -0
  76. setta/lsp/reader_fns/definition.py +2 -0
  77. setta/lsp/reader_fns/diagnostics.py +99 -0
  78. setta/lsp/reader_fns/documentHighlight.py +25 -0
  79. setta/lsp/reader_fns/references.py +34 -0
  80. setta/lsp/reader_fns/signatureHelp.py +99 -0
  81. setta/lsp/server.py +150 -0
  82. setta/lsp/utils.py +60 -0
  83. setta/lsp/writer.py +306 -0
  84. setta/routers/__init__.py +11 -0
  85. setta/routers/artifact.py +105 -0
  86. setta/routers/code_info.py +32 -0
  87. setta/routers/dependencies.py +49 -0
  88. setta/routers/in_memory_fn_stdout_websocket.py +21 -0
  89. setta/routers/interactive.py +119 -0
  90. setta/routers/lsp.py +14 -0
  91. setta/routers/projects.py +188 -0
  92. setta/routers/reference_renaming.py +111 -0
  93. setta/routers/sections.py +174 -0
  94. setta/routers/settings.py +40 -0
  95. setta/routers/terminals.py +83 -0
  96. setta/routers/websocket.py +36 -0
  97. setta/server.py +141 -0
  98. setta/start.py +112 -0
  99. setta/static/constants/BaseUITypes.json +153 -0
  100. setta/static/constants/Settings.json +113 -0
  101. setta/static/constants/constants.json +117 -0
  102. setta/static/constants/db_init.sql +249 -0
  103. setta/static/constants/defaultValues.json +125 -0
  104. setta/static/constants/settingsProject.json +276 -0
  105. setta/static/frontend/android-chrome-192x192.png +0 -0
  106. setta/static/frontend/android-chrome-512x512.png +0 -0
  107. setta/static/frontend/apple-touch-icon.png +0 -0
  108. setta/static/frontend/assets/KaTeX_AMS-Regular-0cdd387c.woff2 +0 -0
  109. setta/static/frontend/assets/KaTeX_AMS-Regular-30da91e8.woff +0 -0
  110. setta/static/frontend/assets/KaTeX_AMS-Regular-68534840.ttf +0 -0
  111. setta/static/frontend/assets/KaTeX_Caligraphic-Bold-07d8e303.ttf +0 -0
  112. setta/static/frontend/assets/KaTeX_Caligraphic-Bold-1ae6bd74.woff +0 -0
  113. setta/static/frontend/assets/KaTeX_Caligraphic-Bold-de7701e4.woff2 +0 -0
  114. setta/static/frontend/assets/KaTeX_Caligraphic-Regular-3398dd02.woff +0 -0
  115. setta/static/frontend/assets/KaTeX_Caligraphic-Regular-5d53e70a.woff2 +0 -0
  116. setta/static/frontend/assets/KaTeX_Caligraphic-Regular-ed0b7437.ttf +0 -0
  117. setta/static/frontend/assets/KaTeX_Fraktur-Bold-74444efd.woff2 +0 -0
  118. setta/static/frontend/assets/KaTeX_Fraktur-Bold-9163df9c.ttf +0 -0
  119. setta/static/frontend/assets/KaTeX_Fraktur-Bold-9be7ceb8.woff +0 -0
  120. setta/static/frontend/assets/KaTeX_Fraktur-Regular-1e6f9579.ttf +0 -0
  121. setta/static/frontend/assets/KaTeX_Fraktur-Regular-51814d27.woff2 +0 -0
  122. setta/static/frontend/assets/KaTeX_Fraktur-Regular-5e28753b.woff +0 -0
  123. setta/static/frontend/assets/KaTeX_Main-Bold-0f60d1b8.woff2 +0 -0
  124. setta/static/frontend/assets/KaTeX_Main-Bold-138ac28d.ttf +0 -0
  125. setta/static/frontend/assets/KaTeX_Main-Bold-c76c5d69.woff +0 -0
  126. setta/static/frontend/assets/KaTeX_Main-BoldItalic-70ee1f64.ttf +0 -0
  127. setta/static/frontend/assets/KaTeX_Main-BoldItalic-99cd42a3.woff2 +0 -0
  128. setta/static/frontend/assets/KaTeX_Main-BoldItalic-a6f7ec0d.woff +0 -0
  129. setta/static/frontend/assets/KaTeX_Main-Italic-0d85ae7c.ttf +0 -0
  130. setta/static/frontend/assets/KaTeX_Main-Italic-97479ca6.woff2 +0 -0
  131. setta/static/frontend/assets/KaTeX_Main-Italic-f1d6ef86.woff +0 -0
  132. setta/static/frontend/assets/KaTeX_Main-Regular-c2342cd8.woff2 +0 -0
  133. setta/static/frontend/assets/KaTeX_Main-Regular-c6368d87.woff +0 -0
  134. setta/static/frontend/assets/KaTeX_Main-Regular-d0332f52.ttf +0 -0
  135. setta/static/frontend/assets/KaTeX_Math-BoldItalic-850c0af5.woff +0 -0
  136. setta/static/frontend/assets/KaTeX_Math-BoldItalic-dc47344d.woff2 +0 -0
  137. setta/static/frontend/assets/KaTeX_Math-BoldItalic-f9377ab0.ttf +0 -0
  138. setta/static/frontend/assets/KaTeX_Math-Italic-08ce98e5.ttf +0 -0
  139. setta/static/frontend/assets/KaTeX_Math-Italic-7af58c5e.woff2 +0 -0
  140. setta/static/frontend/assets/KaTeX_Math-Italic-8a8d2445.woff +0 -0
  141. setta/static/frontend/assets/KaTeX_SansSerif-Bold-1ece03f7.ttf +0 -0
  142. setta/static/frontend/assets/KaTeX_SansSerif-Bold-e99ae511.woff2 +0 -0
  143. setta/static/frontend/assets/KaTeX_SansSerif-Bold-ece03cfd.woff +0 -0
  144. setta/static/frontend/assets/KaTeX_SansSerif-Italic-00b26ac8.woff2 +0 -0
  145. setta/static/frontend/assets/KaTeX_SansSerif-Italic-3931dd81.ttf +0 -0
  146. setta/static/frontend/assets/KaTeX_SansSerif-Italic-91ee6750.woff +0 -0
  147. setta/static/frontend/assets/KaTeX_SansSerif-Regular-11e4dc8a.woff +0 -0
  148. setta/static/frontend/assets/KaTeX_SansSerif-Regular-68e8c73e.woff2 +0 -0
  149. setta/static/frontend/assets/KaTeX_SansSerif-Regular-f36ea897.ttf +0 -0
  150. setta/static/frontend/assets/KaTeX_Script-Regular-036d4e95.woff2 +0 -0
  151. setta/static/frontend/assets/KaTeX_Script-Regular-1c67f068.ttf +0 -0
  152. setta/static/frontend/assets/KaTeX_Script-Regular-d96cdf2b.woff +0 -0
  153. setta/static/frontend/assets/KaTeX_Size1-Regular-6b47c401.woff2 +0 -0
  154. setta/static/frontend/assets/KaTeX_Size1-Regular-95b6d2f1.ttf +0 -0
  155. setta/static/frontend/assets/KaTeX_Size1-Regular-c943cc98.woff +0 -0
  156. setta/static/frontend/assets/KaTeX_Size2-Regular-2014c523.woff +0 -0
  157. setta/static/frontend/assets/KaTeX_Size2-Regular-a6b2099f.ttf +0 -0
  158. setta/static/frontend/assets/KaTeX_Size2-Regular-d04c5421.woff2 +0 -0
  159. setta/static/frontend/assets/KaTeX_Size3-Regular-500e04d5.ttf +0 -0
  160. setta/static/frontend/assets/KaTeX_Size3-Regular-6ab6b62e.woff +0 -0
  161. setta/static/frontend/assets/KaTeX_Size4-Regular-99f9c675.woff +0 -0
  162. setta/static/frontend/assets/KaTeX_Size4-Regular-a4af7d41.woff2 +0 -0
  163. setta/static/frontend/assets/KaTeX_Size4-Regular-c647367d.ttf +0 -0
  164. setta/static/frontend/assets/KaTeX_Typewriter-Regular-71d517d6.woff2 +0 -0
  165. setta/static/frontend/assets/KaTeX_Typewriter-Regular-e14fed02.woff +0 -0
  166. setta/static/frontend/assets/KaTeX_Typewriter-Regular-f01f3e87.ttf +0 -0
  167. setta/static/frontend/assets/cormorant-garamond-all-700-italic-c9b58582.woff +0 -0
  168. setta/static/frontend/assets/cormorant-garamond-cyrillic-700-italic-9101ad5f.woff2 +0 -0
  169. setta/static/frontend/assets/cormorant-garamond-cyrillic-ext-700-italic-950de0d6.woff2 +0 -0
  170. setta/static/frontend/assets/cormorant-garamond-latin-700-italic-0bc53e12.woff2 +0 -0
  171. setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-525738e0.woff2 +0 -0
  172. setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-99563037.woff2 +0 -0
  173. setta/static/frontend/assets/erase-5e0448ea.svg +15 -0
  174. setta/static/frontend/assets/index-1d4b4ecf.css +32 -0
  175. setta/static/frontend/assets/index-ee99dc72.js +678 -0
  176. setta/static/frontend/assets/inter-all-400-normal-054f12d0.woff +0 -0
  177. setta/static/frontend/assets/inter-all-600-normal-c03769e5.woff +0 -0
  178. setta/static/frontend/assets/inter-all-800-normal-15dc6e4b.woff +0 -0
  179. setta/static/frontend/assets/inter-cyrillic-400-normal-a4eee61a.woff2 +0 -0
  180. setta/static/frontend/assets/inter-cyrillic-600-normal-8b14f703.woff2 +0 -0
  181. setta/static/frontend/assets/inter-cyrillic-800-normal-e706eaaa.woff2 +0 -0
  182. setta/static/frontend/assets/inter-cyrillic-ext-400-normal-70047a3b.woff2 +0 -0
  183. setta/static/frontend/assets/inter-cyrillic-ext-600-normal-d4ab9bc4.woff2 +0 -0
  184. setta/static/frontend/assets/inter-cyrillic-ext-800-normal-eae7515a.woff2 +0 -0
  185. setta/static/frontend/assets/inter-greek-400-normal-381ea30d.woff2 +0 -0
  186. setta/static/frontend/assets/inter-greek-600-normal-601f93a2.woff2 +0 -0
  187. setta/static/frontend/assets/inter-greek-800-normal-7af4fb64.woff2 +0 -0
  188. setta/static/frontend/assets/inter-greek-ext-400-normal-27027b17.woff2 +0 -0
  189. setta/static/frontend/assets/inter-greek-ext-600-normal-f2ddf9de.woff2 +0 -0
  190. setta/static/frontend/assets/inter-greek-ext-800-normal-4cb6189e.woff2 +0 -0
  191. setta/static/frontend/assets/inter-latin-400-normal-d56fec21.woff2 +0 -0
  192. setta/static/frontend/assets/inter-latin-600-normal-ff769fa6.woff2 +0 -0
  193. setta/static/frontend/assets/inter-latin-800-normal-5eea1309.woff2 +0 -0
  194. setta/static/frontend/assets/inter-latin-ext-400-normal-bb698d85.woff2 +0 -0
  195. setta/static/frontend/assets/inter-latin-ext-600-normal-ca4808f9.woff2 +0 -0
  196. setta/static/frontend/assets/inter-latin-ext-800-normal-ebdacc0f.woff2 +0 -0
  197. setta/static/frontend/assets/logo/logo.svg +8 -0
  198. setta/static/frontend/assets/pen-455d7d8a.svg +19 -0
  199. setta/static/frontend/assets/source-code-pro-all-500-normal-6bdaa03b.woff +0 -0
  200. setta/static/frontend/assets/source-code-pro-cyrillic-500-normal-288a0d68.woff2 +0 -0
  201. setta/static/frontend/assets/source-code-pro-cyrillic-ext-500-normal-b110a13b.woff2 +0 -0
  202. setta/static/frontend/assets/source-code-pro-greek-500-normal-04328acb.woff2 +0 -0
  203. setta/static/frontend/assets/source-code-pro-latin-500-normal-06edef1e.woff2 +0 -0
  204. setta/static/frontend/assets/source-code-pro-latin-ext-500-normal-6dc60d5e.woff2 +0 -0
  205. setta/static/frontend/assets/web-vitals-44a8e082.js +1 -0
  206. setta/static/frontend/assets/work-sans-all-400-normal-38034a3c.woff +0 -0
  207. setta/static/frontend/assets/work-sans-all-500-normal-550d64e5.woff +0 -0
  208. setta/static/frontend/assets/work-sans-all-600-normal-ccf14060.woff +0 -0
  209. setta/static/frontend/assets/work-sans-all-700-normal-494c2971.woff +0 -0
  210. setta/static/frontend/assets/work-sans-latin-400-normal-36735bc1.woff2 +0 -0
  211. setta/static/frontend/assets/work-sans-latin-500-normal-3790bfda.woff2 +0 -0
  212. setta/static/frontend/assets/work-sans-latin-600-normal-5fba494e.woff2 +0 -0
  213. setta/static/frontend/assets/work-sans-latin-700-normal-a5033d0a.woff2 +0 -0
  214. setta/static/frontend/assets/work-sans-latin-ext-400-normal-c20f571a.woff2 +0 -0
  215. setta/static/frontend/assets/work-sans-latin-ext-500-normal-0f5ac96c.woff2 +0 -0
  216. setta/static/frontend/assets/work-sans-latin-ext-600-normal-97a237d1.woff2 +0 -0
  217. setta/static/frontend/assets/work-sans-latin-ext-700-normal-103e112c.woff2 +0 -0
  218. setta/static/frontend/browserconfig.xml +9 -0
  219. setta/static/frontend/favicon-16x16.png +0 -0
  220. setta/static/frontend/favicon-32x32.png +0 -0
  221. setta/static/frontend/favicon.ico +0 -0
  222. setta/static/frontend/index.html +30 -0
  223. setta/static/frontend/manifest.json +25 -0
  224. setta/static/frontend/mstile-144x144.png +0 -0
  225. setta/static/frontend/mstile-150x150.png +0 -0
  226. setta/static/frontend/mstile-310x150.png +0 -0
  227. setta/static/frontend/mstile-310x310.png +0 -0
  228. setta/static/frontend/mstile-70x70.png +0 -0
  229. setta/static/frontend/robots.txt +3 -0
  230. setta/static/frontend/safari-pinned-tab.svg +18 -0
  231. setta/static/frontend/site.webmanifest +19 -0
  232. setta/static/seed/.DS_Store +0 -0
  233. setta/static/seed/examples/.DS_Store +0 -0
  234. setta/tasks/__init__.py +0 -0
  235. setta/tasks/fns/__init__.py +9 -0
  236. setta/tasks/fns/codeAreaAutocomplete.py +209 -0
  237. setta/tasks/fns/codeAreaFindTemplateVars.py +128 -0
  238. setta/tasks/fns/codeAreaInitializeCode.py +98 -0
  239. setta/tasks/fns/findEVRefs.py +236 -0
  240. setta/tasks/fns/parametersRequest.py +71 -0
  241. setta/tasks/fns/textFieldAutocomplete.py +210 -0
  242. setta/tasks/fns/textFieldInitializeCode.py +99 -0
  243. setta/tasks/fns/typeCheck.py +40 -0
  244. setta/tasks/fns/utils.py +134 -0
  245. setta/tasks/task_runner.py +29 -0
  246. setta/tasks/tasks.py +152 -0
  247. setta/tasks/utils.py +178 -0
  248. setta/terminals/__init__.py +0 -0
  249. setta/terminals/terminals.py +242 -0
  250. setta/terminals/utils.py +37 -0
  251. setta/utils/__init__.py +0 -0
  252. setta/utils/constants.py +148 -0
  253. setta/utils/generate_memorable_string.py +431 -0
  254. setta/utils/generate_new_filename.py +80 -0
  255. setta/utils/section_contents.py +133 -0
  256. setta/utils/utils.py +271 -0
  257. setta/utils/websocket_manager.py +91 -0
  258. setta-0.0.2.dist-info/LICENSE +201 -0
  259. setta-0.0.2.dist-info/METADATA +24 -0
  260. setta-0.0.2.dist-info/RECORD +263 -0
  261. {setta-0.0.1.dist-info → setta-0.0.2.dist-info}/WHEEL +1 -1
  262. setta-0.0.2.dist-info/entry_points.txt +2 -0
  263. setta-0.0.1.dist-info/METADATA +0 -18
  264. setta-0.0.1.dist-info/RECORD +0 -5
  265. {setta-0.0.1.dist-info → setta-0.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,174 @@
1
+ import os
2
+ from pathlib import Path
3
+ from typing import Dict, List
4
+
5
+ from fastapi import APIRouter, HTTPException, status
6
+ from pydantic import BaseModel
7
+
8
+ from setta.code_gen.export_selected import (
9
+ export_param_sweep_section_to_dict,
10
+ export_section_to_dict,
11
+ export_single_run_group_to_dict,
12
+ )
13
+ from setta.code_gen.yaml.section_dict import (
14
+ param_sweep_dict_to_yaml,
15
+ run_group_dict_to_yaml,
16
+ section_dict_to_yaml,
17
+ )
18
+ from setta.database.db.sections.copy import (
19
+ copy_relative_positions,
20
+ copy_sections_and_other_info,
21
+ )
22
+ from setta.database.db.sections.jsonSource import save_json_source_data
23
+ from setta.database.db.sections.load import load_json_sources_into_data_structures
24
+ from setta.utils.constants import C
25
+ from setta.utils.generate_new_filename import generate_new_filename
26
+
27
+ router = APIRouter()
28
+
29
+
30
+ class SectionsMakeCopyRequest(BaseModel):
31
+ sectionsAndOtherInfo: dict
32
+
33
+
34
+ class SectionToYamlRequest(BaseModel):
35
+ codeInfo: dict
36
+ codeInfoChildren: dict
37
+ sectionVariant: dict
38
+ pinnedIds: Dict[str, List[str]]
39
+ unpinnedIds: Dict[str, List[str]]
40
+
41
+
42
+ class ParamSweepSectionToYamlRequest(BaseModel):
43
+ sweep: list
44
+ codeInfo: dict
45
+ codeInfoChildren: dict
46
+
47
+
48
+ class GlobalParamSweepSectionToYamlRequest(BaseModel):
49
+ runGroup: dict | None
50
+ sections: dict
51
+ sectionVariants: dict
52
+
53
+
54
+ class LoadSectionJSONSourceRequest(BaseModel):
55
+ project: dict
56
+ sectionId: str
57
+ jsonSource: str
58
+
59
+
60
+ class SaveSectionJSONSourceRequest(BaseModel):
61
+ project: dict
62
+ sectionId: str
63
+ forking_from: str
64
+
65
+
66
+ class NewJSONVersionNameRequest(BaseModel):
67
+ filenameGlob: str
68
+
69
+
70
+ class GetJSONSourcePathToBeDeleted(BaseModel):
71
+ variantName: str
72
+
73
+
74
+ class DeleteFileRequest(BaseModel):
75
+ filepath: str
76
+
77
+
78
+ @router.post(C.ROUTE_COPY_SECTIONS)
79
+ def route_sections_make_copy(x: SectionsMakeCopyRequest):
80
+ output = copy_sections_and_other_info(x.sectionsAndOtherInfo)
81
+ relativePositions = copy_relative_positions(
82
+ x.sectionsAndOtherInfo["relativePositions"], output["section_id_map"]
83
+ )
84
+ output.pop("section_id_map")
85
+ return {**output, "relativePositions": relativePositions}
86
+
87
+
88
+ @router.post(C.ROUTE_SECTION_TO_YAML)
89
+ def route_section_to_yaml(x: SectionToYamlRequest):
90
+ output = export_section_to_dict(
91
+ x.codeInfo,
92
+ x.codeInfoChildren,
93
+ x.sectionVariant,
94
+ {"pinned": x.pinnedIds, "unpinned": x.unpinnedIds},
95
+ )
96
+
97
+ yamlValue = section_dict_to_yaml(output, x.codeInfo, x.sectionVariant)
98
+
99
+ return {
100
+ "yamlValue": yamlValue,
101
+ "originalObj": {
102
+ "pinned": output["pinned"].output,
103
+ "unpinned": output["unpinned"].output,
104
+ },
105
+ }
106
+
107
+
108
+ @router.post(C.ROUTE_PARAM_SWEEP_SECTION_TO_YAML)
109
+ def route_param_sweep_section_to_yaml(x: ParamSweepSectionToYamlRequest):
110
+ output = export_param_sweep_section_to_dict(x.sweep, x.codeInfo, x.codeInfoChildren)
111
+ yamlValue = param_sweep_dict_to_yaml(output)
112
+ return {"yamlValue": yamlValue, "originalObj": {}}
113
+
114
+
115
+ @router.post(C.ROUTE_GLOBAL_PARAM_SWEEP_SECTION_TO_YAML)
116
+ def route_global_param_sweep_section_to_yaml(x: GlobalParamSweepSectionToYamlRequest):
117
+ output = export_single_run_group_to_dict(
118
+ x.runGroup,
119
+ x.sections,
120
+ x.sectionVariants,
121
+ )
122
+ yamlValue = run_group_dict_to_yaml(output)
123
+ return {"yamlValue": yamlValue, "originalObj": {}}
124
+
125
+
126
+ @router.post(C.ROUTE_LOAD_SECTION_JSON_SOURCE)
127
+ def route_load_section_json_source(x: LoadSectionJSONSourceRequest):
128
+ p = x.project
129
+ p["sections"][x.sectionId]["jsonSource"] = x.jsonSource
130
+ load_json_sources_into_data_structures(
131
+ p["sections"],
132
+ p["codeInfo"],
133
+ p["codeInfoCols"],
134
+ p["sectionVariants"],
135
+ section_ids=[x.sectionId],
136
+ )
137
+ return {"project": p}
138
+
139
+
140
+ @router.post(C.ROUTE_NEW_JSON_VERSION_NAME)
141
+ def route_new_json_version_name(x: NewJSONVersionNameRequest):
142
+ new_filename = generate_new_filename(x.filenameGlob)
143
+ Path(new_filename).parent.mkdir(parents=True, exist_ok=True)
144
+ Path(new_filename).touch()
145
+ return new_filename
146
+
147
+
148
+ @router.post(C.ROUTE_SAVE_SECTION_JSON_SOURCE)
149
+ def route_save_section_json_source(x: SaveSectionJSONSourceRequest):
150
+ save_json_source_data(x.project, [x.sectionId], x.forking_from)
151
+
152
+
153
+ @router.post(C.ROUTE_GET_JSON_SOURCE_PATH_TO_BE_DELETED)
154
+ def route_get_json_source_path_to_be_deleted(x: GetJSONSourcePathToBeDeleted):
155
+ return os.path.abspath(x.variantName)
156
+
157
+
158
+ @router.post(C.ROUTE_DELETE_FILE)
159
+ def route_delete_file(x: DeleteFileRequest):
160
+ file = Path(x.filepath)
161
+ if not file.exists():
162
+ raise HTTPException(
163
+ status_code=status.HTTP_404_NOT_FOUND,
164
+ detail=f"File '{x.filepath}' not found",
165
+ )
166
+
167
+ try:
168
+ file.unlink()
169
+ return {"message": f"File '{x.filepath}' deleted successfully"}
170
+ except Exception as e:
171
+ raise HTTPException(
172
+ status_code=status.HTTP_404_NOT_FOUND,
173
+ detail=f"Failed to delete file: {str(e)}",
174
+ )
@@ -0,0 +1,40 @@
1
+ from fastapi import APIRouter, Depends
2
+ from pydantic import BaseModel
3
+
4
+ from setta.utils.constants import C
5
+
6
+ from .dependencies import get_settings_file
7
+
8
+ router = APIRouter()
9
+
10
+
11
+ class SaveSettingsRequest(BaseModel):
12
+ settings: dict
13
+
14
+
15
+ class SaveSettingsProjectRequest(BaseModel):
16
+ settingsProject: dict
17
+
18
+
19
+ @router.post(C.ROUTE_SAVE_SETTINGS)
20
+ def route_save_settings(
21
+ x: SaveSettingsRequest, settings_file=Depends(get_settings_file)
22
+ ):
23
+ return settings_file.save_settings(x.settings)
24
+
25
+
26
+ @router.post(C.ROUTE_LOAD_SETTINGS)
27
+ def route_load_settings(settings_file=Depends(get_settings_file)):
28
+ return settings_file.load_settings()
29
+
30
+
31
+ @router.post(C.ROUTE_SAVE_SETTINGS_PROJECT)
32
+ def route_save_settings_project(
33
+ x: SaveSettingsProjectRequest, settings_file=Depends(get_settings_file)
34
+ ):
35
+ return settings_file.save_settings_project(x.settingsProject)
36
+
37
+
38
+ @router.post(C.ROUTE_LOAD_SETTINGS_PROJECT)
39
+ def route_load_settings_project(settings_file=Depends(get_settings_file)):
40
+ return settings_file.load_settings_project()
@@ -0,0 +1,83 @@
1
+ import asyncio
2
+ import logging
3
+ from typing import List
4
+
5
+ from fastapi import APIRouter, Depends, WebSocket
6
+ from pydantic import BaseModel
7
+
8
+ from setta.utils.constants import C
9
+
10
+ from .dependencies import (
11
+ get_lsp_writers_from_websocket,
12
+ get_terminal_websockets,
13
+ get_terminal_websockets_from_websocket,
14
+ )
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ router = APIRouter()
20
+
21
+
22
+ class DeleteTerminalsRequest(BaseModel):
23
+ sectionIds: List[str]
24
+
25
+
26
+ @router.websocket(C.ROUTE_TERMINAL)
27
+ async def terminal_websocket_endpoint(
28
+ websocket: WebSocket,
29
+ projectConfigId: str,
30
+ sectionId: str,
31
+ id: str,
32
+ isTemporary: bool,
33
+ terminal_websockets=Depends(get_terminal_websockets_from_websocket),
34
+ lsp_writers=Depends(get_lsp_writers_from_websocket),
35
+ ):
36
+ # First check if terminal exists
37
+ isNew = terminal_websockets.new_terminal(projectConfigId, sectionId, isTemporary)
38
+
39
+ # Start the background task for terminal handling
40
+ async def handle_terminal():
41
+ read_task = asyncio.get_running_loop().create_task(
42
+ terminal_websockets.read_from_terminal(sectionId)
43
+ )
44
+ await read_task
45
+ await terminal_websockets.delete_terminal(sectionId)
46
+
47
+ # Create the background task
48
+ if isNew:
49
+ asyncio.get_running_loop().create_task(handle_terminal())
50
+
51
+ try:
52
+ await terminal_websockets.connect(websocket, sectionId, id)
53
+ write_task = asyncio.get_running_loop().create_task(
54
+ terminal_websockets.write_to_terminal(websocket, lsp_writers, sectionId)
55
+ )
56
+ await write_task
57
+ except:
58
+ pass
59
+ finally:
60
+ # Cleanup
61
+ logger.debug(f"terminal_websocket_endpoint disconnect: {id}")
62
+ terminal_websockets.disconnect(sectionId, id)
63
+
64
+
65
+ @router.post(C.ROUTE_GET_FREE_TERMINAL)
66
+ def route_terminal_get_free_terminal(
67
+ projectConfigId, terminal_websockets=Depends(get_terminal_websockets)
68
+ ):
69
+ return terminal_websockets.get_free_terminal(projectConfigId)
70
+
71
+
72
+ @router.post(C.ROUTE_DELETE_TERMINALS)
73
+ async def route_terminal_delete_terminals(
74
+ x: DeleteTerminalsRequest, terminal_websockets=Depends(get_terminal_websockets)
75
+ ):
76
+ await terminal_websockets.delete_terminals(x.sectionIds)
77
+
78
+
79
+ @router.post(C.ROUTE_GET_EXISTING_TERMINALS)
80
+ def route_terminal_get_existing_terminals(
81
+ projectConfigId, terminal_websockets=Depends(get_terminal_websockets)
82
+ ):
83
+ return terminal_websockets.get_existing_terminals(projectConfigId)
@@ -0,0 +1,36 @@
1
+ import json
2
+ import logging
3
+ import traceback
4
+
5
+ from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect
6
+
7
+ from setta.utils.constants import C
8
+
9
+ from .dependencies import get_tasks_from_websocket, get_websocket_manager_from_websocket
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ router = APIRouter()
14
+
15
+
16
+ @router.websocket(C.ROUTE_WEBSOCKET_MANAGER)
17
+ async def websocket_endpoint(
18
+ websocket: WebSocket,
19
+ websocket_manager=Depends(get_websocket_manager_from_websocket),
20
+ tasks=Depends(get_tasks_from_websocket),
21
+ ):
22
+ id = await websocket_manager.connect(websocket)
23
+ while True:
24
+ try:
25
+ data = await websocket.receive_text()
26
+ await websocket_manager.send_message(
27
+ json.loads(data), fromWebsocketId=id, tasks=tasks
28
+ )
29
+ except WebSocketDisconnect:
30
+ logger.debug("WebSocketDisconnect!")
31
+ await websocket_manager.disconnect(id)
32
+ break
33
+ except Exception as e:
34
+ logger.debug(f"Exception details:\n{traceback.format_exc()}")
35
+ logger.debug(e)
36
+ logger.debug("caught the exception!")
setta/server.py ADDED
@@ -0,0 +1,141 @@
1
+ import logging
2
+ import os
3
+ from contextlib import asynccontextmanager
4
+ from pathlib import Path
5
+
6
+ from fastapi import FastAPI, Request, status
7
+ from fastapi.exceptions import RequestValidationError
8
+ from fastapi.middleware.cors import CORSMiddleware
9
+ from fastapi.responses import HTMLResponse, JSONResponse
10
+ from fastapi.staticfiles import StaticFiles
11
+
12
+ from setta.database.db_init import maybe_create_tables_and_seed
13
+ from setta.database.db_objs import DBQueue
14
+ from setta.database.settings_file import SettingsFile
15
+ from setta.lsp.utils import (
16
+ create_file_watcher,
17
+ create_lsp_readers,
18
+ create_lsp_writers,
19
+ create_lsps,
20
+ kill_lsps,
21
+ start_lsps,
22
+ )
23
+ from setta.routers import (
24
+ artifact_router,
25
+ code_info_router,
26
+ in_memory_fn_stdout_router,
27
+ interactive_code_router,
28
+ lsp_router,
29
+ projects_router,
30
+ reference_renaming_router,
31
+ sections_router,
32
+ settings_router,
33
+ terminals_router,
34
+ websocket_router,
35
+ )
36
+ from setta.tasks.tasks import Tasks
37
+ from setta.terminals.terminals import TerminalWebsockets
38
+ from setta.utils.constants import CODE_FOLDER, USER_SETTINGS, C
39
+ from setta.utils.utils import get_absolute_path, is_dev_mode
40
+ from setta.utils.websocket_manager import WebsocketManager
41
+
42
+
43
+ @asynccontextmanager
44
+ async def lifespan(app: FastAPI):
45
+ # startup
46
+ app.state.settings_file = SettingsFile()
47
+ app.state.lsps = create_lsps(
48
+ workspace_folder=Path(os.getcwd()),
49
+ code_folder=Path(os.getcwd()) / CODE_FOLDER / "temp_folder",
50
+ settings=USER_SETTINGS["languageServer"],
51
+ )
52
+ app.state.lsp_writers = create_lsp_writers(app.state.lsps)
53
+ app.state.file_watcher = create_file_watcher(app.state.lsps, app.state.lsp_writers)
54
+ app.state.terminal_websockets = TerminalWebsockets()
55
+ app.state.websocket_manager = WebsocketManager()
56
+ app.state.tasks = Tasks(app.state.lsp_writers)
57
+ app.state.lsp_readers = create_lsp_readers(
58
+ app.state.lsps, app.state.websocket_manager
59
+ )
60
+ app.state.dbq = DBQueue(
61
+ C.DB_PATH,
62
+ )
63
+
64
+ maybe_create_tables_and_seed(
65
+ app.state.dbq,
66
+ with_examples=C.WITH_EXAMPLES,
67
+ with_base_ui_types=True,
68
+ )
69
+
70
+ app.state.dbq.connect()
71
+ await start_lsps(
72
+ app.state.lsps,
73
+ app.state.lsp_readers,
74
+ app.state.lsp_writers,
75
+ )
76
+ app.state.file_watcher.start()
77
+
78
+ if not is_dev_mode():
79
+ # Mount the 'frontend/dist' directory at '/static'
80
+ frontend_folder = Path("static/frontend")
81
+ dist_path = get_absolute_path(__file__, frontend_folder)
82
+ app.mount(
83
+ "/static",
84
+ StaticFiles(directory=dist_path, html=True),
85
+ name="static",
86
+ )
87
+
88
+ # {full_path:path} is to catch all paths not explicitly covered here
89
+ @app.get("/{full_path:path}", response_class=HTMLResponse)
90
+ async def read_root(full_path: str):
91
+ # Adjust the path to match the location of your 'index.html'
92
+ with open(dist_path / "index.html") as f:
93
+ content = f.read()
94
+ return content
95
+
96
+ print(f"Ready: {C.BACKEND}", flush=True)
97
+ try:
98
+ yield
99
+ finally:
100
+ app.state.tasks.close()
101
+ app.state.file_watcher.stop()
102
+ await kill_lsps(app.state.lsps, app.state.lsp_readers)
103
+
104
+
105
+ app = FastAPI(
106
+ lifespan=lifespan,
107
+ openapi_url=f"{C.ROUTE_PREFIX}{C.ROUTE_OPENAPI_DOCS}",
108
+ docs_url=f"{C.ROUTE_PREFIX}{C.ROUTE_SWAGGER_DOCS}",
109
+ redoc_url=f"{C.ROUTE_PREFIX}{C.ROUTE_REDOC_DOCS}",
110
+ )
111
+
112
+ app.add_middleware(
113
+ CORSMiddleware,
114
+ allow_origins=C.FRONTEND_ORIGINS,
115
+ allow_methods=["*"],
116
+ allow_headers=["*"],
117
+ )
118
+
119
+ kwargs = {"prefix": C.ROUTE_PREFIX}
120
+ app.include_router(projects_router, **kwargs)
121
+ app.include_router(sections_router, **kwargs)
122
+ app.include_router(terminals_router, **kwargs)
123
+ app.include_router(websocket_router, **kwargs)
124
+ app.include_router(code_info_router, **kwargs)
125
+ app.include_router(settings_router, **kwargs)
126
+ app.include_router(interactive_code_router, **kwargs)
127
+ app.include_router(artifact_router, **kwargs)
128
+ app.include_router(reference_renaming_router, **kwargs)
129
+ app.include_router(in_memory_fn_stdout_router, **kwargs)
130
+ app.include_router(lsp_router, **kwargs)
131
+
132
+
133
+ # https://github.com/tiangolo/fastapi/issues/3361#issuecomment-1002120988
134
+ @app.exception_handler(RequestValidationError)
135
+ async def validation_exception_handler(request: Request, exc: RequestValidationError):
136
+ exc_str = f"{exc}".replace("\n", " ").replace(" ", " ")
137
+ logging.error(f"{request}: {exc_str}")
138
+ content = {"status_code": 10422, "message": exc_str, "data": None}
139
+ return JSONResponse(
140
+ content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY
141
+ )
setta/start.py ADDED
@@ -0,0 +1,112 @@
1
+ import asyncio
2
+ import logging
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import click
7
+ import uvicorn
8
+
9
+ from . import __version__
10
+ from .cli.connect import connect as _connect
11
+ from .database.db_init import maybe_create_tables_and_seed
12
+ from .database.db_objs import DBQueue
13
+ from .database.db_path import get_default_db_path
14
+ from .database.export_db.export_db import export_database
15
+ from .database.import_db import import_database
16
+ from .utils.constants import C, set_constants
17
+
18
+
19
+ @click.command()
20
+ @click.argument("websocket_id", required=False)
21
+ @click.option("--host", default=C.DEFAULT_HOST, help="backend host")
22
+ @click.option("--port", default=C.DEFAULT_PORT, help="backend port")
23
+ def connect(websocket_id, host, port):
24
+ set_constants(host=host, port=port)
25
+ asyncio.run(_connect(websocket_id))
26
+
27
+
28
+ @click.command()
29
+ def version():
30
+ print(f"setta version {__version__}")
31
+
32
+
33
+ @click.command()
34
+ @click.argument(
35
+ "path",
36
+ type=click.Path(file_okay=True, dir_okay=False, writable=True),
37
+ required=True,
38
+ )
39
+ @click.option("--with_examples", is_flag=True)
40
+ def init_db(path, with_examples):
41
+ dbq = DBQueue(path)
42
+ maybe_create_tables_and_seed(dbq, with_examples)
43
+
44
+
45
+ @click.command()
46
+ @click.argument("path", default=get_default_db_path(), required=False)
47
+ def export_db(path):
48
+ export_database(path)
49
+
50
+
51
+ @click.command()
52
+ @click.argument("yaml_path", required=True)
53
+ @click.argument("output_path", required=True)
54
+ def import_db(yaml_path, output_path):
55
+ import_database(yaml_path, output_path)
56
+
57
+
58
+ @click.group(
59
+ invoke_without_command=True,
60
+ context_settings=dict(
61
+ ignore_unknown_options=True,
62
+ ),
63
+ )
64
+ @click.option("--reload", is_flag=True)
65
+ @click.option("--with-examples", is_flag=True)
66
+ @click.option("--db", "-d", type=str, default=get_default_db_path())
67
+ @click.option("--host", default=C.DEFAULT_HOST, help="backend host")
68
+ @click.option("--port", default=C.DEFAULT_PORT, help="backend port")
69
+ @click.option(
70
+ "--log-level",
71
+ type=click.Choice(
72
+ ["critical", "error", "warning", "info", "debug"], case_sensitive=False
73
+ ),
74
+ default="critical",
75
+ help="Set the logging level",
76
+ )
77
+ @click.pass_context
78
+ def cli(ctx, reload, with_examples, db, host, port, log_level):
79
+ if ctx.invoked_subcommand is None:
80
+ print("Starting Setta", flush=True)
81
+
82
+ set_constants(
83
+ with_examples=with_examples,
84
+ db_path=db,
85
+ host=host,
86
+ port=port,
87
+ )
88
+
89
+ sys.path.append(str(Path(__file__).resolve().parent))
90
+
91
+ logging.basicConfig(
92
+ level=getattr(logging, log_level.upper()),
93
+ format="%(levelname)s - %(asctime)s - %(name)s - %(message)s",
94
+ )
95
+
96
+ config = uvicorn.Config(
97
+ "server:app",
98
+ host=host,
99
+ port=port,
100
+ log_level=log_level,
101
+ reload=reload,
102
+ )
103
+ server = uvicorn.Server(config)
104
+
105
+ server.run()
106
+
107
+
108
+ cli.add_command(connect)
109
+ cli.add_command(version)
110
+ cli.add_command(init_db)
111
+ cli.add_command(export_db)
112
+ cli.add_command(import_db)