qarnot 2.15.0__tar.gz → 2.16.0__tar.gz

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 (82) hide show
  1. {qarnot-2.15.0/qarnot.egg-info → qarnot-2.16.0}/PKG-INFO +12 -3
  2. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/computeindex.rst +2 -0
  3. qarnot-2.16.0/doc/source/api/compute/forced_network_rule.rst +8 -0
  4. qarnot-2.16.0/doc/source/api/compute/secrets.rst +8 -0
  5. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/conf.py +4 -4
  6. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/_version.py +3 -3
  7. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/connection.py +1 -1
  8. qarnot-2.16.0/qarnot/forced_constant.py +44 -0
  9. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/forced_network_rule.py +1 -1
  10. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/pool.py +33 -1
  11. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/secrets.py +1 -1
  12. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/task.py +8 -45
  13. {qarnot-2.15.0 → qarnot-2.16.0/qarnot.egg-info}/PKG-INFO +12 -3
  14. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot.egg-info/SOURCES.txt +3 -0
  15. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot.egg-info/requires.txt +1 -1
  16. {qarnot-2.15.0 → qarnot-2.16.0}/requirements-lint.txt +2 -2
  17. {qarnot-2.15.0 → qarnot-2.16.0}/requirements-optional.txt +1 -1
  18. qarnot-2.16.0/requirements.txt +6 -0
  19. {qarnot-2.15.0 → qarnot-2.16.0}/setup.py +1 -1
  20. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_task.py +34 -0
  21. qarnot-2.15.0/requirements.txt +0 -6
  22. {qarnot-2.15.0 → qarnot-2.16.0}/LICENSE +0 -0
  23. {qarnot-2.15.0 → qarnot-2.16.0}/MANIFEST.in +0 -0
  24. {qarnot-2.15.0 → qarnot-2.16.0}/README.rst +0 -0
  25. {qarnot-2.15.0 → qarnot-2.16.0}/doc/Makefile +0 -0
  26. {qarnot-2.15.0 → qarnot-2.16.0}/doc/make.bat +0 -0
  27. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/_static/qarnot.png +0 -0
  28. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/hardware_constraint.rst +0 -0
  29. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/job.rst +0 -0
  30. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/paginate.rst +0 -0
  31. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/pool.rst +0 -0
  32. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/privileges.rst +0 -0
  33. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/retry_settings.rst +0 -0
  34. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/scheduling_type.rst +0 -0
  35. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/status.rst +0 -0
  36. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/compute/task.rst +0 -0
  37. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/connection.rst +0 -0
  38. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/exceptions.rst +0 -0
  39. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/storage/advanced_bucket.rst +0 -0
  40. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/storage/bucket.rst +0 -0
  41. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/storage/storage.rst +0 -0
  42. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/api/storage/storageindex.rst +0 -0
  43. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/basic.rst +0 -0
  44. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/index.rst +0 -0
  45. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/installation.rst +0 -0
  46. {qarnot-2.15.0 → qarnot-2.16.0}/doc/source/qarnot.rst +0 -0
  47. {qarnot-2.15.0 → qarnot-2.16.0}/pyproject.toml +0 -0
  48. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/__init__.py +0 -0
  49. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/_filter.py +0 -0
  50. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/_retry.py +0 -0
  51. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/_util.py +0 -0
  52. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/advanced_bucket.py +0 -0
  53. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/bucket.py +0 -0
  54. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/error.py +0 -0
  55. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/exceptions.py +0 -0
  56. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/hardware_constraint.py +0 -0
  57. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/helper.py +0 -0
  58. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/job.py +0 -0
  59. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/paginate.py +0 -0
  60. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/privileges.py +0 -0
  61. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/retry_settings.py +0 -0
  62. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/scheduling_type.py +0 -0
  63. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/status.py +0 -0
  64. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot/storage.py +0 -0
  65. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot.egg-info/dependency_links.txt +0 -0
  66. {qarnot-2.15.0 → qarnot-2.16.0}/qarnot.egg-info/top_level.txt +0 -0
  67. {qarnot-2.15.0 → qarnot-2.16.0}/requirements-doc.txt +0 -0
  68. {qarnot-2.15.0 → qarnot-2.16.0}/requirements-test.txt +0 -0
  69. {qarnot-2.15.0 → qarnot-2.16.0}/setup.cfg +0 -0
  70. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_advanced_bucket.py +0 -0
  71. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_bucket.py +0 -0
  72. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_connection.py +0 -0
  73. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_hardware_constraints.py +0 -0
  74. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_import.py +0 -0
  75. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_job.py +0 -0
  76. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_paginate.py +0 -0
  77. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_pool.py +0 -0
  78. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_retry.py +0 -0
  79. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_secrets.py +0 -0
  80. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_status.py +0 -0
  81. {qarnot-2.15.0 → qarnot-2.16.0}/test/test_util.py +0 -0
  82. {qarnot-2.15.0 → qarnot-2.16.0}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: qarnot
