Skip to content

Commit adc07cb

Browse files
committed
SDK-350: Change getters to property decorators, add sources & verifiers to Django example project
1 parent e174ef0 commit adc07cb

File tree

9 files changed

+480
-189
lines changed

9 files changed

+480
-189
lines changed

examples/yoti_example_django/yoti_example/templates/profile.html

Lines changed: 386 additions & 109 deletions
Large diffs are not rendered by default.

examples/yoti_example_django/yoti_example/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ class AuthView(TemplateView):
2424
def get(self, request, *args, **kwargs):
2525
client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
2626
activity_details = client.get_activity_details(request.GET['token'])
27-
context = activity_details.user_profile
27+
context = activity_details.profile
2828
context['base64_selfie_uri'] = getattr(activity_details, 'base64_selfie_uri')
2929

3030
selfie = context.get('selfie')
3131
if selfie is not None:
32-
self.save_image(selfie)
32+
self.save_image(selfie.value)
3333
return self.render_to_response(context)
3434

3535
@staticmethod

yoti_python_sdk/activity_details.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,27 @@ def try_parse_age_verified_field(self, field, anchors):
6565
raise TypeError("age_verified_field unable to be parsed")
6666

6767
def try_convert_structured_postal_address_to_dict(self, field, anchors):
68-
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
69-
self.user_profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS] = decoder.decode(field.value)
68+
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict, strict=False)
69+
value_to_decode = field.value
70+
if not isinstance(value_to_decode, str):
71+
value_to_decode = value_to_decode.decode()
72+
73+
self.user_profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS] = decoder.decode(value_to_decode)
7074
self.profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS] = attribute.attribute(
7175
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS,
72-
decoder.decode(field.value),
76+
decoder.decode(value_to_decode),
7377
anchors)
7478

7579
def set_address_to_be_formatted_address_if_null(self, anchors):
7680
if config.ATTRIBUTE_POSTAL_ADDRESS not in self.user_profile and config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS in self.user_profile:
7781
if config.KEY_FORMATTED_ADDRESS in self.user_profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS]:
7882
self.user_profile[config.ATTRIBUTE_POSTAL_ADDRESS] = \
79-
self.user_profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS][
80-
config.KEY_FORMATTED_ADDRESS]
83+
self.user_profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS][
84+
config.KEY_FORMATTED_ADDRESS]
8185

8286
if config.ATTRIBUTE_POSTAL_ADDRESS not in self.profile and config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS in self.profile:
83-
if config.KEY_FORMATTED_ADDRESS in self.profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].get_value():
84-
formatted_address = self.profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].get_value()[
87+
if config.KEY_FORMATTED_ADDRESS in self.profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].value:
88+
formatted_address = self.profile[config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].value[
8589
config.KEY_FORMATTED_ADDRESS]
8690
self.profile[config.ATTRIBUTE_POSTAL_ADDRESS] = attribute.attribute(
8791
config.ATTRIBUTE_POSTAL_ADDRESS,

yoti_python_sdk/anchor.py

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@
1313

1414

1515
class Anchor:
16-
anchor_type = "Unknown"
17-
sub_type = ""
18-
value = ""
19-
signed_timestamp = compubapi.SignedTimestamp()
20-
21-
def __init__(self, anchor_type=None, sub_type=None, value=None, signed_timestamp=None):
22-
self.anchor_type = anchor_type
23-
self.sub_type = sub_type
24-
self.value = value
25-
self.signed_timestamp = signed_timestamp
16+
def __init__(self, anchor_type="Unknown", sub_type="", value="", signed_timestamp=None):
17+
self.__anchor_type = anchor_type
18+
self.__sub_type = sub_type
19+
self.__value = value
20+
self.__signed_timestamp = signed_timestamp
2621

2722
def __iter__(self):
2823
return self
@@ -39,9 +34,8 @@ def __next__(self):
3934

4035
@staticmethod
4136
def parse_anchors(anchors):
37+
parsed_anchors = []
4238
for anc in anchors:
43-
parsed_anchors = []
44-
4539
if hasattr(anc, 'origin_server_certs'):
4640
origin_server_certs_list = list(anc.origin_server_certs)
4741
origin_server_certs_item = origin_server_certs_list[0]
@@ -65,9 +59,9 @@ def parse_anchors(anchors):
6559
if hasattr(extension_value, 'value'):
6660
parsed_anchors.append(Anchor(
6761
anchor_type,
68-
Anchor.get_sub_type(anc),
62+
anc.sub_type,
6963
Anchor.decode_asn1_value(extension_value.value),
70-
Anchor.get_signed_timestamp(anc)))
64+
anc.signed_time_stamp))
7165

7266
return parsed_anchors
7367

@@ -85,26 +79,31 @@ def decode_asn1_value(value_to_decode):
8579
utf8_value = twice_decoded_value.decode('utf-8')
8680
return utf8_value
8781

