Skip to content

Commit 2e003b7

Browse files
Merge pull request #255 from getyoti/release/2.13.0
Release 2.13.0
2 parents a29fb7f + 5931a55 commit 2e003b7

Some content is hidden

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

58 files changed

+917
-221
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- pip install -r requirements.txt
2020
- pip install -e .[dev]
2121
script:
22-
- py.test -v
22+
- pytest -v
2323
- <<: *test
2424
python: "3.4"
2525
- <<: *test

README.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ How to manage users
3434
1) [Running the examples](#running-the-examples) -
3535
How to retrieve a Yoti profile using the token
3636

37-
1) [Running the tests](#running-the-tests) -
38-
Running tests for SDK example
39-
4037
1) [API Coverage](#api-coverage) -
4138
Attributes defined
4239

@@ -196,14 +193,6 @@ To run the Flask or Django container:
196193
* [Profile - Flask](examples/yoti_example_flask)
197194
* [Doc Scan](examples/doc_scan)
198195

199-
## Running the Tests
200-
201-
Running the tests is done by the following process, ensuring you are using Python 3.0+:
202-
203-
1. Install dependencies: `pip install -r requirements.txt`
204-
1. Install the SDK and development dependencies: `pip install .[dev]`
205-
1. Execute in the main project dir: `py.test`
206-
207196
## API Coverage
208197

209198
* Activity Details

examples/doc_scan/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
1. Rename the [.env.example](.env.example) file to `.env` and fill in the required configuration values
66
1. Install the dependencies with `pip install -r requirements.txt`
77
1. Start the server `flask run --cert=adhoc`
8-
1. Visit `https://localhost:5000`
8+
1. Visit `https://localhost:5000`

examples/doc_scan/app.py

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
import base64
2-
from io import BytesIO
3-
41
import yoti_python_sdk
5-
from filetype import filetype
6-
from flask import Flask, Response, render_template, request, send_file, session
2+
from flask import Flask, Response, render_template, request, session
73
from yoti_python_sdk.doc_scan import (
84
DocScanClient,
95
RequestedDocumentAuthenticityCheckBuilder,
106
RequestedFaceMatchCheckBuilder,
7+
RequestedIDDocumentComparisonCheckBuilder,
118
RequestedLivenessCheckBuilder,
129
RequestedTextExtractionTaskBuilder,
1310
SdkConfigBuilder,
1411
SessionSpecBuilder,
1512
)
1613
from yoti_python_sdk.doc_scan.exception import DocScanException
14+
from yoti_python_sdk.doc_scan.session.create.filter import (
15+
RequiredIdDocumentBuilder,
16+
DocumentRestrictionBuilder,
17+
DocumentRestrictionsFilterBuilder,
18+
)
1719

1820
from .settings import YOTI_APP_BASE_URL, YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH
1921

@@ -48,26 +50,49 @@ def create_session():
4850
.with_client_session_token_ttl(600)
4951
.with_resources_ttl(90000)
5052
.with_user_tracking_id("some-user-tracking-id")
51-
.with_requested_check(RequestedDocumentAuthenticityCheckBuilder().build())
53+
.with_requested_check(
54+
RequestedDocumentAuthenticityCheckBuilder()
55+
.with_manual_check_never()
56+
.build()
57+
)
5258
.with_requested_check(
5359
RequestedLivenessCheckBuilder()
5460
.for_zoom_liveness()
5561
.with_max_retries(1)
5662
.build()
5763
)
5864
.with_requested_check(
59-
RequestedFaceMatchCheckBuilder().with_manual_check_fallback().build()
65+
RequestedFaceMatchCheckBuilder().with_manual_check_never().build()
6066
)
67+
.with_requested_check(RequestedIDDocumentComparisonCheckBuilder().build())
6168
.with_requested_task(
62-
RequestedTextExtractionTaskBuilder().with_manual_check_always().build()
69+
RequestedTextExtractionTaskBuilder()
70+
.with_manual_check_never()
71+
.with_chip_data_desired()
72+
.build()
6373
)
6474
.with_sdk_config(sdk_config)
75+
.with_required_document(build_required_id_document_restriction("PASSPORT"))
76+
.with_required_document(
77+
build_required_id_document_restriction("DRIVING_LICENCE")
78+
)
6579
.build()
6680
)
6781

6882
return doc_scan_client.create_session(session_spec)
6983

7084

85+
def build_required_id_document_restriction(document_type):
86+
document_restriction = (
87+
DocumentRestrictionBuilder().with_document_types([document_type]).build()
88+
)
89+
90+
filter_builder = DocumentRestrictionsFilterBuilder().for_whitelist()
91+
filter_builder.with_document_restriction(document_restriction)
92+
93+
return RequiredIdDocumentBuilder().with_filter(filter_builder.build()).build()
94+
95+
7196
@app.route("/")
7297
def index():
7398
try:
@@ -118,8 +143,6 @@ def media():
118143