3
- Version: 2.15.0
3
+ Version: 2.16.0
4
4
  Summary: Qarnot Computing SDK
5
5
  Home-page: https://computing.qarnot.com
6
6
  Author: Qarnot computing
@@ -17,10 +17,19 @@ Classifier: License :: OSI Approved :: Apache Software License
17
17
  Requires-Python: >=3.6
18
18
  License-File: LICENSE
19
19
  Requires-Dist: requests
20
- Requires-Dist: boto3
20
+ Requires-Dist: boto3>=1.36
21
21
  Requires-Dist: wheel
22
22
  Requires-Dist: deprecation
23
23
  Requires-Dist: simplejson
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: description
28
+ Dynamic: home-page
29
+ Dynamic: license
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
24
33
 
25
34
  Qarnot computing Python SDK
26
35
  ===========================
@@ -12,4 +12,6 @@ Compute
12
12
  privileges
13
13
  hardware_constraint
14
14
  retry_settings
15
+ scheduling_type
16
+ secrets
15
17
 
@@ -0,0 +1,8 @@
1
+ Forced Network Rule
2
+ -------------------
3
+
4
+ .. automodule:: qarnot.forced_network_rule
5
+ :members:
6
+ :show-inheritance:
7
+ :special-members:
8
+ :exclude-members: __dict__,__weakref__,__eq__,__str__,__repr__
@@ -0,0 +1,8 @@
1
+ Secrets
2
+ -------
3
+
4
+ .. automodule:: qarnot.secrets
5
+ :members:
6
+ :show-inheritance:
7
+ :special-members:
8
+ :exclude-members: __dict__,__weakref__,__eq__,__str__,__repr__
@@ -78,7 +78,7 @@ release = v
78
78
  #
79
79
  # This is also used if you do content translation via gettext catalogs.
80
80
  # Usually you set "language" from the command line for these cases.
81
- language = None
81
+ language = 'en'
82
82
 
83
83
  # List of patterns, relative to source directory, that match files and
84
84
  # directories to ignore when looking for source files.
@@ -106,7 +106,7 @@ html_theme = 'sphinx_rtd_theme'
106
106
  #html_theme_options = {}
107
107
 
108
108
  # Add any paths that contain custom themes here, relative to this directory.
109
- html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
109
+ #html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # WARNING: Calling get_html_theme_path is deprecated. If you are calling it to define html_theme_path, you are safe to remove that code.
110
110
 
111
111
  # The name for this set of Sphinx documents. If None, it defaults to
112
112
  # "<project> v<release> documentation".
@@ -187,6 +187,6 @@ texinfo_documents = [
187
187
  ]
188
188
 
189
189
  # Example configuration for intersphinx: refer to the Python standard library.
190
- intersphinx_mapping = {'https://docs.python.org/3': None,
191
- 'http://boto3.readthedocs.io/en/latest/': None}
190
+ intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
191
+ 'boto': ('http://boto3.readthedocs.io/en/latest/', None)}
192
192
  autodoc_member_order = 'bysource'
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-08-27T11:29:32+0200",
11
+ "date": "2025-02-07T16:27:29+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "8fe176158583e7c2db929a8a25031075991e9e36",
15
- "version": "v2.15.0"
14
+ "full-revisionid": "23daecdc71207c207e56afae3e55190f0734bd0d",
15
+ "version": "v2.16.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -196,7 +196,7 @@ class Connection(object):
196
196
 
197
197
  user = self.user_info
198
198
  session = boto3.session.Session()
199
- conf = botocore.config.Config(user_agent=self._version)
199
+ conf = botocore.config.Config(user_agent=self._version, request_checksum_calculation="when_required")
200
200
 
