Skip to content

Commit 235cd60

Browse files
Add new routes to SDK
1 parent aa53474 commit 235cd60

File tree

4 files changed

+331
-0
lines changed

4 files changed

+331
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ With the job or batch id, you can get the job result or batch status with:
158158
client.get_batch_status("BATCH_ID") # Batches
159159
client.get_job_result("JOB_ID", "JOB_ID") # Simple jobs
160160
client.get_job_result("BATCH_ID", "JOB_ID") # Jobs belonging to batches
161+
client.get_batch_result("BATCH_ID") # Get batch jobs result as array
162+
client.get_batch_result_storage("BATCH_ID", params=params) # Get batch jobs result in a file
163+
164+
# More details about job and batch
165+
client.get_batch_info("BATCH_ID") # Batches info (without jobs info)
166+
client.get_job_info("JOB_ID") # Jobs info (single jobs only)
161167
```
162168

163169
Alternatively, you can use a utily `wait_for_job_done` or `wait_for_batch_done`:

tests/test_functions.py

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,3 +1007,158 @@ def test_create_and_wait_job_timeout():
10071007
unittest.TestCase().assertRaises(
10081008
TimeoutException, c.create_and_wait_job, "rg", "./requirements.txt"
10091009
)
1010+
1011+
@responses.activate
1012+
def test_get_batch_info():
1013+
responses.add(
1014+
responses.GET,
1015+
f"{BASE_URL}/ocr/batch/info/123",
1016+
json={
1017+
"company_id": "1234",
1018+
"client_id": "12345",
1019+
"batch_id": "123",
1020+
"created_at": "2022-06-22T20:58:09Z",
1021+
"service": "rg",
1022+
"status": "processing",
1023+
"source": "API",
1024+
"total_jobs": 3,
1025+
"total_processed": 2,
1026+
},
1027+
status=200,
1028+
)
1029+
1030+
c = Client()
1031+
res = c.get_batch_info("123")
1032+
1033+
assert res.get("batch_id")
1034+
assert res.get("service")
1035+
assert res.get("client_id")
1036+
assert res.get("status")
1037+
1038+
assert res.get("batch_id") == "123"
1039+
assert res.get("client_id") == "12345"
1040+
assert res.get("service") == "rg"
1041+
assert res.get("status") == "processing"
1042+
1043+
1044+
@responses.activate
1045+
def test_get_batch_info_unauthorized():
1046+
responses.add(
1047+
responses.GET,
1048+
f"{BASE_URL}/ocr/batch/info/123",
1049+
status=401,
1050+
)
1051+
1052+
c = Client()
1053+
unittest.TestCase().assertRaises(
1054+
InvalidStatusCodeException, c.get_batch_info, "123"
1055+
)
1056+
1057+
@responses.activate
1058+
def test_get_job_info():
1059+
responses.add(
1060+
responses.GET,
1061+
f"{BASE_URL}/ocr/job/info/123",
1062+
json={
1063+
"client_id": "12345",
1064+
"job_id": "123",
1065+
"service": "rg",
1066+
"status": "processing",
1067+
},
1068+
status=200,
1069+
)
1070+
1071+
c = Client()
1072+
res = c.get_job_info("123")
1073+
1074+
assert res.get("job_id")
1075+
assert res.get("service")
1076+
assert res.get("client_id")
1077+
assert res.get("status")
1078+
1079+
assert res.get("job_id") == "123"
1080+
assert res.get("client_id") == "12345"
1081+
assert res.get("service") == "rg"
1082+
assert res.get("status") == "processing"
1083+
1084+
1085+
@responses.activate
1086+
def test_get_job_info_unauthorized():
1087+
responses.add(
1088+
responses.GET,
1089+
f"{BASE_URL}/ocr/job/info/123",
1090+
status=401,
1091+
)
1092+
1093+
c = Client()
1094+
unittest.TestCase().assertRaises(
1095+
InvalidStatusCodeException, c.get_job_info, "123"
1096+
)
1097+
1098+
@responses.activate
1099+
def test_get_batch_result():
1100+
responses.add(
1101+
responses.GET,
1102+
f"{BASE_URL}/ocr/batch/result/123",
1103+
json=[
1104+
{
1105+
"job_ksuid": "123",
1106+
"service": "rg",
1107+
"status": "processing",
1108+
},
1109+
],
1110+
status=200,
1111+
)
1112+
1113+
c = Client()
1114+
res = c.get_batch_result("123")
1115+
1116+
assert res
1117+
assert len(res) == 1
1118+
1119+
@responses.activate
1120+
def test_get_batch_result_unauthorized():
1121+
responses.add(
1122+
responses.GET,
1123+
f"{BASE_URL}/ocr/batch/result/123",
1124+
status=401,
1125+
)
1126+
1127+
c = Client()
1128+
unittest.TestCase().assertRaises(
1129+
InvalidStatusCodeException, c.get_batch_result, "123"
1130+
)
1131+
1132+
@responses.activate
1133+
def test_get_batch_result_storage():
1134+
responses.add(
1135+
responses.GET,
1136+
f"{BASE_URL}/ocr/batch/result/123",
1137+
json={
1138+
"exp": "60000",
1139+
"url": "https://presignedurldemo.s3.eu-west-2.amazonaws.com/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host"
1140+
},
1141+
status=200,
1142+
)
1143+
1144+
c = Client()
1145+
res = c.get_batch_result_storage("123")
1146+
1147+
assert res.get("exp")
1148+
assert res.get("url")
1149+
1150+
assert res.get("exp") == "60000"
1151+
1152+
1153+
@responses.activate
1154+
def test_get_batch_result_storage_unauthorized():
1155+
responses.add(
1156+
responses.GET,
1157+
f"{BASE_URL}/ocr/batch/result/123",
1158+
status=401,
1159+
)
1160+
1161+
c = Client()
1162+
unittest.TestCase().assertRaises(
1163+
InvalidStatusCodeException, c.get_batch_result_storage, "123"
1164+
)

ultraocr/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
KEY_FACEMATCH = "facematch"
1414
KEY_EXTRA = "extra-document"
1515
FLAG_TRUE = "true"
16+
RETURN_REQUEST = "request"
17+
RETURN_STORAGE = "storage"
1618

1719

1820
class Resource(Enum):

ultraocr/functions.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
FLAG_TRUE,
2626
KEY_EXTRA,
2727
KEY_FACEMATCH,
28+
RETURN_REQUEST,
29+
RETURN_STORAGE,
2830
)
2931

3032

@@ -121,6 +123,14 @@ def _auto_authenticate(self) -> None:
121123
if self.auto_refresh and datetime.now() > self.expires_at:
122124
self.authenticate(self.client_id, self.client_secret, self.expires)
123125

126+
def _get_batch_result(self, batch_id: str, params: dict = None):
127+
url = f"{self.base_url}/ocr/batch/result/{batch_id}"
128+
129+
resp = self._get(url, params=params)
130+
validate_status_code(resp.status_code, HTTPStatus.OK)
131+
132+
return resp.json()
133+
124134
def authenticate(
125135
self, client_id: str, client_secret: str, expires: int = DEFAULT_EXPIRATION_TIME
126136
) -> None:
@@ -785,3 +795,161 @@ def create_and_wait_batch(
785795
batch_id = res.get("id")
786796

787797
return self.wait_for_batch_done(batch_id, wait_jobs)
798+
799+
def get_job_info(self, job_id: str):
800+
"""Get job info.
801+
802+
Get the info with more details.
803+
804+
Args:
805+
job_id: The id of the job, given on job creation or on batch status.
806+
807+
Returns:
808+
A json response containing the client data (if given on job creation), the metadata (if
809+
given on job creation), job id, company id, client id creation time, service, source,
810+
status (may be "waiting", "error", "processing", "validating" or "done") and the result
811+
or error depending on the status. For example:
812+
{
813+
"client_data": { },
814+
"metadata": { },
815+
"created_at": "2022-06-22T20:58:09Z",
816+
"company_id": "123",
817+
"client_id": "1234",
818+
"job_id": "2AwrSd7bxEMbPrQ5jZHGDzQ4qL3",
819+
"source": "API",
820+
"result": {
821+
"Time": "7.45",
822+
"Document": [
823+
{
824+
"Page": 1,
825+
"Data": {
826+
"DocumentType": {
827+
"conf": 99,
828+
"value": "CNH"
829+
}
830+
}
831+
}
832+
]
833+
},
834+
"service": "idtypification",
835+
"status": "done"
836+
}
837+
838+
Raises:
839+
InvalidStatusCodeException: If status code is not 200.
840+
"""
841+
url = f"{self.base_url}/ocr/job/info/{job_id}"
842+
843+
resp = self._get(url)
844+
validate_status_code(resp.status_code, HTTPStatus.OK)
845+
846+
return resp.json()
847+
848+
def get_batch_info(self, batch_id: str):
849+
"""Get document batch info.
850+
851+
Get the info of the batch with more details, checking whether it was processed or not.
852+
853+
Args:
854+
batch_id: The id of the batch, given on batch creation.
855+
856+
Returns:
857+
A json response containing the id, company id, client id, creation time, service,
858+
source, number of jobs, number of processed jobs and status (may be "waiting", "error",
859+
"processing" or "done"). For example:
860+
{
861+
"company_id": "123",
862+
"client_id": "1234",
863+
"batch_id": "2AwrSd7bxEMbPrQ5jZHGDzQ4qL3",
864+
"created_at": "2022-06-22T20:58:09Z",
865+
"service": "cnh",
866+
"status": "done",
867+
"source": "API",
868+
"total_jobs": 3,
869+
"total_processed": 2,
870+
}
871+
872+
Raises:
873+
InvalidStatusCodeException: If status code is not 200.
874+
"""
875+
url = f"{self.base_url}/ocr/batch/info/{batch_id}"
876+
877+
resp = self._get(url)
878+
validate_status_code(resp.status_code, HTTPStatus.OK)
879+
880+
return resp.json()
881+
882+
def get_batch_result(self, batch_id: str):
883+
"""Get batch jobs results.
884+
885+
Get the batch jobs results as array.
886+
887+
Args:
888+
batch_id: The id of the batch, given on batch creation.
889+
890+
Returns:
891+
A json response containing the url to download and the expiration time (1 minute).
892+
For example:
893+
[
894+
{
895+
"client_data": { },
896+
"created_at": "2022-06-22T20:58:09Z",
897+
"job_ksuid": "2AwrSd7bxEMbPrQ5jZHGDzQ4qL3",
898+
"result": {
899+
"Time": "7.45",
900+
"Document": [
901+
{
902+
"Page": 1,
903+
"Data": {
904+
"DocumentType": {
905+
"conf": 99,
906+
"value": "CNH"
907+
}
908+
}
909+
}
910+
]
911+
},
912+
"service": "idtypification",
913+
"status": "done",
914+
"filename": "123.jpg"
915+
}
916+
]
917+
918+
Raises:
919+
InvalidStatusCodeException: If status code is not 200.
920+
"""
921+
params = {
922+
"return": RETURN_REQUEST,
923+
}
924+
925+
return self._get_batch_result(batch_id, params)
926+
927+
def get_batch_result_storage(self, batch_id: str, params: dict = None):
928+
"""Get batch jobs results as file.
929+
930+
Generate url to download a file containing the batch jobs results.
931+
932+
Args:
933+
batch_id: The id of the batch, given on batch creation.
934+
params: The query parameters based on UltraOCR Docs.
935+
936+
Returns:
937+
A json response containing the url to download and the expiration time (1 minute).
938+
For example:
939+
{
940+
"exp": "60000",
941+
"url": "https://presignedurldemo.s3.eu-west-2.amazonaws.com/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host"
942+
}
943+
944+
Raises:
945+
InvalidStatusCodeException: If status code is not 200.
946+
"""
947+
if params is None:
948+
params = {}
949+
950+
params = {
951+
**params,
952+
"return": RETURN_STORAGE,
953+
}
954+
955+
return self._get_batch_result(batch_id, params)

0 commit comments

Comments
 (0)