119144
doc_scan_client = DocScanClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
120145

121-
base64_req = request.args.get("base64", "0")
122-
123146
session_id = session.get("doc_scan_session_id", None)
124147
if session_id is None:
125148
return Response("No session ID available", status=404)
@@ -129,21 +152,6 @@ def media():
129152
except DocScanException as e:
130153
return render_template("error.html", error=e.text)
131154

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-
147155
return Response(
148156
retrieved_media.content, content_type=retrieved_media.mime_type, status=200
149157
)

examples/doc_scan/templates/success.html

Lines changed: 89 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ <h1>Get Session Result</h1>
3434
<td>User Tracking ID</td>
3535
<td>{{ session_result.user_tracking_id }}</td>
3636
</tr>
37+
{% if session_result.biometric_consent_timestamp is not none %}
38+
<tr>
39+
<td>Biometric Consent Timestamp</td>
40+
<td>{{ session_result.biometric_consent_timestamp }}</td>
41+
</tr>
42+
{% endif %}
3743
</tbody>
3844
</table>
3945
</div>
@@ -134,6 +140,29 @@ <h3 class="mb-0">
134140
</div>
135141
</div>
136142
{% endif %}
143+
144+
{% if session_result.id_document_comparison_checks|length > 0 %}
145+
<div class="card">
146+
<div class="card-header" id="comparison-checks">
147+
<h3 class="mb-0">
148+
<button aria-controls="collapse-comparison-checks" aria-expanded="true" class="btn btn-link"
149+
data-target="#collapse-comparison-checks" data-toggle="collapse"
150+
type="button">
151+
ID Document Comparison Checks
152+
</button>
153+
</h3>
154+
</div>
155+
<div aria-labelledby="comparison-checks" class="collapse" id="collapse-comparison-checks">
156+
<div class="card-body">
157+
{% for check in session_result.id_document_comparison_checks %}
158+
{% with check=check %}
159+
{% include "partials/check.html" %}
160+
{% endwith %}
161+
{% endfor %}
162+
</div>
163+
</div>
164+
</div>
165+
{% endif %}
137166
</div>
138167
</div>
139168
</div>
@@ -149,7 +178,7 @@ <h2>ID Documents</h2>
149178

150179
{% with doc_num=0 %}
151180
{% for document in session_result.resources.id_documents %}
152-
{% set doc_num = loop.index + 1 %}
181+
{% set doc_num = loop.index %}
153182
<div class="row pt-4">
154183
<div class="col">
155184

@@ -193,6 +222,26 @@ <h5>Media</h5>
193222
</div>
194223
</div>
195224
{% endif %}
225+
226+
{% if document.document_id_photo is not none %}
227+
<div class="card">
228+
<div class="card-header" id="document-id-photo-{{ doc_num }}">
229+
<h4 class="mb-0">
230+
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapse-document-id-photo-{{ doc_num }}" aria-expanded="true" aria-controls="collapse-document-id-photo-{{ doc_num }}">
231+
Document ID Photo
232+
</button>
233+
</h4>
234+
</div>
235+
<div id="collapse-document-id-photo-{{ doc_num }}" class="collapse" aria-labelledby="document-id-photo-{{ doc_num }}">
236+
<div class="card-body">
237+
{% if document.document_fields.media is not none %}
238+
<img class="card-img-top" src="/media?mediaId={{ document.document_id_photo.media.id }}" />
239+
{% endif %}
240+
</div>
241+
</div>
242+
</div>
243+
{% endif %}
244+
196245
{% if document.text_extraction_tasks|length > 0 %}
197246
<div class="card">
198247
<div class="card-header" id="text-extraction-tasks-{{ doc_num }}">
@@ -256,36 +305,54 @@ <h5>Generated Media</h5>
256305
{% endif %}
257306

