xlwings-server 1.1.0__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.
Files changed (313) hide show
  1. xlwings_server/.env.template +145 -0
  2. xlwings_server/__init__.py +12 -0
  3. xlwings_server/_version.py +34 -0
  4. xlwings_server/auth/__init__.py +0 -0
  5. xlwings_server/auth/custom/__init__.py +26 -0
  6. xlwings_server/auth/entraid/__init__.py +131 -0
  7. xlwings_server/auth/entraid/jwks.py +10 -0
  8. xlwings_server/azure_functions_templates/.funcignore +28 -0
  9. xlwings_server/azure_functions_templates/function_app.py +28 -0
  10. xlwings_server/azure_functions_templates/host.json +22 -0
  11. xlwings_server/azure_functions_templates/local.settings.json +8 -0
  12. xlwings_server/build_utils/__init__.py +9 -0
  13. xlwings_server/build_utils/static_file_hasher.py +212 -0
  14. xlwings_server/cli.py +1592 -0
  15. xlwings_server/config.py +228 -0
  16. xlwings_server/custom_functions/__init__.py +8 -0
  17. xlwings_server/custom_functions/examples.py +177 -0
  18. xlwings_server/custom_scripts/__init__.py +8 -0
  19. xlwings_server/custom_scripts/examples.py +94 -0
  20. xlwings_server/databases.py +19 -0
  21. xlwings_server/dependencies.py +126 -0
  22. xlwings_server/docker_templates/.dockerignore +15 -0
  23. xlwings_server/docker_templates/Dockerfile +60 -0
  24. xlwings_server/docker_templates/docker-compose.yaml +32 -0
  25. xlwings_server/hotreload.py +59 -0
  26. xlwings_server/main.py +242 -0
  27. xlwings_server/models/__init__.py +14 -0
  28. xlwings_server/models/user.py +53 -0
  29. xlwings_server/object_handles.py +142 -0
  30. xlwings_server/routers/__init__.py +0 -0
  31. xlwings_server/routers/manifest.py +82 -0
  32. xlwings_server/routers/root.py +16 -0
  33. xlwings_server/routers/socketio.py +69 -0
  34. xlwings_server/routers/taskpane.py +12 -0
  35. xlwings_server/routers/xlwings.py +197 -0
  36. xlwings_server/security_headers.json +53 -0
  37. xlwings_server/serializers/__init__.py +25 -0
  38. xlwings_server/serializers/default_serializer.py +19 -0
  39. xlwings_server/serializers/dictionary_serializer.py +25 -0
  40. xlwings_server/serializers/framework.py +50 -0
  41. xlwings_server/serializers/numpy_serializer.py +26 -0
  42. xlwings_server/serializers/pandas_serializer.py +95 -0
  43. xlwings_server/static/css/core.css +28 -0
  44. xlwings_server/static/css/style.css +0 -0
  45. xlwings_server/static/images/favicon.png +0 -0
  46. xlwings_server/static/images/xlwings-16.png +0 -0
  47. xlwings_server/static/images/xlwings-32.png +0 -0
  48. xlwings_server/static/images/xlwings-64.png +0 -0
  49. xlwings_server/static/images/xlwings-80.png +0 -0
  50. xlwings_server/static/js/auth.js +13 -0
  51. xlwings_server/static/js/config.js +4 -0
  52. xlwings_server/static/js/core/alpinejs-csp-boilerplate.js +11 -0
  53. xlwings_server/static/js/core/bootstrap-customizations.js +7 -0
  54. xlwings_server/static/js/core/custom-functions-code.js +296 -0
  55. xlwings_server/static/js/core/examples.js +62 -0
  56. xlwings_server/static/js/core/hotreload.js +3 -0
  57. xlwings_server/static/js/core/htmx-handlers.js +86 -0
  58. xlwings_server/static/js/core/officejs-history-fix-part1.js +3 -0
  59. xlwings_server/static/js/core/officejs-history-fix-part2.js +2 -0
  60. xlwings_server/static/js/core/reload-custom-functions.js +79 -0
  61. xlwings_server/static/js/core/socketio-handlers.js +34 -0
  62. xlwings_server/static/js/core/xlwings-alert.js +22 -0
  63. xlwings_server/static/js/core/xlwingsjs/alert.js +85 -0
  64. xlwings_server/static/js/core/xlwingsjs/auth.js +63 -0
  65. xlwings_server/static/js/core/xlwingsjs/sheet-buttons.js +133 -0
  66. xlwings_server/static/js/core/xlwingsjs/utils.js +119 -0
  67. xlwings_server/static/js/core/xlwingsjs/wasm.js +131 -0
  68. xlwings_server/static/js/core/xlwingsjs/xlwings.js +1060 -0
  69. xlwings_server/static/js/main.js +0 -0
  70. xlwings_server/static/js/ribbon.js +17 -0
  71. xlwings_server/static/vendor/@alpinejs/LICENSE +21 -0
  72. xlwings_server/static/vendor/@alpinejs/csp/dist/cdn.min.js +7 -0
  73. xlwings_server/static/vendor/@microsoft/office-js/LICENSE.md +76 -0
  74. xlwings_server/static/vendor/@microsoft/office-js/dist/af-za/office_strings.js +8 -0
  75. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/agaveerrorux.js +18 -0
  76. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/agavedefaulticon32x32.png +0 -0
  77. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/agavedefaulticon96x96.png +0 -0
  78. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/businessbarclose_16x16x32.png +0 -0
  79. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/dropdownarrow_16x16x32.png +0 -0
  80. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/ellipsis_16x16x32.png +0 -0
  81. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/miniinfoblue_16x16x32.png +0 -0
  82. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/moe_default_icon.png +0 -0
  83. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/moe_status_icons.png +0 -0
  84. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/office.png +0 -0
  85. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/images/refresh_16x16x32.png +0 -0
  86. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/index.html +16 -0
  87. xlwings_server/static/vendor/@microsoft/office-js/dist/agaveerrorux/style/agaveerrorux.css +482 -0
  88. xlwings_server/static/vendor/@microsoft/office-js/dist/am-et/office_strings.js +1 -0
  89. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-ae/office_strings.js +8 -0
  90. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-bh/office_strings.js +8 -0
  91. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-dz/office_strings.js +8 -0
  92. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-eg/office_strings.js +8 -0
  93. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-iq/office_strings.js +8 -0
  94. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-jo/office_strings.js +8 -0
  95. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-kw/office_strings.js +8 -0
  96. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-lb/office_strings.js +8 -0
  97. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-ly/office_strings.js +8 -0
  98. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-ma/office_strings.js +8 -0
  99. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-om/office_strings.js +8 -0
  100. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-qa/office_strings.js +8 -0
  101. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-sa/office_strings.js +1 -0
  102. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-sy/office_strings.js +8 -0
  103. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-tn/office_strings.js +8 -0
  104. xlwings_server/static/vendor/@microsoft/office-js/dist/ar-ye/office_strings.js +8 -0
  105. xlwings_server/static/vendor/@microsoft/office-js/dist/ariatelemetry/aria-web-telemetry-2.8.0.min.js +2 -0
  106. xlwings_server/static/vendor/@microsoft/office-js/dist/ariatelemetry/aria-web-telemetry-2.9.0.min.js +2 -0
  107. xlwings_server/static/vendor/@microsoft/office-js/dist/ariatelemetry/aria-web-telemetry.js +1 -0
  108. xlwings_server/static/vendor/@microsoft/office-js/dist/az-latn-az/office_strings.js +8 -0
  109. xlwings_server/static/vendor/@microsoft/office-js/dist/be-by/office_strings.js +8 -0
  110. xlwings_server/static/vendor/@microsoft/office-js/dist/bg-bg/office_strings.js +1 -0
  111. xlwings_server/static/vendor/@microsoft/office-js/dist/bn-in/office_strings.js +1 -0
  112. xlwings_server/static/vendor/@microsoft/office-js/dist/bs-latn-ba/office_strings.js +8 -0
  113. xlwings_server/static/vendor/@microsoft/office-js/dist/ca-es/office_strings.js +1 -0
  114. xlwings_server/static/vendor/@microsoft/office-js/dist/cs-cz/office_strings.js +1 -0
  115. xlwings_server/static/vendor/@microsoft/office-js/dist/cy-gb/office_strings.js +1 -0
  116. xlwings_server/static/vendor/@microsoft/office-js/dist/da-dk/office_strings.js +1 -0
  117. xlwings_server/static/vendor/@microsoft/office-js/dist/de-at/office_strings.js +8 -0
  118. xlwings_server/static/vendor/@microsoft/office-js/dist/de-ch/office_strings.js +8 -0
  119. xlwings_server/static/vendor/@microsoft/office-js/dist/de-de/office_strings.js +1 -0
  120. xlwings_server/static/vendor/@microsoft/office-js/dist/de-li/office_strings.js +8 -0
  121. xlwings_server/static/vendor/@microsoft/office-js/dist/de-lu/office_strings.js +8 -0
  122. xlwings_server/static/vendor/@microsoft/office-js/dist/el-gr/office_strings.js +1 -0
  123. xlwings_server/static/vendor/@microsoft/office-js/dist/en-029/office_strings.js +8 -0
  124. xlwings_server/static/vendor/@microsoft/office-js/dist/en-au/office_strings.js +8 -0
  125. xlwings_server/static/vendor/@microsoft/office-js/dist/en-bz/office_strings.js +8 -0
  126. xlwings_server/static/vendor/@microsoft/office-js/dist/en-ca/office_strings.js +8 -0
  127. xlwings_server/static/vendor/@microsoft/office-js/dist/en-gb/office_strings.js +8 -0
  128. xlwings_server/static/vendor/@microsoft/office-js/dist/en-ie/office_strings.js +8 -0
  129. xlwings_server/static/vendor/@microsoft/office-js/dist/en-in/office_strings.js +8 -0
  130. xlwings_server/static/vendor/@microsoft/office-js/dist/en-jm/office_strings.js +8 -0
  131. xlwings_server/static/vendor/@microsoft/office-js/dist/en-my/office_strings.js +8 -0
  132. xlwings_server/static/vendor/@microsoft/office-js/dist/en-nz/office_strings.js +8 -0
  133. xlwings_server/static/vendor/@microsoft/office-js/dist/en-ph/office_strings.js +8 -0
  134. xlwings_server/static/vendor/@microsoft/office-js/dist/en-sg/office_strings.js +8 -0
  135. xlwings_server/static/vendor/@microsoft/office-js/dist/en-tt/office_strings.js +8 -0
  136. xlwings_server/static/vendor/@microsoft/office-js/dist/en-us/office_strings.js +8 -0
  137. xlwings_server/static/vendor/@microsoft/office-js/dist/en-za/office_strings.js +8 -0
  138. xlwings_server/static/vendor/@microsoft/office-js/dist/en-zw/office_strings.js +8 -0
  139. xlwings_server/static/vendor/@microsoft/office-js/dist/es-ar/office_strings.js +8 -0
  140. xlwings_server/static/vendor/@microsoft/office-js/dist/es-bo/office_strings.js +8 -0
  141. xlwings_server/static/vendor/@microsoft/office-js/dist/es-cl/office_strings.js +8 -0
  142. xlwings_server/static/vendor/@microsoft/office-js/dist/es-co/office_strings.js +8 -0
  143. xlwings_server/static/vendor/@microsoft/office-js/dist/es-cr/office_strings.js +8 -0
  144. xlwings_server/static/vendor/@microsoft/office-js/dist/es-do/office_strings.js +8 -0
  145. xlwings_server/static/vendor/@microsoft/office-js/dist/es-ec/office_strings.js +8 -0
  146. xlwings_server/static/vendor/@microsoft/office-js/dist/es-es/office_strings.js +1 -0
  147. xlwings_server/static/vendor/@microsoft/office-js/dist/es-gt/office_strings.js +8 -0
  148. xlwings_server/static/vendor/@microsoft/office-js/dist/es-hn/office_strings.js +8 -0
  149. xlwings_server/static/vendor/@microsoft/office-js/dist/es-mx/office_strings.js +1 -0
  150. xlwings_server/static/vendor/@microsoft/office-js/dist/es-ni/office_strings.js +8 -0
  151. xlwings_server/static/vendor/@microsoft/office-js/dist/es-pa/office_strings.js +8 -0
  152. xlwings_server/static/vendor/@microsoft/office-js/dist/es-pe/office_strings.js +8 -0
  153. xlwings_server/static/vendor/@microsoft/office-js/dist/es-pr/office_strings.js +8 -0
  154. xlwings_server/static/vendor/@microsoft/office-js/dist/es-py/office_strings.js +8 -0
  155. xlwings_server/static/vendor/@microsoft/office-js/dist/es-sv/office_strings.js +8 -0
  156. xlwings_server/static/vendor/@microsoft/office-js/dist/es-us/office_strings.js +8 -0
  157. xlwings_server/static/vendor/@microsoft/office-js/dist/es-uy/office_strings.js +8 -0
  158. xlwings_server/static/vendor/@microsoft/office-js/dist/es-ve/office_strings.js +8 -0
  159. xlwings_server/static/vendor/@microsoft/office-js/dist/es6-promise.js +5 -0
  160. xlwings_server/static/vendor/@microsoft/office-js/dist/et-ee/office_strings.js +1 -0
  161. xlwings_server/static/vendor/@microsoft/office-js/dist/eu-es/office_strings.js +1 -0
  162. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-15.01.js +11 -0
  163. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-15.02.js +11 -0
  164. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-15.js +11 -0
  165. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-mac-16.00-core.js +11 -0
  166. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-mac-16.00.js +25 -0
  167. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-web-16.00-core.js +11 -0
  168. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-web-16.00.js +25 -0
  169. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-win32-16.00.js +19 -0
  170. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-win32-16.01-core.js +11 -0
  171. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-win32-16.01.js +25 -0
  172. xlwings_server/static/vendor/@microsoft/office-js/dist/excel-winrt-16.00.js +25 -0
  173. xlwings_server/static/vendor/@microsoft/office-js/dist/excelios-15.js +11 -0
  174. xlwings_server/static/vendor/@microsoft/office-js/dist/excelwebapp-15.01.js +11 -0
  175. xlwings_server/static/vendor/@microsoft/office-js/dist/excelwebapp-15.02.js +11 -0
  176. xlwings_server/static/vendor/@microsoft/office-js/dist/excelwebapp-15.js +11 -0
  177. xlwings_server/static/vendor/@microsoft/office-js/dist/fa-ir/office_strings.js +1 -0
  178. xlwings_server/static/vendor/@microsoft/office-js/dist/fi-fi/office_strings.js +1 -0
  179. xlwings_server/static/vendor/@microsoft/office-js/dist/fil-ph/office_strings.js +1 -0
  180. xlwings_server/static/vendor/@microsoft/office-js/dist/fr-be/office_strings.js +8 -0
  181. xlwings_server/static/vendor/@microsoft/office-js/dist/fr-ca/office_strings.js +1 -0
  182. xlwings_server/static/vendor/@microsoft/office-js/dist/fr-ch/office_strings.js +8 -0
  183. xlwings_server/static/vendor/@microsoft/office-js/dist/fr-fr/office_strings.js +1 -0
  184. xlwings_server/static/vendor/@microsoft/office-js/dist/fr-lu/office_strings.js +8 -0
  185. xlwings_server/static/vendor/@microsoft/office-js/dist/fr-mc/office_strings.js +8 -0
  186. xlwings_server/static/vendor/@microsoft/office-js/dist/ga-ie/office_strings.js +8 -0
  187. xlwings_server/static/vendor/@microsoft/office-js/dist/gl-es/office_strings.js +1 -0
  188. xlwings_server/static/vendor/@microsoft/office-js/dist/gu-in/office_strings.js +1 -0
  189. xlwings_server/static/vendor/@microsoft/office-js/dist/he-il/office_strings.js +1 -0
  190. xlwings_server/static/vendor/@microsoft/office-js/dist/hi-in/office_strings.js +1 -0
  191. xlwings_server/static/vendor/@microsoft/office-js/dist/hr-ba/office_strings.js +8 -0
  192. xlwings_server/static/vendor/@microsoft/office-js/dist/hr-hr/office_strings.js +1 -0
  193. xlwings_server/static/vendor/@microsoft/office-js/dist/html2canvas.js +8 -0
  194. xlwings_server/static/vendor/@microsoft/office-js/dist/hu-hu/office_strings.js +1 -0
  195. xlwings_server/static/vendor/@microsoft/office-js/dist/hy-am/office_strings.js +8 -0
  196. xlwings_server/static/vendor/@microsoft/office-js/dist/id-id/office_strings.js +1 -0
  197. xlwings_server/static/vendor/@microsoft/office-js/dist/is-is/office_strings.js +1 -0
  198. xlwings_server/static/vendor/@microsoft/office-js/dist/it-ch/office_strings.js +8 -0
  199. xlwings_server/static/vendor/@microsoft/office-js/dist/it-it/office_strings.js +1 -0
  200. xlwings_server/static/vendor/@microsoft/office-js/dist/ja-jp/office_strings.js +1 -0
  201. xlwings_server/static/vendor/@microsoft/office-js/dist/ka-ge/office_strings.js +8 -0
  202. xlwings_server/static/vendor/@microsoft/office-js/dist/kk-kz/office_strings.js +1 -0
  203. xlwings_server/static/vendor/@microsoft/office-js/dist/km-kh/office_strings.js +8 -0
  204. xlwings_server/static/vendor/@microsoft/office-js/dist/kn-in/office_strings.js +1 -0
  205. xlwings_server/static/vendor/@microsoft/office-js/dist/ko-kr/office_strings.js +1 -0
  206. xlwings_server/static/vendor/@microsoft/office-js/dist/lb-lu/office_strings.js +8 -0
  207. xlwings_server/static/vendor/@microsoft/office-js/dist/lo-la/office_strings.js +1 -0
  208. xlwings_server/static/vendor/@microsoft/office-js/dist/lt-lt/office_strings.js +1 -0
  209. xlwings_server/static/vendor/@microsoft/office-js/dist/lv-lv/office_strings.js +1 -0
  210. xlwings_server/static/vendor/@microsoft/office-js/dist/mk-mk/office_strings.js +8 -0
  211. xlwings_server/static/vendor/@microsoft/office-js/dist/ml-in/office_strings.js +1 -0
  212. xlwings_server/static/vendor/@microsoft/office-js/dist/mn-mn/office_strings.js +8 -0
  213. xlwings_server/static/vendor/@microsoft/office-js/dist/mr-in/office_strings.js +1 -0
  214. xlwings_server/static/vendor/@microsoft/office-js/dist/ms-bn/office_strings.js +8 -0
  215. xlwings_server/static/vendor/@microsoft/office-js/dist/ms-my/office_strings.js +1 -0
  216. xlwings_server/static/vendor/@microsoft/office-js/dist/mt-mt/office_strings.js +8 -0
  217. xlwings_server/static/vendor/@microsoft/office-js/dist/nb-no/office_strings.js +1 -0
  218. xlwings_server/static/vendor/@microsoft/office-js/dist/ne-np/office_strings.js +8 -0
  219. xlwings_server/static/vendor/@microsoft/office-js/dist/nl-be/office_strings.js +8 -0
  220. xlwings_server/static/vendor/@microsoft/office-js/dist/nl-nl/office_strings.js +1 -0
  221. xlwings_server/static/vendor/@microsoft/office-js/dist/nn-no/office_strings.js +1 -0
  222. xlwings_server/static/vendor/@microsoft/office-js/dist/o15apptofilemappingtable.js +11 -0
  223. xlwings_server/static/vendor/@microsoft/office-js/dist/office-vsdoc.js +28596 -0
  224. xlwings_server/static/vendor/@microsoft/office-js/dist/office.js +84 -0
  225. xlwings_server/static/vendor/@microsoft/office-js/dist/pl-pl/office_strings.js +1 -0
  226. xlwings_server/static/vendor/@microsoft/office-js/dist/pt-br/office_strings.js +1 -0
  227. xlwings_server/static/vendor/@microsoft/office-js/dist/pt-pt/office_strings.js +1 -0
  228. xlwings_server/static/vendor/@microsoft/office-js/dist/ro-ro/office_strings.js +1 -0
  229. xlwings_server/static/vendor/@microsoft/office-js/dist/ru-ru/office_strings.js +1 -0
  230. xlwings_server/static/vendor/@microsoft/office-js/dist/si-lk/office_strings.js +8 -0
  231. xlwings_server/static/vendor/@microsoft/office-js/dist/sk-sk/office_strings.js +1 -0
  232. xlwings_server/static/vendor/@microsoft/office-js/dist/sl-si/office_strings.js +1 -0
  233. xlwings_server/static/vendor/@microsoft/office-js/dist/sq-al/office_strings.js +8 -0
  234. xlwings_server/static/vendor/@microsoft/office-js/dist/sr-cyrl-cs/office_strings.js +1 -0
  235. xlwings_server/static/vendor/@microsoft/office-js/dist/sr-cyrl-rs/office_strings.js +1 -0
  236. xlwings_server/static/vendor/@microsoft/office-js/dist/sr-latn-cs/office_strings.js +1 -0
  237. xlwings_server/static/vendor/@microsoft/office-js/dist/sr-latn-rs/office_strings.js +1 -0
  238. xlwings_server/static/vendor/@microsoft/office-js/dist/sv-fi/office_strings.js +8 -0
  239. xlwings_server/static/vendor/@microsoft/office-js/dist/sv-se/office_strings.js +1 -0
  240. xlwings_server/static/vendor/@microsoft/office-js/dist/sw-ke/office_strings.js +1 -0
  241. xlwings_server/static/vendor/@microsoft/office-js/dist/ta-in/office_strings.js +1 -0
  242. xlwings_server/static/vendor/@microsoft/office-js/dist/te-in/office_strings.js +1 -0
  243. xlwings_server/static/vendor/@microsoft/office-js/dist/telemetry/oteljs.js +1 -0
  244. xlwings_server/static/vendor/@microsoft/office-js/dist/telemetry/oteljs_agave.js +1 -0
  245. xlwings_server/static/vendor/@microsoft/office-js/dist/th-th/office_strings.js +1 -0
  246. xlwings_server/static/vendor/@microsoft/office-js/dist/tr-tr/office_strings.js +1 -0
  247. xlwings_server/static/vendor/@microsoft/office-js/dist/uk-ua/office_strings.js +1 -0
  248. xlwings_server/static/vendor/@microsoft/office-js/dist/ur-pk/office_strings.js +1 -0
  249. xlwings_server/static/vendor/@microsoft/office-js/dist/vi-vn/office_strings.js +1 -0
  250. xlwings_server/static/vendor/@microsoft/office-js/dist/webauth/webauth.browserauth.js +77 -0
  251. xlwings_server/static/vendor/@microsoft/office-js/dist/webauth/webauth.implicit.js +35 -0
  252. xlwings_server/static/vendor/@microsoft/office-js/dist/zh-cn/office_strings.js +1 -0
  253. xlwings_server/static/vendor/@microsoft/office-js/dist/zh-hk/office_strings.js +8 -0
  254. xlwings_server/static/vendor/@microsoft/office-js/dist/zh-mo/office_strings.js +8 -0
  255. xlwings_server/static/vendor/@microsoft/office-js/dist/zh-sg/office_strings.js +8 -0
  256. xlwings_server/static/vendor/@microsoft/office-js/dist/zh-tw/office_strings.js +1 -0
  257. xlwings_server/static/vendor/axios/dist/axios.min.js +3 -0
  258. xlwings_server/static/vendor/axios/dist/axios.min.js.map +1 -0
  259. xlwings_server/static/vendor/bootstrap/LICENSE +21 -0
  260. xlwings_server/static/vendor/bootstrap/dist/js/bootstrap.bundle.min.js +7 -0
  261. xlwings_server/static/vendor/bootstrap/dist/js/bootstrap.bundle.min.js.map +1 -0
  262. xlwings_server/static/vendor/bootstrap-xlwings/dist/bootstrap-xlwings.min.css +12 -0
  263. xlwings_server/static/vendor/bootstrap-xlwings/dist/bootstrap-xlwings.min.css.map +1 -0
  264. xlwings_server/static/vendor/htmx-ext-head-support/head-support.js +144 -0
  265. xlwings_server/static/vendor/htmx-ext-loading-states/loading-states.js +184 -0
  266. xlwings_server/static/vendor/htmx.org/LICENSE +13 -0
  267. xlwings_server/static/vendor/htmx.org/dist/htmx.min.js +1 -0
  268. xlwings_server/static/vendor/socket.io/LICENSE +22 -0
  269. xlwings_server/static/vendor/socket.io/client-dist/socket.io.min.js +7 -0
  270. xlwings_server/static/vendor/socket.io/client-dist/socket.io.min.js.map +1 -0
  271. xlwings_server/templates/_book.html +8 -0
  272. xlwings_server/templates/alert_base.html +16 -0
  273. xlwings_server/templates/base.html +117 -0
  274. xlwings_server/templates/examples/alpine/README.md +26 -0
  275. xlwings_server/templates/examples/alpine/taskpane.html +47 -0
  276. xlwings_server/templates/examples/auth/README.md +38 -0
  277. xlwings_server/templates/examples/auth/protected.html +8 -0
  278. xlwings_server/templates/examples/auth/public.html +11 -0
  279. xlwings_server/templates/examples/excel_object_model/README.md +49 -0
  280. xlwings_server/templates/examples/excel_object_model/add_name_form.html +27 -0
  281. xlwings_server/templates/examples/hello_world/README.md +9 -0
  282. xlwings_server/templates/examples/hello_world/taskpane_hello.html +24 -0
  283. xlwings_server/templates/examples/htmx_form/README.md +44 -0
  284. xlwings_server/templates/examples/htmx_form/_greeting.html +6 -0
  285. xlwings_server/templates/examples/htmx_form/taskpane_htmx_form.html +21 -0
  286. xlwings_server/templates/examples/live_form_validation/README.md +60 -0
  287. xlwings_server/templates/examples/live_form_validation/add_name_form.html +33 -0
  288. xlwings_server/templates/examples/multi_app/README.md +34 -0
  289. xlwings_server/templates/examples/multi_app/taskpane1.html +7 -0
  290. xlwings_server/templates/examples/multi_app/taskpane2.html +7 -0
  291. xlwings_server/templates/examples/multi_app/taskpane_loader.html +5 -0
  292. xlwings_server/templates/examples/navigation/README.md +28 -0
  293. xlwings_server/templates/examples/navigation/_navigation.html +16 -0
  294. xlwings_server/templates/examples/navigation/taskpane_one.html +8 -0
  295. xlwings_server/templates/examples/navigation/taskpane_three.html +8 -0
  296. xlwings_server/templates/examples/navigation/taskpane_two.html +8 -0
  297. xlwings_server/templates/examples/pictures/README.md +42 -0
  298. xlwings_server/templates/examples/pictures/_picture.html +4 -0
  299. xlwings_server/templates/examples/pictures/taskpane_pictures.html +26 -0
  300. xlwings_server/templates/manifest.xml +155 -0
  301. xlwings_server/templates/taskpane.html +1 -0
  302. xlwings_server/templates/xlwings_alert.html +27 -0
  303. xlwings_server/templates.py +61 -0
  304. xlwings_server/utils.py +32 -0
  305. xlwings_server/wasm/__init__.py +0 -0
  306. xlwings_server/wasm/config.py +24 -0
  307. xlwings_server/wasm/main.py +236 -0
  308. xlwings_server/wasm/requirements.txt +5 -0
  309. xlwings_server-1.1.0.dist-info/METADATA +61 -0
  310. xlwings_server-1.1.0.dist-info/RECORD +313 -0
  311. xlwings_server-1.1.0.dist-info/WHEEL +4 -0
  312. xlwings_server-1.1.0.dist-info/entry_points.txt +2 -0
  313. xlwings_server-1.1.0.dist-info/licenses/LICENSE.md +223 -0
