Skip to content

Add types #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@ jobs:
cache: 'poetry'
- name: Install dependencies
run: poetry install
- name: test code
- name: Type checking
# Mypy configuration defined in pyproject.toml
run: poetry run mypy
- name: Run tests
run: poetry run pytest
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- improved the documentation.
- Added github action to release the package.
- Added types to IdApi, ServerError, Utilities, and WebApi classes

## [1.0.9] - 2022-11-01
### Added
Expand Down Expand Up @@ -52,4 +53,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed python semantics.
- Moved zipfile out from webapi class.

## [0.0.12] - 2022-08-19
## [0.0.12] - 2022-08-19
73 changes: 72 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ pycryptodome = "3.9.8"
pytest = "^7.0.0"
responses = "0.13.3"
black = "22.8.0"
mypy = "^0.971"
types-requests = "^2.28.11.2"

[tool.mypy]
files = "smile_id_core,tests"
pretty = true
show_error_codes = true
strict_equality = true
warn_unused_configs = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true

[build-system]
requires = ["poetry-core"]
Expand Down
18 changes: 11 additions & 7 deletions smile_id_core/IdApi.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import json
from typing import Dict
from typing import Optional, Dict, Union

from requests import Response

from smile_id_core.Utilities import (
Utilities,
Expand All @@ -14,23 +16,23 @@


class IdApi:
def __init__(self, partner_id: str, api_key: str, sid_server: str or int):
def __init__(self, partner_id: str, api_key: str, sid_server: Union[str, int]):
if not partner_id or not api_key:
raise ValueError("partner_id or api_key cannot be null or empty")
self.partner_id = partner_id
self.api_key = api_key
if sid_server in [0, 1, "0", "1"]:
self.url = sid_server_map[int(sid_server)]
else:
self.url = sid_server
self.url = str(sid_server)

def submit_job(
self,
partner_params: Dict,
id_params: Dict,
use_validation_api=True,
options_params: Dict = None,
):
options_params: Optional[Dict] = None,
) -> Response:
if not options_params:
options_params = {}

Expand Down Expand Up @@ -59,7 +61,9 @@ def submit_job(
)
return response

def __configure_json(self, partner_params, id_params, sec_key):
def __configure_json(
self, partner_params: Dict, id_params: Dict, sec_key: Dict
) -> Dict:
validate_sec_params(sec_key)
payload = {
**sec_key,
Expand All @@ -69,7 +73,7 @@ def __configure_json(self, partner_params, id_params, sec_key):
payload.update(id_params)
return payload

def __execute_http(self, payload):
def __execute_http(self, payload: Dict) -> Response:
data = json.dumps(payload)
resp = requests.post(
url=f"{self.url}/id_verification",
Expand Down
2 changes: 1 addition & 1 deletion smile_id_core/ServerError.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@


class ServerError(Exception):
def __init__(self, message):
def __init__(self, message: str):
self.message = message
57 changes: 35 additions & 22 deletions smile_id_core/Utilities.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import json
from typing import Dict
from typing import Union, Optional, Dict

import requests
from requests import Response

from smile_id_core.Signature import Signature
from smile_id_core.ServerError import ServerError
Expand All @@ -15,18 +16,23 @@


class Utilities:
def __init__(self, partner_id, api_key, sid_server):
def __init__(self, partner_id: str, api_key: str, sid_server: Union[int, str]):
if not partner_id or not api_key:
raise ValueError("partner_id or api_key cannot be null or empty")
self.partner_id = partner_id
self.api_key = api_key
self.sid_server = sid_server
if sid_server in [0, 1]:
self.url = sid_server_map[sid_server]
if sid_server in [0, 1, "0", "1"]:
self.url = sid_server_map[int(sid_server)]
else:
self.url = sid_server

def get_job_status(self, partner_params, option_params, sec_params=None):
self.url = str(sid_server)

def get_job_status(
self,
partner_params: Dict,
option_params: Dict,
sec_params: Optional[Dict] = None,
) -> Response:
if sec_params is None:
sec_params = get_signature(
self.partner_id, self.api_key, option_params.get("signature")
Expand All @@ -47,13 +53,15 @@ def get_job_status(self, partner_params, option_params, sec_params=None):
else:
options = option_params
return self.__query_job_status(
partner_params.get("user_id"),
partner_params.get("job_id"),
str(partner_params.get("user_id")),
str(partner_params.get("job_id")),
options,
sec_params,
)

def __query_job_status(self, user_id, job_id, option_params, sec_params):
def __query_job_status(
self, user_id: str, job_id: str, option_params: Dict, sec_params: Dict
) -> Response:
job_status = Utilities.execute_post(
f"{self.url}/job_status",
self.__configure_job_query(user_id, job_id, option_params, sec_params),
Expand All @@ -77,7 +85,9 @@ def __query_job_status(self, user_id, job_id, option_params, sec_params):
)
return job_status

def __configure_job_query(self, user_id, job_id, options, sec_params):
def __configure_job_query(
self, user_id: str, job_id: str, options: Dict, sec_params: Dict
) -> Dict:
return {
**sec_params,
"partner_id": self.partner_id,
Expand All @@ -88,7 +98,7 @@ def __configure_job_query(self, user_id, job_id, options, sec_params):
}

@staticmethod
def validate_partner_params(partner_params):
def validate_partner_params(partner_params: Dict) -> None:
if not partner_params:
raise ValueError("Please ensure that you send through partner params")

Expand All @@ -110,8 +120,11 @@ def validate_partner_params(partner_params):

@staticmethod
def validate_id_params(
sid_server, id_info_params, partner_params, use_validation_api=False
):
sid_server: Union[str, int],
id_info_params: Dict,
partner_params: Dict,
use_validation_api=False,
) -> None:
job_type = partner_params.get("job_type")
if job_type != 6 and not id_info_params.get("entered"):
return
Expand Down Expand Up @@ -161,11 +174,11 @@ def validate_id_params(
raise ValueError(f"key {key} cannot be empty")

@staticmethod
def get_smile_id_services(sid_server):
if sid_server in [0, 1]:
url = sid_server_map[sid_server]
def get_smile_id_services(sid_server: Union[str, int]) -> Response:
if sid_server in [0, 1, "0", "1"]:
url = sid_server_map[int(sid_server)]
else:
url = sid_server
url = str(sid_server)
response = Utilities.execute_get(f"{url}/services")
if response.status_code != 200:
raise ServerError(
Expand All @@ -174,7 +187,7 @@ def get_smile_id_services(sid_server):
return response

@staticmethod
def execute_get(url):
def execute_get(url: str) -> Response:
resp = requests.get(
url=url,
headers={
Expand All @@ -185,7 +198,7 @@ def execute_get(url):
return resp

@staticmethod
def execute_post(url, payload):
def execute_post(url: str, payload: Dict) -> Response:
data = json.dumps(payload)
resp = requests.post(
url=url,
Expand All @@ -199,14 +212,14 @@ def execute_post(url, payload):
return resp


def validate_sec_params(sec_key_dict: Dict):
def validate_sec_params(sec_key_dict: Dict) -> None:
if not sec_key_dict.get("sec_key") and not sec_key_dict.get("signature"):
raise Exception("Missing key, must provide a 'sec_key' or 'signature' field")
if not sec_key_dict.get("timestamp"):
raise Exception("Missing 'timestamp' field")


def get_signature(partner_id, api_key, is_signature):
def get_signature(partner_id: str, api_key: str, is_signature) -> Dict[str, str]:
sec_key_gen = Signature(partner_id, api_key)
sec_key_object = (
sec_key_gen.generate_signature()
Expand Down
Loading