201
201
  should_verify_or_certificate_path = True
202
202
  if storage_unsafe:
@@ -0,0 +1,44 @@
1
+ from typing import Optional, Union, Dict
2
+ from enum import Enum
3
+
4
+
5
+ class ForcedConstantAccess(Enum):
6
+ ReadWrite = "ReadWrite"
7
+ ReadOnly = "ReadOnly"
8
+
9
+
10
+ class ForcedConstant(object):
11
+ """Forced Constant Information
12
+
13
+ .. note:: For internal usage only
14
+ """
15
+
16
+ def __init__(self, forced_value: str, force_export_in_environment: Optional[bool] = None, access: Optional[ForcedConstantAccess] = None):
17
+ self.forced_value = forced_value
18
+ """:type: :class:`str`
19
+
20
+ Forced value for the constant."""
21
+
22
+ self.force_export_in_environment = force_export_in_environment
23
+ """:type: :class:`bool`
24
+
25
+ Whether the constant should be forced in the execution environment or not."""
26
+
27
+ self.access = access
28
+ """:type: :class:`~qarnot.forced_constant.ForcedConstantAccess`
29
+
30
+ The access level of the constant: ReadOnly or ReadWrite."""
31
+
32
+ def to_json(self, name: str):
33
+ result: Dict[str, Union[str, bool]] = {
34
+ "constantName": name,
35
+ "forcedValue": self.forced_value,
36
+ }
37
+
38
+ if self.force_export_in_environment is not None:
39
+ result["forceExportInEnvironment"] = self.force_export_in_environment
40
+
41
+ if self.access is not None:
42
+ result["access"] = self.access.value
43
+
44
+ return result
@@ -81,7 +81,7 @@ class ForcedNetworkRule(object):
81
81
  """Create the forced network rule from json.
82
82
 
83
83
  :param dict json: Dictionary representing the forced network rule
84
- :returns: The created :class:`~qarnot.retry_settings.ForcedNetworkRule`
84
+ :returns: The created :class:`~qarnot.forced_network_rule.ForcedNetworkRule`
85
85
  """
86
86
 
87
87
  inbound: bool = bool(json["inbound"])
@@ -23,6 +23,7 @@ from qarnot.secrets import SecretsAccessRights
23
23
 
24
24
  from . import raise_on_error, get_url, _util
25
25
  from .bucket import Bucket
26
+ from .forced_constant import ForcedConstant
26
27
  from .status import Status
27
28
  from .hardware_constraint import HardwareConstraint
28
29
  from .scheduling_type import SchedulingType
@@ -77,6 +78,7 @@ class Pool(object):
77
78
  with :meth:`qarnot.connection.Connection.retrieve_profile`.
78
79
  """
79
80
  self._constraints: Dict[str, str] = {}
81
+ self._forced_constants: Dict[str, ForcedConstant] = {}
80
82
  self._labels: Dict[str, str] = {}
81
83
  self._auto_update = True
82
84
  self._last_auto_update_state = self._auto_update
@@ -252,6 +254,10 @@ class Pool(object):
252
254
  {'key': key, 'value': value}
253
255
  for key, value in self._constraints.items()
254
256
  ]
257
+ forced_const_list = [
258
+ value.to_json(key)
259
+ for key, value in self._forced_constants.items()
260
+ ]
255
261
 
256
262
  elastic_dict = {
257
263
  "isElastic": self._is_elastic,
@@ -267,6 +273,7 @@ class Pool(object):
267
273
  'name': self._name,
268
274
  'profile': self._profile,
269
275
  'constants': const_list,
276
+ 'forcedConstants': forced_const_list,
270
277
  'constraints': constr_list,
271
278
  'instanceCount': self._instancecount,
272
279
  'tags': self._tags,
@@ -1099,6 +1106,31 @@ class Pool(object):
1099
1106
 
1100
1107
  self._secrets_access_rights = value
1101
1108
 
1109
+ @property
1110
+ def forced_constants(self):
1111
+ """:type: dictionary{:class:`str` : :class:`~qarnot.forced_constant.ForcedConstant`}
1112
+ :getter: Returns this pool's forced constants dictionary.
1113
+ :setter: set the pool's forced constants dictionary.
1114
+
1115
+ Update the forced constants if needed.
1116
+ Forced constants are reserved for internal use.
1117
+ """
1118
+ self._update_if_summary()
1119
+ if self._auto_update:
1120
+ self.update()
1121
+
1122
+ return self._forced_constants
1123
+
1124
+ @forced_constants.setter
1125
+ def forced_constants(self, value: Dict[str, "ForcedConstant"]):
1126
+ """Setter for forced_constants
1127
+ """
1128
+ self._update_if_summary()
1129
+ if self._auto_update:
1130
+ self.update()
1131
+
1132
+ self._forced_constants = value
1133
+
1102
1134
  @property
1103
1135
  def forced_network_rules(self):
1104
1136
  """:type: list{:class:`~qarnot.forced_network_rule.ForcedNetworkRule`}
