gamsapi 52.2.0__cp314-cp314-win_amd64.whl → 52.4.0__cp314-cp314-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 (294) hide show
  1. gams/__init__.py +2 -2
  2. gams/_version.py +1 -1
  3. gams/connect/__init__.py +2 -2
  4. gams/connect/agents/__init__.py +2 -2
  5. gams/connect/agents/_excel/__init__.py +2 -2
  6. gams/connect/agents/_excel/excelagent.py +2 -2
  7. gams/connect/agents/_excel/workbook.py +2 -2
  8. gams/connect/agents/_sqlconnectors/__init__.py +2 -2
  9. gams/connect/agents/_sqlconnectors/_accesshandler.py +2 -2
  10. gams/connect/agents/_sqlconnectors/_databasehandler.py +2 -2
  11. gams/connect/agents/_sqlconnectors/_mysqlhandler.py +2 -2
  12. gams/connect/agents/_sqlconnectors/_postgreshandler.py +2 -2
  13. gams/connect/agents/_sqlconnectors/_pyodbchandler.py +2 -2
  14. gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +2 -2
  15. gams/connect/agents/_sqlconnectors/_sqlitehandler.py +2 -2
  16. gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +2 -2
  17. gams/connect/agents/concatenate.py +2 -2
  18. gams/connect/agents/connectagent.py +2 -2
  19. gams/connect/agents/csvreader.py +2 -2
  20. gams/connect/agents/csvwriter.py +2 -2
  21. gams/connect/agents/domainwriter.py +2 -2
  22. gams/connect/agents/excelreader.py +2 -2
  23. gams/connect/agents/excelwriter.py +2 -2
  24. gams/connect/agents/filter.py +2 -2
  25. gams/connect/agents/gamsreader.py +2 -2
  26. gams/connect/agents/gamswriter.py +2 -2
  27. gams/connect/agents/gdxreader.py +2 -2
  28. gams/connect/agents/gdxwriter.py +2 -2
  29. gams/connect/agents/labelmanipulator.py +2 -2
  30. gams/connect/agents/projection.py +2 -2
  31. gams/connect/agents/pythoncode.py +2 -2
  32. gams/connect/agents/rawcsvreader.py +2 -2
  33. gams/connect/agents/rawexcelreader.py +2 -2
  34. gams/connect/agents/sqlreader.py +2 -2
  35. gams/connect/agents/sqlwriter.py +2 -2
  36. gams/connect/connectdatabase.py +2 -2
  37. gams/connect/connectvalidator.py +2 -2
  38. gams/connect/errors.py +2 -2
  39. gams/control/__init__.py +2 -2
  40. gams/control/database.py +2 -2
  41. gams/control/execution.py +2 -2
  42. gams/control/options.py +2 -2
  43. gams/control/workspace.py +2 -2
  44. gams/core/__init__.py +2 -2
  45. gams/core/cfg/__init__.py +2 -2
  46. gams/core/cfg/_cfgmcc.cp314-win_amd64.pyd +0 -0
  47. gams/core/dct/__init__.py +2 -2
  48. gams/core/dct/_dctmcc.cp314-win_amd64.pyd +0 -0
  49. gams/core/embedded/__init__.py +2 -2
  50. gams/core/embedded/gamsemb.py +2 -2
  51. gams/core/emp/__init__.py +2 -2
  52. gams/core/emp/emplexer.py +2 -2
  53. gams/core/emp/empyacc.py +2 -2
  54. gams/core/gdx/__init__.py +2 -2
  55. gams/core/gdx/_gdxcc.cp314-win_amd64.pyd +0 -0
  56. gams/core/gev/__init__.py +2 -2
  57. gams/core/gev/_gevmcc.cp314-win_amd64.pyd +0 -0
  58. gams/core/gmd/__init__.py +2 -2
  59. gams/core/gmd/_gmdcc.cp314-win_amd64.pyd +0 -0
  60. gams/core/gmo/__init__.py +2 -2
  61. gams/core/gmo/_gmomcc.cp314-win_amd64.pyd +0 -0
  62. gams/core/idx/__init__.py +2 -2
  63. gams/core/idx/_idxcc.cp314-win_amd64.pyd +0 -0
  64. gams/core/numpy/__init__.py +2 -2
  65. gams/core/numpy/_gams2numpy.cp314-win_amd64.pyd +0 -0
  66. gams/core/numpy/gams2numpy.py +2 -2
  67. gams/core/opt/__init__.py +2 -2
  68. gams/core/opt/_optcc.cp314-win_amd64.pyd +0 -0
  69. gams/engine/__init__.py +193 -16
  70. gams/engine/api/__init__.py +13 -3
  71. gams/engine/api/auth_api.py +7545 -3618
  72. gams/engine/api/cleanup_api.py +712 -320
  73. gams/engine/api/default_api.py +838 -369
  74. gams/engine/api/hypercube_api.py +2576 -1198
  75. gams/engine/api/jobs_api.py +5170 -2458
  76. gams/engine/api/licenses_api.py +2170 -1014
  77. gams/engine/api/namespaces_api.py +7663 -3557
  78. gams/engine/api/usage_api.py +5575 -1867
  79. gams/engine/api/users_api.py +5880 -2382
  80. gams/engine/api_client.py +579 -641
  81. gams/engine/api_response.py +21 -0
  82. gams/engine/configuration.py +233 -102
  83. gams/engine/exceptions.py +86 -29
  84. gams/engine/models/__init__.py +83 -68
  85. gams/engine/models/bad_input.py +89 -0
  86. gams/engine/models/cleanable_job_result.py +104 -0
  87. gams/engine/models/cleanable_job_result_page.py +113 -0
  88. gams/engine/models/engine_license.py +107 -0
  89. gams/engine/models/files_not_found.py +93 -0
  90. gams/engine/models/forwarded_token_response.py +112 -0
  91. gams/engine/models/generic_key_value_pair.py +89 -0
  92. gams/engine/models/hypercube.py +160 -0
  93. gams/engine/models/hypercube_page.py +111 -0
  94. gams/engine/models/hypercube_summary.py +91 -0
  95. gams/engine/models/hypercube_token.py +97 -0
  96. gams/engine/models/identity_provider.py +107 -0
  97. gams/engine/models/identity_provider_ldap.py +121 -0
  98. gams/engine/models/identity_provider_oauth2.py +146 -0
  99. gams/engine/models/identity_provider_oauth2_scope.py +89 -0
  100. gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
  101. gams/engine/models/identity_provider_oidc.py +133 -0
  102. gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
  103. gams/engine/models/inex.py +91 -0
  104. gams/engine/models/invitation.py +136 -0
  105. gams/engine/models/invitation_quota.py +106 -0
  106. gams/engine/models/invitation_token.py +87 -0
  107. gams/engine/models/job.py +165 -0
  108. gams/engine/models/job_no_text_entry.py +138 -0
  109. gams/engine/models/job_no_text_entry_page.py +111 -0
  110. gams/engine/models/license.py +91 -0
  111. gams/engine/models/log_piece.py +96 -0
  112. gams/engine/models/message.py +87 -0
  113. gams/engine/models/message_and_token.py +99 -0
  114. gams/engine/models/message_with_webhook_id.py +89 -0
  115. gams/engine/models/model_auth_token.py +87 -0
  116. gams/engine/models/model_configuration.py +125 -0
  117. gams/engine/models/model_default_instance.py +99 -0
  118. gams/engine/models/model_default_user_instance.py +98 -0
  119. gams/engine/models/model_hypercube_job.py +106 -0
  120. gams/engine/models/model_hypercube_usage.py +130 -0
  121. gams/engine/models/model_instance_info.py +116 -0
  122. gams/engine/models/model_instance_info_full.py +123 -0
  123. gams/engine/models/model_instance_pool_info.py +112 -0
  124. gams/engine/models/model_job_labels.py +179 -0
  125. gams/engine/models/model_job_usage.py +133 -0
  126. gams/engine/models/model_pool_usage.py +124 -0
  127. gams/engine/models/model_usage.py +115 -0
  128. gams/engine/models/model_user.py +96 -0
  129. gams/engine/models/model_userinstance_info.py +119 -0
  130. gams/engine/models/model_userinstancepool_info.py +95 -0
  131. gams/engine/models/model_version.py +91 -0
  132. gams/engine/models/models.py +120 -0
  133. gams/engine/models/namespace.py +104 -0
  134. gams/engine/models/namespace_quota.py +96 -0
  135. gams/engine/models/namespace_with_permission.py +96 -0
  136. gams/engine/models/not_found.py +91 -0
  137. gams/engine/models/password_policy.py +97 -0
  138. gams/engine/models/perm_and_username.py +89 -0
  139. gams/engine/models/quota.py +117 -0
  140. gams/engine/models/quota_exceeded.py +97 -0
  141. gams/engine/models/status_code_meaning.py +89 -0
  142. gams/engine/models/stream_entry.py +89 -0
  143. gams/engine/models/system_wide_license.py +92 -0
  144. gams/engine/models/text_entries.py +87 -0
  145. gams/engine/models/text_entry.py +101 -0
  146. gams/engine/models/time_span.py +95 -0
  147. gams/engine/models/time_span_pool_worker.py +99 -0
  148. gams/engine/models/token_forward_error.py +87 -0
  149. gams/engine/models/user.py +127 -0
  150. gams/engine/models/user_group_member.py +96 -0
  151. gams/engine/models/user_groups.py +108 -0
  152. gams/engine/models/vapid_info.py +87 -0
  153. gams/engine/models/webhook.py +138 -0
  154. gams/engine/models/webhook_parameterized_event.py +99 -0
  155. gams/engine/py.typed +0 -0
  156. gams/engine/rest.py +141 -229
  157. gams/magic/__init__.py +2 -2
  158. gams/magic/gams_magic.py +2 -2
  159. gams/magic/interactive.py +2 -2
  160. gams/tools/__init__.py +2 -2
  161. gams/tools/errors.py +2 -2
  162. gams/tools/toolcollection/__init__.py +2 -2
  163. gams/tools/toolcollection/alg/__init__.py +2 -2
  164. gams/tools/toolcollection/alg/rank.py +2 -2
  165. gams/tools/toolcollection/data/__init__.py +2 -2
  166. gams/tools/toolcollection/data/csvread.py +2 -2
  167. gams/tools/toolcollection/data/exceldump.py +2 -2
  168. gams/tools/toolcollection/data/sqlitewrite.py +2 -2
  169. gams/tools/toolcollection/gdxservice/__init__.py +2 -2
  170. gams/tools/toolcollection/gdxservice/gdxencoding.py +2 -2
  171. gams/tools/toolcollection/gdxservice/gdxrename.py +2 -2
  172. gams/tools/toolcollection/linalg/__init__.py +2 -2
  173. gams/tools/toolcollection/linalg/cholesky.py +2 -2
  174. gams/tools/toolcollection/linalg/eigenvalue.py +2 -2
  175. gams/tools/toolcollection/linalg/eigenvector.py +2 -2
  176. gams/tools/toolcollection/linalg/invert.py +2 -2
  177. gams/tools/toolcollection/linalg/ols.py +2 -2
  178. gams/tools/toolcollection/tooltemplate.py +2 -2
  179. gams/tools/toolcollection/win32/__init__.py +2 -2
  180. gams/tools/toolcollection/win32/excelmerge.py +2 -2
  181. gams/tools/toolcollection/win32/exceltalk.py +2 -2
  182. gams/tools/toolcollection/win32/msappavail.py +2 -2
  183. gams/tools/toolcollection/win32/shellexecute.py +2 -2
  184. gams/tools/tools.py +2 -2
  185. gams/transfer/__init__.py +2 -2
  186. gams/transfer/_abcs/__init__.py +2 -2
  187. gams/transfer/_abcs/container_abcs.py +2 -2
  188. gams/transfer/_internals/__init__.py +2 -2
  189. gams/transfer/_internals/algorithms.py +2 -2
  190. gams/transfer/_internals/casepreservingdict.py +2 -2
  191. gams/transfer/_internals/constants.py +2 -2
  192. gams/transfer/_internals/domainviolation.py +2 -2
  193. gams/transfer/_internals/specialvalues.py +2 -2
  194. gams/transfer/containers/__init__.py +2 -2
  195. gams/transfer/containers/_container.py +2 -2
  196. gams/transfer/containers/_io/__init__.py +2 -2
  197. gams/transfer/containers/_io/containers.py +2 -2
  198. gams/transfer/containers/_io/gdx.py +2 -2
  199. gams/transfer/containers/_io/gmd.py +2 -2
  200. gams/transfer/containers/_mixins/__init__.py +2 -2
  201. gams/transfer/containers/_mixins/ccc.py +2 -2
  202. gams/transfer/syms/__init__.py +2 -2
  203. gams/transfer/syms/_methods/__init__.py +2 -2
  204. gams/transfer/syms/_methods/tables.py +2 -2
  205. gams/transfer/syms/_methods/toDict.py +2 -2
  206. gams/transfer/syms/_methods/toList.py +2 -2
  207. gams/transfer/syms/_methods/toValue.py +2 -2
  208. gams/transfer/syms/_mixins/__init__.py +2 -2
  209. gams/transfer/syms/_mixins/equals.py +2 -2
  210. gams/transfer/syms/_mixins/generateRecords.py +2 -2
  211. gams/transfer/syms/_mixins/pivot.py +2 -2
  212. gams/transfer/syms/_mixins/pve.py +2 -2
  213. gams/transfer/syms/_mixins/sa.py +2 -2
  214. gams/transfer/syms/_mixins/sapve.py +2 -2
  215. gams/transfer/syms/_mixins/saua.py +2 -2
  216. gams/transfer/syms/_mixins/sauapve.py +2 -2
  217. gams/transfer/syms/_mixins/spve.py +2 -2
  218. gams/transfer/syms/_mixins/ve.py +2 -2
  219. gams/transfer/syms/container_syms/__init__.py +2 -2
  220. gams/transfer/syms/container_syms/_alias.py +2 -2
  221. gams/transfer/syms/container_syms/_equation.py +2 -2
  222. gams/transfer/syms/container_syms/_parameter.py +2 -2
  223. gams/transfer/syms/container_syms/_set.py +2 -2
  224. gams/transfer/syms/container_syms/_universe_alias.py +2 -2
  225. gams/transfer/syms/container_syms/_variable.py +2 -2
  226. {gamsapi-52.2.0.dist-info → gamsapi-52.4.0.dist-info}/METADATA +12 -10
  227. gamsapi-52.4.0.dist-info/RECORD +257 -0
  228. {gamsapi-52.2.0.dist-info → gamsapi-52.4.0.dist-info}/licenses/LICENSE +2 -2
  229. gams/engine/apis/__init__.py +0 -25
  230. gams/engine/model/__init__.py +0 -5
  231. gams/engine/model/bad_input.py +0 -259
  232. gams/engine/model/cleanable_job_result.py +0 -285
  233. gams/engine/model/cleanable_job_result_page.py +0 -277
  234. gams/engine/model/engine_license.py +0 -263
  235. gams/engine/model/files_not_found.py +0 -267
  236. gams/engine/model/forwarded_token_response.py +0 -275
  237. gams/engine/model/generic_key_value_pair.py +0 -259
  238. gams/engine/model/hypercube.py +0 -331
  239. gams/engine/model/hypercube_page.py +0 -273
  240. gams/engine/model/hypercube_summary.py +0 -263
  241. gams/engine/model/hypercube_token.py +0 -265
  242. gams/engine/model/identity_provider.py +0 -287
  243. gams/engine/model/identity_provider_ldap.py +0 -303
  244. gams/engine/model/identity_provider_oauth2.py +0 -309
  245. gams/engine/model/identity_provider_oauth2_scope.py +0 -259
  246. gams/engine/model/identity_provider_oauth2_with_secret.py +0 -321
  247. gams/engine/model/identity_provider_oidc.py +0 -299
  248. gams/engine/model/identity_provider_oidc_with_secret.py +0 -319
  249. gams/engine/model/inex.py +0 -259
  250. gams/engine/model/invitation.py +0 -309
  251. gams/engine/model/invitation_quota.py +0 -263
  252. gams/engine/model/invitation_token.py +0 -255
  253. gams/engine/model/job.py +0 -337
  254. gams/engine/model/job_no_text_entry.py +0 -313
  255. gams/engine/model/job_no_text_entry_page.py +0 -273
  256. gams/engine/model/license.py +0 -263
  257. gams/engine/model/log_piece.py +0 -263
  258. gams/engine/model/message.py +0 -255
  259. gams/engine/model/message_and_token.py +0 -269
  260. gams/engine/model/model_auth_token.py +0 -255
  261. gams/engine/model/model_configuration.py +0 -268
  262. gams/engine/model/model_hypercube_job.py +0 -273
  263. gams/engine/model/model_hypercube_usage.py +0 -303
  264. gams/engine/model/model_instance_info.py +0 -285
  265. gams/engine/model/model_instance_info_full.py +0 -289
  266. gams/engine/model/model_job_labels.py +0 -295
  267. gams/engine/model/model_job_usage.py +0 -299
  268. gams/engine/model/model_usage.py +0 -267
  269. gams/engine/model/model_userinstance_info.py +0 -273
  270. gams/engine/model/model_version.py +0 -263
  271. gams/engine/model/models.py +0 -297
  272. gams/engine/model/namespace.py +0 -269
  273. gams/engine/model/namespace_quota.py +0 -263
  274. gams/engine/model/namespace_with_permission.py +0 -263
  275. gams/engine/model/not_found.py +0 -263
  276. gams/engine/model/perm_and_username.py +0 -259
  277. gams/engine/model/quota.py +0 -275
  278. gams/engine/model/quota_exceeded.py +0 -265
  279. gams/engine/model/result_user.py +0 -263
  280. gams/engine/model/status_code_meaning.py +0 -259
  281. gams/engine/model/stream_entry.py +0 -259
  282. gams/engine/model/system_wide_license.py +0 -255
  283. gams/engine/model/text_entries.py +0 -255
  284. gams/engine/model/text_entry.py +0 -263
  285. gams/engine/model/time_span.py +0 -259
  286. gams/engine/model/token_forward_error.py +0 -255
  287. gams/engine/model/user.py +0 -283
  288. gams/engine/model/user_group_member.py +0 -269
  289. gams/engine/model/user_groups.py +0 -279
  290. gams/engine/model/webhook.py +0 -292
  291. gams/engine/model_utils.py +0 -2037
  292. gamsapi-52.2.0.dist-info/RECORD +0 -248
  293. {gamsapi-52.2.0.dist-info → gamsapi-52.4.0.dist-info}/WHEEL +0 -0
  294. {gamsapi-52.2.0.dist-info → gamsapi-52.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ GAMS Engine
5
+
6
+ With GAMS Engine you can register and solve GAMS models. It has a namespace management system, so you can restrict your users to certain models.
7
+
8
+ The version of the OpenAPI document: latest
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+ from pydantic import BaseModel, ConfigDict, StrictStr, field_validator
21
+ from typing import Any, ClassVar, Dict, List, Optional
22
+ from typing import Optional, Set
23
+ from typing_extensions import Self
24
+
25
+ class WebhookParameterizedEvent(BaseModel):
26
+ """
27
+ WebhookParameterizedEvent
28
+ """ # noqa: E501
29
+ event: Optional[StrictStr] = None
30
+ parameters: Optional[List[StrictStr]] = None
31
+ __properties: ClassVar[List[str]] = ["event", "parameters"]
32
+
33
+ @field_validator('event')
34
+ def event_validate_enum(cls, value):
35
+ """Validates the enum"""
36
+ if value is None:
37
+ return value
38
+
39
+ if value not in set(['ALL', 'JOB_FINISHED', 'HC_JOB_FINISHED', 'JOB_OUT_OF_RESOURCES', 'HC_JOB_OUT_OF_RESOURCES', 'VOLUME_QUOTA_THRESHOLD', 'JOB_DURATION_THRESHOLD', 'HC_JOB_DURATION_THRESHOLD', 'INVALIDATE_CACHE']):
40
+ raise ValueError("must be one of enum values ('ALL', 'JOB_FINISHED', 'HC_JOB_FINISHED', 'JOB_OUT_OF_RESOURCES', 'HC_JOB_OUT_OF_RESOURCES', 'VOLUME_QUOTA_THRESHOLD', 'JOB_DURATION_THRESHOLD', 'HC_JOB_DURATION_THRESHOLD', 'INVALIDATE_CACHE')")
41
+ return value
42
+
43
+ model_config = ConfigDict(
44
+ populate_by_name=True,
45
+ validate_assignment=True,
46
+ protected_namespaces=(),
47
+ )
48
+
49
+
50
+ def to_str(self) -> str:
51
+ """Returns the string representation of the model using alias"""
52
+ return pprint.pformat(self.model_dump(by_alias=True))
53
+
54
+ def to_json(self) -> str:
55
+ """Returns the JSON representation of the model using alias"""
56
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
57
+ return json.dumps(self.to_dict())
58
+
59
+ @classmethod
60
+ def from_json(cls, json_str: str) -> Optional[Self]:
61
+ """Create an instance of WebhookParameterizedEvent from a JSON string"""
62
+ return cls.from_dict(json.loads(json_str))
63
+
64
+ def to_dict(self) -> Dict[str, Any]:
65
+ """Return the dictionary representation of the model using alias.
66
+
67
+ This has the following differences from calling pydantic's
68
+ `self.model_dump(by_alias=True)`:
69
+
70
+ * `None` is only added to the output dict for nullable fields that
71
+ were set at model initialization. Other fields with value `None`
72
+ are ignored.
73
+ """
74
+ excluded_fields: Set[str] = set([
75
+ ])
76
+
77
+ _dict = self.model_dump(
78
+ by_alias=True,
79
+ exclude=excluded_fields,
80
+ exclude_none=True,
81
+ )
82
+ return _dict
83
+
84
+ @classmethod
85
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
86
+ """Create an instance of WebhookParameterizedEvent from a dict"""
87
+ if obj is None:
88
+ return None
89
+
90
+ if not isinstance(obj, dict):
91
+ return cls.model_validate(obj)
92
+
93
+ _obj = cls.model_validate({
94
+ "event": obj.get("event"),
95
+ "parameters": obj.get("parameters")
96
+ })
97
+ return _obj
98
+
99
+
gams/engine/py.typed ADDED
File without changes
gams/engine/rest.py CHANGED
@@ -1,54 +1,68 @@
1
+ # coding: utf-8
2
+
1
3
  """
2
4
  GAMS Engine
3
5
 
4
- With GAMS Engine you can register and solve GAMS models. It has a namespace management system, so you can restrict your users to certain models. # noqa: E501
6
+ With GAMS Engine you can register and solve GAMS models. It has a namespace management system, so you can restrict your users to certain models.
5
7
 
6
8
  The version of the OpenAPI document: latest
7
- Generated by: https://openapi-generator.tech
8
- """
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
9
13
 
10
14
 
11
15
  import io
12
16
  import json
13
- import logging
14
17
  import re
15
18
  import ssl
16
- from urllib.parse import urlencode
17
- from urllib.parse import urlparse
18
- from urllib.request import proxy_bypass_environment
19
+
19
20
  import urllib3
20
- import ipaddress
21
21
 
22
- from gams.engine.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError
22
+ from gams.engine.exceptions import ApiException, ApiValueError
23
23
 
24
+ SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"}
25
+ RESTResponseType = urllib3.HTTPResponse
24
26
 
25
- logger = logging.getLogger(__name__)
27
+
28
+ def is_socks_proxy_url(url):
29
+ if url is None:
30
+ return False
31
+ split_section = url.split("://")
32
+ if len(split_section) < 2:
33
+ return False
34
+ else:
35
+ return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES
26
36
 
27
37
 
28
38
  class RESTResponse(io.IOBase):
29
39
 
30
- def __init__(self, resp):
31
- self.urllib3_response = resp
40
+ def __init__(self, resp) -> None:
41
+ self.response = resp
32
42
  self.status = resp.status
33
43
  self.reason = resp.reason
34
- self.data = resp.data
44
+ self.data = None
45
+
46
+ def read(self):
47
+ if self.data is None:
48
+ self.data = self.response.data
49
+ return self.data
35
50
 
36
51
  def getheaders(self):
37
52
  """Returns a dictionary of the response headers."""
38
- return self.urllib3_response.getheaders()
53
+ return self.response.headers
39
54
 
40
55
  def getheader(self, name, default=None):
41
56
  """Returns a given response header."""
42
- return self.urllib3_response.getheader(name, default)
57
+ return self.response.headers.get(name, default)
43
58
 
44
59
 
45
- class RESTClientObject(object):
60
+ class RESTClientObject:
46
61
 
47
- def __init__(self, configuration, pools_size=4, maxsize=None):
62
+ def __init__(self, configuration) -> None:
48
63
  # urllib3.PoolManager will pass all kw parameters to connectionpool
49
64
  # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
50
65
  # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
51
- # maxsize is the number of requests to host that are allowed in parallel # noqa: E501
52
66
  # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
53
67
 
54
68
  # cert_reqs
@@ -57,70 +71,80 @@ class RESTClientObject(object):
57
71
  else:
58
72
  cert_reqs = ssl.CERT_NONE
59
73
 
60
- addition_pool_args = {}
74
+ pool_args = {
75
+ "cert_reqs": cert_reqs,
76
+ "ca_certs": configuration.ssl_ca_cert,
77
+ "cert_file": configuration.cert_file,
78
+ "key_file": configuration.key_file,
79
+ "ca_cert_data": configuration.ca_cert_data,
80
+ }
61
81
  if configuration.assert_hostname is not None:
62
- addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
82
+ pool_args['assert_hostname'] = (
83
+ configuration.assert_hostname
84
+ )
63
85
 
64
86
  if configuration.retries is not None:
65
- addition_pool_args['retries'] = configuration.retries
87
+ pool_args['retries'] = configuration.retries
88
+
89
+ if configuration.tls_server_name:
90
+ pool_args['server_hostname'] = configuration.tls_server_name
91
+
66
92
 
67
93
  if configuration.socket_options is not None:
68
- addition_pool_args['socket_options'] = configuration.socket_options
94
+ pool_args['socket_options'] = configuration.socket_options
69
95
 
70
- if maxsize is None:
71
- if configuration.connection_pool_maxsize is not None:
72
- maxsize = configuration.connection_pool_maxsize
73
- else:
74
- maxsize = 4
96
+ if configuration.connection_pool_maxsize is not None:
97
+ pool_args['maxsize'] = configuration.connection_pool_maxsize
75
98
 
76
99
  # https pool manager
77
- if configuration.proxy and not should_bypass_proxies(configuration.host, no_proxy=configuration.no_proxy or ''):
78
- self.pool_manager = urllib3.ProxyManager(
79
- num_pools=pools_size,
80
- maxsize=maxsize,
81
- cert_reqs=cert_reqs,
82
- ca_certs=configuration.ssl_ca_cert,
83
- cert_file=configuration.cert_file,
84
- key_file=configuration.key_file,
85
- proxy_url=configuration.proxy,
86
- proxy_headers=configuration.proxy_headers,
87
- **addition_pool_args
88
- )
100
+ self.pool_manager: urllib3.PoolManager
101
+
102
+ if configuration.proxy:
103
+ if is_socks_proxy_url(configuration.proxy):
104
+ from urllib3.contrib.socks import SOCKSProxyManager
105
+ pool_args["proxy_url"] = configuration.proxy
106
+ pool_args["headers"] = configuration.proxy_headers
107
+ self.pool_manager = SOCKSProxyManager(**pool_args)
108
+ else:
109
+ pool_args["proxy_url"] = configuration.proxy
110
+ pool_args["proxy_headers"] = configuration.proxy_headers
111
+ self.pool_manager = urllib3.ProxyManager(**pool_args)
89
112
  else:
90
- self.pool_manager = urllib3.PoolManager(
91
- num_pools=pools_size,
92
- maxsize=maxsize,
93
- cert_reqs=cert_reqs,
94
- ca_certs=configuration.ssl_ca_cert,
95
- cert_file=configuration.cert_file,
96
- key_file=configuration.key_file,
97
- **addition_pool_args
98
- )
99
-
100
- def request(self, method, url, query_params=None, headers=None,
101
- body=None, post_params=None, _preload_content=True,
102
- _request_timeout=None):
113
+ self.pool_manager = urllib3.PoolManager(**pool_args)
114
+
115
+ def request(
116
+ self,
117
+ method,
118
+ url,
119
+ headers=None,
120
+ body=None,
121
+ post_params=None,
122
+ _request_timeout=None
123
+ ):
103
124
  """Perform requests.
104
125
 
105
126
  :param method: http request method
106
127
  :param url: http request url
107
- :param query_params: query parameters in the url
108
128
  :param headers: http request headers
109
129
  :param body: request json body, for `application/json`
110
130
  :param post_params: request post parameters,
111
131
  `application/x-www-form-urlencoded`
112
132
  and `multipart/form-data`
113
- :param _preload_content: if False, the urllib3.HTTPResponse object will
114
- be returned without reading/decoding response
115
- data. Default is True.
116
133
  :param _request_timeout: timeout setting for this request. If one
117
134
  number provided, it will be total request
118
135
  timeout. It can also be a pair (tuple) of
119
136
  (connection, read) timeouts.
120
137
  """
121
138
  method = method.upper()
122
- assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
123
- 'PATCH', 'OPTIONS']
139
+ assert method in [
140
+ 'GET',
141
+ 'HEAD',
142
+ 'DELETE',
143
+ 'POST',
144
+ 'PUT',
145
+ 'PATCH',
146
+ 'OPTIONS'
147
+ ]
124
148
 