258307
{% if document.pages|length > 0 %}
308+
{% with page_num=0 %}
309+
{% for page in document.pages %}
310+
{% set page_num = loop.index %}
259311
<div class="card">
260-
<div class="card-header" id="document-pages-{{ doc_num }}">
312+
<div class="card-header" id="document-pages-{{ doc_num }}-{{ page_num }}">
261313
<h4 class="mb-0">
262314
<button class="btn btn-link" type="button" data-toggle="collapse"
263-
data-target="#collapse-document-pages-{{ doc_num }}"
315+
data-target="#collapse-document-pages-{{ doc_num }}-{{ page_num }}"
264316
aria-expanded="true"
265-
aria-controls="collapse-document-pages-{{ doc_num }}">
266-
Pages
317+
aria-controls="collapse-document-pages-{{ doc_num }}-{{ page_num }}">
318+
Page {{ page_num }}
267319
</button>
268320
</h4>
269321
</div>
270-
<div id="collapse-document-pages-{{ doc_num }}" class="collapse"
271-
aria-labelledby="document-pages-{{ doc_num }}">
272-
<div class="card-body">
273-
<div class="card-group">
274-
{% for page in document.pages %}
275-
{% if page.media is not none %}
276-
<div class="card" style="width: 18rem;">
277-
<img class="card-img-top"
278-
src="/media?mediaId={{ page.media.id }}"/>
279-
<div class="card-body">
280-
<p>Method: {{ page.capture_method }}</p>
281-
</div>
322+
<div id="collapse-document-pages-{{ doc_num }}-{{ page_num }}" class="collapse"
323+
aria-labelledby="document-pages-{{ doc_num }}-{{ page_num }}">
324+
325+
<div class="card-group">
326+
{% if page.media is not none %}
327+
<div class="card" style="width: 18rem;">
328+
<img class="card-img-top"
329+
src="/media?mediaId={{ page.media.id }}"/>
330+
<div class="card-body">
331+
<p>Method: {{ page.capture_method }}</p>
332+
</div>
333+
</div>
334+
{% endif %}
335+
</div>
336+
337+
{% if page.frames|length > 0 %}
338+
<div class="card-group">
339+
{% for frame in page.frames %}
340+
{% if frame.media is not none %}
341+
<div class="card">
342+
<img class="card-img-top" src="/media?mediaId={{ frame.media.id }}" />
343+
<div class="card-body">
344+
<h5 class="card-title">Frame</h5>
282345
</div>
283-
{% endif %}
284-
{% endfor %}
285-
</div>
346+
</div>
347+
{% endif %}
348+
{% endfor %}
286349
</div>
350+
{% endif %}
351+
287352
</div>
288353
</div>
354+
{% endfor %}
355+
{% endwith %}
289356
{% endif %}
290357
</div>
291358
</div>
@@ -303,7 +370,7 @@ <h2>Zoom Liveness Resources</h2>
303370

304371
{% with liveness_num=0 %}
305372
{% for liveness in session_result.resources.zoom_liveness_resources %}
306-
{% set liveness_num = loop.index + 1 %}
373+
{% set liveness_num = loop.index %}
307374
<div class="row pt-4">
308375
<div class="col">
309376
<table class="table table-striped table-light">
@@ -317,39 +384,6 @@ <h2>Zoom Liveness Resources</h2>
317384

318385
<div class="accordion mt-3">
319386

320-
{% if liveness.facemap is not none %}
321-
<div class="card">
322-
<div class="card-header" id="liveness-{{ liveness_num }}-facemap">
323-
<h3 class="mb-0">
324-
<button class="btn btn-link" type="button" data-toggle="collapse"
325-
data-target="#collapse-liveness-{{ liveness_num }}-facemap" aria-expanded="true"
326-
aria-controls="collapse-liveness-{{ liveness_num }}-facemap">
327-
Face Map
328-
</button>
329-
</h3>
330-
</div>
331-
<div id="collapse-liveness-{{ liveness_num }}-facemap" class="collapse" aria-labelledby="liveness-{{ liveness_num }}-facemap">
332-
<div class="card-body">
333-
{% if liveness.facemap.media is not none %}
334-
<h4>Media</h4>
335-
<table class="table table-striped">
336-
<tbody>
337-
<tr>
338-
<td>ID</td>
339-
<td>
340-
<a href="/media?mediaId={{ liveness.facemap.media.id }}&base64=1">
341-
{{ liveness.facemap.media.id }}
342-
</a>
343-
</td>
344-
</tr>
345-
</tbody>
346-
</table>
347-
{% endif %}
348-
</div>
349-
</div>
350-
</div>
351-
{% endif %}
352-
353387
{% if liveness.frames|length > 0 %}
354388
<div class="card">
355389
<div class="card-header" id="liveness-{{ liveness_num }}-frames">
@@ -383,4 +417,4 @@ <h5 class="card-title">Frame</h5>
383417
{% endfor %}
384418
{% endwith %}
385419
</div>
386-
{% include "layout/footer.html" %}
420+
{% include "layout/footer.html" %}

examples/yoti_example_django/yoti_example/static/index.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
font-size: 40px;
2727
font-weight: 700;
2828
line-height: 1.2;
29-
30-
margin: 0;
29+
margin-top: 0;
30+
margin-bottom: 80px;
3131

3232
text-align: center;
3333

@@ -45,8 +45,8 @@
4545
}
4646

4747
#yoti-share-button {
48-
width: 130px;
49-
height: 50px;
48+
width: 250px;
49+
height: 45px;
5050
}
5151

5252
.yoti-login-or-separator {
@@ -56,7 +56,7 @@
5656
font-weight: bold;
5757
line-height: 1.5;
5858
text-align: center;
59-
margin-bottom: 30px;
59+
margin-top: 30px;
6060
}
6161

6262
.yoti-login-dialog {

0 commit comments

Comments
 (0)