@@ -1116,7 +1148,7 @@ class Pool(object):
1116
1148
 
1117
1149
  @forced_network_rules.setter
1118
1150
  def forced_network_rules(self, value: List["ForcedNetworkRule"]):
1119
- """Setter for forced_constants
1151
+ """Setter for forced_network_rules
1120
1152
  """
1121
1153
  if self.uuid is not None:
1122
1154
  raise AttributeError("can't set attribute on a launched pool")
@@ -97,7 +97,7 @@ class SecretsAccessRights(object):
97
97
 
98
98
  :param by_secret: the list of secrets the task will have access to, described using an exact key match
99
99
  :type by_secret: `List[~qarnot.secrets.SecretAccessRightBySecret]`
100
- :param by_prefix:the list of secrets the task will have access to, described using a prefix key match
100
+ :param by_prefix: the list of secrets the task will have access to, described using a prefix key match
101
101
  :type by_prefix: `List[~qarnot.secrets.SecretAccessRightByPrefix]`
102
102
  """
103
103
  self._by_secret: List[SecretAccessRightBySecret] = by_secret or []
@@ -19,7 +19,6 @@ from os import makedirs, path
19
19
  import time
20
20
  import warnings
21
21
  import sys
22
- from enum import Enum
23
22
  from typing import Dict, Optional, Union, List, Any, Callable
24
23
 
25
24
  from qarnot.retry_settings import RetrySettings
@@ -29,6 +28,7 @@ from qarnot.secrets import SecretsAccessRights
29
28
  from . import get_url, raise_on_error, _util
30
29
  from .status import Status
31
30
  from .hardware_constraint import HardwareConstraint
31
+ from .forced_constant import ForcedConstant
32
32
  from .scheduling_type import SchedulingType
33
33
  from .privileges import Privileges
34
34
  from .bucket import Bucket
@@ -458,6 +458,9 @@ class Task(object):
458
458
  if 'resultBucket' in json_task and json_task['resultBucket']:
459
459
  self._result_object_id = json_task['resultBucket']
460
460
 
461
+ if 'ResultsCacheTTLSec' in json_task and self._result_object is not None:
462
+ self._result_object._cache_ttl_sec = json_task['ResultsCacheTTLSec']
463
+
461
464
  if 'status' in json_task:
462
465
  self._status = json_task['status']
463
466
  self._creation_date = _util.parse_datetime(json_task['creationDate'])
@@ -1340,7 +1343,7 @@ class Task(object):
1340
1343
 
1341
1344
  @property
1342
1345
  def forced_constants(self):
1343
- """:type: dictionary{:class:`str` : :class:`~qarnot.task.ForcedConstant`}
1346
+ """:type: dictionary{:class:`str` : :class:`~qarnot.forced_constant.ForcedConstant`}
1344
1347
  :getter: Returns this task's forced constants dictionary.
1345
1348
  :setter: set the task's forced constants dictionary.
1346
1349
 
@@ -1380,7 +1383,7 @@ class Task(object):
1380
1383
 
1381
1384
  @forced_network_rules.setter
1382
1385
  def forced_network_rules(self, value: List["ForcedNetworkRule"]):
