diff --git a/.travis.yml b/.travis.yml index 412f3df2..07e16563 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: python dist: xenial git: - depth: false + depth: 3 jobs: allow_failures: diff --git a/requirements.in b/requirements.in index 479122b4..5b435b12 100644 --- a/requirements.in +++ b/requirements.in @@ -1,15 +1,14 @@ asn1==2.2.0 -click==6.6 -cryptography>=2.7.0 +cryptography>=2.8.0 cffi>=1.13.0 -future==0.15.2 +future==0.18.2 itsdangerous==0.24 pbr==1.10.0 -protobuf==3.7.0 +protobuf==3.11.3 pyopenssl==18.0.0 PyYAML==5.2 # PyYAML 5.3 does not support Python 3.4 pytz==2018.9 requests>=2.20.0 urllib3>=1.24.2 deprecated==1.2.6 -wheel==0.24.0 \ No newline at end of file +wheel==0.24.0 diff --git a/requirements.txt b/requirements.txt index 32904d2c..6125c9a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,28 +4,26 @@ # # pip-compile --output-file=requirements.txt requirements.in # -asn1==2.2.0 -asn1crypto==0.24.0 # via cryptography +asn1==2.2.0 # via -r requirements.in certifi==2018.11.29 # via requests -cffi==1.13.0 +cffi==1.13.0 # via -r requirements.in, cryptography chardet==3.0.4 # via requests -click==6.6 -cryptography==2.7 -deprecated==1.2.6 -future==0.15.2 +cryptography==2.8 # via -r requirements.in, pyopenssl +deprecated==1.2.6 # via -r requirements.in +future==0.18.2 # via -r requirements.in idna==2.7 # via requests -itsdangerous==0.24 -pbr==1.10.0 -protobuf==3.7.0 +itsdangerous==0.24 # via -r requirements.in +pbr==1.10.0 # via -r requirements.in +protobuf==3.11.3 # via -r requirements.in pycparser==2.18 # via cffi -pyopenssl==18.0.0 -pytz==2018.9 -pyyaml==5.2 -requests==2.21.0 +pyopenssl==18.0.0 # via -r requirements.in +pytz==2018.9 # via -r requirements.in +pyyaml==5.2 # via -r requirements.in +requests==2.21.0 # via -r requirements.in six==1.10.0 # via cryptography, protobuf, pyopenssl -urllib3==1.24.2 -wheel==0.24.0 +urllib3==1.24.2 # via -r requirements.in, requests +wheel==0.24.0 # via -r requirements.in wrapt==1.11.2 # via deprecated # The following packages are considered to be unsafe in a requirements file: -# setuptools==43.0.0 # via protobuf +# setuptools diff --git a/setup.py b/setup.py index 8d5fe232..f1bde78f 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -from setuptools import setup, find_packages - -from yoti_python_sdk import __version__ +from setuptools import find_packages +from setuptools import setup long_description = ( "This package contains the tools you need to quickly " @@ -10,10 +9,14 @@ "application in a secure and trusted way." ) +version = {} +with open("yoti_python_sdk/version.py") as fp: + exec(fp.read(), version) + setup( name="yoti", - version=__version__, - packages=find_packages(), + version=version["__version__"], + packages=find_packages(include=["yoti_python_sdk", "yoti_python_sdk.*"]), license="MIT", description="The Yoti Python SDK, providing API support for Login, Verify (2FA) and Age Verification.", long_description=long_description, @@ -21,13 +24,13 @@ author="Yoti", author_email="websdk@yoti.com", install_requires=[ + "deprecated==1.2.6", "cryptography>=2.2.1", "protobuf>=3.1.0", "requests>=2.11.1", "future>=0.11.0", "asn1==2.2.0", "pyopenssl>=18.0.0", - "deprecated==1.2.6", ], extras_require={ "examples": [ @@ -35,7 +38,7 @@ "Flask>=0.10", "python-dotenv>=0.7.1", "django-sslserver>=0.2", - "Werkzeug==0.11.15", + "Werkzeug==0.15.3", ], "dev": [ "pre-commit==1.17.0", @@ -46,7 +49,7 @@ "python-coveralls==2.9.3", "coverage==4.5.4", "mock==2.0.0", - "virtualenv==15.2", + "virtualenv==20.0.13", ], }, classifiers=[ diff --git a/sonar-project.properties b/sonar-project.properties index 12c5d404..c505ef56 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,7 @@ sonar.host.url = https://sonarcloud.io sonar.organization = getyoti sonar.projectKey = getyoti:python sonar.projectName = Python SDK -sonar.projectVersion = 2.10.1 +sonar.projectVersion = 2.10.2 sonar.exclusions = yoti_python_sdk/tests/**,examples/**,yoti_python_sdk/protobuf/**/* sonar.python.pylint.reportPath = coverage.out diff --git a/yoti_python_sandbox/__init__.py b/yoti_python_sandbox/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/yoti_python_sandbox/age_verification.py b/yoti_python_sandbox/age_verification.py deleted file mode 100644 index cb158d57..00000000 --- a/yoti_python_sandbox/age_verification.py +++ /dev/null @@ -1,97 +0,0 @@ -from yoti_python_sandbox.attribute import SandboxAttribute -from yoti_python_sdk import config - - -class SandboxAgeVerification(object): - def __init__(self, date_of_birth, supported_age_derivation, anchors=None): - - if anchors is None: - anchors = [] - - self.__date_of_birth = date_of_birth - self.__supported_age_derivation = supported_age_derivation - self.__anchors = anchors - - def to_attribute(self): - """ - Converts the age verification object into an Attribute - - :return: Instance of SandboxAttribute - """ - return ( - SandboxAttribute.builder() - .with_name(config.ATTRIBUTE_DATE_OF_BIRTH) - .with_value(self.__date_of_birth) - .with_derivation(self.__supported_age_derivation) - .with_anchors(self.__anchors) - .build() - ) - - @staticmethod - def builder(): - """ - Creates a sandbox age verification builder - - :return: Instance of SandboxAgeVerificationBuilder - """ - return SandboxAgeVerificationBuilder() - - -class SandboxAgeVerificationBuilder(object): - def __init__(self): - self.__date_of_birth = None - self.__derivation = None - self.__anchors = None - - def with_date_of_birth(self, date_of_birth): - """ - Set the date of birth on the builder - - :param str date_of_birth: the date of birth - :return: the updated builder - """ - self.__date_of_birth = date_of_birth - return self - - def with_derivation(self, derivation): - """ - Set the derivation of the age verification - - :param str derivation: the derivation - :return: the updated builder - """ - self.__derivation = derivation - return self - - def with_age_over(self, age_over): - """ - Set the age over value of the age verification - - :param int age_over: the age over value - :return: the updated builder - """ - return self.with_derivation(config.ATTRIBUTE_AGE_OVER + str(age_over)) - - def with_age_under(self, age_under): - """ - Set the age under value of the age verification - - :param int age_under: - :return: the updated builder - """ - return self.with_derivation(config.ATTRIBUTE_AGE_UNDER + str(age_under)) - - def with_anchors(self, anchors): - """ - Set the anchors for the age verification - - :param list[SandboxAnchor] anchors: - :return: the updated builder - """ - self.__anchors = anchors - return self - - def build(self): - return SandboxAgeVerification( - self.__date_of_birth, self.__derivation, self.__anchors - ) diff --git a/yoti_python_sandbox/anchor.py b/yoti_python_sandbox/anchor.py deleted file mode 100644 index 4d85a2aa..00000000 --- a/yoti_python_sandbox/anchor.py +++ /dev/null @@ -1,127 +0,0 @@ -from yoti_python_sdk.anchor import UNKNOWN_ANCHOR_TYPE - - -class SandboxAnchor(object): - def __init__(self, anchor_type=None, sub_type=None, value=None, timestamp=None): - if anchor_type is None: - anchor_type = UNKNOWN_ANCHOR_TYPE - if sub_type is None: - sub_type = "" - if value is None: - value = "" - - self.__anchor_type = anchor_type - self.__sub_type = sub_type - self.__value = value - self.__timestamp = timestamp - - @property - def anchor_type(self): - """ - Returns the anchor type - - :return: the type - """ - return self.__anchor_type - - @property - def sub_type(self): - """ - Returns the anchor sub-type - - :return: the sub-type - """ - return self.__sub_type - - @property - def value(self): - """ - Returns the anchor value - - :return: the value - """ - return self.__value - - @property - def timestamp(self): - """ - Returns the anchor timestamp - - :return: the timestamp - """ - return self.__timestamp - - def __dict__(self): - return { - "type": self.anchor_type, - "value": self.value, - "sub_type": self.sub_type, - "timestamp": self.timestamp, - } - - @staticmethod - def builder(): - """ - Creates an instance of the sandbox anchor builder - - :return: instance of SandboxAnchorBuilder - """ - return SandboxAnchorBuilder() - - -class SandboxAnchorBuilder(object): - def __init__(self): - self.__type = None - self.__value = None - self.__sub_type = None - self.__timestamp = None - - def with_type(self, type): - """ - Sets the type of the anchor on the builder - - :param str type: the anchor type - :return: the updated builder - """ - self.__type = type - return self - - def with_value(self, value): - """ - Sets the value of the anchor on the builder - - :param str value: the anchor value - :return: the updated builder - """ - self.__value = value - return self - - def with_sub_type(self, sub_type): - """ - Sets the sub type of the anchor on the builder - - :param str sub_type: the anchor sub type - :return: the updated builder - """ - self.__sub_type = sub_type - return self - - def with_timestamp(self, timestamp): - """ - Sets the timestamp of the anchor on the builder - - :param int timestamp: the anchor timestamp - :return: the updated builder - """ - self.__timestamp = timestamp - return self - - def build(self): - """ - Creates a SandboxAnchor using values supplied to the builder - - :return: the sandbox anchor - """ - return SandboxAnchor( - self.__type, self.__sub_type, self.__value, self.__timestamp - ) diff --git a/yoti_python_sandbox/attribute.py b/yoti_python_sandbox/attribute.py deleted file mode 100644 index fb6eb505..00000000 --- a/yoti_python_sandbox/attribute.py +++ /dev/null @@ -1,154 +0,0 @@ -from yoti_python_sdk import config - - -class SandboxAttribute(object): - def __init__(self, name=None, value=None, anchors=None, derivation=None): - if name is None: - name = "" - - if value is None: - value = "" - - if anchors is None: - anchors = [] - - if derivation is None: - derivation = "" - - self.__name = name - self.__value = value - self.__anchors = anchors - self.__derivation = derivation - - @property - def name(self): - """ - Returns the name of the attribute - - :return: the name - """ - return self.__name - - @property - def value(self): - """ - Returns the value of the attribute - - :return: the value - """ - return self.__value - - @property - def anchors(self): - """ - Returns the anchors associated with the attribute - - :return: the anchors - """ - return self.__anchors - - @property - def sources(self): - """ - Returns a filtered list of the associated anchors, only returning source anchors - - :return: list of filtered source anchors - """ - return list( - filter(lambda a: a.anchor_type == config.ANCHOR_SOURCE, self.__anchors) - ) - - @property - def verifiers(self): - """ - Returns a filtered list of the associated anchors, only returning verifier anchors - - :return: list of filtered verifier anchors - """ - return list( - filter(lambda a: a.anchor_type == config.ANCHOR_VERIFIER, self.__anchors) - ) - - @property - def derivation(self): - """ - Returns the derivation of the attribute - - :return: the derivation - """ - return self.__derivation - - def __dict__(self): - return { - "name": self.name, - "value": self.value, - "anchors": self.anchors, - "derivation": self.derivation, - } - - @staticmethod - def builder(): - """ - Creates an instance of the sandbox attribute builder - - :return: the sandbox attribute builder - """ - return SandboxAttributeBuilder() - - -class SandboxAttributeBuilder(object): - def __init__(self): - self.__name = None - self.__value = None - self.__anchors = None - self.__derivation = None - - def with_name(self, name): - """ - Sets the name of the attribute on the builder - - :param str name: the name of the attribute - :return: the updated builder - """ - self.__name = name - return self - - def with_value(self, value): - """ - Sets the value of the attribute on the builder - - :param value: the value of the attribute - :return: the updated builder - """ - self.__value = value - return self - - def with_anchors(self, anchors): - """ - Sets the list of anchors associated with the attribute - - :param list[SandboxAnchor] anchors: the associated anchors - :return: - """ - self.__anchors = anchors - return self - - def with_derivation(self, derivation): - """ - Sets the derivation of the attribute on the builder - - :param str derivation: the derivation - :return: the updated builder - """ - self.__derivation = derivation - return self - - def build(self): - """ - Create an instance of SandboxAttribute using values supplied to the builder - - :return: instance of SandboxAttribute - """ - return SandboxAttribute( - self.__name, self.__value, self.__anchors, self.__derivation - ) diff --git a/yoti_python_sandbox/client.py b/yoti_python_sandbox/client.py deleted file mode 100644 index d615a4cf..00000000 --- a/yoti_python_sandbox/client.py +++ /dev/null @@ -1,181 +0,0 @@ -from yoti_python_sandbox.endpoint import SandboxEndpoint -from cryptography.fernet import base64 -from os.path import expanduser, isfile -from past.builtins import basestring - -import json -import requests -import yoti_python_sdk -from yoti_python_sdk.config import ( - X_YOTI_AUTH_KEY, - X_YOTI_AUTH_DIGEST, - X_YOTI_SDK, - SDK_IDENTIFIER, - X_YOTI_SDK_VERSION, - JSON_CONTENT_TYPE, -) -from yoti_python_sdk.client import HTTP_SUPPORTED_METHODS -from yoti_python_sandbox.token import YotiTokenRequest, YotiTokenResponse -from yoti_python_sandbox.attribute import SandboxAttribute -from yoti_python_sandbox.anchor import SandboxAnchor -from yoti_python_sdk.crypto import Crypto -from json import JSONEncoder - - -class SandboxEncoder(JSONEncoder): - def default(self, o): - if isinstance(o, YotiTokenRequest): - return o.__dict__() - if isinstance(o, SandboxAttribute): - return o.__dict__() - if isinstance(o, SandboxAnchor): - return o.__dict__() - - return json.JSONEncoder.default(self, o) - - -class SandboxClient(object): - def __init__(self, sdk_id, pem_file, sandbox_url): - self.sdk_id = sdk_id - self.__endpoint = SandboxEndpoint(sdk_id) - self.__sandbox_url = sandbox_url - - pem_data = SandboxClient.__read_pem_file( - pem_file, "failed in SandboxClient __init__" - ) - - self.__crypto = Crypto(pem_data) - - def setup_sharing_profile(self, request_token): - """ - Using the supplied YotiTokenRequest, this function will make a request - to the defined sandbox environment to create a profile with the supplied values. - The returned token can be used against the sandbox environment to retrieve the profile - using the standard YotiClient. - - :param YotiTokenRequest request_token: - :return: the token for accessing a profile - """ - request_path = self.__endpoint.get_sandbox_path() - response = SandboxClient.post( - self.__sandbox_url, request_path, self.__crypto, request_token - ) - response_payload = response.json() - return YotiTokenResponse(response_payload["token"]) - - @staticmethod - def builder(): - """ - Creates an instance of the sandbox client builder - - :return: instance of SandboxClientBuilder - """ - return SandboxClientBuilder() - - @staticmethod - def post(host, path, key, content): - payload = json.dumps(content, cls=SandboxEncoder) - payload_bytes = payload.encode() - headers = SandboxClient.__get_request_headers(path, "POST", payload_bytes, key) - return requests.post(host + path, payload_bytes, headers=headers, verify=False) - - @staticmethod - def __get_request_headers(path, http_method, content, crypto): - request = SandboxClient.__create_request(http_method, path, content) - sdk_version = yoti_python_sdk.__version__ - - return { - X_YOTI_AUTH_KEY: crypto.get_public_key(), - X_YOTI_AUTH_DIGEST: crypto.sign(request), - X_YOTI_SDK: SDK_IDENTIFIER, - X_YOTI_SDK_VERSION: "{0}-{1}".format(SDK_IDENTIFIER, sdk_version), - "Content-Type": JSON_CONTENT_TYPE, - "Accept": JSON_CONTENT_TYPE, - } - - @staticmethod - def __read_pem_file(key_file_path, error_source): - try: - key_file_path = expanduser(key_file_path) - - if not isinstance(key_file_path, basestring) or not isfile(key_file_path): - raise IOError("File not found: {0}".format(key_file_path)) - with open(key_file_path, "rb") as pem_file: - return pem_file.read().strip() - except (AttributeError, IOError, TypeError, OSError) as exc: - error = 'Could not read private key file: "{0}", passed as: {1} '.format( - key_file_path, error_source - ) - exception = "{0}: {1}".format(type(exc).__name__, exc) - raise RuntimeError("{0}: {1}".format(error, exception)) - - @staticmethod - def __create_request(http_method, path, content): - if http_method not in HTTP_SUPPORTED_METHODS: - raise ValueError( - "{} is not in the list of supported methods: {}".format( - http_method, HTTP_SUPPORTED_METHODS - ) - ) - - request = "{}&{}".format(http_method, path) - - if content is not None: - b64encoded = base64.b64encode(content) - b64ascii = b64encoded.decode("ascii") - request += "&" + b64ascii - - return request - - -class SandboxClientBuilder(object): - def __init__(self): - self.__sdk_id = None - self.__pem_file = None - self.__sandbox_url = None - - def for_application(self, sdk_id): - """ - Sets the application ID on the builder - - :param str sdk_id: the SDK ID supplied from Yoti Hub - :return: the updated builder - """ - self.__sdk_id = sdk_id - return self - - def with_pem_file(self, pem_file): - """ - Sets the pem file to be used on the builder - - :param str pem_file: path to the PEM file - :return: the updated builder - """ - self.__pem_file = pem_file - return self - - def with_sandbox_url(self, sandbox_url): - """ - Sets the URL of the sandbox environment on the builder - - :param str sandbox_url: the sandbox environment URL - :return: the updated builder - """ - self.__sandbox_url = sandbox_url - return self - - def build(self): - """ - Using all supplied values, create an instance of the SandboxClient. - - :raises ValueError: one or more of the values is None - :return: instance of SandboxClient - """ - if ( - self.__sdk_id is None - or self.__pem_file is None - or self.__sandbox_url is None - ): - raise ValueError("SDK ID/PEM file/sandbox url must not be None") - - return SandboxClient(self.__sdk_id, self.__pem_file, self.__sandbox_url) diff --git a/yoti_python_sandbox/endpoint.py b/yoti_python_sandbox/endpoint.py deleted file mode 100644 index 194dd812..00000000 --- a/yoti_python_sandbox/endpoint.py +++ /dev/null @@ -1,12 +0,0 @@ -from yoti_python_sdk.endpoint import Endpoint -from yoti_python_sdk.utils import create_timestamp, create_nonce - - -class SandboxEndpoint(Endpoint): - def __init__(self, sdk_id): - super(SandboxEndpoint, self).__init__(sdk_id) - - def get_sandbox_path(self): - return "/apps/{sdk_id}/tokens?timestamp={timestamp}&nonce={nonce}".format( - sdk_id=self.sdk_id, nonce=create_nonce(), timestamp=create_timestamp() - ) diff --git a/yoti_python_sandbox/tests/__init__.py b/yoti_python_sandbox/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/yoti_python_sandbox/tests/test_sandbox_client.py b/yoti_python_sandbox/tests/test_sandbox_client.py deleted file mode 100644 index def3c533..00000000 --- a/yoti_python_sandbox/tests/test_sandbox_client.py +++ /dev/null @@ -1,49 +0,0 @@ -from yoti_python_sandbox.client import SandboxClient -from yoti_python_sandbox.token import YotiTokenRequest, YotiTokenResponse -from yoti_python_sdk.tests.conftest import PEM_FILE_PATH - -try: - from unittest.mock import patch -except ImportError: - from mock import patch - -import pytest - - -def test_builder_should_throw_error_for_missing_sdk_id(): - builder = SandboxClient.builder().with_pem_file("some_pem.pem") - with pytest.raises(ValueError): - builder.build() - - -def test_builder_should_throw_error_for_missing_pem_file(): - builder = SandboxClient.builder().for_application("my_application") - with pytest.raises(ValueError): - builder.build() - - -def test_builder_should_build_client(): - client = ( - SandboxClient.builder() - .for_application("some_app") - .with_pem_file(PEM_FILE_PATH) - .with_sandbox_url("https://localhost") - .build() - ) - - assert client.sdk_id == "some_app" - assert isinstance(client, SandboxClient) - - -@patch("yoti_python_sandbox.client.SandboxClient") -def test_client_should_return_token_from_sandbox(sandbox_client_mock): - sandbox_client_mock.setup_profile_share.return_value = YotiTokenResponse( - "some-token" - ) - - token_request = ( - YotiTokenRequest.builder().with_remember_me_id("remember_me_pls").build() - ) - response = sandbox_client_mock.setup_profile_share(token_request) - - assert response.token == "some-token" diff --git a/yoti_python_sandbox/token.py b/yoti_python_sandbox/token.py deleted file mode 100644 index 6bdf2972..00000000 --- a/yoti_python_sandbox/token.py +++ /dev/null @@ -1,252 +0,0 @@ -from yoti_python_sandbox.attribute import SandboxAttribute -from yoti_python_sdk import config -import base64 - - -class YotiTokenResponse(object): - def __init__(self, token): - self.__token = token - - @property - def token(self): - """ - The token to be used by the Client - - :return: the token - """ - return self.__token - - -class YotiTokenRequest(object): - def __init__(self, remember_me_id=None, sandbox_attributes=None): - if remember_me_id is None: - remember_me_id = "" - - if sandbox_attributes is None: - sandbox_attributes = [] - - self.remember_me_id = remember_me_id - self.sandbox_attributes = sandbox_attributes - - def __dict__(self): - return { - "remember_me_id": self.remember_me_id, - "profile_attributes": self.sandbox_attributes, - } - - @staticmethod - def builder(): - """ - Creates an instance of the yoti token request builder - - :return: instance of YotiTokenRequestBuilder - """ - return YotiTokenRequestBuilder() - - -class YotiTokenRequestBuilder(object): - def __init__(self): - self.remember_me_id = None - self.attributes = [] - - def with_remember_me_id(self, remember_me_id): - """ - Sets the remember me id on the builder - - :param remember_me_id: the remember me id - :return: the updated builder - """ - self.remember_me_id = remember_me_id - return self - - def with_attribute(self, sandbox_attribute): - """ - Appends a SandboxAttribute to the list of attributes on the builder - - :param SandboxAttribute sandbox_attribute: - :return: the updated builder - """ - self.attributes.append(sandbox_attribute) - return self - - def with_given_names(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for given names - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_GIVEN_NAMES, value, anchors - ) - return self.with_attribute(attribute) - - def with_family_name(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for family name - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_FAMILY_NAME, value, anchors - ) - return self.with_attribute(attribute) - - def with_full_name(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for full name - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute(config.ATTRIBUTE_FULL_NAME, value, anchors) - return self.with_attribute(attribute) - - def with_date_of_birth(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for date of birth - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_DATE_OF_BIRTH, value, anchors - ) - return self.with_attribute(attribute) - - def with_age_verification(self, age_verification): - """ - Creates and appends a SandboxAttribute with a given age verification - - :param SandboxAgeVerification age_verification: the age verification - :return: - """ - return self.with_attribute(age_verification.to_attribute()) - - def with_gender(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for gender - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute(config.ATTRIBUTE_GENDER, value, anchors) - return self.with_attribute(attribute) - - def with_phone_number(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for phone number - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_PHONE_NUMBER, value, anchors - ) - return self.with_attribute(attribute) - - def with_nationality(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for nationality - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_NATIONALITY, value, anchors - ) - return self.with_attribute(attribute) - - def with_postal_address(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for postal address - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_POSTAL_ADDRESS, value, anchors - ) - return self.with_attribute(attribute) - - def with_structured_postal_address(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for structured postal address - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_STRUCTURED_POSTAL_ADDRESS, value, anchors - ) - return self.with_attribute(attribute) - - def with_selfie(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for a selfie - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - base64_selfie = base64.b64encode(value).decode("utf-8") - return self.with_base64_selfie(base64_selfie, anchors) - - def with_base64_selfie(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for given names - - :param str value: base64 encoded value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute(config.ATTRIBUTE_SELFIE, value, anchors) - return self.with_attribute(attribute) - - def with_email_address(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for email address - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_EMAIL_ADDRESS, value, anchors - ) - return self.with_attribute(attribute) - - def with_document_details(self, value, anchors=None): - """ - Creates and appends a SandboxAttribute for document details - - :param str value: the value - :param list[SandboxAnchor] anchors: optional list of anchors - :return: - """ - attribute = self.__create_attribute( - config.ATTRIBUTE_DOCUMENT_DETAILS, value, anchors - ) - return self.with_attribute(attribute) - - def build(self): - """ - Creates an instance of YotiTokenRequest using the supplied values - - :return: instance of YotiTokenRequest - """ - return YotiTokenRequest(self.remember_me_id, self.attributes) - - @staticmethod - def __create_attribute(name, value, anchors=None): - return SandboxAttribute(name, value, anchors) diff --git a/yoti_python_sdk/version.py b/yoti_python_sdk/version.py index 6f7b7c7d..0bcaa459 100644 --- a/yoti_python_sdk/version.py +++ b/yoti_python_sdk/version.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -__version__ = "2.10.1" +__version__ = "2.10.2"