88-
@staticmethod
89-
def get_sub_type(anchor):
90-
if hasattr(anchor, 'sub_type'):
91-
return anchor.sub_type
92-
else:
93-
return ""
82+
@property
83+
def anchor_type(self):
84+
return self.__anchor_type
9485

95-
@staticmethod
96-
def get_signed_timestamp(anchor):
97-
if hasattr(anchor, 'signed_time_stamp'):
98-
signed_timestamp_object = compubapi.SignedTimestamp()
99-
signed_timestamp_object.MergeFromString(anchor.signed_time_stamp)
100-
101-
try:
102-
signed_timestamp_parsed = datetime.datetime.fromtimestamp(
103-
signed_timestamp_object.timestamp / float(1000000))
104-
except OSError:
105-
print("Unable to parse timestamp from integer: '{0}'".format(signed_timestamp_object.timestamp))
106-
return ""
107-
108-
return signed_timestamp_parsed
109-
else:
86+
@property
87+
def value(self):
88+
return self.__value
89+
90+
@property
91+
def sub_type(self):
92+
return self.__sub_type
93+
94+
@property
95+
def signed_timestamp(self):
96+
if self.__signed_timestamp is None:
97+
return None
98+
99+
signed_timestamp_object = compubapi.SignedTimestamp()
100+
signed_timestamp_object.MergeFromString(self.__signed_timestamp)
101+
102+
try:
103+
signed_timestamp_parsed = datetime.datetime.fromtimestamp(
104+
signed_timestamp_object.timestamp / float(1000000))
105+
except OSError:
106+
print("Unable to parse timestamp from integer: '{0}'".format(signed_timestamp_object.timestamp))
110107
return ""
108+
109+
return signed_timestamp_parsed

yoti_python_sdk/attribute.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,27 @@
22

33

44
class attribute:
5-
name = ""
6-
value = ""
7-
anchors = {}
8-
9-
def __init__(self, name, value, anchors):
10-
self.name = name
11-
self.value = value
12-
self.anchors = anchors
13-
14-
def get_name(self):
15-
return self.name
16-
17-
def get_value(self):
18-
return self.value
19-
20-
def get_anchors(self):
21-
return self.anchors
22-
23-
def get_sources(self):
24-
return list(filter(lambda a: a.anchor_type == config.ANCHOR_SOURCE, self.anchors))
25-
26-
def get_verifiers(self):
27-
return list(filter(lambda a: a.anchor_type == config.ANCHOR_VERIFIER, self.anchors))
5+
def __init__(self, name="", value="", anchors={}):
6+
self.__name = name
7+
self.__value = value
8+
self.__anchors = anchors
9+
10+
@property
11+
def name(self):
12+
return self.__name
13+
14+
@property
15+
def value(self):
16+
return self.__value
17+
18+
@property
19+
def anchors(self):
20+
return self.__anchors
21+
22+
@property
23+
def sources(self):
24+
return list(filter(lambda a: a.anchor_type == config.ANCHOR_SOURCE, self.__anchors))
25+
26+
@property
27+
def verifiers(self):
28+
return list(filter(lambda a: a.anchor_type == config.ANCHOR_VERIFIER, self.__anchors))

yoti_python_sdk/tests/test_activity_details.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_try_parse_age_verified_field_age_over():
109109

110110
ActivityDetails.try_parse_age_verified_field(activity_details, activity_details.field, None)
111111
assert activity_details.user_profile['is_age_verified'] is True
112-
assert activity_details.profile['is_age_verified'].get_value() is True
112+
assert activity_details.profile['is_age_verified'].value is True
113113

114114

115115
def test_try_parse_age_verified_field_age_under():
@@ -118,7 +118,7 @@ def test_try_parse_age_verified_field_age_under():
118118

119119
ActivityDetails.try_parse_age_verified_field(activity_details, activity_details.field, None)
120120
assert activity_details.user_profile['is_age_verified'] is False
121-
assert activity_details.profile['is_age_verified'].get_value() is False
121+
assert activity_details.profile['is_age_verified'].value is False
122122

123123

124124
def test_try_parse_age_verified_field_non_bool_value_throws_error():
@@ -160,7 +160,7 @@ def test_try_parse_structured_postal_address_uk():
160160
assert actual_structured_postal_address_user_profile[FORMATTED_ADDRESS_KEY] == FORMATTED_ADDRESS_VALUE
161161

162162
actual_structured_postal_address_profile = activity_details.profile[
163-
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].get_value()
163+
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].value
164164

165165
assert type(actual_structured_postal_address_profile) is collections.OrderedDict
166166
assert actual_structured_postal_address_profile[ADDRESS_FORMAT_KEY] == ADDRESS_FORMAT_VALUE
@@ -214,7 +214,7 @@ def test_try_parse_structured_postal_address_india():
214214
assert actual_structured_postal_address_user_profile[FORMATTED_ADDRESS_KEY] == INDIA_FORMATTED_ADDRESS_VALUE
215215

