diff --git a/.github/workflows/run-smoke-test.yml b/.github/workflows/run-smoke-test.yml index 58bf3db..4d81c8a 100755 --- a/.github/workflows/run-smoke-test.yml +++ b/.github/workflows/run-smoke-test.yml @@ -21,12 +21,10 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install --upgrade setuptools wheel - python -m pip install --upgrade pipenv==2018.11.26 - name: Install test dependencies - run: pipenv install --dev - working-directory: example + run: pip install -e ./ - name: Run smoke test - run: pipenv run python example.py + run: python example.py working-directory: example env: API_BASE_PATH: "http://test-api.regulaforensics.com" diff --git a/.gitignore b/.gitignore index d89e878..5b82fb4 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea example/portrait.jpg example/document-image.jpg +example/regula.license # Byte-compiled / optimized / DLL files diff --git a/README.md b/README.md index 0faeb15..a5ba5de 100755 --- a/README.md +++ b/README.md @@ -1,17 +1,67 @@ -# Regula Document Reader web application python client +# Regula Document Reader web API Python 3.5+ client -## Development +[![pypi](https://img.shields.io/pypi/v/regula.documentreader.webclient?style=flat-square)](https://support.regulaforensics.com/hc/en-us/articles/115000916306-Documentation) +[![OpenAPI](https://img.shields.io/badge/OpenAPI-defs-8c0a56?style=flat-square)](https://github.com/regulaforensics/DocumentReader-web-openapi) +[![documentation](https://img.shields.io/badge/docs-en-f6858d?style=flat-square)](https://support.regulaforensics.com/hc/en-us/articles/115000916306-Documentation) +[![live](https://img.shields.io/badge/live-demo-0a8c42?style=flat-square)](https://api.regulaforensics.com/) + +Documents recognition as easy as reading two bytes. + +If you have any problems with or questions about this client, please contact us +through a [GitHub issue](https://github.com/regulaforensics/DocumentReader-web-python-client/issues). +You are invited to contribute [new features, fixes, or updates](https://github.com/regulaforensics/DocumentReader-web-python-client/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22), large or small; +We are always thrilled to receive pull requests, and do our best to process them as fast as we can. +See [dev guide](./dev.md) + +## Install package +`regula.documentreader.webclient` is on the Python Package Index (PyPI): -To regenerate models from openapi definition, -clone [latest open api definitions](https://github.com/regulaforensics/DocumentReader-api-openapi) -and set `DEFINITION_FOLDER` as path to cloned directory, for example: ```bash -DEFINITION_FOLDER="/home/user/projects/DocumentReader-api-openapi" +pip install regula.documentreader.webclient ``` -Then use next command from the project root: + +Or using `pipenv` ```bash -docker run --rm -v "${PWD}:/client" -v "${DEFINITION_FOLDER}:/definitions" \ -openapitools/openapi-generator-cli generate -g python \ --i /definitions/index.yml -o /client -c /client/generator-config.json \ --t /client/generator-templates +pipenv install regula.documentreader.webclient +``` + +## Example +Performing request: +```python +from regula.documentreader.webclient.ext.api import DocumentReaderApi +from regula.documentreader.webclient.ext.models import * +from regula.documentreader.webclient.gen.models import * + +with open("australia_passport.jpg", "rb") as f: + input_image = f.read() + +with DocumentReaderApi(host='http://localhost:8080') as api: + params = ProcessParams( + scenario=Scenario.FULL_PROCESS, + result_type_output=[Result.DOCUMENT_IMAGE, Result.STATUS, Result.TEXT, Result.IMAGES] + ) + request = RecognitionRequest(process_params=params, images=[input_image]) + response = api.process(request) +``` + +Parsing results: +```python +# status examples +response_status = response.status +doc_overall_status = "valid" if response_status.overall_status == CheckResult.OK else "not valid" + +# text fields example +doc_number_field = response.text.get_field(TextFieldType.DOCUMENT_NUMBER) +doc_number_mrz = doc_number_field.get_value() +doc_number_visual = doc_number_field.get_value(Source.VISUAL) +doc_number_visual_validity = doc_number_field.source_validity(Source.VISUAL) +doc_number_mrz_validity = doc_number_field.source_validity(Source.MRZ) +doc_number_mrz_visual_matching = doc_number_field.cross_source_comparison(Source.MRZ, Source.VISUAL) + +# images fields example +normalized_input_image = response.images.document_image() +portrait_field = response.images.get_field(GraphicFieldType.PORTRAIT) +portrait_from_visual = portrait_field.get_value(Source.VISUAL) +portrait_from_rfid = portrait_field.get_value(Source.RFID, original=True) ``` +You can find more detailed guide and run this sample in [example](./example) folder. diff --git a/dev.md b/dev.md new file mode 100644 index 0000000..60d766a --- /dev/null +++ b/dev.md @@ -0,0 +1,14 @@ +# Development + +To regenerate models, clone [latest OpenAPI definitions](https://github.com/regulaforensics/DocumentReader-web-openapi) +and set `DEFINITION_FOLDER` as path to cloned directory, for example: +```bash +DEFINITION_FOLDER="/home/user/projects/DocumentReader-web-openapi" +``` +Then use next command from the project root: +```bash +docker run --rm -v "${PWD}:/client" -v "${DEFINITION_FOLDER}:/definitions" \ +openapitools/openapi-generator-cli generate -g python \ +-i /definitions/index.yml -o /client -c /client/generator-config.json \ +-t /client/generator-templates +``` diff --git a/example/Pipfile b/example/Pipfile deleted file mode 100755 index dcfc727..0000000 --- a/example/Pipfile +++ /dev/null @@ -1,15 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true -name = "pypi" - -[[source]] -url = "https://test.pypi.org/simple/" -verify_ssl = true -name = "test-pypi" - -[packages] -"regula.documentreader.webclient" = {editable = true,path = "./.."} - -[requires] -python_version = "3.5" diff --git a/example/Pipfile.lock b/example/Pipfile.lock deleted file mode 100755 index 00a2513..0000000 --- a/example/Pipfile.lock +++ /dev/null @@ -1,64 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "5096dd2d4162b442dbae72ea134b4c170c06dcf6967c2dbc661f5be6e4cac554" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.5" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - }, - { - "name": "test-pypi", - "url": "https://test.pypi.org/simple/", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", - "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" - ], - "version": "==2020.6.20" - }, - "future": { - "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" - ], - "version": "==0.18.2" - }, - "python-dateutil": { - "hashes": [ - "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", - "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" - ], - "version": "==2.8.1" - }, - "regula.documentreader.webclient": { - "editable": true, - "path": "./.." - }, - "six": { - "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" - ], - "version": "==1.15.0" - }, - "urllib3": { - "hashes": [ - "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a", - "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461" - ], - "version": "==1.25.10" - } - }, - "develop": {} -} diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..172e692 --- /dev/null +++ b/example/README.md @@ -0,0 +1,66 @@ +# Regula Document Reader web API Python 3.5+ client + +:bulb: Before you start: if you just want to play with an online demo, visit our [playground](https://api.regulaforensics.com). + +:warning: NOTE: for some systems `python3` and `pip3` commands should be used, instead of `python` and `pip`. + +Requirements: +- installed python 3.5 or higher +- installed [pip](https://pip.pypa.io/en/stable/installing/) + +Verify Python and pip versions: +```bash +python --version +> Python 3.8.2 +pip --version +> pip 20.2.1 from /home/user/.local/lib/python3.8/site-packages/pip (python 3.8) +``` + +Cloning example: +```bash +git clone https://github.com/regulaforensics/DocumentReader-web-python-client.git +cd DocumentReader-web-python-client +``` + +Setup project and download dependencies: +```bash +pip install -e ./ +``` + +### Running with local Regula Document Reader web API installation + +Follow [the instructions](https://docs.regulaforensics.com/web/quick-start-guide) to run Regula Document Reader web API. +Assuming you have successfully launched instance, use next line command to run example: +```bash +cd example +python example.py + +# If Regula Document Reader web API is running not on localhost, specify host via env variable: +API_BASE_PATH="http://192.168.0.101:8080" python example.py +``` + +### Running using Regula Document Reader web API test SaaS + +Get your [free trial here](https://mobile.regulaforensics.com/). You should obtain `regula.license` file. +Copy it to **example** folder. You are ready for running! + +Execute example: +```bash +cd example +API_BASE_PATH="https://test-api.regulaforensics.com" python example.py +``` + +### Output +This sample generates next text output: +```text + --------------------------------------------------------------------------- + Document Overall Status: not valid + Document Number Visual: U0996738 + Document Number MRZ: U0996738 + Validity Of Document Number Visual: 1 + Validity Of Document Number MRZ: 1 + MRZ-Visual values comparison: 1 + --------------------------------------------------------------------------- +``` +Also, it creates [portrait](portrait.jpg) and [document image](document-image.jpg) pictures inside current folder. +Edit on your own [example.py](./example.py), and re-run to see your results. diff --git a/example/example.py b/example/example.py index 58f97d5..2b4bb76 100755 --- a/example/example.py +++ b/example/example.py @@ -6,13 +6,19 @@ CheckResult, GraphicFieldType host = os.getenv("API_BASE_PATH", "http://localhost:8080") -license = os.getenv("TEST_LICENSE", None) # optional, used here only for smoke test purposes +regula_license = os.getenv("TEST_LICENSE", None) # optional, used here only for smoke test purposes + +# read optional local license file +if os.path.isfile('regula.license') and os.access('regula.license', os.R_OK): + with open("regula.license", "rb") as f: + print("Found local license file. Using it for performing request...") + regula_license = f.read() with open("australia_passport.jpg", "rb") as f: input_image = f.read() with DocumentReaderApi(host) as api: - api.license = license # used here only for smoke test purposes, most clients will attach license on server side + api.license = regula_license params = ProcessParams( scenario=Scenario.FULL_PROCESS, @@ -27,21 +33,20 @@ # text fields example doc_number_field = response.text.get_field(TextFieldType.DOCUMENT_NUMBER) - doc_number_visual = doc_number_field.get_value() - doc_number_mrz = doc_number_field.get_value(Source.MRZ) + doc_number_mrz = doc_number_field.get_value() + doc_number_visual = doc_number_field.get_value(Source.VISUAL) doc_number_visual_validity = doc_number_field.source_validity(Source.VISUAL) doc_number_mrz_validity = doc_number_field.source_validity(Source.MRZ) doc_number_mrz_visual_matching = doc_number_field.cross_source_comparison(Source.MRZ, Source.VISUAL) # images fields example document_image = response.images.document_image() - portrait_Field = response.images.get_field(GraphicFieldType.PORTRAIT) - portrait_From_Visual = portrait_Field.get_value(Source.VISUAL) - with open('portrait.jpg', 'wb') as f: f.write(portrait_From_Visual) - with open('document-image.jpg', 'wb') as f: f.write(document_image) - - # low-lvl(original) response - response.low_lvl_response + portrait_field = response.images.get_field(GraphicFieldType.PORTRAIT) + portrait_from_visual = portrait_field.get_value(Source.VISUAL) + with open('portrait.jpg', 'wb') as f: + f.write(portrait_from_visual) + with open('document-image.jpg', 'wb') as f: + f.write(document_image) print(""" --------------------------------------------------------------------------- diff --git a/regula/documentreader/webclient/ext/api/document_reader_api.py b/regula/documentreader/webclient/ext/api/document_reader_api.py index 9cdf95c..fa4daa4 100755 --- a/regula/documentreader/webclient/ext/api/document_reader_api.py +++ b/regula/documentreader/webclient/ext/api/document_reader_api.py @@ -1,8 +1,13 @@ +import base64 +from typing import Union + from regula.documentreader.webclient.ext.models.recognition_response import RecognitionResponse from regula.documentreader.webclient.gen import ApiClient, Configuration from regula.documentreader.webclient.gen.api import DefaultApi from regula.documentreader.webclient.gen.models import ProcessRequest +Base64String = str + class DocumentReaderApi(DefaultApi): @@ -24,12 +29,15 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.api_client.close() @property - def license(self) -> str: + def license(self) -> Base64String: return self.__license @license.setter - def license(self, value: str): - self.__license = value + def license(self, value: Union[Base64String, bytes]): + if isinstance(value, bytes): + self.__license = base64.b64encode(value).decode("utf-8") + else: + self.__license = value def process(self, process_request: ProcessRequest) -> RecognitionResponse: process_request.system_info.license = self.license