Skip to content

Commit c6b564d

Browse files
authored
Merge pull request #52 from Sindri-Labs/kp-slim-status-endpoint
Use new status endpoints for circuit/proof polling
2 parents 7f9baf2 + 4588aaa commit c6b564d

2 files changed

Lines changed: 97 additions & 44 deletions

File tree

src/sindri/sindri.py

Lines changed: 94 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,28 @@ def _get_circuit(self, circuit_id: str, include_verification_key: bool = False)
160160
raise Sindri.APIError("Received unexpected type for circuit detail response.")
161161
return response_json
162162

163+
def _get_circuit_status(
164+
self,
165+
circuit_id: str,
166+
) -> str:
167+
"""Hit the circuit_status API endpoint and validate the response. Do not print anything.
168+
This may raise `Sindri.APIError` if the response is invalid."""
169+
response_status_code, response_json = self._hit_api(
170+
"GET",
171+
f"circuit/{circuit_id}/status",
172+
)
173+
if response_status_code != 200:
174+
raise Sindri.APIError(
175+
f"Unable to fetch circuit_id={circuit_id}."
176+
f" status={response_status_code} response={response_json}"
177+
)
178+
if not isinstance(response_json, dict):
179+
raise Sindri.APIError("Received unexpected type for circuit status response.")
180+
status = response_json.get("status", "")
181+
if status == "":
182+
raise Sindri.APIError("Received unexpected type for circuit status response.")
183+
return status
184+
163185
def _get_proof(
164186
self,
165187
proof_id: str,
@@ -189,27 +211,49 @@ def _get_proof(
189211
raise Sindri.APIError("Received unexpected type for proof detail response.")
190212
return response_json
191213

214+
def _get_proof_status(
215+
self,
216+
proof_id: str,
217+
) -> str:
218+
"""Hit the proof_status API endpoint and validate the response. Do not print anything.
219+
This may raise `Sindri.APIError` if the response is invalid."""
220+
response_status_code, response_json = self._hit_api(
221+
"GET",
222+
f"proof/{proof_id}/status",
223+
)
224+
if response_status_code != 200:
225+
raise Sindri.APIError(
226+
f"Unable to fetch proof_id={proof_id}."
227+
f" status={response_status_code} response={response_json}"
228+
)
229+
if not isinstance(response_json, dict):
230+
raise Sindri.APIError("Received unexpected type for proof status response.")
231+
status = response_json.get("status", "")
232+
if status == "":
233+
raise Sindri.APIError("Received unexpected type for proof status response.")
234+
return status
235+
192236
def _get_verbose_1_circuit_detail(self, circuit_detail: dict) -> dict:
193237
"""Return a slim circuit detail object for printing."""
194238
return {
239+
"status": circuit_detail.get("status", None),
240+
"project_name": circuit_detail.get("project_name", None),
195241
"circuit_id": circuit_detail.get("circuit_id", None),
196-
"circuit_name": circuit_detail.get("circuit_name", None),
242+
"tags": circuit_detail.get("tags", None),
197243
"circuit_type": circuit_detail.get("circuit_type", None),
198244
"compute_time": circuit_detail.get("compute_time", None),
199-
"date_created": circuit_detail.get("date_created", None),
200-
"status": circuit_detail.get("status", None),
201245
}
202246

203247
def _get_verbose_1_proof_detail(self, proof_detail: dict) -> dict:
204248
"""Return a slim proof detail object for printing."""
205249
return {
250+
"status": proof_detail.get("status", None),
251+
"proof_id": proof_detail.get("proof_id", None),
252+
"project_name": proof_detail.get("project_name", None),
206253
"circuit_id": proof_detail.get("circuit_id", None),
207-
"circuit_name": proof_detail.get("circuit_name", None),
254+
"tags": proof_detail.get("tags", None),
208255
"circuit_type": proof_detail.get("circuit_type", None),
209256
"compute_time": proof_detail.get("compute_time", None),
210-
"date_created": proof_detail.get("date_created", None),
211-
"proof_id": proof_detail.get("proof_id", None),
212-
"status": proof_detail.get("status", None),
213257
}
214258

215259
def _hit_api(self, method: str, path: str, data=None, files=None) -> tuple[int, dict | list]:
@@ -288,19 +332,11 @@ def _print_sindri_logo(self):
288332
# https://ascii-generator.site/ 32 columns
289333
print(
290334
f"""Sindri API Python SDK - {self.version}
291-
.+******************+.
292-
=********************=
293-
.:. -==================-
294-
=****
295-
=****-
296-
.::-*+==================-
297-
=********************=
298-
.+******************+.
299-
=**+:
300-
:*****
301-
.:::::::::::::::::::::++==-
302-
.***********************+
303-
.***********************-"""
335+
-++++++-
336+
-+.
337+
+******=
338+
.*-
339+
-*******="""
304340
)
305341

306342
def _set_json_request_headers(self) -> None:
@@ -379,8 +415,9 @@ def create_circuit(
379415
)
380416
if not isinstance(response_json, dict):
381417
raise Sindri.APIError("Received unexpected type for circuit detail response.")
382-
# Obtain circuit_id from response
383-
circuit_id = response_json.get("circuit_id", "")
418+
# Obtain circuit_id
419+
circuit = response_json
420+
circuit_id = circuit.get("circuit_id", "")
384421
if self.verbose_level > 0:
385422
print(f" circuit_id: {circuit_id}")
386423

@@ -389,20 +426,26 @@ def create_circuit(
389426
if self.verbose_level > 0:
390427
print("Circuit: Poll until Ready/Failed")
391428
for _ in range(self.max_polling_iterations):
392-
circuit = self._get_circuit(circuit_id, include_verification_key=False)
393-
circuit_status = circuit.get("status", "")
394-
if circuit_status == "Failed":
395-
raise Sindri.APIError(
396-
f"Circuit compilation failed." f" error={circuit.get('error', '')}"
397-
)
398-
if circuit_status == "Ready":
429+
circuit_status = self._get_circuit_status(circuit_id)
430+
if circuit_status in ["Ready", "Failed"]:
399431
break
400432
time.sleep(self.polling_interval_sec)
401433
else:
402434
raise Sindri.APIError("Circuit compile polling timed out.")
403435

436+
# Done polling. Fetch the full detail.
437+
circuit = self._get_circuit(circuit_id, include_verification_key=True)
438+
circuit_status = circuit.get("status", "")
439+
if circuit_status == "Failed":
440+
raise Sindri.APIError(
441+
f"Circuit compilation failed." f" error={circuit.get('error', '')}"
442+
)
443+
404444
if self.verbose_level > 0:
405-
self.get_circuit(circuit_id, include_verification_key=True)
445+
circuit_detail = circuit.copy()
446+
if self.verbose_level == 1:
447+
circuit_detail = self._get_verbose_1_circuit_detail(circuit_detail)
448+
print(f"{pformat(circuit_detail, indent=4)}\n")
406449

407450
# Circuit compilation success!
408451
return circuit_id
@@ -749,8 +792,9 @@ def prove_circuit(
749792
)
750793
if not isinstance(response_json, dict):
751794
raise Sindri.APIError("Received unexpected type for proof detail response.")
752-
# Obtain proof_id from response
753-
proof_id = response_json.get("proof_id", "")
795+
# Obtain proof_id
796+
proof = response_json
797+
proof_id = proof.get("proof_id", "")
754798
if self.verbose_level > 0:
755799
print(f" proof_id: {proof_id}")
756800

@@ -759,24 +803,30 @@ def prove_circuit(
759803
if self.verbose_level > 0:
760804
print("Proof: Poll until Ready/Failed")
761805
for _ in range(self.max_polling_iterations):
762-
proof = self._get_proof(
763-
proof_id,
764-
include_proof=False,
765-
include_public=False,
766-
include_smart_contract_calldata=False,
767-
include_verification_key=False,
768-
)
769-
proof_status = proof.get("status", "")
770-
if proof_status == "Failed":
771-
raise Sindri.APIError(f"Prove circuit failed. error={proof.get('error', '')}")
772-
if proof_status == "Ready":
806+
proof_status = self._get_proof_status(proof_id)
807+
if proof_status in ["Ready", "Failed"]:
773808
break
774809
time.sleep(self.polling_interval_sec)
775810
else:
776811
raise Sindri.APIError("Prove circuit polling timed out.")
777812

813+
# Done polling. Fetch the full detail.
814+
proof = self._get_proof(
815+
proof_id,
816+
include_proof=True,
817+
include_public=True,
818+
include_smart_contract_calldata=True,
819+
include_verification_key=True,
820+
)
821+
proof_status = proof.get("status", "")
822+
if proof_status == "Failed":
823+
raise Sindri.APIError(f"Prove circuit failed." f" error={proof.get('error', '')}")
824+
778825
if self.verbose_level > 0:
779-
self.get_proof(proof_id)
826+
proof_detail = proof.copy()
827+
if self.verbose_level == 1:
828+
proof_detail = self._get_verbose_1_proof_detail(proof_detail)
829+
print(f"{pformat(proof_detail, indent=4)}\n")
780830

781831
# Prove circuit success!
782832
return proof_id

tests/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ If you are running the Sindri api locally at `~/myproject` with `~/myproject/API
5252
```bash
5353
SINDRI_BASE_URL=http://localhost SINDRI_API_KEY=$(cat ~/myproject/API_KEY) pytest
5454
```
55+
56+
#### Show standard output during pytest
57+
Add the `-s` flag to `pytest` to print standard output to the terminal for successful tests.

0 commit comments

Comments
 (0)