gamsapi 52.5.0__cp312-cp312-win_amd64.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 (257) hide show
  1. gams/__init__.py +27 -0
  2. gams/_version.py +1 -0
  3. gams/connect/__init__.py +28 -0
  4. gams/connect/agents/__init__.py +24 -0
  5. gams/connect/agents/_excel/__init__.py +32 -0
  6. gams/connect/agents/_excel/excelagent.py +312 -0
  7. gams/connect/agents/_excel/workbook.py +155 -0
  8. gams/connect/agents/_sqlconnectors/__init__.py +42 -0
  9. gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
  10. gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
  11. gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
  12. gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
  13. gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
  14. gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
  15. gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
  16. gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
  17. gams/connect/agents/concatenate.py +440 -0
  18. gams/connect/agents/connectagent.py +743 -0
  19. gams/connect/agents/csvreader.py +675 -0
  20. gams/connect/agents/csvwriter.py +151 -0
  21. gams/connect/agents/domainwriter.py +143 -0
  22. gams/connect/agents/excelreader.py +756 -0
  23. gams/connect/agents/excelwriter.py +467 -0
  24. gams/connect/agents/filter.py +223 -0
  25. gams/connect/agents/gamsreader.py +112 -0
  26. gams/connect/agents/gamswriter.py +239 -0
  27. gams/connect/agents/gdxreader.py +109 -0
  28. gams/connect/agents/gdxwriter.py +146 -0
  29. gams/connect/agents/labelmanipulator.py +303 -0
  30. gams/connect/agents/projection.py +539 -0
  31. gams/connect/agents/pythoncode.py +71 -0
  32. gams/connect/agents/rawcsvreader.py +248 -0
  33. gams/connect/agents/rawexcelreader.py +312 -0
  34. gams/connect/agents/schema/CSVReader.yaml +92 -0
  35. gams/connect/agents/schema/CSVWriter.yaml +44 -0
  36. gams/connect/agents/schema/Concatenate.yaml +52 -0
  37. gams/connect/agents/schema/DomainWriter.yaml +25 -0
  38. gams/connect/agents/schema/ExcelReader.yaml +121 -0
  39. gams/connect/agents/schema/ExcelWriter.yaml +78 -0
  40. gams/connect/agents/schema/Filter.yaml +74 -0
  41. gams/connect/agents/schema/GAMSReader.yaml +20 -0
  42. gams/connect/agents/schema/GAMSWriter.yaml +47 -0
  43. gams/connect/agents/schema/GDXReader.yaml +23 -0
  44. gams/connect/agents/schema/GDXWriter.yaml +32 -0
  45. gams/connect/agents/schema/LabelManipulator.yaml +99 -0
  46. gams/connect/agents/schema/Projection.yaml +24 -0
  47. gams/connect/agents/schema/PythonCode.yaml +6 -0
  48. gams/connect/agents/schema/RawCSVReader.yaml +34 -0
  49. gams/connect/agents/schema/RawExcelReader.yaml +42 -0
  50. gams/connect/agents/schema/SQLReader.yaml +75 -0
  51. gams/connect/agents/schema/SQLWriter.yaml +103 -0
  52. gams/connect/agents/sqlreader.py +301 -0
  53. gams/connect/agents/sqlwriter.py +276 -0
  54. gams/connect/connectdatabase.py +275 -0
  55. gams/connect/connectvalidator.py +93 -0
  56. gams/connect/errors.py +34 -0
  57. gams/control/__init__.py +136 -0
  58. gams/control/database.py +2231 -0
  59. gams/control/execution.py +1900 -0
  60. gams/control/options.py +2792 -0
  61. gams/control/workspace.py +1198 -0
  62. gams/core/__init__.py +24 -0
  63. gams/core/cfg/__init__.py +26 -0
  64. gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
  65. gams/core/cfg/cfgmcc.py +519 -0
  66. gams/core/dct/__init__.py +26 -0
  67. gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
  68. gams/core/dct/dctmcc.py +574 -0
  69. gams/core/embedded/__init__.py +26 -0
  70. gams/core/embedded/gamsemb.py +1024 -0
  71. gams/core/emp/__init__.py +24 -0
  72. gams/core/emp/emplexer.py +89 -0
  73. gams/core/emp/empyacc.py +281 -0
  74. gams/core/gdx/__init__.py +26 -0
  75. gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
  76. gams/core/gdx/gdxcc.py +866 -0
  77. gams/core/gev/__init__.py +26 -0
  78. gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
  79. gams/core/gev/gevmcc.py +855 -0
  80. gams/core/gmd/__init__.py +26 -0
  81. gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
  82. gams/core/gmd/gmdcc.py +917 -0
  83. gams/core/gmo/__init__.py +26 -0
  84. gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
  85. gams/core/gmo/gmomcc.py +2046 -0
  86. gams/core/idx/__init__.py +26 -0
  87. gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
  88. gams/core/idx/idxcc.py +510 -0
  89. gams/core/numpy/__init__.py +29 -0
  90. gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
  91. gams/core/numpy/gams2numpy.py +1048 -0
  92. gams/core/opt/__init__.py +26 -0
  93. gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
  94. gams/core/opt/optcc.py +840 -0
  95. gams/engine/__init__.py +204 -0
  96. gams/engine/api/__init__.py +13 -0
  97. gams/engine/api/auth_api.py +7653 -0
  98. gams/engine/api/cleanup_api.py +751 -0
  99. gams/engine/api/default_api.py +887 -0
  100. gams/engine/api/hypercube_api.py +2629 -0
  101. gams/engine/api/jobs_api.py +5229 -0
  102. gams/engine/api/licenses_api.py +2220 -0
  103. gams/engine/api/namespaces_api.py +7783 -0
  104. gams/engine/api/usage_api.py +5627 -0
  105. gams/engine/api/users_api.py +5931 -0
  106. gams/engine/api_client.py +804 -0
  107. gams/engine/api_response.py +21 -0
  108. gams/engine/configuration.py +601 -0
  109. gams/engine/exceptions.py +216 -0
  110. gams/engine/models/__init__.py +86 -0
  111. gams/engine/models/bad_input.py +89 -0
  112. gams/engine/models/cleanable_job_result.py +104 -0
  113. gams/engine/models/cleanable_job_result_page.py +113 -0
  114. gams/engine/models/engine_license.py +107 -0
  115. gams/engine/models/files_not_found.py +93 -0
  116. gams/engine/models/forwarded_token_response.py +112 -0
  117. gams/engine/models/generic_key_value_pair.py +89 -0
  118. gams/engine/models/hypercube.py +160 -0
  119. gams/engine/models/hypercube_page.py +111 -0
  120. gams/engine/models/hypercube_summary.py +91 -0
  121. gams/engine/models/hypercube_token.py +97 -0
  122. gams/engine/models/identity_provider.py +107 -0
  123. gams/engine/models/identity_provider_ldap.py +121 -0
  124. gams/engine/models/identity_provider_oauth2.py +146 -0
  125. gams/engine/models/identity_provider_oauth2_scope.py +89 -0
  126. gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
  127. gams/engine/models/identity_provider_oidc.py +133 -0
  128. gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
  129. gams/engine/models/inex.py +91 -0
  130. gams/engine/models/invitation.py +136 -0
  131. gams/engine/models/invitation_quota.py +106 -0
  132. gams/engine/models/invitation_token.py +87 -0
  133. gams/engine/models/job.py +165 -0
  134. gams/engine/models/job_no_text_entry.py +138 -0
  135. gams/engine/models/job_no_text_entry_page.py +111 -0
  136. gams/engine/models/license.py +91 -0
  137. gams/engine/models/log_piece.py +96 -0
  138. gams/engine/models/message.py +87 -0
  139. gams/engine/models/message_and_token.py +99 -0
  140. gams/engine/models/message_with_webhook_id.py +89 -0
  141. gams/engine/models/model_auth_token.py +87 -0
  142. gams/engine/models/model_configuration.py +125 -0
  143. gams/engine/models/model_default_instance.py +99 -0
  144. gams/engine/models/model_default_user_instance.py +98 -0
  145. gams/engine/models/model_hypercube_job.py +106 -0
  146. gams/engine/models/model_hypercube_usage.py +130 -0
  147. gams/engine/models/model_instance_info.py +116 -0
  148. gams/engine/models/model_instance_info_full.py +123 -0
  149. gams/engine/models/model_instance_pool_info.py +112 -0
  150. gams/engine/models/model_job_labels.py +179 -0
  151. gams/engine/models/model_job_usage.py +133 -0
  152. gams/engine/models/model_pool_usage.py +124 -0
  153. gams/engine/models/model_usage.py +115 -0
  154. gams/engine/models/model_user.py +96 -0
  155. gams/engine/models/model_userinstance_info.py +119 -0
  156. gams/engine/models/model_userinstancepool_info.py +95 -0
  157. gams/engine/models/model_version.py +91 -0
  158. gams/engine/models/models.py +120 -0
  159. gams/engine/models/namespace.py +104 -0
  160. gams/engine/models/namespace_quota.py +96 -0
  161. gams/engine/models/namespace_with_permission.py +96 -0
  162. gams/engine/models/not_found.py +91 -0
  163. gams/engine/models/password_policy.py +97 -0
  164. gams/engine/models/perm_and_username.py +89 -0
  165. gams/engine/models/quota.py +117 -0
  166. gams/engine/models/quota_exceeded.py +97 -0
  167. gams/engine/models/status_code_meaning.py +89 -0
  168. gams/engine/models/stream_entry.py +89 -0
  169. gams/engine/models/system_wide_license.py +92 -0
  170. gams/engine/models/text_entries.py +87 -0
  171. gams/engine/models/text_entry.py +101 -0
  172. gams/engine/models/time_span.py +95 -0
  173. gams/engine/models/time_span_pool_worker.py +99 -0
  174. gams/engine/models/token_forward_error.py +87 -0
  175. gams/engine/models/user.py +127 -0
  176. gams/engine/models/user_group_member.py +96 -0
  177. gams/engine/models/user_groups.py +108 -0
  178. gams/engine/models/vapid_info.py +87 -0
  179. gams/engine/models/webhook.py +138 -0
  180. gams/engine/models/webhook_parameterized_event.py +99 -0
  181. gams/engine/py.typed +0 -0
  182. gams/engine/rest.py +258 -0
  183. gams/magic/__init__.py +32 -0
  184. gams/magic/gams_magic.py +142 -0
  185. gams/magic/interactive.py +402 -0
  186. gams/tools/__init__.py +30 -0
  187. gams/tools/errors.py +34 -0
  188. gams/tools/toolcollection/__init__.py +24 -0
  189. gams/tools/toolcollection/alg/__init__.py +24 -0
  190. gams/tools/toolcollection/alg/rank.py +51 -0
  191. gams/tools/toolcollection/data/__init__.py +24 -0
  192. gams/tools/toolcollection/data/csvread.py +444 -0
  193. gams/tools/toolcollection/data/csvwrite.py +311 -0
  194. gams/tools/toolcollection/data/exceldump.py +47 -0
  195. gams/tools/toolcollection/data/sqlitewrite.py +276 -0
  196. gams/tools/toolcollection/gdxservice/__init__.py +24 -0
  197. gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
  198. gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
  199. gams/tools/toolcollection/linalg/__init__.py +24 -0
  200. gams/tools/toolcollection/linalg/cholesky.py +57 -0
  201. gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
  202. gams/tools/toolcollection/linalg/eigenvector.py +58 -0
  203. gams/tools/toolcollection/linalg/invert.py +55 -0
  204. gams/tools/toolcollection/linalg/ols.py +138 -0
  205. gams/tools/toolcollection/tooltemplate.py +321 -0
  206. gams/tools/toolcollection/win32/__init__.py +24 -0
  207. gams/tools/toolcollection/win32/excelmerge.py +93 -0
  208. gams/tools/toolcollection/win32/exceltalk.py +76 -0
  209. gams/tools/toolcollection/win32/msappavail.py +49 -0
  210. gams/tools/toolcollection/win32/shellexecute.py +54 -0
  211. gams/tools/tools.py +116 -0
  212. gams/transfer/__init__.py +35 -0
  213. gams/transfer/_abcs/__init__.py +37 -0
  214. gams/transfer/_abcs/container_abcs.py +433 -0
  215. gams/transfer/_internals/__init__.py +63 -0
  216. gams/transfer/_internals/algorithms.py +436 -0
  217. gams/transfer/_internals/casepreservingdict.py +124 -0
  218. gams/transfer/_internals/constants.py +270 -0
  219. gams/transfer/_internals/domainviolation.py +103 -0
  220. gams/transfer/_internals/specialvalues.py +172 -0
  221. gams/transfer/containers/__init__.py +26 -0
  222. gams/transfer/containers/_container.py +1794 -0
  223. gams/transfer/containers/_io/__init__.py +28 -0
  224. gams/transfer/containers/_io/containers.py +164 -0
  225. gams/transfer/containers/_io/gdx.py +1029 -0
  226. gams/transfer/containers/_io/gmd.py +872 -0
  227. gams/transfer/containers/_mixins/__init__.py +26 -0
  228. gams/transfer/containers/_mixins/ccc.py +1274 -0
  229. gams/transfer/syms/__init__.py +33 -0
  230. gams/transfer/syms/_methods/__init__.py +24 -0
  231. gams/transfer/syms/_methods/tables.py +120 -0
  232. gams/transfer/syms/_methods/toDict.py +115 -0
  233. gams/transfer/syms/_methods/toList.py +83 -0
  234. gams/transfer/syms/_methods/toValue.py +60 -0
  235. gams/transfer/syms/_mixins/__init__.py +32 -0
  236. gams/transfer/syms/_mixins/equals.py +626 -0
  237. gams/transfer/syms/_mixins/generateRecords.py +499 -0
  238. gams/transfer/syms/_mixins/pivot.py +313 -0
  239. gams/transfer/syms/_mixins/pve.py +627 -0
  240. gams/transfer/syms/_mixins/sa.py +27 -0
  241. gams/transfer/syms/_mixins/sapve.py +27 -0
  242. gams/transfer/syms/_mixins/saua.py +27 -0
  243. gams/transfer/syms/_mixins/sauapve.py +199 -0
  244. gams/transfer/syms/_mixins/spve.py +1528 -0
  245. gams/transfer/syms/_mixins/ve.py +936 -0
  246. gams/transfer/syms/container_syms/__init__.py +31 -0
  247. gams/transfer/syms/container_syms/_alias.py +984 -0
  248. gams/transfer/syms/container_syms/_equation.py +333 -0
  249. gams/transfer/syms/container_syms/_parameter.py +973 -0
  250. gams/transfer/syms/container_syms/_set.py +604 -0
  251. gams/transfer/syms/container_syms/_universe_alias.py +461 -0
  252. gams/transfer/syms/container_syms/_variable.py +321 -0
  253. gamsapi-52.5.0.dist-info/METADATA +150 -0
  254. gamsapi-52.5.0.dist-info/RECORD +257 -0
  255. gamsapi-52.5.0.dist-info/WHEEL +5 -0
  256. gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
  257. gamsapi-52.5.0.dist-info/top_level.txt +1 -0