125
149
  if post_params and body:
126
150
  raise ApiValueError(
@@ -132,60 +156,83 @@ class RESTClientObject(object):
132
156
 
133
157
  timeout = None
134
158
  if _request_timeout:
135
- if isinstance(_request_timeout, (int, float)): # noqa: E501,F821
159
+ if isinstance(_request_timeout, (int, float)):
136
160
  timeout = urllib3.Timeout(total=_request_timeout)
137
- elif (isinstance(_request_timeout, tuple) and
138
- len(_request_timeout) == 2):
161
+ elif (
162
+ isinstance(_request_timeout, tuple)
163
+ and len(_request_timeout) == 2
164
+ ):
139
165
  timeout = urllib3.Timeout(
140
- connect=_request_timeout[0], read=_request_timeout[1])
166
+ connect=_request_timeout[0],
167
+ read=_request_timeout[1]
168
+ )
141
169
 
142
170
  try:
143
171
  # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
144
172
  if method in ['POST', 'PUT', 'PATCH', 'OPTIONS']:
145
- # Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
146
- if (method != 'DELETE') and ('Content-Type' not in headers):
147
- headers['Content-Type'] = 'application/json'
148
- if query_params:
149
- url += '?' + urlencode(query_params)
150
- if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
173
+
174
+ # no content type provided or payload is json
175
+ content_type = headers.get('Content-Type')
176
+ if (
177
+ not content_type
178
+ or re.search('json', content_type, re.IGNORECASE)
179
+ ):
151
180
  request_body = None
