Skip to content

Commit e39c365

Browse files
authored
Merge pull request #103 from getyoti/release-2.9.0
Release 2.9.0
2 parents b6eec66 + 149f6be commit e39c365

Some content is hidden

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

53 files changed

+2455
-373
lines changed

.coveragerc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
[run]
2-
omit=yoti/tests/*
2+
omit =
3+
yoti_python_sdk/tests/**
4+
examples/**

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ htmlcov/
4242
.cache
4343
nosetests.xml
4444
coverage.*
45+
coverage-reports
4546
*,cover
4647
.hypothesis/
4748

@@ -103,4 +104,4 @@ examples/yoti_example_flask/static/YotiSelfie.jpg
103104
examples/yoti_example_django/*.pem
104105
examples/yoti_example_flask/*.pem
105106

106-
.scannerwork
107+
.scannerwork

.pylintrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[MASTER]
2+
ignore=yoti_python_sdk/tests/**,examples/**

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ Running the tests is done by the following process, ensuring you are using Pytho
295295
* [X] Address `postal_address`
296296
* [X] Gender `gender`
297297
* [X] Nationality `nationality`
298+
* [X] Application Profile `application_profile`
299+
* [X] Name `application_name`
300+
* [X] URL `application_url`
301+
* [X] Logo `application_logo`
302+
* [X] Receipt Background Color `application_receipt_bg_color`
298303
* [X] Base64 Selfie URI `base64_selfie_uri`
299304

300305
## Support

examples/yoti_example_django/yoti_example/templates/attribute_snippet.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<span class="yoti-attribute-name-cell-text">{{ name }}</span>
77
</div>
88
</div>
9-
9+
1010
<div class="yoti-attribute-value">
1111
<div class="yoti-attribute-value-text">
1212
{% if prop.name == "document_images" %}
@@ -34,6 +34,21 @@
3434
</tr>
3535
{% endfor %}
3636
</table>
37+
{% elif prop.name == "age_verified" %}
38+
<table>
39+
<tr>
40+
<td>Check Type</td>
41+
<td>{{ prop.value.check_type }}</td>
42+
</tr>
43+
<tr>
44+
<td>Age</td>
45+
<td>{{ prop.value.age }}</td>
46+
</tr>
47+
<tr>
48+
<td>Result</td>
49+
<td>{{ prop.value.result }}</td>
50+
</tr>
51+
</table>
3752
{% else %}
3853
{{ prevalue }}
3954
{{ prop.value }}

examples/yoti_example_django/yoti_example/urls.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@
1616
from django.conf.urls import url
1717
from django.contrib import admin
1818

19-
from .views import IndexView, AuthView, DynamicShareView
19+
from .views import IndexView, AuthView, DynamicShareView, SourceConstraintsView
2020

2121
urlpatterns = [
2222
url(r"^$", IndexView.as_view(), name="index"),
2323
url(r"^yoti/auth/$", AuthView.as_view(), name="auth"),
2424
url(r"^admin/", admin.site.urls),
2525
url(r"^dynamic-share/$", DynamicShareView.as_view(), name="dynamic-share"),
26+
url(
27+
r"^source-constraint/$",
28+
SourceConstraintsView.as_view(),
29+
name="source-constraints",
30+
),
2631
]

examples/yoti_example_django/yoti_example/views.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
DynamicScenarioBuilder,
88
create_share_url,
99
)
10-
from yoti_python_sdk.dynamic_sharing_service.policy import DynamicPolicyBuilder
10+
from yoti_python_sdk.dynamic_sharing_service.policy import (
11+
DynamicPolicyBuilder,
12+
SourceConstraintBuilder,
13+
)
1114

1215
load_dotenv(find_dotenv())
1316

@@ -53,6 +56,34 @@ def get(self, request, *args, **kwargs):
5356
return self.render_to_response(context)
5457

5558

59+
class SourceConstraintsView(TemplateView):
60+
template_name = "dynamic-share.html"
61+
62+
def get(self, request, *args, **kwargs):
63+
client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
64+
constraint = (
65+
SourceConstraintBuilder().with_driving_licence().with_passport().build()
66+
)
67+
policy = (
68+
DynamicPolicyBuilder()
69+
.with_full_name(constraints=constraint)
70+
.with_structured_postal_address(constraints=constraint)
71+
.build()
72+
)
73+
scenario = (
74+
DynamicScenarioBuilder()
75+
.with_policy(policy)
76+
.with_callback_endpoint("/yoti/auth")
77+
.build()
78+
)
79+
share = create_share_url(client, scenario)
80+
context = {
81+
"yoti_client_sdk_id": YOTI_CLIENT_SDK_ID,
82+
"yoti_share_url": share.share_url,
83+
}
84+
return self.render_to_response(context)
85+
86+
5687
class AuthView(TemplateView):
5788
template_name = "profile.html"
5889

@@ -71,10 +102,18 @@ def get(self, request, *args, **kwargs):
71102
context["receipt_id"] = getattr(activity_details, "receipt_id")
72103
context["timestamp"] = getattr(activity_details, "timestamp")
73104

74-
# change this string according to the age condition defined in Yoti Hub
75-
age_verified = profile.get_attribute("age_over:18")
105+
# change this number according to the age condition defined in Yoti Hub
106+
age_verified = profile.find_age_over_verification(18)
107+
108+
# Age verification objects don't have the same properties as an attribute,
109+
# so for this example we had to mock an object with the same properties
76110
if age_verified is not None:
77-
context["age_verified"] = age_verified
111+
context["age_verified"] = {
112+
"name": "age_verified",
113+
"value": age_verified,
114+
"sources": age_verified.attribute.sources,
115+
"verifiers": age_verified.attribute.verifiers,
116+
}
78117

79118
selfie = context.get("selfie")
80119
if selfie is not None:

examples/yoti_example_flask/app.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
from flask import Flask, render_template, request
77

88
from yoti_python_sdk import Client
9-
from yoti_python_sdk.dynamic_sharing_service.policy import DynamicPolicyBuilder
9+
from yoti_python_sdk.dynamic_sharing_service.policy import (
10+
DynamicPolicyBuilder,
11+
SourceConstraintBuilder,
12+
)
1013
from yoti_python_sdk.dynamic_sharing_service import DynamicScenarioBuilder
1114
from yoti_python_sdk.dynamic_sharing_service import create_share_url
1215

@@ -52,6 +55,32 @@ def dynamic_share():
5255
)
5356

5457

58+
@app.route("/source-constraints")
59+
def source_constraints():
60+
client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
61+
constraint = (
62+
SourceConstraintBuilder().with_driving_licence().with_passport().build()
63+
)
64+
policy = (
65+
DynamicPolicyBuilder()
66+
.with_full_name(constraints=constraint)
67+
.with_structured_postal_address(constraints=constraint)
68+
.build()
69+
)
70+
scenario = (
71+
DynamicScenarioBuilder()
72+
.with_policy(policy)
73+
.with_callback_endpoint("/yoti/auth")
74+
.build()
75+
)
76+
share = create_share_url(client, scenario)
77+
return render_template(
78+
"dynamic-share.html",
79+
yoti_client_sdk_id=YOTI_CLIENT_SDK_ID,
80+
yoti_share_url=share.share_url,
81+
)
82+
83+
5584
@app.route("/yoti/auth")
5685
def auth():
5786
client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
@@ -68,10 +97,18 @@ def auth():
6897
context["receipt_id"] = getattr(activity_details, "receipt_id")
6998
context["timestamp"] = getattr(activity_details, "timestamp")
7099

71-
# change this string according to the age condition defined in Yoti Hub
72-
age_verified = profile.get_attribute("age_over:18")
100+
# change this number according to the age condition defined in Yoti Hub
101+
age_verified = profile.find_age_over_verification(18)
102+
103+
# Age verification objects don't have the same properties as an attribute,
104+
# so for this example we had to mock an object with the same properties
73105
if age_verified is not None:
74-
context["age_verified"] = age_verified
106+
context["age_verified"] = {
107+
"name": "age_verified",
108+
"value": age_verified,
109+
"sources": age_verified.attribute.sources,
110+
"verifiers": age_verified.attribute.verifiers,
111+
}
75112

76113
selfie = context.get("selfie")
77114
if selfie is not None:

examples/yoti_example_flask/templates/profile.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@
2929
</table>
3030
{% endmacro %}
3131

32+
{% macro parse_age_verification(prop) %}
33+
<table>
34+
<tr>
35+
<td>Check Type</td>
36+
<td>{{ prop.value.check_type }}</td>
37+
</tr>
38+
<tr>
39+
<td>Age</td>
40+
<td>{{ prop.value.age }}</td>
41+
</tr>
42+
<tr>
43+
<td>Result</td>
44+
<td>{{ prop.value.result }}</td>
45+
</tr>
46+
</table>
47+
{% endmacro %}
48+
3249
{% macro attribute(name, icon, prop, prevalue="") %}
3350
{% if prop %}
3451
{% if prop.value %}
@@ -48,6 +65,8 @@
4865
{{ parse_structured_address(prop) }}
4966
{% elif prop.name == "document_details" %}
5067
{{ parse_document_details(prop) }}
68+
{% elif prop.name == "age_verified" %}
69+
{{ parse_age_verification(prop) }}
5170
{% else %}
5271
{{ prevalue }}
5372
{{ prop.value }}

pytest.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[pytest]
2-
testpaths = yoti_python_sdk/tests
3-
norecursedirs = venv
2+
testpaths = yoti_python_sdk/tests/
3+
norecursedirs = venv

0 commit comments

Comments
 (0)