zipher-sdk 0.3.0__tar.gz → 0.4.1__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 (26) hide show
  1. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/PKG-INFO +78 -5
  2. zipher-sdk-0.3.0/zipher_sdk.egg-info/PKG-INFO → zipher_sdk-0.4.1/README.md +65 -15
  3. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/setup.py +1 -1
  4. zipher_sdk-0.4.1/zipher/__init__.py +2 -0
  5. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/acl/zipher_installer.py +1 -1
  6. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/client.py +23 -7
  7. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/models.py +7 -0
  8. zipher-sdk-0.3.0/README.md → zipher_sdk-0.4.1/zipher_sdk.egg-info/PKG-INFO +90 -0
  9. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher_sdk.egg-info/entry_points.txt +0 -1
  10. zipher-sdk-0.3.0/zipher/__init__.py +0 -1
  11. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/LICENSE +0 -0
  12. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/setup.cfg +0 -0
  13. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/tests/__init__.py +0 -0
  14. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/tests/test_acl/__init__.py +0 -0
  15. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/tests/test_acl/sample_job.py +0 -0
  16. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/tests/test_acl/test_acl.py +0 -0
  17. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/tests/test_client.py +0 -0
  18. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/acl/__init__.py +0 -0
  19. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/acl/models.py +0 -0
  20. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/cli.py +0 -0
  21. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/exceptions.py +0 -0
  22. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher/utils.py +0 -0
  23. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher_sdk.egg-info/SOURCES.txt +0 -0
  24. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher_sdk.egg-info/dependency_links.txt +0 -0
  25. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher_sdk.egg-info/requires.txt +0 -0
  26. {zipher-sdk-0.3.0 → zipher_sdk-0.4.1}/zipher_sdk.egg-info/top_level.txt +0 -0
@@ -1,17 +1,25 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: zipher-sdk
3
- Version: 0.3.0
3
+ Version: 0.4.1
4
4
  Summary: Python SDK for programmatic access to the Zipher API
5
- Home-page: UNKNOWN
6
5
  Author: Zipher Inc.
7
6
  Author-email: yoav@zipher.cloud
8
- License: UNKNOWN
9
- Platform: UNKNOWN
10
7
  Classifier: Programming Language :: Python :: 3
11
8
  Classifier: License :: OSI Approved :: MIT License
12
9
  Classifier: Operating System :: OS Independent
13
10
  Description-Content-Type: text/markdown
14
11
  License-File: LICENSE
12
+ Requires-Dist: pydantic==2.11.3
13
+ Requires-Dist: requests==2.32.3
14
+ Requires-Dist: databricks-sdk==0.52.0
15
+ Dynamic: author
16
+ Dynamic: author-email
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: license-file
21
+ Dynamic: requires-dist
22
+ Dynamic: summary
15
23
 
16
24
 
17
25
  # Zipher SDK