152
181
  if body is not None:
153
182
  request_body = json.dumps(body)
154
183
  r = self.pool_manager.request(
155
- method, url,
184
+ method,
185
+ url,
156
186
  body=request_body,
157
- preload_content=_preload_content,
158
187
  timeout=timeout,
159
- headers=headers)
160
- elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
188
+ headers=headers,
189
+ preload_content=False
190
+ )
191
+ elif content_type == 'application/x-www-form-urlencoded':
161
192
  r = self.pool_manager.request(
162
- method, url,
193
+ method,
194
+ url,
163
195
  fields=post_params,
164
196
  encode_multipart=False,
165
- preload_content=_preload_content,
166
197
  timeout=timeout,
167
- headers=headers)
168
- elif headers['Content-Type'] == 'multipart/form-data':
198
+ headers=headers,
199
+ preload_content=False
200
+ )
201
+ elif content_type == 'multipart/form-data':
169
202
  # must del headers['Content-Type'], or the correct
170
203
  # Content-Type which generated by urllib3 will be
171
204
  # overwritten.
172
205
  del headers['Content-Type']
206
+ # Ensures that dict objects are serialized
207
+ post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a,b) for a, b in post_params]
173
208
  r = self.pool_manager.request(
174
- method, url,
209
+ method,
210
+ url,
175
211
  fields=post_params,
176
212
  encode_multipart=True,
177
- preload_content=_preload_content,
178
213
  timeout=timeout,
179
- headers=headers)
214
+ headers=headers,
215
+ preload_content=False
216
+ )
180
217
  # Pass a `string` parameter directly in the body to support