1383
- """Setter for forced_constants
1386
+ """Setter for forced_network_rules
1384
1387
  """
1385
1388
  if self.uuid is not None:
1386
1389
  raise AttributeError("can't set attribute on a launched task")
@@ -1815,6 +1818,8 @@ class Task(object):
1815
1818
 
1816
1819
  if self._result_object is not None:
1817
1820
  json_task['resultBucket'] = self._result_object.uuid
1821
+ if self._result_object._cache_ttl_sec is not None:
1822
+ json_task['ResultsCacheTTLSec'] = self._result_object._cache_ttl_sec
1818
1823
 
1819
1824
  if self._advanced_range is not None:
1820
1825
  json_task['advancedRanges'] = self._advanced_range
@@ -1975,45 +1980,3 @@ class BulkTaskResponse(object):
1975
1980
  return ', '.join("{0}={1}".format(key, val) for (key, val) in self.__dict__.items())
1976
1981
  else:
1977
1982
  return ', '.join("{0}={1}".format(key, val) for (key, val) in self.__dict__.iteritems()) # pylint: disable=no-member
1978
-
1979
-
1980
- class ForcedConstantAccess(Enum):
1981
- ReadWrite = "ReadWrite"
1982
- ReadOnly = "ReadOnly"
1983
-
1984
-
1985
- class ForcedConstant(object):
1986
- """Forced Constant Information
1987
-
1988
- .. note:: For internal usage only
1989
- """
1990
-
1991
- def __init__(self, forced_value: str, force_export_in_environment: Optional[bool] = None, access: Optional[ForcedConstantAccess] = None):
1992
- self.forced_value = forced_value
1993
- """:type: :class:`str`
1994
-
1995
- Forced value for the constant."""
1996
-
1997
- self.force_export_in_environment = force_export_in_environment
1998
- """:type: :class:`bool`
1999
-
2000
- Whether the constant should be forced in the execution environment or not."""
2001
-
2002
- self.access = access
2003
- """:type: :class:`~qarnot.task.ForcedConstantAccess`
2004
-
2005
- The access level of the constant: ReadOnly or ReadWrite."""
2006
-
2007
- def to_json(self, name: str):
2008
- result: Dict[str, Union[str, bool]] = {
2009
- "constantName": name,
2010
- "forcedValue": self.forced_value,
2011
- }
2012
-
2013
- if self.force_export_in_environment is not None:
2014
- result["forceExportInEnvironment"] = self.force_export_in_environment
2015
-
2016
- if self.access is not None:
2017
- result["access"] = self.access.value
2018
-
2019
- return result
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: qarnot
3
- Version: 2.15.0
3
+ Version: 2.16.0
4
4
  Summary: Qarnot Computing SDK
5
5
  Home-page: https://computing.qarnot.com
6
6
  Author: Qarnot computing
@@ -17,10 +17,19 @@ Classifier: License :: OSI Approved :: Apache Software License
17
17
  Requires-Python: >=3.6
18
18
  License-File: LICENSE
19
19
  Requires-Dist: requests
20
- Requires-Dist: boto3
20
+ Requires-Dist: boto3>=1.36
21
21
  Requires-Dist: wheel
22
22
  Requires-Dist: deprecation
23
23
  Requires-Dist: simplejson
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: description
28
+ Dynamic: home-page
29
+ Dynamic: license
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
24
33
 
25
34
  Qarnot computing Python SDK
26
35
  ===========================
@@ -21,6 +21,7 @@ doc/source/_static/qarnot.png
21
21
  doc/source/api/connection.rst
22
22
  doc/source/api/exceptions.rst
23
23
  doc/source/api/compute/computeindex.rst
24
+ doc/source/api/compute/forced_network_rule.rst
24
25
  doc/source/api/compute/hardware_constraint.rst
25
26
  doc/source/api/compute/job.rst
26
27
  doc/source/api/compute/paginate.rst
@@ -28,6 +29,7 @@ doc/source/api/compute/pool.rst
28
29
  doc/source/api/compute/privileges.rst
29
30
  doc/source/api/compute/retry_settings.rst
30
31
  doc/source/api/compute/scheduling_type.rst
32
+ doc/source/api/compute/secrets.rst
31
33
  doc/source/api/compute/status.rst
32
34
  doc/source/api/compute/task.rst
33
35
  doc/source/api/storage/advanced_bucket.rst
@@ -44,6 +46,7 @@ qarnot/bucket.py
44
46
  qarnot/connection.py
45
47
  qarnot/error.py
46
48
  qarnot/exceptions.py
49
+ qarnot/forced_constant.py
47
50
  qarnot/forced_network_rule.py
48
51
  qarnot/hardware_constraint.py
49
52
  qarnot/helper.py
@@ -1,5 +1,5 @@
1
1
  requests
2
- boto3
2
+ boto3>=1.36
3
3
  wheel
4
4
  deprecation
5
5
  simplejson
@@ -5,5 +5,5 @@ pylint
5
5
  # libraries stubs for lint
6
6
  types-requests
7
7
  types-simplejson
8
- boto3-stubs
9
- botocore-stubs
8
+ boto3-stubs[boto3]
9
+ botocore-stubs
@@ -1,2 +1,2 @@
1
1
  requests-toolbelt==0.8.0
2
- progressbar2==4.0.0
2
+ progressbar2==4.5.0
@@ -0,0 +1,6 @@
1
+ requests==2.32.3
2
+ boto3==1.36.6
3
+ wheel==0.45.1
4
+ deprecation==2.1.0
5
+ simplejson==3.19.3
6
+ setuptools==75.7.0
@@ -25,7 +25,7 @@ setup(name='qarnot',
25
25
  url='https://computing.qarnot.com',
26
26
  setup_requires=['wheel'],
27
27
  packages=['qarnot'],
28
- install_requires=['requests', 'boto3', 'wheel', 'deprecation', 'simplejson'],
28
+ install_requires=['requests', 'boto3>=1.36', 'wheel', 'deprecation', 'simplejson'],
29
29
  tests_require=['pytest'],
30
30
  python_requires='>=3.6',
31
31
  classifiers=['Development Status :: 5 - Production/Stable',
@@ -141,6 +141,40 @@ class TestTaskProperties:
141
141
  assert "prefix1" == json_bucket["filtering"]["prefixFiltering"]["prefix"]
142
142
  assert "prefix2" == json_bucket["resourcesTransformation"]["stripPrefix"]["prefix"]
143
143
 
144
+ @pytest.mark.parametrize("cache_ttl", [1000, None])
145
+ def test_result_bucket_with_ResultsCacheTTL_to_json(self, mock_conn, cache_ttl):
146
+ task = Task(mock_conn, "task-with-a-ResultsCacheTTLSec", "profile")
147
+ resultsCacheTTLSec = cache_ttl
148
+ bucket = Bucket(mock_conn, "name", False)
149
+ bucket_copy_with_TTL = bucket.with_cache_ttl(resultsCacheTTLSec)
150
+ bucket_created_with_TTL = Bucket(mock_conn, "name", False, cacheTTLSec=resultsCacheTTLSec)
151
+
152
+ task.results = bucket_created_with_TTL
153
+ json_task = task._to_json()
154
+ if cache_ttl is None:
155
+ assert "ResultsCacheTTLSec" not in json_task
156
+ else:
157
+ assert resultsCacheTTLSec == json_task["ResultsCacheTTLSec"]
158
+
159
+ task = Task(mock_conn, "task-with-a-ResultsCacheTTLSec", "profile")
160
+ task.results = bucket_copy_with_TTL
161
+ json_task = task._to_json()
162
+ if cache_ttl is None:
163
+ assert "ResultsCacheTTLSec" not in json_task
164
+ else:
165
+ assert resultsCacheTTLSec == json_task["ResultsCacheTTLSec"]
166
+
167
+ def test_update_task_with_ResultsCacheTTL_(self, mock_conn):
168
+ task = Task(mock_conn, "task-name")
169
+ resultsCacheTTLSec = 10000
170
+ bucket_created_with_TTL = Bucket(mock_conn, "name", False, cacheTTLSec=resultsCacheTTLSec)
171
+ task.results = bucket_created_with_TTL
172
+ json_task_with_ResultsCacheTTLSec = default_json_task.copy()
173
+ json_task_with_ResultsCacheTTLSec["ResultsCacheTTLSec"] = resultsCacheTTLSec
174
+ task._update(json_task_with_ResultsCacheTTLSec)
175
+ task_json = task._to_json()
176
+ assert task_json["ResultsCacheTTLSec"] == resultsCacheTTLSec
177
+
144
178
  def test_bucket_in_task_from_json(self, mock_conn):
145
179
  json_bucket = "bucket-name"
146
180
  json_task = {
@@ -1,6 +0,0 @@
1
- requests==2.32.3
2
- boto3==1.21.38
3
- wheel==0.38.1
4
- deprecation==2.1.0
5
- simplejson==3.18.3
6
- setuptools==70.3.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes