Skip to content

Commit d4ed035

Browse files
authored
Merge pull request #193 from getyoti/release-2.12.0
Release 2.12.0
2 parents c98bf4c + c7dff81 commit d4ed035

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1839
-43
lines changed

README.md

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -247,31 +247,12 @@ To run the Flask or Django container:
247247

248248
### Running Locally
249249

250-
1. Both example applications utilise the env variables described in [Configuration](#configuration), make sure they are accessible.
251-
1. Ensure pip is up to date: `easy_install --upgrade pip`
252-
1. Ensure setuptools and wheel are up to date: `python -m pip install --upgrade setuptools wheel`
250+
#### Follow instructions in the README for each example:
253251

254-
#### Flask
255-
256-
1. Change directories to the Flask project: `cd examples/yoti_example_flask`
257-
1. Install dependencies: `pip install -r requirements.txt`
258-
1. Run `python app.py`
259-
1. Navigate to https://localhost:5000
260-
261-
#### Django
262-
263-
1. You will need Python 3+ to run the Django example
264-
1. Change directories to the Django project: `cd examples/yoti_example_django`
265-
1. Install dependencies: `pip install -r requirements.txt`
266-
1. Apply migrations before the first start by running: `python manage.py migrate`
267-
1. Run: `python manage.py runsslserver 0.0.0.0:5000`
268-
1. Navigate to https://localhost:5000
269-
270-
#### AML Example
271-
272-
1. Change directories to the AML folder: `cd examples/aml`
273-
1. Install requirements with `pip install -r requirements.txt`
274-
1. Run: `python app.py`
252+
* [Profile - Django](examples/yoti_example_django)
253+
* [Profile - Flask](examples/yoti_example_flask)
254+
* [AML](examples/aml)
255+
* [Doc Scan](examples/doc_scan)
275256

276257
## Running the Tests
277258

examples/aml/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
### AML Example Project
2+
3+
1. Rename the [.env.example](.env.example) file to `.env` and fill in the required configuration values
4+
1. Install requirements with `pip install -r requirements.txt`
5+
1. Run: `python app.py`

examples/doc_scan/.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Required Keys
2+
YOTI_CLIENT_SDK_ID=yourClientSdkId
3+
YOTI_KEY_FILE_PATH=yourKeyFilePath

examples/doc_scan/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pem

examples/doc_scan/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Doc Scan Example
2+
3+
## Running the example
4+
5+
1. Rename the [.env.example](.env.example) file to `.env` and fill in the required configuration values
6+
1. Install the dependencies with `pip install -r requirements.txt`
7+
1. Start the server `flask run --cert=adhoc`
8+
1. Visit `https://localhost:5000`

examples/doc_scan/__init__.py

Whitespace-only changes.

examples/doc_scan/app.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import base64
2+
from io import BytesIO
3+
4+
import yoti_python_sdk
5+
from filetype import filetype
6+
from flask import Flask, Response, render_template, request, send_file, session
7+
from yoti_python_sdk.doc_scan import (
8+
DocScanClient,
9+
RequestedDocumentAuthenticityCheckBuilder,
10+
RequestedFaceMatchCheckBuilder,
11+
RequestedLivenessCheckBuilder,
12+
RequestedTextExtractionTaskBuilder,
13+
SdkConfigBuilder,
14+
SessionSpecBuilder,
15+
)
16+
from yoti_python_sdk.doc_scan.exception import DocScanException
17+
18+
from .settings import YOTI_APP_BASE_URL, YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH
19+
20+
app = Flask(__name__)
21+
app.secret_key = "someSecretKey"
22+
23+
24+
def create_session():
25+
"""
26+
Creates a Doc Scan session
27+
28+
:return: the create session result
29+
:rtype: CreateSessionResult
30+
"""
31+
doc_scan_client = DocScanClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
32+
33+
sdk_config = (
34+
SdkConfigBuilder()
35+
.with_allows_camera_and_upload()
36+
.with_primary_colour("#2d9fff")
37+
.with_secondary_colour("#FFFFFF")
38+
.with_font_colour("#FFFFFF")
39+
.with_locale("en-GB")
40+
.with_preset_issuing_country("GBR")
41+
.with_success_url("{url}/success".format(url=YOTI_APP_BASE_URL))
42+
.with_error_url("{url}/error".format(url=YOTI_APP_BASE_URL))
43+
.build()
44+
)
45+
46+
session_spec = (
47+
SessionSpecBuilder()
48+
.with_client_session_token_ttl(600)
49+
.with_resources_ttl(90000)
50+
.with_user_tracking_id("some-user-tracking-id")
51+
.with_requested_check(RequestedDocumentAuthenticityCheckBuilder().build())
52+
.with_requested_check(
53+
RequestedLivenessCheckBuilder()
54+
.for_zoom_liveness()
55+
.with_max_retries(1)
56+
.build()
57+
)
58+
.with_requested_check(
59+
RequestedFaceMatchCheckBuilder().with_manual_check_fallback().build()
60+
)
61+
.with_requested_task(
62+
RequestedTextExtractionTaskBuilder().with_manual_check_always().build()
63+
)
64+
.with_sdk_config(sdk_config)
65+
.build()
66+
)
67+
68+
return doc_scan_client.create_session(session_spec)
69+
70+
71+
@app.route("/")
72+
def index():
73+
try:
74+
result = create_session()
75+
except DocScanException as e:
76+
return render_template("error.html", error=e.text)
77+
78+
session["doc_scan_session_id"] = result.session_id
79+
80+
iframe_url = "{base_url}/web/index.html?sessionID={session_id}&sessionToken={session_token}".format(
81+
base_url=yoti_python_sdk.YOTI_DOC_SCAN_API_URL,
82+
session_id=result.session_id,
83+
session_token=result.client_session_token,
84+
)
85+
86+
return render_template("index.html", iframe_url=iframe_url)
87+
88+
89+
@app.route("/success")
90+
def success():
91+
doc_scan_client = DocScanClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
92+
93+
session_id = session.get("doc_scan_session_id", None)
94+
95+
try:
96+
session_result = doc_scan_client.get_session(session_id)
97+
except DocScanException as e:
98+
return render_template("error.html", error=e.text)
99+
100+
return render_template("success.html", session_result=session_result)
101+
102+
103+
@app.route("/error")
104+
def error():
105+
error_message = "An unknown error occurred"
106+
107+
if request.args.get("yotiErrorCode", None) is not None:
108+
error_message = "Error Code: {}".format(request.args.get("yotiErrorCode"))
109+
110+
return render_template("error.html", error=error_message)
111+
112+
113+
@app.route("/media")
114+
def media():
115+
media_id = request.args.get("mediaId", None)
116+
if media_id is None:
117+
return Response(status=404)
118+
119+
doc_scan_client = DocScanClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
120+
121+
base64_req = request.args.get("base64", "0")
122+
123+
session_id = session.get("doc_scan_session_id", None)
124+
if session_id is None:
125+
return Response("No session ID available", status=404)
126+
127+
try:
128+
retrieved_media = doc_scan_client.get_media_content(session_id, media_id)
129+
except DocScanException as e:
130+
return render_template("error.html", error=e.text)
131+
132+
if base64_req == "1" and retrieved_media.mime_type == "application/octet-stream":
133+
decoded = base64.b64decode(retrieved_media.content)
134+
info = filetype.guess(decoded)
135+
136+
buffer = BytesIO()
137+
buffer.write(decoded)
138+
buffer.seek(0)
139+
140+
return send_file(
141+
buffer,
142+
attachment_filename="media." + info.extension,
143+
mimetype=info.mime,
144+
as_attachment=True,
145+
)
146+
147+
return Response(
148+
retrieved_media.content, content_type=retrieved_media.mime_type, status=200
149+
)
150+
151+
152+
if __name__ == "__main__":
153+
app.run()

examples/doc_scan/requirements.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
flask>=1.1.2
2+
python-dotenv>=0.13.0
3+
yoti>=2.11.2
4+
filetype>=1.0.7
5+
pyopenssl>=19.1.0

examples/doc_scan/requirements.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#
2+
# This file is autogenerated by pip-compile
3+
# To update, run:
4+
#
5+
# pip-compile --output-file=requirements.txt requirements.in
6+
#
7+
asn1==2.2.0 # via yoti
8+
certifi==2020.4.5.1 # via requests
9+
cffi==1.14.0 # via cryptography
10+
chardet==3.0.4 # via requests
11+
click==7.1.2 # via flask
12+
cryptography==2.9.2 # via pyopenssl, yoti
13+
deprecated==1.2.6 # via yoti
14+
filetype==1.0.7 # via -r requirements.in
15+
flask==1.1.2 # via -r requirements.in
16+
future==0.18.2 # via yoti
17+
idna==2.9 # via requests
18+
iso8601==0.1.12 # via yoti
19+
itsdangerous==1.1.0 # via flask
20+
jinja2==2.11.2 # via flask
21+
markupsafe==1.1.1 # via jinja2
22+
protobuf==3.11.3 # via yoti
23+
pycparser==2.20 # via cffi
24+
pyopenssl==19.1.0 # via -r requirements.in, yoti
25+
python-dotenv==0.13.0 # via -r requirements.in
26+
requests==2.23.0 # via yoti
27+
six==1.14.0 # via cryptography, protobuf, pyopenssl
28+
urllib3==1.25.9 # via requests
29+
werkzeug==1.0.1 # via flask
30+
wrapt==1.12.1 # via deprecated
31+
yoti==2.11.2 # via -r requirements.in
32+
33+
# The following packages are considered to be unsafe in a requirements file:
34+
# setuptools

examples/doc_scan/settings.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from os import environ
2+
from os.path import dirname, join
3+
4+
from dotenv import load_dotenv
5+
6+
dotenv_path = join(dirname(__file__), ".env")
7+
load_dotenv(dotenv_path)
8+
9+
YOTI_CLIENT_SDK_ID = environ.get("YOTI_CLIENT_SDK_ID", None)
10+
YOTI_KEY_FILE_PATH = environ.get("YOTI_KEY_FILE_PATH", None)
11+
12+
if YOTI_CLIENT_SDK_ID is None or YOTI_KEY_FILE_PATH is None:
13+
raise ValueError("YOTI_CLIENT_SDK_ID or YOTI_KEY_FILE_PATH is None")
14+
15+
YOTI_APP_BASE_URL = environ.get("YOTI_APP_BASE_URL", "https://localhost:5000")

0 commit comments

Comments
 (0)