@@ -136,4 +144,69 @@ optimized_cluster = client.update_existing_conf(job_id="my-job-id", existing_con
136
144
 
137
145
  ```
138
146
 
147
+ ### Update Existing Multiple Tasks Configuration
139
148
 
149
+ You can update multiple databricks tasks by initializing a zipher Client and sending a JSON representing a list of dbx SubmitTask objects to
150
+ the `get_optimized_tasks` function.
151
+
152
+ ```python
153
+ from zipher import Client
154
+
155
+ client = Client(customer_id="my_customer_id") # assuming the zipher API key is stored in ZIPHER_API_KEY environment variable
156
+
157
+ tasks_to_optimize = [
158
+ {
159
+ "task_key": "task_1",
160
+ "description": "Test notebook task",
161
+ "notebook_task": {
162
+ "notebook_path": "/path/to/your/notebook",
163
+ "base_parameters": {
164
+ "param1": "value1"
165
+ }
166
+ },
167
+ "new_cluster": {
168
+ "spark_version": "14.3.x-scala2.12",
169
+ "node_type_id": "m6id.large",
170
+ "driver_node_type_id": "m6id.large",
171
+ "num_workers": 2,
172
+ "aws_attributes": {
173
+ "first_on_demand": 0,
174
+ "availability": "SPOT",
175
+ "zone_id": "auto",
176
+ "spot_bid_price_percent": 100,
177
+ "ebs_volume_count": 0
178
+ },
179
+ "spark_conf": {
180
+ "spark.driver.maxResultSize": "4g"
181
+ }
182
+ }
183
+ },
184
+ {
185
+ "task_key": "task_2",
186
+ "description": "Test Python task",
187
+ "spark_python_task": {
188
+ "python_file": "/path/to/your/python_file.py",
189
+ },
190
+ "new_cluster": {
191
+ "spark_version": "14.3.x-scala2.12",
192
+ "node_type_id": "m6id.large",
193
+ "driver_node_type_id": "m6id.large",
194
+ "num_workers": 2,
195
+ "spark_conf": {
196
+ "spark.driver.maxResultSize": "4g"
197
+ }
198
+ },
199
+ "timeout_seconds": 3600,
200
+ "depends_on": [
201
+ {
202
+ "task_key": "task_1"
203
+ }
204
+ ]
205
+ }
206
+ ]
207
+
208
+ # Update tasks
209
+ optimized_tasks = client.get_optimized_tasks(job_id="my-job-id", tasks=tasks_to_optimize)
210
+
211
+ # Continue with sending the optimized tasks to Databricks via the Databricks python SDK, Airflow operator, etc.
212
+ ```
@@ -1,18 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: zipher-sdk
3
- Version: 0.3.0
4
- Summary: Python SDK for programmatic access to the Zipher API
5
- Home-page: UNKNOWN
6
- Author: Zipher Inc.
7
- Author-email: yoav@zipher.cloud
8
- License: UNKNOWN
9
- Platform: UNKNOWN
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
-
16
1
 
17
2
  # Zipher SDK
18
3
 
@@ -136,4 +121,69 @@ optimized_cluster = client.update_existing_conf(job_id="my-job-id", existing_con
136
121
 
137
122
  ```
138
123
 
124
+ ### Update Existing Multiple Tasks Configuration
125
+
126
+ You can update multiple databricks tasks by initializing a zipher Client and sending a JSON representing a list of dbx SubmitTask objects to
127
+ the `get_optimized_tasks` function.
128
+
129
+ ```python
130
+ from zipher import Client
131
+
132
+ client = Client(customer_id="my_customer_id") # assuming the zipher API key is stored in ZIPHER_API_KEY environment variable
133
+
134
+ tasks_to_optimize = [
135
+ {
136
+ "task_key": "task_1",
137
+ "description": "Test notebook task",
138
+ "notebook_task": {
139
+ "notebook_path": "/path/to/your/notebook",
140
+ "base_parameters": {
141
+ "param1": "value1"
142
+ }
143
+ },
144
+ "new_cluster": {
145
+ "spark_version": "14.3.x-scala2.12",
146
+ "node_type_id": "m6id.large",
147
+ "driver_node_type_id": "m6id.large",
148
+ "num_workers": 2,
149
+ "aws_attributes": {
150
+ "first_on_demand": 0,
151
+ "availability": "SPOT",
152
+ "zone_id": "auto",
153
+ "spot_bid_price_percent": 100,
154
+ "ebs_volume_count": 0
155
+ },
156
+ "spark_conf": {
157
+ "spark.driver.maxResultSize": "4g"
158
+ }
159
+ }
160
+ },
161
+ {
162
+ "task_key": "task_2",
163
+ "description": "Test Python task",
164
+ "spark_python_task": {
165
+ "python_file": "/path/to/your/python_file.py",
166
+ },
167
+ "new_cluster": {
168
+ "spark_version": "14.3.x-scala2.12",
169
+ "node_type_id": "m6id.large",
170
+ "driver_node_type_id": "m6id.large",
171
+ "num_workers": 2,
172
+ "spark_conf": {
173
+ "spark.driver.maxResultSize": "4g"
174
+ }
175
+ },
176
+ "timeout_seconds": 3600,
177
+ "depends_on": [
178
+ {
179
+ "task_key": "task_1"
180
+ }
181
+ ]
182
+ }
183
+ ]
184
+
185
+ # Update tasks
186
+ optimized_tasks = client.get_optimized_tasks(job_id="my-job-id", tasks=tasks_to_optimize)
139
187
 
188
+ # Continue with sending the optimized tasks to Databricks via the Databricks python SDK, Airflow operator, etc.
189
+ ```
@@ -8,7 +8,7 @@ with open('README.md', encoding='utf-8') as f:
8
8
 
9
9
  setup(
10
10
  name='zipher-sdk',
11
- version='0.3.0',
11
+ version='0.4.1',
12
12
  description='Python SDK for programmatic access to the Zipher API',
13
13
  long_description=long_description,
14
14
  long_description_content_type='text/markdown',
@@ -0,0 +1,2 @@
1
+ from .client import Client
2
+ from .models import Config
@@ -122,7 +122,7 @@ class ZipherInstaller:
122
122
  start_date = datetime.now() - timedelta(days=days_back)
123
123
  start_date_ms_int = int(start_date.timestamp() * 1000)
124
124
 
125
- jobs = self.dbx_client.jobs.list(limit=100)
125
+ jobs = self.dbx_client.jobs.list()
126
126
  runs = self.dbx_client.jobs.list_runs(limit=0, start_time_from=start_date_ms_int)
127
127
 
128
128
  all_job_ids = set()
@@ -4,11 +4,9 @@ from typing import Dict, Optional
4
4
 
5
5
  import requests
6
6
  from databricks.sdk.service.compute import ClusterSpec
7
-
8
- from zipher.models import ConfFetcherRequest, Config
7
+ from zipher.models import ConfFetcherRequest, GetOptimizedTasksRequest, Config
9
8
  from zipher.exceptions import MissingAPIKeyError
10
9
 
11
-
12
10
  class Client:
13
11
  def __init__(self, customer_id: str, zipher_api_key: str = '', config: Optional[Config] = None):
14
12
  self.config = config or Config()
@@ -33,17 +31,35 @@ class Client:
33
31
  else:
34
32
  response.raise_for_status()
35
33
 
36
- def get_optimized_config(self, job_id: str) -> Dict:
37
- params = ConfFetcherRequest(customer_id=self.customer_id, job_id=job_id)
34
+ def _call_get_optimized_tasks_api(self, params: GetOptimizedTasksRequest):
35
+ headers = {
36
+ 'x-api-key': self.zipher_api_key
37
+ }
38
+ response = requests.get(
39
+ url=self.config.zipher_get_optimized_tasks_api_endpoint,
40
+ headers=headers,
41
+ params=params.model_dump()
42
+ )
43
+ if response.ok:
44
+ return response.json()
45
+ else:
46
+ response.raise_for_status()
47
+
48
+ def get_optimized_tasks(self, job_id: str, tasks: list[dict]) -> list[dict]:
49
+ params = GetOptimizedTasksRequest(customer_id=self.customer_id, job_id=job_id, tasks=json.dumps(tasks))
50
+ return self._call_get_optimized_tasks_api(params)
51
+
52
+ def get_optimized_config(self, job_id: str, task_key: Optional[str] = None) -> Dict:
53
+ params = ConfFetcherRequest(customer_id=self.customer_id, job_id=job_id, task_key=task_key)
38
54
  return self._call_conf_fetcher_api(params)
39
55
 
40
56
  def get_optimized_config_as_dbx_cluster_spec(self, job_id: str) -> ClusterSpec:
41
57
  return ClusterSpec.from_dict(self.get_optimized_config(job_id))
42
58
 
43
- def update_existing_conf(self, job_id: str, existing_conf: Dict) -> Dict:
59
+ def update_existing_conf(self, job_id: str, existing_conf: Dict, task_key: Optional[str] = None) -> Dict:
44
60
  if 'new_cluster' in existing_conf:
45
61
  existing_conf = existing_conf['new_cluster']
46
- params = ConfFetcherRequest(customer_id=self.customer_id, job_id=job_id, merge_with=json.dumps(existing_conf))
62
+ params = ConfFetcherRequest(customer_id=self.customer_id, job_id=job_id, merge_with=json.dumps(existing_conf), task_key=task_key)
47
63
  try:
48
64
  return self._call_conf_fetcher_api(params)
49
65
  except:
@@ -12,6 +12,7 @@ class WorkspaceClientAuthType(Enum):
12
12
  class ConfFetcherRequest(BaseModel):
13
13
  job_id: str
14
14
  customer_id: str
15
+ task_key: Optional[str] = None
15
16
  merge_with: Optional[str] = None
16
17
 
17
18
 
@@ -24,3 +25,9 @@ class Config(BaseModel, extra='forbid', use_enum_values=True):
24
25
  databricks_client_secret_env_var: str = 'DATABRICKS_CLIENT_SECRET'
25
26
 
26
27
  zipher_config_fetcher_api_endpoint: str = 'https://api.zipher.cloud/default/get_clusterspec'
28
+ zipher_get_optimized_tasks_api_endpoint: str = 'https://api.zipher.cloud/default/get_optimized_tasks'
29
+
30
+ class GetOptimizedTasksRequest(BaseModel):
31
+ customer_id: str
32
+ job_id: str
33
+ tasks: Optional[str] = None
@@ -1,3 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: zipher-sdk
3
+ Version: 0.4.1
4
+ Summary: Python SDK for programmatic access to the Zipher API
5
+ Author: Zipher Inc.
6
+ Author-email: yoav@zipher.cloud
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: pydantic==2.11.3
13
+ Requires-Dist: requests==2.32.3
14
+ Requires-Dist: databricks-sdk==0.52.0
15
+ Dynamic: author
16
+ Dynamic: author-email
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: license-file
21
+ Dynamic: requires-dist
22
+ Dynamic: summary
23
+
1
24
 
2
25
  # Zipher SDK
3
26
 
@@ -120,3 +143,70 @@ optimized_cluster = client.update_existing_conf(job_id="my-job-id", existing_con
120
143
  # Continue with sending the optimized configuration to Databricks via the Databricks python SDK, Airflow operator, etc.
121
144
 
122
145
  ```
146
+
147
+ ### Update Existing Multiple Tasks Configuration
148
+
149
+ You can update multiple databricks tasks by initializing a zipher Client and sending a JSON representing a list of dbx SubmitTask objects to
150
+ the `get_optimized_tasks` function.
151
+
152
+ ```python
153
+ from zipher import Client
154
+
155
+ client = Client(customer_id="my_customer_id") # assuming the zipher API key is stored in ZIPHER_API_KEY environment variable
156
+
157
+ tasks_to_optimize = [
158
+ {
159
+ "task_key": "task_1",
160
+ "description": "Test notebook task",
161
+ "notebook_task": {
162
+ "notebook_path": "/path/to/your/notebook",
163
+ "base_parameters": {
164
+ "param1": "value1"
165
+ }
166
+ },
167
+ "new_cluster": {
168
+ "spark_version": "14.3.x-scala2.12",
169
+ "node_type_id": "m6id.large",
170
+ "driver_node_type_id": "m6id.large",
171
+ "num_workers": 2,
172
+ "aws_attributes": {
173
+ "first_on_demand": 0,
174
+ "availability": "SPOT",
175
+ "zone_id": "auto",
176
+ "spot_bid_price_percent": 100,
177
+ "ebs_volume_count": 0
178
+ },
179
+ "spark_conf": {
180
+ "spark.driver.maxResultSize": "4g"
181
+ }
182
+ }
183
+ },
184
+ {
185
+ "task_key": "task_2",
186
+ "description": "Test Python task",
187
+ "spark_python_task": {
188
+ "python_file": "/path/to/your/python_file.py",
189
+ },
190
+ "new_cluster": {
191
+ "spark_version": "14.3.x-scala2.12",
192
+ "node_type_id": "m6id.large",
193
+ "driver_node_type_id": "m6id.large",
194
+ "num_workers": 2,
195
+ "spark_conf": {
196
+ "spark.driver.maxResultSize": "4g"
197
+ }
198
+ },
199
+ "timeout_seconds": 3600,
200
+ "depends_on": [
201
+ {
202
+ "task_key": "task_1"
203
+ }
204
+ ]
205
+ }
206
+ ]
207
+
208
+ # Update tasks
209
+ optimized_tasks = client.get_optimized_tasks(job_id="my-job-id", tasks=tasks_to_optimize)
210
+
211
+ # Continue with sending the optimized tasks to Databricks via the Databricks python SDK, Airflow operator, etc.
212
+ ```
@@ -1,3 +1,2 @@
1
1
  [console_scripts]
2
2
  zipher = zipher.cli:main
3
-
@@ -1 +0,0 @@
1
- from .client import Client
File without changes
File without changes
File without changes
File without changes
File without changes