@@ -0,0 +1,8 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block content %}
4
+ <div class="container-fluid ps-3">
5
+ {% include "examples/navigation/_navigation.html" %}
6
+ <h1>This is Page 3</h1>
7
+ </div>
8
+ {% endblock content %}
@@ -0,0 +1,8 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block content %}
4
+ <div class="container-fluid ps-3">
5
+ {% include "examples/navigation/_navigation.html" %}
6
+ <h1>This is Page 2</h1>
7
+ </div>
8
+ {% endblock content %}
@@ -0,0 +1,42 @@
1
+ # Pictures via htmx and Bootstrap dropdown
2
+
3
+ This sample populates a Bootstrap dropdown (see https://getbootstrap.com/docs/5.3/components/dropdowns/#single-button) with the names of the png pictures in the `app/static/images/ribbon/examples` directory.
4
+ When you select a picture name from the dropdown, it displays it below.
5
+
6
+ To try it out, replace `app/routers/taskpane.py` with the following code:
7
+
8
+ ```python
9
+ from fastapi import APIRouter, Form, Request
10
+
11
+ from ..config import settings
12
+ from ..templates import TemplateResponse
13
+
14
+ router = APIRouter(prefix=settings.app_path)
15
+
16
+
17
+ @router.get("/taskpane")
18
+ @router.get("/taskpane.html")
19
+ async def taskpane(request: Request):
20
+ directory = settings.static_dir / "images" / "ribbon" / "examples"
21
+ picture_names = []
22
+ for path in directory.glob("*.png"):
23
+ picture_names.append(path.name)
24
+ return TemplateResponse(
25
+ request=request,
26
+ name="examples/pictures/taskpane_pictures.html",
27
+ context={"picture_names": picture_names},
28
+ )
29
+
30
+
31
+ @router.post("/picture")
32
+ async def picture(request: Request, picture_name: str = Form(None)):
33
+ return TemplateResponse(
34
+ request=request,
35
+ name="examples/pictures/_picture.html",
36
+ context={"picture_name": picture_name},
37
+ )
38
+ ```
39
+
40
+ This sample also depends on:
41
+
42
+ - pictures in `app/static/images/ribbon/examples`
@@ -0,0 +1,4 @@
1
+ <img
2
+ src="{{ url_for('static', path='/images/ribbon/examples/' + picture_name) }}"
3
+ class="img-fluid"
4
+ alt="{{ picture_name }}" />
@@ -0,0 +1,26 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block content %}
4
+ <div class="container-fluid pt-3 ps-3">
5
+ <h1>A picture is worth a thousand words</h1>
6
+ <div class="dropdown">
7
+ <button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
8
+ Select a picture
9
+ </button>
10
+ <ul class="dropdown-menu">
11
+ {% for name in picture_names %}
12
+ <li>
13
+ <a
14
+ class="dropdown-item"
15
+ hx-post="{{ url_for('picture') }}"
16
+ hx-target="#picture"
17
+ hx-vals='{"picture_name": "{{ name }}"}'
18
+ >{{ name }}</a
19
+ >
20
+ </li>
21
+ {% endfor %}
22
+ </ul>
23
+ </div>
24
+ <div id="picture" class="mt-4"></div>
25
+ </div>
26
+ {% endblock content %}
@@ -0,0 +1,155 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
5
+ xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
6
+ <Id>{{ manifest_id }}</Id>
7
+ <Version>1.0.0.0</Version>
8
+ <ProviderName>xlwings</ProviderName>
9
+ <DefaultLocale>en-US</DefaultLocale>
10
+ <DisplayName DefaultValue="{{ settings.project_name }}{{ ' [' + settings.environment + ']' if settings.environment != 'prod'}}" />
11
+ <Description DefaultValue="{{ settings.project_name }}{{ ' [' + settings.environment + ']' if settings.environment != 'prod'}}" />
12
+ <IconUrl DefaultValue="{{ base_url }}{{ settings.static_url_path }}/images/xlwings-32.png" />
13
+ <HighResolutionIconUrl DefaultValue="{{ base_url }}{{ settings.static_url_path }}/images/xlwings-64.png" />
14
+ <SupportUrl DefaultValue="https://www.xlwings.org/contact" />
15
+ <AppDomains>
16
+ <AppDomain>{{ base_url_with_app_path }}</AppDomain>
17
+ </AppDomains>
18
+ <Hosts>
19
+ <Host Name="Workbook" />
20
+ </Hosts>
21
+ <!-- SharedRuntime for Custom Functions -->
22
+ <Requirements>
23
+ <Sets DefaultMinVersion="1.1">
24
+ <Set Name="SharedRuntime" MinVersion="1.1" />
25
+ </Sets>
26
+ </Requirements>
27
+ <DefaultSettings>
28
+ <SourceLocation DefaultValue="{{ base_url_with_app_path }}/taskpane.html" />
29
+ </DefaultSettings>
30
+ <Permissions>ReadWriteDocument</Permissions>
31
+ <VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
32
+ <Hosts>
33
+ <Host xsi:type="Workbook">
34
+ <!-- Custom Functions -->
35
+ <Runtimes>
36
+ <Runtime resid="Taskpane.Url" lifetime="long" />
37
+ </Runtimes>
38
+ <AllFormFactors>
39
+ <ExtensionPoint xsi:type="CustomFunctions">
40
+ <Script>
41
+ <SourceLocation resid="Functions.Script.Url" />
42
+ </Script>
43
+ <Page>
44
+ <SourceLocation resid="Taskpane.Url" />
45
+ </Page>
46
+ <Metadata>
47
+ <SourceLocation resid="Functions.Metadata.Url" />
48
+ </Metadata>
49
+ {% if settings.functions_namespace or settings.environment != 'prod' %}
50
+ <Namespace resid="Functions.Namespace" />
51
+ {% endif %}
52
+ </ExtensionPoint>
53
+ </AllFormFactors>
54
+
55
+ <DesktopFormFactor>
56
+ <!-- FunctionFile is used to bind functions directly to Ribbon buttons -->
57
+ <FunctionFile resid="Taskpane.Url" />
58
+ <ExtensionPoint xsi:type="PrimaryCommandSurface">
59
+ <CustomTab id="MyTab">
60
+ <Group id="MyCommandsGroup">
61
+ <Label resid="MyCommandsGroup.Label" />
62
+ <Icon>
63
+ <bt:Image size="16" resid="Icon.16x16" />
64
+ <bt:Image size="32" resid="Icon.32x32" />
65
+ <bt:Image size="80" resid="Icon.80x80" />
66
+ </Icon>
67
+
68
+ <!-- Ribbon button that calls a function -->
69
+ <Control xsi:type="Button" id="MyFunctionButton">
70
+ <!-- Label for your button. resid must point to a ShortString resource -->
71
+ <Label resid="MyFunctionButton.Label" />
72
+ <Supertip>
73
+ <!-- ToolTip title. resid must point to a ShortString resource -->
74
+ <Title resid="MyFunctionButton.Label" />
75
+ <!-- ToolTip description. resid must point to a LongString resource -->
76
+ <Description resid="MyFunctionButton.Tooltip" />
77
+ </Supertip>
78
+ <Icon>
79
+ <bt:Image size="16" resid="Icon.16x16" />
80
+ <bt:Image size="32" resid="Icon.32x32" />
81
+ <bt:Image size="80" resid="Icon.80x80" />
82
+ </Icon>
83
+ <!--Action type must be ExecuteFunction -->
84
+ <Action xsi:type="ExecuteFunction">
85
+ <!-- This is the name that you use in Office.actions.associate() to connect it to a function -->
86
+ <FunctionName>hello-ribbon</FunctionName>
87
+ </Action>
88
+ </Control>
89
+
90
+ <!-- Ribbon button that opens the task pane -->
91
+ <Control xsi:type="Button" id="MyTaskpaneButton">
92
+ <Label resid="MyTaskpaneButton.Label" />
93
+ <Supertip>
94
+ <Title resid="MyTaskpaneButton.Label" />
95
+ <Description resid="MyTaskpaneButton.Tooltip" />
96
+ </Supertip>
97
+ <Icon>
98
+ <bt:Image size="16" resid="Icon.16x16" />
99
+ <bt:Image size="32" resid="Icon.32x32" />
100
+ <bt:Image size="80" resid="Icon.80x80" />
101
+ </Icon>
102
+ <!-- Action type must be ShowTaskpane -->
103
+ <Action xsi:type="ShowTaskpane">
104
+ <TaskpaneId>ButtonId1</TaskpaneId>
105
+ <!-- resid must point to a Url Resource -->
106
+ <SourceLocation resid="Taskpane.Url" />
107
+ </Action>
108
+ </Control>
109
+ </Group>
110
+ <Label resid="MyTab.TabLabel" />
111
+ </CustomTab>
112
+ </ExtensionPoint>
113
+ </DesktopFormFactor>
114
+ </Host>
115
+ </Hosts>
116
+
117
+ <Resources>
118
+ <bt:Images>
119
+ <bt:Image id="Icon.16x16" DefaultValue="{{ base_url }}{{ settings.static_url_path }}/images/xlwings-16.png" />
120
+ <bt:Image id="Icon.32x32" DefaultValue="{{ base_url }}{{ settings.static_url_path }}/images/xlwings-32.png" />
121
+ <bt:Image id="Icon.80x80" DefaultValue="{{ base_url }}{{ settings.static_url_path }}/images/xlwings-80.png" />
122
+ </bt:Images>
123
+ <bt:Urls>
124
+ <!-- This must point to the HTML document with the task pane -->
125
+ <bt:Url id="Taskpane.Url" DefaultValue="{{ base_url_with_app_path }}/taskpane.html" />
126
+ <bt:Url id="Functions.Script.Url" DefaultValue="{{ base_url_with_app_path }}/xlwings/custom-functions-code.js" />
127
+ <bt:Url id="Functions.Metadata.Url" DefaultValue="{{ base_url_with_app_path }}/xlwings/custom-functions-meta.json" />
128
+ </bt:Urls>
129
+ <bt:ShortStrings>
130
+ {% if settings.functions_namespace or settings.environment != 'prod' %}
131
+ <bt:String id="Functions.Namespace" DefaultValue="{{ settings.functions_namespace|upper }}{{ '_' if settings.functions_namespace and settings.environment != 'prod'}}{{ settings.environment|upper if settings.environment != 'prod'}}" />
132
+ {% endif %}
133
+ <bt:String id="MyTab.TabLabel" DefaultValue="{{ settings.project_name }}{{ ' [' + settings.environment + ']' if settings.environment != 'prod'}}" />
134
+ <bt:String id="MyCommandsGroup.Label" DefaultValue="MyGroup" />
135
+ <bt:String id="MyFunctionButton.Label" DefaultValue="Hello World" />
136
+ <bt:String id="MyTaskpaneButton.Label" DefaultValue="Show Taskpane" />
137
+ </bt:ShortStrings>
138
+ <bt:LongStrings>
139
+ <bt:String id="MyFunctionButton.Tooltip" DefaultValue="Click to call the hello function" />
140
+ <bt:String id="MyTaskpaneButton.Tooltip" DefaultValue="Click to show the task pane" />
141
+ </bt:LongStrings>
142
+ </Resources>
143
+
144
+ {% if "entraid" in settings.auth_providers %}
145
+ <WebApplicationInfo>
146
+ <Id>{{ settings.auth_entraid_client_id }}</Id>
147
+ <Resource>api://{{ base_url_with_app_path|replace("https://", "") }}/{{ settings.auth_entraid_client_id }}</Resource>
148
+ <Scopes>
149
+ <Scope>openid</Scope>
150
+ <Scope>profile</Scope>
151
+ </Scopes>
152
+ </WebApplicationInfo>
153
+ {% endif %}
154
+ </VersionOverrides>
155
+ </OfficeApp>
@@ -0,0 +1 @@
1
+ {% extends "base.html" %}
@@ -0,0 +1,27 @@
1
+ {% extends "alert_base.html" %}
2
+
3
+ {% block content %}
4
+ <div id="callback" data-callback="{{ callback }}"></div>
5
+ <div class="container-fluid">
6
+ <div class="d-flex flex-column pb-3 px-2 vh-100">
7
+ <h1 class="pt-4">{{ title }}</h1>
8
+ <p>{{ prompt|replace("\n", "<br>"|safe) }}</p>
9
+ <div class="mt-auto">
10
+ <div class="float-end">
11
+ {% if "ok" in buttons %}
12
+ <button id="ok" type="button" class="btn btn-primary btn-xl-alert">OK</button>
13
+ {% endif %}
14
+ {% if "yes" in buttons %}
15
+ <button id="yes" type="button" class="btn btn-primary btn-xl-alert">Yes</button>
16
+ {% endif %}
17
+ {% if "no" in buttons %}
18
+ <button id="no" type="button" class="btn btn-outline-secondary btn-xl-alert">No</button>
19
+ {% endif %}
20
+ {% if "cancel" in buttons %}
21
+ <button id="cancel" type="button" class="btn btn-outline-secondary btn-xl-alert">Cancel</button>
22
+ {% endif %}
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ {% endblock content %}
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ from fastapi import Request
6
+ from jinja2 import ChoiceLoader, FileSystemLoader
7
+ from jinja2_fragments.fastapi import Jinja2Blocks
8
+ from starlette.background import BackgroundTask
9
+
10
+ from xlwings_server.config import PACKAGE_DIR, PROJECT_DIR, settings
11
+
12
+ # Create Jinja2 loader that checks dist templates first (if exists),
13
+ # then project templates, then package templates
14
+ loaders = []
15
+ dist_templates = PROJECT_DIR / "dist" / "templates"
16
+ if dist_templates.exists() and settings.environment != "dev":
17
+ loaders.append(FileSystemLoader(dist_templates))
18
+ loaders.extend(
19
+ [
20
+ FileSystemLoader(PROJECT_DIR / "templates"),
21
+ FileSystemLoader(PACKAGE_DIR / "templates"),
22
+ ]
23
+ )
24
+ loader = ChoiceLoader(loaders)
25
+
26
+
27
+ templates = Jinja2Blocks(
28
+ directory=PROJECT_DIR / "templates",
29
+ loader=loader,
30
+ trim_blocks=True,
31
+ lstrip_blocks=True,
32
+ )
33
+
34
+
35
+ # Align with FastAPIs changes to the function signature
36
+ def TemplateResponse(
37
+ request: Request,
38
+ name: str,
39
+ context: dict[str, typing.Any] | None = None,
40
+ status_code: int = 200,
41
+ headers: typing.Mapping[str, str] | None = None,
42
+ media_type: str | None = None,
43
+ background: BackgroundTask | None = None,
44
+ block_names: str | list[str] | None = None,
45
+ **kwargs: typing.Any,
46
+ ):
47
+ if context is None:
48
+ context = {}
49
+ context["request"] = request
50
+ context["settings"] = settings
51
+ return templates.TemplateResponse(
52
+ name,
53
+ context,
54
+ status_code,
55
+ headers,
56
+ media_type,
57
+ background,
58
+ block_name=block_names if isinstance(block_names, str) else None,
59
+ block_names=block_names if isinstance(block_names, list) else [],
60
+ **kwargs,
61
+ )
@@ -0,0 +1,32 @@
1
+ import logging
2
+
3
+ import redis
4
+
5
+ from . import object_handles
6
+ from .config import settings
7
+ from .routers import socketio as socketio_router, xlwings as xlwings_router
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ async def trigger_script(script, **options):
13
+ sid = xlwings_router.socketio_id_context.get()
14
+ if not isinstance(script, str):
15
+ script = script.__name__
16
+ await socketio_router.sio.emit(
17
+ "xlwings:trigger-script",
18
+ {"script_name": script, **options},
19
+ to=sid,
20
+ )
21
+ logger.info(f"Script '{script}' triggered for sid '{sid}' with config: {options}")
22
+
23
+
24
+ async def clear_object_cache():
25
+ if settings.object_cache_url:
26
+ redis_client: redis.Redis = xlwings_router.redis_client_context.get()
27
+ keys = redis_client.scan_iter(match="object:*")
28
+ for key in keys:
29
+ redis_client.delete(key)
30
+ logger.info("Cleared all keys starting with 'object:' from the Redis cache")
31
+ else:
32
+ object_handles.cache = {}
File without changes
@@ -0,0 +1,24 @@
1
+ import os
2
+
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv(".env")
6
+
7
+ # xlwings depends on this, so set before importing xlwings
8
+ os.environ["XLWINGS_ON_SERVER"] = "true"
9
+
10
+
11
+ def read_bool(env_name: str, default: str = "false") -> bool:
12
+ return os.getenv(env_name, default).lower() == "true"
13
+
14
+
15
+ class Settings:
16
+ enable_examples: bool = read_bool("XLWINGS_ENABLE_EXAMPLES")
17
+ enable_wasm: bool = True
18
+ enable_tests: bool = read_bool("XLWINGS_ENABLE_TESTS")
19
+ environment: str = os.getenv("XLWINGS_ENVIRONMENT", "prod")
20
+ functions_namespace: str = os.getenv("XLWINGS_FUNCTIONS_NAMESPACE", "XLWINGS")
21
+ is_official_lite_addin: bool = read_bool("XLWINGS_IS_OFFICIAL_LITE_ADDIN")
22
+
23
+
24
+ settings = Settings()
@@ -0,0 +1,236 @@
1
+ from config import settings # noqa: F401, I001 Must be first import to load env vars
2
+ import platform
3
+ import traceback
4
+ import importlib.util
5
+ import sys
6
+ import contextlib
7
+ from io import StringIO
8
+ import ast
9
+ import inspect
10
+ from textwrap import dedent
11
+
12
+ import custom_functions
13
+ import custom_scripts
14
+ import js # type: ignore
15
+ import pyodide_js # type: ignore
16
+ import xlwings as xw
17
+ import xlwings.server
18
+ from pyodide.ffi import to_js # type: ignore
19
+
20
+ try:
21
+ import matplotlib as mpl
22
+
23
+ mpl.use("agg")
24
+ except ImportError:
25
+ mpl = None
26
+
27
+
28
+ # xlwings <0.33.13 doesn't have custom_scripts_meta
29
+ if not hasattr(xlwings.server, "custom_scripts_meta"):
30
+ xlwings.server.custom_scripts_meta = lambda module: []
31
+
32
+
33
+ class HtmlOutput:
34
+ def __init__(self, div_id):
35
+ self.div_id = div_id
36
+ self.buffer = StringIO()
37
+
38
+ def write(self, text):
39
+ self.buffer.write(text)
40
+ content = self.buffer.getvalue()
41
+ div = js.document.getElementById(self.div_id)
42
+ if div:
43
+ js.document.getElementById(self.div_id).innerHTML = f"<pre>{content}</pre>"
44
+ # Scroll to bottom
45
+ outputContainer = js.document.querySelector("#output-container")
46
+ if outputContainer:
47
+ outputContainer.scrollTop = outputContainer.scrollHeight
48
+
49
+ def flush(self):
50
+ pass
51
+
52
+
53
+ if settings.is_official_lite_addin:
54
+ html_output = HtmlOutput("output")
55
+ try:
56
+ import pyodide_http # type: ignore
57
+ except ImportError:
58
+ pyodide_http = None
59
+ if pyodide_http:
60
+ pyodide_http.patch_all() # Fixes pd.read_csv()
61
+
62
+
63
+ # Print Python and Pyodide versions
64
+ def print_versions():
65
+ if settings.is_official_lite_addin:
66
+ html_output = HtmlOutput("output")
67
+ with (
68
+ contextlib.redirect_stdout(html_output),
69
+ contextlib.redirect_stderr(html_output),
70
+ ):
71
+ print(
72
+ f"Python {platform.python_version()}|Pyodide {pyodide_js.version}|xlwings {xw.__version__}"
73
+ )
74
+
75
+
76
+ def create_module_from_string(module_string, module_name, html_output=None):
77
+ spec = importlib.util.spec_from_loader(
78
+ module_name,
79
+ loader=None,
80
+ )
81
+ module = importlib.util.module_from_spec(spec)
82
+ if html_output:
83
+ with (
84
+ contextlib.redirect_stdout(html_output),
85
+ contextlib.redirect_stderr(html_output),
86
+ ):
87
+ exec(module_string, module.__dict__)
88
+ else:
89
+ exec(module_string, module.__dict__)
90
+ sys.modules[module_name] = module
91
+ return module
92
+
93
+
94
+ async def custom_functions_call(data):
95
+ if settings.is_official_lite_addin:
96
+ import main_editor
97
+
98
+ module = main_editor
99
+ else:
100
+ module = custom_functions
101
+
102
+ data = data.to_py()
103
+ try:
104
+ if settings.is_official_lite_addin:
105
+ with (
106
+ contextlib.redirect_stdout(html_output),
107
+ contextlib.redirect_stderr(html_output),
108
+ ):
109
+ result = await xlwings.server.custom_functions_call(
110
+ data,
111
+ module=module,
112
+ )
113
+ else:
114
+ result = await xlwings.server.custom_functions_call(
115
+ data,
116
+ module=module,
117
+ )
118
+ except Exception as e:
119
+ result = {"error": str(e), "details": traceback.format_exc()}
120
+ # Note: converts None to undefined
121
+ return to_js(result, dict_converter=js.Object.fromEntries)
122
+
123
+
124
+ async def custom_scripts_call(data, script_name):
125
+ if settings.is_official_lite_addin:
126
+ import main_editor
127
+
128
+ module = main_editor
129
+ else:
130
+ module = custom_scripts
131
+
132
+ book = xw.Book(json=data.to_py())
133
+ try:
134
+ if settings.is_official_lite_addin:
135
+ with (
136
+ contextlib.redirect_stdout(html_output),
137
+ contextlib.redirect_stderr(html_output),
138
+ ):
139
+ book = await xlwings.server.custom_scripts_call(
140
+ module=module,
141
+ script_name=script_name,
142
+ typehint_to_value={xw.Book: book},
143
+ )
144
+ else:
145
+ book = await xlwings.server.custom_scripts_call(
146
+ module=module,
147
+ script_name=script_name,
148
+ typehint_to_value={xw.Book: book},
149
+ )
150
+ result = book.json()
151
+ return to_js(result, dict_converter=js.Object.fromEntries)
152
+ except Exception as e:
153
+ error_traceback = traceback.format_exc()
154
+ if settings.is_official_lite_addin:
155
+ error_output = HtmlOutput(
156
+ "output"
157
+ ) # Clear output before writing out an error
158
+ error_output.write(f'<span style="color: red">{error_traceback}</span>')
159
+ return to_js({"actions": []}, dict_converter=js.Object.fromEntries)
160
+ else:
161
+ result = {"error": str(e), "details": error_traceback}
162
+ return to_js(result, dict_converter=js.Object.fromEntries)
163
+
164
+
165
+ def custom_scripts_meta():
166
+ if settings.is_official_lite_addin:
167
+ import main_editor
168
+
169
+ module = main_editor
170
+ else:
171
+ module = custom_scripts
172
+ scripts_meta = xlwings.server.custom_scripts_meta(module)
173
+ return to_js(scripts_meta, dict_converter=js.Object.fromEntries)
174
+
175
+
176
+ def get_xlwings_scripts(code_string, script_button_text):
177
+ try:
178
+ tree = ast.parse(code_string)
179
+ except: # noqa: E722
180
+ return to_js([script_button_text])
181
+ xlwings_functions = []
182
+
183
+ for node in ast.walk(tree):
184
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
185
+ for decorator in node.decorator_list:
186
+ decorator_str = ast.unparse(decorator)
187
+ if "script" in decorator_str:
188
+ xlwings_functions.append(node.name)
189
+ break
190
+
191
+ # If currently selected script is still here, return it at beginning
192
+ if script_button_text in xlwings_functions:
193
+ remaining = [x for x in xlwings_functions if x != script_button_text]
194
+ return to_js([script_button_text] + remaining)
195
+
196
+ return to_js(xlwings_functions)
197
+
198
+
199
+ html_output = HtmlOutput("output")
200
+
201
+
202
+ def custom_functions_meta(module_string):
203
+ try:
204
+ module = create_module_from_string(module_string, "main")
205
+ except Exception as e: # noqa: E722
206
+ js.console.log(f"Parsing error [custom_functions_meta]: {e}")
207
+ return to_js({}, dict_converter=js.Object.fromEntries)
208
+ return to_js(
209
+ xlwings.server.custom_functions_meta(module),
210
+ dict_converter=js.Object.fromEntries,
211
+ )
212
+
213
+
214
+ def custom_functions_code(module_string):
215
+ try:
216
+ module = create_module_from_string(module_string, "main")
217
+ except Exception as e: # noqa: E722
218
+ js.console.log(f"Parsing error [custom_functions_code]: {e}")
219
+ return ""
220
+ code = ""
221
+ for _, obj in inspect.getmembers(module):
222
+ if hasattr(obj, "__xlfunc__"):
223
+ xlfunc = obj.__xlfunc__
224
+ func_name = xlfunc["name"]
225
+ streaming = "true" if inspect.isasyncgenfunction(obj) else "false"
226
+ code += dedent(
227
+ f"""\
228
+ async function {func_name}() {{
229
+ let args = ["{func_name}", {streaming}]
230
+ args.push.apply(args, arguments);
231
+ return await base.apply(null, args);
232
+ }}
233
+ CustomFunctions.associate("{func_name.upper()}", {func_name});
234
+ """
235
+ )
236
+ return code
@@ -0,0 +1,5 @@
1
+ xlwings==0.33.15
2
+ python-dotenv==1.1.1
3
+ pyodide-http
4
+ pandas
5
+ matplotlib