gams/__init__.py ADDED
@@ -0,0 +1,27 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ from gams._version import __version__
27
+ from gams.control import *
gams/_version.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "52.5.0"
@@ -0,0 +1,28 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ from gams.connect.connectdatabase import ConnectDatabase
27
+
28
+ __all__ = ["ConnectDatabase"]
@@ -0,0 +1,24 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
@@ -0,0 +1,32 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ from gams.connect.agents._excel.workbook import Workbook
27
+ from gams.connect.agents._excel.excelagent import ExcelAgent
28
+
29
+ __all__ = [
30
+ "Workbook",
31
+ "ExcelAgent",
32
+ ]
@@ -0,0 +1,312 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ from abc import abstractmethod
27
+ from gams.connect.agents.connectagent import ConnectAgent
28
+ import numpy as np
29
+ from openpyxl.utils.cell import column_index_from_string, coordinate_from_string
30
+
31
+
32
+ class ExcelAgent(ConnectAgent):
33
+ @abstractmethod
34
+ def __init__(self, cdb, inst, agent_index):
35
+ super().__init__(cdb, inst, agent_index)
36
+
37
+ def _to_int_if_whole_vec(x):
38
+ if isinstance(x, float) and x.is_integer():
39
+ return int(x)
40
+ return x
41
+
42
+ self._to_int_if_whole = np.vectorize(_to_int_if_whole_vec, otypes=[object])
43
+
44
+ @abstractmethod
45
+ def _create_symbol_instructions(self, rec): ...
46
+
47
+ def _key_map(self, key, index_parameter_map):
48
+ if key is None:
49
+ return None
50
+ key = key.lower().strip()
51
+ if key in index_parameter_map:
52
+ return index_parameter_map[key]
53
+ if self._trace > 1 and key != "":
54
+ self._cdb.print_log(f"Ignoring unsupported option >{key}<.")
55
+ return ""
56
+
57
+ def _parse_key_value(self, value, index_parameter_map):
58
+ args = value
59
+ args = args.replace("=", " ")
60
+ args = args.split(" ")
61
+ args = list(
62
+ filter(lambda x: x != " ", args)
63
+ ) # NOTE: This part of code doesnt allow spaces when specifying key-value pairs (e.g. ignoreColumns = 1:3 raises an error -> ignoreColumns=1:3)
64
+ ret = {}
65
+ for args_idx in range(0, len(args), 2):
66
+ key = args[args_idx].strip()
67
+ key = self._key_map(key, index_parameter_map)
68
+ if key is not None and len(key) != 0:
69
+ if args_idx + 1 >= len(args):
70
+ self._connect_error(
71
+ f"Error parsing >{value}< from index sheet. Option >{key}< does not have a value specified."
72
+ )
73
+ v = args[args_idx + 1].strip()
74
+ if v is not None:
75
+ v = self._value_map(key, v, index_parameter_map)
76
+ ret[key] = v
77
+ return ret
78
+
79
+ def _value_map(self, key, value, index_parameter_map):
80
+ if isinstance(value, str):
81
+ value = value.strip()
82
+ bool_mapping = {
83
+ # 1: True,
84
+ True: True,
85
+ "true": True,
86
+ "1": True,
87
+ # 0: False,
88
+ False: False,
89
+ "false": False,
90
+ "0": False,
91
+ }
92
+ m = {}
93
+ supported_keys = dict.fromkeys(index_parameter_map.values())
94
+ for k in supported_keys:
95
+ if k == "autoMerge":
96
+ m["autoMerge"] = bool_mapping
97
+ if k == "mergedCells":
98
+ m["mergedCells"] = bool_mapping
99
+ if k == "ignoreText":
100
+ m["ignoreText"] = bool_mapping
101
+ if k == "clearSheet":
102
+ m["clearSheet"] = bool_mapping
103
+ v = value
104
+ if key in supported_keys:
105
+ if key in ["autoMerge", "ignoreText", "mergedCells", "clearSheet"]:
106
+ if isinstance(value, str):
107
+ value = value.lower()
108
+ v = m[key].get(value, None)
109
+ if v is None:
110
+ self._connect_error(
111
+ f"Invalid value >{value}< for {key}. Allowed values are {', '.join(str(x) for x in m[key].keys())}."
112
+ )
113
+ elif key == "ignoreRows":
114
+ if isinstance(value, str):
115
+ l = value.split(",")
116
+ l = [x.strip() for x in l]
117
+ v = []
118
+ # [9, "4:7", 11] -> [9, 4, 5, 6, 7, 11]
119
+ for x in l:
120
+ if x.isnumeric():
121
+ v.append(int(x))
122
+ elif ":" in x:
123
+ v.extend(self._parse_rows_range(x))
124
+ else:
125
+ self._connect_error(
126
+ f"Value >{x}< for ignoreRows in index file need to be either numeric or in range format e.g. 3:7."
127
+ )
128
+ else:
129
+ v = [value]
130
+ elif key == "ignoreColumns":
131
+ if isinstance(value, str):
132
+ l = value.split(",")
133
+ l = [x.strip() for x in l]
134
+ v = []
135
+ for x in l:
136
+ if x.isnumeric():
137
+ v.append(int(x))
138
+ elif ":" in x:
139
+ v.extend(self._parse_columns_range(x))
140
+ else:
141
+ v.append(column_index_from_string(x))
142
+ else:
143
+ v = [value]
144
+ elif isinstance(value, str) and value.isnumeric():
145
+ v = int(value)
146
+ return v
147
+
148
+ def _coords_to_row_col(self, coordinates):
149
+ c = coordinate_from_string(coordinates)
150
+ return c[1], column_index_from_string(c[0])
151
+
152
+ def normalize_range(self, sym_range):
153
+ if sym_range.endswith("!"):
154
+ sym_range += "A1"
155
+ return sym_range
156
+
157
+ def _split_range(self, sym_range, wb):
158
+ if "!" not in sym_range: # named range
159
+ rng_dict = {x.lower(): x for x in wb.defined_names}
160
+ sym_range_lower = sym_range.lower()
161
+ if sym_range_lower not in rng_dict:
162
+ self._connect_error(f"Named range >{sym_range}< does not exist.")
163
+ rng = wb.resolve_named_range(rng_dict[sym_range_lower])
164
+ if len(rng) == 0:
165
+ self._connect_error(
166
+ f"Named range >{sym_range}< with invalid reference."
167
+ )
168
+ if len(rng) > 1:
169
+ self._connect_error(
170
+ f"Named range is not contiguous: {sym_range} -> {rng}"
171
+ )
172
+ rng = rng[0]
173
+ resolved_range = "!".join(rng)
174
+ sym_range = resolved_range
175
+ sym_range = self.normalize_range(sym_range)
176
+ return sym_range.split("!")
177
+
178
+ def _range_to_coords(self, rng):
179
+ nw, se = rng.split(":") if ":" in rng else (rng, None)
180
+ nw_row, nw_col = self._coords_to_row_col(nw)
181
+ se_col = se_row = None
182
+ if se is not None:
183
+ se_row, se_col = self._coords_to_row_col(se)
184
+ return nw_col - 1, nw_row - 1, se_col, se_row
185
+
186
+ def parse_range(self, sym_range, wb, clear_sheet=False, create_missing=False):
187
+ sheet, rng = self._split_range(sym_range, wb)
188
+ toc_range = f"'{sheet}'!{rng.split(':')[0]}"
189
+ sheet = self.sheet_by_name(sheet, wb, clear_sheet, create_missing)
190
+ nw_col, nw_row, se_col, se_row = self._range_to_coords(rng)
191
+ return sheet, nw_col, nw_row, se_col, se_row, toc_range
192
+
193
+ def parse_index(self, index, wb, index_parameter_map):
194
+ if self._trace > 1:
195
+ self._cdb.print_log(f"Parsing index sheet using range >{index}<")
196
+ sheet, nw_col, nw_row, se_col, se_row, _ = self.parse_range(index, wb)
197
+ data = wb.get_sheet_data(sheet)
198
+ if self._engine == "xlwings":
199
+ data = self._to_int_if_whole(data)
200
+
201
+ data = data[nw_row:se_row, nw_col:se_col]
202
+ header = data[0]
203
+ for idx, h in enumerate(header):
204
+ header[idx] = self._key_map(h, index_parameter_map)
205
+
206
+ symbols = []
207
+ global_par = {}
208
+ for rec in data[1:]:
209
+ local_par = self._create_symbol_instructions(rec)
210
+ is_symbol = len(local_par) > 0
211
+ for idx, h in enumerate(header[3:]):
212
+ key = self._key_map(h, index_parameter_map)
213
+ value = rec[idx + 3]
214
+ if isinstance(value, str):
215
+ value = value.strip()
216
+ params = {}
217
+ if key is None: # parse arbitrary key-value pairs
218
+ if value is not None:
219
+ params = self._parse_key_value(value, index_parameter_map)
220
+ elif len(key) == 0:
221
+ continue
222
+ elif value is not None:
223
+ params = {key: self._value_map(key, value, index_parameter_map)}
224
+
225
+ for k, v in params.items():
226
+ if is_symbol:
227
+ if self._trace > 1:
228
+ self._cdb.print_log(
229
+ f"Adding option >{k}: {v}< for symbol >{local_par['name']}<."
230
+ )
231
+ local_par[k] = v
232
+ else:
233
+ if self._trace > 1:
234
+ self._cdb.print_log(f"\nAdding root option >{k}: {v}<.")
235
+ global_par[k] = v
236
+
237
+ if is_symbol:
238
+ sym = global_par.copy()
239
+ sym.update(local_par)
240
+ symbols.append(sym)
241
+ return symbols
242
+
243
+ def sheet_by_name(self, sheet, wb, clear_sheet=False, create_missing=False):
244
+ for idx, s in enumerate(wb.sheetnames):
245
+ if sheet.lower() == s.lower():
246
+ if clear_sheet:
247
+ wb.delete_sheet(s)
248
+ return wb.create_sheet(s, idx)
249
+ return wb.get_sheet(s)
250
+ if create_missing:
251
+ return wb.create_sheet(sheet)
252
+ else:
253
+ self._connect_error(f"Sheet >{sheet}< not found.")
254
+
255
+ def _parse_rows_range(self, rng):
256
+ """
257
+ Parse a range string in the format 'start:end' and return a list of all integers in the range.
258
+ e.g. 3:7 -> [3, 4, 5, 6, 7]
259
+ """
260
+ r_components = rng.split(":")
261
+ r_components = [comp.strip() for comp in r_components]
262
+ if len(r_components) != 2:
263
+ self._connect_error(
264
+ f"Invalid range in ignoreRows >{rng}<. Must be specified in the format 'start:end'"
265
+ )
266
+
267
+ if not all(x.isnumeric() for x in r_components):
268
+ self._connect_error(
269
+ f"Invalid range in ignoreRows >{rng}<. Both 'start' and 'end' must be integers in 'start:end'"
270
+ )
271
+
272
+ r_from_to = list(map(int, r_components))
273
+
274
+ if r_from_to[0] > r_from_to[1]:
275
+ self._connect_error(
276
+ f"Invalid range in ignoreRows >{rng}<. 'start' >{r_components[0]}< must be less than or equal to 'end' >{r_components[1]}< in 'start:end'"
277
+ )
278
+
279
+ r_all = list(range(r_from_to[0], r_from_to[1] + 1))
280
+ return r_all
281
+
282
+ def _parse_columns_range(self, rng):
283
+ """
284
+ Parse a range string in the format 'start:end' and return a list of all integers in the range.
285
+ e.g. C:G -> [3, 4, 5, 6, 7] , 2 : E -> [2, 3, 4, 5] , D :7 -> [4, 5, 6, 7]
286
+ """
287
+ r_components = rng.split(":")
288
+ r_components = [comp.strip() for comp in r_components]
289
+ if len(r_components) != 2:
290
+ self._connect_error(
291
+ f"Invalid range in ignoreColumns >{rng}<. Must be specified in the format 'start:end'"
292
+ )
293
+
294
+ if not all(x.isnumeric() or x.isalpha() for x in r_components):
295
+ self._connect_error(
296
+ f"Invalid range in ignoreColumns >{rng}<. Both 'start' and 'end' must be either integers or letters in 'start:end'"
297
+ )
298
+
299
+ r_components = [
300
+ (column_index_from_string(comp) if comp.isalpha() else int(comp))
301
+ for comp in r_components
302
+ ]
303
+
304
+ if r_components[0] > r_components[1]:
305
+ self._connect_error(
306
+ f"Invalid range in ignoreColumns >{rng}<. 'start' >{r_components[0]}< must be less than or equal to 'end' >{r_components[1]}< in 'start:end'"
307
+ )
308
+
309
+ r_from_to = list(map(int, r_components))
310
+
311
+ r_all = list(range(r_from_to[0], r_from_to[1] + 1))
312
+ return r_all
@@ -0,0 +1,155 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ import sys
27
+ import numpy as np
28
+
29
+
30
+ class Workbook:
31
+ def __init__(self, file=None, engine="openpyxl", read_only=False, data_only=False):
32
+ self._engine = engine
33
+ self._file = file
34
+
35
+ if self._engine == "xlwings":
36
+ import xlwings
37
+
38
+ self._app = xlwings.App(visible=False, add_book=False)
39
+ self._wb = self._app.books.open(self._file, read_only=read_only)
40
+ elif self._engine == "openpyxl":
41
+ import openpyxl
42
+
43
+ if self._file is None:
44
+ self._wb = openpyxl.Workbook()
45
+ # remove default sheet
46
+ self._wb.remove(self._wb.active)
47
+ else:
48
+ self._wb = openpyxl.load_workbook(
49
+ self._file, read_only=read_only, data_only=data_only
50
+ )
51
+ else:
52
+ raise Exception("Invalid engine.")
53
+
54
+ def close(self):
55
+ if self._engine == "xlwings":
56
+ if self._app is not None:
57
+ self._app.quit()
58
+ elif self._engine == "openpyxl":
59
+ if self._wb is not None:
60
+ self._wb.close()
61
+ else:
62
+ raise Exception("Invalid engine.")
63
+
64
+ def save(self, path):
65
+ if self._engine == "xlwings":
66
+ self._wb.save(path)
67
+ elif self._engine == "openpyxl":
68
+ self._wb.save(path)
69
+ else:
70
+ raise Exception("Invalid engine.")
71
+
72
+ def get_sheet(self, sheet_name):
73
+ if self._engine == "xlwings":
74
+ return self._wb.sheets[sheet_name]
75
+ elif self._engine == "openpyxl":
76
+ return self._wb[sheet_name]
77
+ else:
78
+ raise Exception("Invalid engine.")
79
+
80
+ def index(self, worksheet):
81
+ if self._engine == "xlwings":
82
+ raise Exception("Not implemented.")
83
+ elif self._engine == "openpyxl":
84
+ return self._wb.index(worksheet)
85
+ else:
86
+ raise Exception("Invalid engine.")
87
+
88
+ def move_sheet(self, sheet, offset=0):
89
+ if self._engine == "xlwings":
90
+ raise Exception("Not implemented.")
91
+ elif self._engine == "openpyxl":
92
+ self._wb.move_sheet(sheet, offset)
93
+ else:
94
+ raise Exception("Invalid engine.")
95
+
96
+ def get_sheet_data(self, sheet):
97
+ if self._engine == "xlwings":
98
+ last_cell = sheet.used_range.last_cell
99
+ full_range = sheet.range(sheet.range("A1"), last_cell)
100
+ return full_range.options(
101
+ np.array,
102
+ ndim=2,
103
+ dtype=object,
104
+ empty=None,
105
+ err_to_str=True,
106
+ ).value
107
+ elif self._engine == "openpyxl":
108
+ return np.array(
109
+ list(sheet.values), dtype=object
110
+ ) # dtype=object is required to not convert int values (e.g. 1) to float automatically (e.g. 1.0)
111
+ else:
112
+ raise Exception("Invalid engine.")
113
+
114
+ def delete_sheet(self, sheet_name):
115
+ if self._engine == "xlwings":
116
+ self._wb.sheets[sheet_name].delete()
117
+ elif self._engine == "openpyxl":
118
+ del self._wb[sheet_name]
119
+ else:
120
+ raise Exception("Invalid engine.")
121
+
122
+ def create_sheet(self, sheet_name, index=None):
123
+ if self._engine == "xlwings":
124
+ raise Exception("Not imlemented.")
125
+ elif self._engine == "openpyxl":
126
+ return self._wb.create_sheet(sheet_name, index)
127
+ else:
128
+ raise Exception("Invalid engine.")
129
+
130
+ def resolve_named_range(self, sym_range):
131
+ if self._engine == "xlwings":
132
+ nr = self._wb.names[sym_range].refers_to_range
133
+ return [(nr.sheet.name, nr.address)]
134
+ elif self._engine == "openpyxl":
135
+ return list(self.defined_names[sym_range].destinations)
136
+ else:
137
+ raise Exception("Invalid engine.")
138
+
139
+ @property
140
+ def defined_names(self):
141
+ if self._engine == "xlwings":
142
+ return [x.name for x in self._wb.names]
143
+ elif self._engine == "openpyxl":
144
+ return self._wb.defined_names
145
+ else:
146
+ raise Exception("Invalid engine.")
147
+
148
+ @property
149
+ def sheetnames(self):
150
+ if self._engine == "xlwings":
151
+ return [s.name for s in self._wb.sheets]
152
+ elif self._engine == "openpyxl":
153
+ return self._wb.sheetnames
154
+ else:
155
+ raise Exception("Invalid engine.")
@@ -0,0 +1,42 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ from gams.connect.agents._sqlconnectors._accesshandler import AccessConnector
27
+ from gams.connect.agents._sqlconnectors._mysqlhandler import MySQLConnector
28
+ from gams.connect.agents._sqlconnectors._postgreshandler import PostgresConnector
29
+ from gams.connect.agents._sqlconnectors._pyodbchandler import PyodbcConnector
30
+ from gams.connect.agents._sqlconnectors._sqlalchemyhandler import SQLAlchemyConnector
31
+ from gams.connect.agents._sqlconnectors._sqlitehandler import SQLiteConnector
32
+ from gams.connect.agents._sqlconnectors._sqlserverhandler import SQLServerConnector
33
+
34
+ __all__ = [
35
+ "AccessConnector",
36
+ "MySQLConnector",
37
+ "PostgresConnector",
38
+ "PyodbcConnector",
39
+ "SQLAlchemyConnector",
40
+ "SQLiteConnector",
41
+ "SQLServerConnector",
42
+ ]