181
- # other content types than Json when `body` argument is
182
- # provided in serialized form
218
+ # other content types than JSON when `body` argument is
219
+ # provided in serialized form.
183
220
  elif isinstance(body, str) or isinstance(body, bytes):
184
- request_body = body
185
221
  r = self.pool_manager.request(
186
- method, url,
222
+ method,
223
+ url,
224
+ body=body,
225
+ timeout=timeout,
226
+ headers=headers,
227
+ preload_content=False
228
+ )
229
+ elif headers['Content-Type'].startswith('text/') and isinstance(body, bool):
230
+ request_body = "true" if body else "false"
231
+ r = self.pool_manager.request(
232
+ method,
233
+ url,
187
234
  body=request_body,
188
- preload_content=_preload_content,
235
+ preload_content=False,
189
236
  timeout=timeout,
190
237
  headers=headers)
191
238
  else:
@@ -196,151 +243,16 @@ class RESTClientObject(object):
196
243
  raise ApiException(status=0, reason=msg)
197
244
  # For `GET`, `HEAD`
198
245
  else:
199
- r = self.pool_manager.request(method, url,
200
- fields=query_params,
201
- preload_content=_preload_content,
202
- timeout=timeout,
203
- headers=headers)
246
+ r = self.pool_manager.request(
247
+ method,
248
+ url,
249
+ fields={},
250
+ timeout=timeout,
251
+ headers=headers,
252
+ preload_content=False
253
+ )
204
254
  except urllib3.exceptions.SSLError as e:
205
- msg = "{0}\n{1}".format(type(e).__name__, str(e))
255
+ msg = "\n".join([type(e).__name__, str(e)])
206
256
  raise ApiException(status=0, reason=msg)
207
257
 
208
- if _preload_content:
209
- r = RESTResponse(r)
210
-
211
- # log response body
212
- logger.debug("response body: %s", r.data)
213
-
214
- if not 200 <= r.status <= 299:
215
- if r.status == 401:
216
- raise UnauthorizedException(http_resp=r)
217
-
218
- if r.status == 403:
219
- raise ForbiddenException(http_resp=r)
220
-
221
- if r.status == 404:
222
- raise NotFoundException(http_resp=r)
223
-
224
- if 500 <= r.status <= 599:
225
- raise ServiceException(http_resp=r)
226
-
227
- raise ApiException(http_resp=r)
228
-
229
- return r
230
-
231
- def GET(self, url, headers=None, query_params=None, _preload_content=True,
232
- _request_timeout=None):
233
- return self.request("GET", url,
234
- headers=headers,
235
- _preload_content=_preload_content,
236
- _request_timeout=_request_timeout,
237
- query_params=query_params)
238
-
239
- def HEAD(self, url, headers=None, query_params=None, _preload_content=True,
240
- _request_timeout=None):
241
- return self.request("HEAD", url,
242
- headers=headers,
243
- _preload_content=_preload_content,
244
- _request_timeout=_request_timeout,
245
- query_params=query_params)
246
-
247
- def OPTIONS(self, url, headers=None, query_params=None, post_params=None,
248
- body=None, _preload_content=True, _request_timeout=None):
249
- return self.request("OPTIONS", url,
250
- headers=headers,
251
- query_params=query_params,
252
- post_params=post_params,
253
- _preload_content=_preload_content,
254
- _request_timeout=_request_timeout,
255
- body=body)
256
-
257
- def DELETE(self, url, headers=None, query_params=None, body=None,
258
- _preload_content=True, _request_timeout=None):
259
- return self.request("DELETE", url,
260
- headers=headers,
261
- query_params=query_params,
262
- _preload_content=_preload_content,
263
- _request_timeout=_request_timeout,
264
- body=body)
265
-
266
- def POST(self, url, headers=None, query_params=None, post_params=None,
267
- body=None, _preload_content=True, _request_timeout=None):
268
- return self.request("POST", url,
269
- headers=headers,
270
- query_params=query_params,
271
- post_params=post_params,
272
- _preload_content=_preload_content,
273
- _request_timeout=_request_timeout,
274
- body=body)
275
-
276
- def PUT(self, url, headers=None, query_params=None, post_params=None,
277
- body=None, _preload_content=True, _request_timeout=None):
278
- return self.request("PUT", url,
279
- headers=headers,
280
- query_params=query_params,
281
- post_params=post_params,
282
- _preload_content=_preload_content,
283
- _request_timeout=_request_timeout,
284
- body=body)
285
-
286
- def PATCH(self, url, headers=None, query_params=None, post_params=None,
287
- body=None, _preload_content=True, _request_timeout=None):
288
- return self.request("PATCH", url,
289
- headers=headers,
290
- query_params=query_params,
291
- post_params=post_params,
292
- _preload_content=_preload_content,
293
- _request_timeout=_request_timeout,
294
- body=body)
295
-
296
- # end of class RESTClientObject
297
- def is_ipv4(target):
298
- """ Test if IPv4 address or not
299
- """
300
- try:
301
- chk = ipaddress.IPv4Address(target)
302
- return True
303
- except ipaddress.AddressValueError:
304
- return False
305
-
306
- def in_ipv4net(target, net):
307
- """ Test if target belongs to given IPv4 network
308
- """
309
- try:
310
- nw = ipaddress.IPv4Network(net)
311
- ip = ipaddress.IPv4Address(target)
312
- if ip in nw:
313
- return True
314
- return False
315
- except ipaddress.AddressValueError:
316
- return False
317
- except ipaddress.NetmaskValueError:
318
- return False
319
-
320
- def should_bypass_proxies(url, no_proxy=None):
321
- """ Yet another requests.should_bypass_proxies
322
- Test if proxies should not be used for a particular url.
323
- """
324
-
325
- parsed = urlparse(url)
326
-
327
- # special cases
328
- if parsed.hostname in [None, '']:
329
- return True
330
-
331
- # special cases
332
- if no_proxy in [None , '']:
333
- return False
334
- if no_proxy == '*':
335
- return True
336
-
337
- no_proxy = no_proxy.lower().replace(' ','');
338
- entries = (
339
- host for host in no_proxy.split(',') if host
340
- )
341
-
342
- if is_ipv4(parsed.hostname):
343
- for item in entries:
344
- if in_ipv4net(parsed.hostname, item):
345
- return True
346
- return proxy_bypass_environment(parsed.hostname, {'no': no_proxy} )
258
+ return RESTResponse(r)
gams/magic/__init__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal
gams/magic/gams_magic.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal
gams/magic/interactive.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal
gams/tools/__init__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal
gams/tools/errors.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # GAMS - General Algebraic Modeling System Python API
3
3
  #
4
- # Copyright (c) 2017-2025 GAMS Development Corp. <support@gams.com>
5
- # Copyright (c) 2017-2025 GAMS Software GmbH <support@gams.com>
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to deal