masstack-python-client 0.0.1__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {masstack_python_client-0.0.1/src/masstack_python_client.egg-info → masstack_python_client-0.0.3}/PKG-INFO +8 -1
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/README.md +7 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/pyproject.toml +7 -3
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/__init__.py +1 -1
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/auth/token_manager.py +6 -5
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/exceptions.py +8 -6
- masstack_python_client-0.0.3/src/masstack_python_client/resources/customers.py +106 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/enums/document_type_search.py +9 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/models/client_address.py +11 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/models/client_attribute.py +27 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/models/client_payment.py +14 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/models/products.py +90 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/models/signup.py +78 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/models/user.py +42 -0
- masstack_python_client-0.0.3/src/masstack_python_client/resources/utils/serialize.py +7 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3/src/masstack_python_client.egg-info}/PKG-INFO +8 -1
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client.egg-info/SOURCES.txt +11 -1
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/tests/test_client.py +4 -13
- masstack_python_client-0.0.3/tests/test_exceptions.py +14 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/LICENSE +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/MANIFEST.in +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/setup.cfg +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/auth/__init__.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/auth/token.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/auth/token_store.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/client.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/data/data_utils.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/data/province_translation.csv +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/data/street_type_translation.csv +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/data/unit_translation.csv +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/resources/__init__.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/resources/feasibility.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/resources/models/address.py +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client.egg-info/dependency_links.txt +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client.egg-info/requires.txt +0 -0
- {masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: masstack-python-client
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: This Python API client provides access to masmovil core API domains
|
|
5
5
|
Author-email: Borja Gimeno <borja.gimeno@somconnexio.coop>
|
|
6
6
|
License: GPL-3.0-only
|
|
@@ -38,6 +38,13 @@ This Python API client provides access to masmovil core API domains.
|
|
|
38
38
|
- get: returns a unit by id with a list of coverages
|
|
39
39
|
- get_coverage: returns coverage info for a unit id and territory_owner
|
|
40
40
|
|
|
41
|
+
* Customers
|
|
42
|
+
- Signups - access to signups new clients
|
|
43
|
+
- post new client
|
|
44
|
+
- Users
|
|
45
|
+
- returns customer tree data associated to a given document identification, email or number of the client.
|
|
46
|
+
- returns user data by userId
|
|
47
|
+
|
|
41
48
|
## Installation
|
|
42
49
|
|
|
43
50
|
```commandline
|
|
@@ -21,6 +21,13 @@ This Python API client provides access to masmovil core API domains.
|
|
|
21
21
|
- get: returns a unit by id with a list of coverages
|
|
22
22
|
- get_coverage: returns coverage info for a unit id and territory_owner
|
|
23
23
|
|
|
24
|
+
* Customers
|
|
25
|
+
- Signups - access to signups new clients
|
|
26
|
+
- post new client
|
|
27
|
+
- Users
|
|
28
|
+
- returns customer tree data associated to a given document identification, email or number of the client.
|
|
29
|
+
- returns user data by userId
|
|
30
|
+
|
|
24
31
|
## Installation
|
|
25
32
|
|
|
26
33
|
```commandline
|
|
@@ -74,7 +74,6 @@ requires = ["tox>=4.20"]
|
|
|
74
74
|
env_list = [
|
|
75
75
|
"style",
|
|
76
76
|
"py3119",
|
|
77
|
-
"coverage",
|
|
78
77
|
"pep8"
|
|
79
78
|
]
|
|
80
79
|
|
|
@@ -90,9 +89,9 @@ commands = [
|
|
|
90
89
|
["pre-commit", "run", "--all-files", "--show-diff-on-failure"],
|
|
91
90
|
]
|
|
92
91
|
|
|
93
|
-
[tool.tox.env.
|
|
92
|
+
[tool.tox.env.py3119]
|
|
94
93
|
commands = [
|
|
95
|
-
["pytest", "--cov", "--cov-report
|
|
94
|
+
["pytest", "--cov=masstack_python_client", "--cov-report=term:skip-covered", "--cov-report=html", "--cov-report=term-missing"],
|
|
96
95
|
]
|
|
97
96
|
|
|
98
97
|
[tool.tox.env.pep8]
|
|
@@ -100,3 +99,8 @@ deps = ["flake8"]
|
|
|
100
99
|
commands = [
|
|
101
100
|
["flake8"],
|
|
102
101
|
]
|
|
102
|
+
|
|
103
|
+
[tool.tox.env.coverage]
|
|
104
|
+
commands = [
|
|
105
|
+
["pytest", "--cov=masstack_python_client", "--cov-report=term-missing", "--cov-fail-under=95"],
|
|
106
|
+
]
|
|
@@ -56,17 +56,18 @@ class TokenManager:
|
|
|
56
56
|
try:
|
|
57
57
|
key = RSAKey.import_key(self._private_key)
|
|
58
58
|
assertion = jwt.encode(jwt_header, claims, key)
|
|
59
|
+
data = {
|
|
60
|
+
"assertion": assertion,
|
|
61
|
+
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
62
|
+
}
|
|
59
63
|
response = requests.post(
|
|
60
64
|
self._token_uri,
|
|
61
|
-
data=
|
|
62
|
-
"assertion": assertion,
|
|
63
|
-
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
64
|
-
},
|
|
65
|
+
data=data,
|
|
65
66
|
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
66
67
|
)
|
|
67
68
|
response.raise_for_status()
|
|
68
69
|
except HTTPError:
|
|
69
|
-
raise ErrorFetchingToKen(response.status_code, response.text)
|
|
70
|
+
raise ErrorFetchingToKen(response.status_code, response.text, data)
|
|
70
71
|
except Exception as e:
|
|
71
72
|
raise ErrorFetchingToKen(500, str(e))
|
|
72
73
|
data = response.json()
|
|
@@ -8,19 +8,19 @@ class MasstackClientException(Exception):
|
|
|
8
8
|
_message: Optional[str] = None
|
|
9
9
|
|
|
10
10
|
def __init__(self, status_code: int, message: str):
|
|
11
|
-
super(
|
|
11
|
+
super(MasstackClientException, self).__init__(message)
|
|
12
12
|
self._message = message
|
|
13
13
|
self._status_code = status_code
|
|
14
14
|
|
|
15
15
|
@property
|
|
16
16
|
def status_code(self) -> int:
|
|
17
17
|
"""The status_code property."""
|
|
18
|
-
return self._status_code
|
|
18
|
+
return 0 if self._status_code is None else self._status_code
|
|
19
19
|
|
|
20
20
|
@property
|
|
21
21
|
def message(self) -> str:
|
|
22
22
|
"""The error message property."""
|
|
23
|
-
return self._message
|
|
23
|
+
return "" if self._message is None else self._message
|
|
24
24
|
|
|
25
25
|
def _params_to_string(self, params):
|
|
26
26
|
if not params or len(params) == 0:
|
|
@@ -32,9 +32,11 @@ class MasstackClientException(Exception):
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
class ErrorFetchingToKen(MasstackClientException):
|
|
35
|
-
def __init__(self, status_code: int, error_msg: str):
|
|
36
|
-
message =
|
|
37
|
-
|
|
35
|
+
def __init__(self, status_code: int, error_msg: str, body: Optional[dict] = None):
|
|
36
|
+
message = (
|
|
37
|
+
"Error fetching token with the next error message: {}\nBody:\n{}".format(
|
|
38
|
+
error_msg, self._params_to_string(body)
|
|
39
|
+
)
|
|
38
40
|
)
|
|
39
41
|
super(ErrorFetchingToKen, self).__init__(status_code, message)
|
|
40
42
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from dataclasses import asdict
|
|
3
|
+
|
|
4
|
+
from masstack_python_client.client import MasstackClient
|
|
5
|
+
from masstack_python_client.resources.enums.document_type_search import (
|
|
6
|
+
DocumentTypeSearch,
|
|
7
|
+
)
|
|
8
|
+
from masstack_python_client.resources.models.signup import (
|
|
9
|
+
SignupRequestData,
|
|
10
|
+
SignupsResponseData,
|
|
11
|
+
)
|
|
12
|
+
from masstack_python_client.resources.models.user import UserData
|
|
13
|
+
from masstack_python_client.resources.utils.serialize import remove_none
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CustomersResource:
|
|
17
|
+
"""Provide the necessary functionality to be able to give
|
|
18
|
+
E2E coverage to the entire life-cycle of a client
|
|
19
|
+
https://developers.masstack.com/en/docs/apis_customers_doc_swagger/2/apioverview
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
_api_domain = "customers"
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def _request(
|
|
26
|
+
cls,
|
|
27
|
+
method: str,
|
|
28
|
+
endpoint: str,
|
|
29
|
+
params: Optional[dict] = None,
|
|
30
|
+
data: Optional[dict] = None,
|
|
31
|
+
) -> dict:
|
|
32
|
+
client = MasstackClient()
|
|
33
|
+
func = getattr(client, method)
|
|
34
|
+
|
|
35
|
+
return func(
|
|
36
|
+
api=cls._api_domain,
|
|
37
|
+
version=cls._version,
|
|
38
|
+
endpoint=endpoint,
|
|
39
|
+
params=params,
|
|
40
|
+
data=data,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SignupsResource(CustomersResource):
|
|
45
|
+
_api_path = "signups"
|
|
46
|
+
_version = "v2"
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def add_customer(cls, customer_data: SignupRequestData) -> SignupsResponseData:
|
|
50
|
+
"""Add new customers including products purchased.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
customer_data (SignupRequestData): The data of the customer to be added.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
SignupsResponseData
|
|
57
|
+
"""
|
|
58
|
+
payload = remove_none(asdict(customer_data))
|
|
59
|
+
result = cls._request(
|
|
60
|
+
method="post",
|
|
61
|
+
endpoint=cls._api_path,
|
|
62
|
+
data=payload,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return SignupsResponseData(
|
|
66
|
+
sell_id=result["sell_id"],
|
|
67
|
+
customer_id=result["customer_id"],
|
|
68
|
+
work_order_id=[result["work_order_id"]],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class Users(CustomersResource):
|
|
73
|
+
_api_path = "users"
|
|
74
|
+
_version = "v2"
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def get_user_id_by_doc(cls, doc: str, doc_type: DocumentTypeSearch) -> str:
|
|
78
|
+
"""
|
|
79
|
+
Get user ID associated to a given document identification
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
doc (str): The user's document number.
|
|
83
|
+
doc_type (DocumentTypeSearch): The type of document.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
user id.
|
|
87
|
+
"""
|
|
88
|
+
data = {"document_type": doc_type.value, "document": doc}
|
|
89
|
+
|
|
90
|
+
return cls._request(method="post", endpoint=f"{cls._api_path}/tree", data=data)[
|
|
91
|
+
"id"
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
@classmethod
|
|
95
|
+
def get_user_by_id(cls, user_id: str) -> dict:
|
|
96
|
+
"""
|
|
97
|
+
Get user information by user ID
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
user_id (str): The user's ID.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
UserData
|
|
104
|
+
"""
|
|
105
|
+
user = cls._request(method="get", endpoint=f"{cls._api_path}/{user_id}")
|
|
106
|
+
return UserData.from_dict(**user)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
|
|
4
|
+
from masstack_python_client.resources.models.client_address import ClientAddress
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True)
|
|
8
|
+
class ClientAttribute:
|
|
9
|
+
type: str
|
|
10
|
+
document_type_id: int
|
|
11
|
+
document_value: str
|
|
12
|
+
email: str
|
|
13
|
+
birthdate: str
|
|
14
|
+
nationality_id: int
|
|
15
|
+
contact_phone: str
|
|
16
|
+
gender: str
|
|
17
|
+
language_id: int
|
|
18
|
+
address: ClientAddress
|
|
19
|
+
name: str = None
|
|
20
|
+
company_name: str = None
|
|
21
|
+
middlename: str = "."
|
|
22
|
+
lastname: str = "."
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def from_dict(cls, data: Dict[str, Any]) -> "ClientAttribute":
|
|
26
|
+
data_address = data.pop("address")
|
|
27
|
+
return cls(address=ClientAddress(**data_address), **data)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass(frozen=True)
|
|
5
|
+
class BankAccount:
|
|
6
|
+
bank_account: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class ScoringAccount:
|
|
11
|
+
id_value: float = 1.01
|
|
12
|
+
scoring_value: int = 71
|
|
13
|
+
up_front: float = 1.01
|
|
14
|
+
forced_value: float = 0.01
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import List, Dict, Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass(frozen=True)
|
|
6
|
+
class Contact:
|
|
7
|
+
name: str
|
|
8
|
+
phone: str
|
|
9
|
+
email: str
|
|
10
|
+
document_type_id: str
|
|
11
|
+
document_value: str
|
|
12
|
+
middlename: str = "."
|
|
13
|
+
lastname: str = "."
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class Address:
|
|
18
|
+
street_type_id: int
|
|
19
|
+
street_name: str
|
|
20
|
+
number: int
|
|
21
|
+
supplement: str
|
|
22
|
+
state_id: int
|
|
23
|
+
locality: str
|
|
24
|
+
postal_code: str
|
|
25
|
+
gescal: str
|
|
26
|
+
address_id: str
|
|
27
|
+
pair_vacancy: bool = True
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class Info:
|
|
32
|
+
contact: Contact
|
|
33
|
+
address: Address
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_dict(
|
|
37
|
+
cls,
|
|
38
|
+
data: Dict[str, Any],
|
|
39
|
+
) -> "Info":
|
|
40
|
+
return cls(
|
|
41
|
+
contact=Contact(**data["contact"]),
|
|
42
|
+
address=Address(**data["address"]),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class Landline:
|
|
48
|
+
product_id: int
|
|
49
|
+
number: str
|
|
50
|
+
services: List = field(default_factory=list)
|
|
51
|
+
wants_communications: bool = False
|
|
52
|
+
# TODO portability_info
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(frozen=True)
|
|
56
|
+
class Ftth:
|
|
57
|
+
product_id: int
|
|
58
|
+
connection_type: str = ""
|
|
59
|
+
installer: str = "MM"
|
|
60
|
+
wants_communications: bool = False
|
|
61
|
+
# TODO access_reuse
|
|
62
|
+
# TODO access_reuse_choice
|
|
63
|
+
# TODO iua
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass(frozen=True)
|
|
67
|
+
class Bundle:
|
|
68
|
+
bundle_id: int
|
|
69
|
+
territory_owner: str
|
|
70
|
+
installation_info: Info
|
|
71
|
+
delivery_info: Info
|
|
72
|
+
landline: Landline
|
|
73
|
+
ftth: Ftth
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def from_dict(
|
|
77
|
+
cls,
|
|
78
|
+
bundle_id: int,
|
|
79
|
+
territory_owner: str,
|
|
80
|
+
**data,
|
|
81
|
+
) -> "Bundle":
|
|
82
|
+
info = Info.from_dict(data["client_info"])
|
|
83
|
+
return cls(
|
|
84
|
+
bundle_id,
|
|
85
|
+
territory_owner,
|
|
86
|
+
installation_info=info,
|
|
87
|
+
delivery_info=info,
|
|
88
|
+
landline=Landline(**data["land_line"]),
|
|
89
|
+
ftth=Ftth(**data["ftth"]),
|
|
90
|
+
)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import List, Dict, Any
|
|
3
|
+
|
|
4
|
+
from masstack_python_client.resources.models.client_attribute import ClientAttribute
|
|
5
|
+
from masstack_python_client.resources.models.client_payment import (
|
|
6
|
+
BankAccount,
|
|
7
|
+
ScoringAccount,
|
|
8
|
+
)
|
|
9
|
+
from masstack_python_client.resources.models.products import Bundle
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class SalesInfo:
|
|
14
|
+
dealer_id: str
|
|
15
|
+
shop_id: str
|
|
16
|
+
channel: str = "dealer"
|
|
17
|
+
logistic: bool = False
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class Clients:
|
|
22
|
+
attributes: List[ClientAttribute]
|
|
23
|
+
sector_id: int = 1
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Clients":
|
|
27
|
+
client_types = ["client", "account"]
|
|
28
|
+
return cls(
|
|
29
|
+
attributes=[
|
|
30
|
+
ClientAttribute.from_dict({"type": client_type, **data})
|
|
31
|
+
for client_type in client_types
|
|
32
|
+
]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class ClientPayment:
|
|
38
|
+
info: BankAccount
|
|
39
|
+
scoring: ScoringAccount = ScoringAccount()
|
|
40
|
+
billing_type_id: int = 1
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def from_dict(cls, data: Dict[str, Any]) -> "ClientPayment":
|
|
44
|
+
return cls(info=BankAccount(bank_account=data["bank_account"]))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class Products:
|
|
49
|
+
bundle: Bundle
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Products":
|
|
53
|
+
return cls(bundle=Bundle.from_dict(**data))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True)
|
|
57
|
+
class SignupRequestData:
|
|
58
|
+
sales_info: SalesInfo
|
|
59
|
+
clients: Clients
|
|
60
|
+
payment: ClientPayment
|
|
61
|
+
products: Products
|
|
62
|
+
sales_type: str = "telecomunications"
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def from_dict(cls, data: Dict[str, Any]) -> "SignupRequestData":
|
|
66
|
+
return cls(
|
|
67
|
+
sales_info=SalesInfo(**data["sales"]),
|
|
68
|
+
clients=Clients.from_dict(data["client"]),
|
|
69
|
+
payment=ClientPayment.from_dict(data["payment"]),
|
|
70
|
+
products=Products.from_dict(data["products"]),
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass(frozen=True)
|
|
75
|
+
class SignupsResponseData:
|
|
76
|
+
sell_id: int
|
|
77
|
+
customer_id: int
|
|
78
|
+
work_order_id: str
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass(frozen=True)
|
|
5
|
+
class UserData:
|
|
6
|
+
id: int
|
|
7
|
+
document_value: str
|
|
8
|
+
document_type_id: int
|
|
9
|
+
gender: str
|
|
10
|
+
first_name: str
|
|
11
|
+
middle_name: str
|
|
12
|
+
last_name: str
|
|
13
|
+
nationality: str
|
|
14
|
+
email: str
|
|
15
|
+
birthdate: str
|
|
16
|
+
phone: str
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def from_dict(
|
|
20
|
+
cls,
|
|
21
|
+
id,
|
|
22
|
+
document_value: str,
|
|
23
|
+
document_type: dict,
|
|
24
|
+
nationality: dict,
|
|
25
|
+
personal: dict,
|
|
26
|
+
**kwargs,
|
|
27
|
+
):
|
|
28
|
+
return cls(
|
|
29
|
+
**{
|
|
30
|
+
"id": id,
|
|
31
|
+
"document_value": document_value,
|
|
32
|
+
"document_type_id": document_type["id"],
|
|
33
|
+
"gender": personal["gender"],
|
|
34
|
+
"first_name": personal["first_name"],
|
|
35
|
+
"middle_name": personal["middle_name"],
|
|
36
|
+
"last_name": personal["last_name"],
|
|
37
|
+
"nationality": nationality["value"],
|
|
38
|
+
"email": personal["email"],
|
|
39
|
+
"birthdate": personal["birthdate"],
|
|
40
|
+
"phone": personal["other_phone"],
|
|
41
|
+
}
|
|
42
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: masstack-python-client
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: This Python API client provides access to masmovil core API domains
|
|
5
5
|
Author-email: Borja Gimeno <borja.gimeno@somconnexio.coop>
|
|
6
6
|
License: GPL-3.0-only
|
|
@@ -38,6 +38,13 @@ This Python API client provides access to masmovil core API domains.
|
|
|
38
38
|
- get: returns a unit by id with a list of coverages
|
|
39
39
|
- get_coverage: returns coverage info for a unit id and territory_owner
|
|
40
40
|
|
|
41
|
+
* Customers
|
|
42
|
+
- Signups - access to signups new clients
|
|
43
|
+
- post new client
|
|
44
|
+
- Users
|
|
45
|
+
- returns customer tree data associated to a given document identification, email or number of the client.
|
|
46
|
+
- returns user data by userId
|
|
47
|
+
|
|
41
48
|
## Installation
|
|
42
49
|
|
|
43
50
|
```commandline
|
|
@@ -19,6 +19,16 @@ src/masstack_python_client/data/province_translation.csv
|
|
|
19
19
|
src/masstack_python_client/data/street_type_translation.csv
|
|
20
20
|
src/masstack_python_client/data/unit_translation.csv
|
|
21
21
|
src/masstack_python_client/resources/__init__.py
|
|
22
|
+
src/masstack_python_client/resources/customers.py
|
|
22
23
|
src/masstack_python_client/resources/feasibility.py
|
|
24
|
+
src/masstack_python_client/resources/enums/document_type_search.py
|
|
23
25
|
src/masstack_python_client/resources/models/address.py
|
|
24
|
-
|
|
26
|
+
src/masstack_python_client/resources/models/client_address.py
|
|
27
|
+
src/masstack_python_client/resources/models/client_attribute.py
|
|
28
|
+
src/masstack_python_client/resources/models/client_payment.py
|
|
29
|
+
src/masstack_python_client/resources/models/products.py
|
|
30
|
+
src/masstack_python_client/resources/models/signup.py
|
|
31
|
+
src/masstack_python_client/resources/models/user.py
|
|
32
|
+
src/masstack_python_client/resources/utils/serialize.py
|
|
33
|
+
tests/test_client.py
|
|
34
|
+
tests/test_exceptions.py
|
|
@@ -25,7 +25,6 @@ class ClientTestCase(unittest.TestCase):
|
|
|
25
25
|
self.version = "v1"
|
|
26
26
|
self.endpoint = "testapi"
|
|
27
27
|
self.params = {"param1": "value1", "param2": "value2"}
|
|
28
|
-
self.header = {"Custom-Header": "HeaderValue"}
|
|
29
28
|
|
|
30
29
|
"""
|
|
31
30
|
test get
|
|
@@ -36,9 +35,7 @@ class ClientTestCase(unittest.TestCase):
|
|
|
36
35
|
status_code=200, json=lambda: {"data": "test_data"}
|
|
37
36
|
)
|
|
38
37
|
self.assertEqual(
|
|
39
|
-
MasstackClient().get(
|
|
40
|
-
self.api, self.version, self.endpoint, self.params, self.header
|
|
41
|
-
),
|
|
38
|
+
MasstackClient().get(self.api, self.version, self.endpoint, self.params),
|
|
42
39
|
{"data": "test_data"},
|
|
43
40
|
)
|
|
44
41
|
mock_token_manager.assert_called_once()
|
|
@@ -48,7 +45,6 @@ class ClientTestCase(unittest.TestCase):
|
|
|
48
45
|
headers={
|
|
49
46
|
"Authorization": "Bearer test_token",
|
|
50
47
|
"Accept": "application/json",
|
|
51
|
-
**self.header,
|
|
52
48
|
},
|
|
53
49
|
json=None,
|
|
54
50
|
params=self.params,
|
|
@@ -65,7 +61,6 @@ class ClientTestCase(unittest.TestCase):
|
|
|
65
61
|
self.version,
|
|
66
62
|
self.endpoint,
|
|
67
63
|
self.params,
|
|
68
|
-
self.header,
|
|
69
64
|
)
|
|
70
65
|
|
|
71
66
|
"""
|
|
@@ -73,16 +68,13 @@ class ClientTestCase(unittest.TestCase):
|
|
|
73
68
|
"""
|
|
74
69
|
|
|
75
70
|
def test_post_ok(self, mock_request, mock_token_manager):
|
|
71
|
+
extra_header = {"Custom-Header": "HeaderValue"}
|
|
76
72
|
mock_request.return_value = Mock(
|
|
77
73
|
status_code=200, json=lambda: {"data": "test_data"}
|
|
78
74
|
)
|
|
79
75
|
self.assertEqual(
|
|
80
76
|
MasstackClient().post(
|
|
81
|
-
self.api,
|
|
82
|
-
self.version,
|
|
83
|
-
self.endpoint,
|
|
84
|
-
self.params,
|
|
85
|
-
self.header,
|
|
77
|
+
self.api, self.version, self.endpoint, self.params, extra_header
|
|
86
78
|
),
|
|
87
79
|
{"data": "test_data"},
|
|
88
80
|
)
|
|
@@ -93,7 +85,7 @@ class ClientTestCase(unittest.TestCase):
|
|
|
93
85
|
headers={
|
|
94
86
|
"Authorization": "Bearer test_token",
|
|
95
87
|
"Accept": "application/json",
|
|
96
|
-
**
|
|
88
|
+
**extra_header,
|
|
97
89
|
},
|
|
98
90
|
json=self.params,
|
|
99
91
|
params=None,
|
|
@@ -110,5 +102,4 @@ class ClientTestCase(unittest.TestCase):
|
|
|
110
102
|
self.version,
|
|
111
103
|
self.endpoint,
|
|
112
104
|
self.params,
|
|
113
|
-
self.header,
|
|
114
105
|
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from masstack_python_client.exceptions import MasstackClientException
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MasstackClientExceptionTestCase(unittest.TestCase):
|
|
7
|
+
def test_exception_fallback_properties(self):
|
|
8
|
+
exc = MasstackClientException(0, "")
|
|
9
|
+
|
|
10
|
+
exc._status_code = None
|
|
11
|
+
exc._message = None
|
|
12
|
+
|
|
13
|
+
self.assertEqual(exc.status_code, 0)
|
|
14
|
+
self.assertEqual(exc.message, "")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{masstack_python_client-0.0.1 → masstack_python_client-0.0.3}/src/masstack_python_client/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|