216216
actual_structured_postal_address_profile = activity_details.profile[
217-
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].get_value()
217+
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].value
218218

219219
assert type(actual_structured_postal_address_profile) is collections.OrderedDict
220220
assert actual_structured_postal_address_profile[ADDRESS_FORMAT_KEY] == INDIA_FORMAT_VALUE
@@ -263,7 +263,7 @@ def test_try_parse_structured_postal_address_usa():
263263
assert actual_structured_postal_address_user_profile[FORMATTED_ADDRESS_KEY] == USA_FORMATTED_ADDRESS_VALUE
264264

265265
actual_structured_postal_address_profile = activity_details.profile[
266-
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].get_value()
266+
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].value
267267

268268
assert type(actual_structured_postal_address_profile) is collections.OrderedDict
269269
assert actual_structured_postal_address_profile[ADDRESS_FORMAT_KEY] == USA_FORMAT_VALUE
@@ -319,7 +319,7 @@ def test_try_parse_structured_postal_address_nested_json():
319319
assert actual_structured_postal_address_user_profile[FORMATTED_ADDRESS_KEY] == formatted_address_json
320320

321321
actual_structured_postal_address_profile = activity_details.profile[
322-
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].get_value()
322+
config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS].value
323323

324324
assert type(actual_structured_postal_address_profile) is collections.OrderedDict
325325
assert actual_structured_postal_address_profile[ADDRESS_FORMAT_KEY] == ADDRESS_FORMAT_VALUE
@@ -348,4 +348,4 @@ def test_set_address_to_be_formatted_address():
348348
ActivityDetails.set_address_to_be_formatted_address_if_null(activity_details, None)
349349

350350
assert activity_details.user_profile[config.ATTRIBUTE_POSTAL_ADDRESS] == FORMATTED_ADDRESS_VALUE
351-
assert activity_details.profile[config.ATTRIBUTE_POSTAL_ADDRESS].get_value() == FORMATTED_ADDRESS_VALUE
351+
assert activity_details.profile[config.ATTRIBUTE_POSTAL_ADDRESS].value == FORMATTED_ADDRESS_VALUE

yoti_python_sdk/tests/test_anchor.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
import datetime
3+
import yoti_python_sdk
34

45
from yoti_python_sdk import config
56
from yoti_python_sdk.tests import anchor_parser
@@ -30,3 +31,12 @@ def test_parse_yoti_admin():
3031
assert parsed_anchor.signed_timestamp == datetime.datetime(2018, 4, 11, 13, 13, 4, 95238)
3132
assert parsed_anchor.sub_type == ""
3233
assert parsed_anchor.value == "YOTI_ADMIN"
34+
35+
36+
def test_anchor_returns_correct_default_values():
37+
anchor = yoti_python_sdk.anchor.Anchor()
38+
39+
assert anchor.anchor_type == "Unknown"
40+
assert anchor.signed_timestamp is None
41+
assert anchor.sub_type == ""
42+
assert anchor.value == ""

yoti_python_sdk/tests/test_attribute.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ def test_attribute_get_values():
1212

1313
attribute = yoti_python_sdk.attribute.attribute(NAME, VALUE, parsed_anchors)
1414

15-
assert attribute.get_name() == NAME
16-
assert attribute.get_value() == VALUE
17-
assert attribute.get_anchors() == parsed_anchors
15+
assert attribute.name == NAME
16+
assert attribute.value == VALUE
17+
assert attribute.anchors == parsed_anchors
1818

1919

2020
def test_attribute_get_sources():
2121
anchors = create_source_and_verifier_anchors()
2222
attribute = yoti_python_sdk.attribute.attribute(NAME, VALUE, anchors)
23-
sources = attribute.get_sources()
23+
sources = attribute.sources
2424

2525
assert len(sources) == 1
2626
assert sources[0].anchor_type == config.ANCHOR_SOURCE
@@ -29,7 +29,7 @@ def test_attribute_get_sources():
2929
def test_attribute_get_verifiers():
3030
anchors = create_source_and_verifier_anchors()
3131
attribute = yoti_python_sdk.attribute.attribute(NAME, VALUE, anchors)
32-
verifiers = attribute.get_verifiers()
32+
verifiers = attribute.verifiers
3333

3434
assert len(verifiers) == 1
3535
assert verifiers[0].anchor_type == config.ANCHOR_VERIFIER

yoti_python_sdk/tests/test_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def test_requesting_activity_details_with_correct_data(
144144
selfie_user_profile = activity_details.user_profile.get('selfie')
145145
assert isinstance(selfie_user_profile, basestring)
146146

147-
selfie_profile = activity_details.profile.get('selfie').get_value()
147+
selfie_profile = activity_details.profile.get('selfie').value
148148
assert isinstance(selfie_profile, basestring)
149149

150150
base64_selfie_uri = getattr(activity_details, 'base64_selfie_uri')

0 commit comments

Comments
 (0)