Skip to content

Commit 87a46dd

Browse files
Merge branch 'upstream'
# Conflicts: # connect/models/fulfillment.py
2 parents 0c7616f + c94ef38 commit 87a46dd

File tree

15 files changed

+391
-106
lines changed

15 files changed

+391
-106
lines changed

connect/exceptions.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import List
77

88
from deprecation import deprecated
9+
import six
910

1011
from .models.parameters import Param
1112

@@ -25,6 +26,9 @@ class Message(Exception):
2526
""" (str) Additional information. """
2627

2728
def __init__(self, message='', code='', obj=None):
29+
# On Python 2, Unicode messages must be utf-8 encoded
30+
if six.PY2 and isinstance(message, six.string_types) and not isinstance(message, str):
31+
message = message.encode('utf-8')
2832
super(Message, self).__init__(message)
2933
self.code = code
3034
self.obj = obj
@@ -141,11 +145,3 @@ class FileRetrievalError(Message):
141145
def __init__(self, message):
142146
# type: (str) -> None
143147
super(FileRetrievalError, self).__init__(message, 'fileretrieval')
144-
145-
146-
class MigrationAbortError(Exception):
147-
pass
148-
149-
150-
class MigrationParamError(Exception):
151-
pass

connect/models/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from .company import Company, User
1010
from .connection import Connection
1111
from .contact import Contact, ContactInfo, PhoneNumber
12+
from .conversation import Conversation, ConversationMessage
1213
from .event import EventInfo, Events
1314
from .fulfillment import Fulfillment
1415
from .hub import Hub, HubInstance, ExtIdHub, HubStats
@@ -17,12 +18,10 @@
1718
from .product import CustomerUiSettings, Document, DownloadLink, Item, Product, \
1819
ProductConfiguration, Renewal
1920
from .server_error_response import ServerErrorResponse
20-
from .tier_config import Account, Template, TierConfig, TierConfigRequest
21-
from .tiers import Tier, Tiers
21+
from .tier_config import Template, TierAccount, TierAccounts, TierConfig, TierConfigRequest
2222
from .usage import UsageFile, UsageListing, UsageRecord, UsageRecords
2323

2424
__all__ = [
25-
'Account',
2625
'Activation',
2726
'ActivationTemplateResponse',
2827
'ActivationTileResponse',
@@ -36,6 +35,8 @@
3635
'Contact',
3736
'ContactInfo',
3837
'Contract',
38+
'Conversation',
39+
'ConversationMessage',
3940
'CustomerUiSettings',
4041
'Document',
4142
'DownloadLink',
@@ -55,10 +56,10 @@
5556
'Renewal',
5657
'ServerErrorResponse',
5758
'Template',
58-
'Tier',
59+
'TierAccount',
60+
'TierAccounts',
5961
'TierConfig',
6062
'TierConfigRequest',
61-
'Tiers',
6263
'UsageFile',
6364
'UsageListing',
6465
'UsageRecord',

connect/models/asset.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .connection import Connection
1010
from .parameters import Param
1111
from .product import Item, Product
12-
from .tiers import Tiers
12+
from .tier_config import TierAccounts
1313
from connect.models.schemas import AssetSchema
1414

1515

@@ -71,8 +71,8 @@ class Asset(BaseModel):
7171
params = None # type: List[Param]
7272
""" (List[:py:class:`.Param`]) List of product parameter objects. """
7373

74-
tiers = None # type: Tiers
75-
""" (:py:class:`.Tiers`) Supply chain accounts. """
74+
tiers = None # type: TierAccounts
75+
""" (:py:class:`.TierAccounts`) Supply chain accounts. """
7676

7777
def get_param_by_id(self, id_):
7878
""" Get a parameter of the asset.

connect/models/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def deserialize(cls, json_str):
4040
:param str json_str: String containing the JSON data to be deserialized.
4141
:return: An instance of the same class as the receiver of the call, or a list of instances.
4242
:rtype: Any|list[Any]
43+
:raises TypeError: Raised if the data cannot be deserialized.
4344
"""
4445
return cls.deserialize_json(json.loads(json_str))
4546

@@ -50,6 +51,7 @@ def deserialize_json(cls, json_data):
5051
:param dict|list json_data: JSON list or dictionary to be deserialized.
5152
:return: An instance of the same class as the receiver of the call, or a list of instances.
5253
:rtype: Any|list[Any]
54+
:raises TypeError: Raised if the data cannot be deserialized.
5355
"""
5456
objects, error = cls._schema.load(json_data, many=isinstance(json_data, list))
5557
if error:

connect/models/conversation.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# This file is part of the Ingram Micro Cloud Blue Connect SDK.
4+
# Copyright (c) 2019 Ingram Micro. All Rights Reserved.
5+
6+
import datetime
7+
8+
from typing import List
9+
10+
from .base import BaseModel
11+
from .company import User
12+
from connect.models.schemas import ConversationMessageSchema, ConversationSchema
13+
14+
15+
class ConversationMessage(BaseModel):
16+
""" Message in a :py:class:`.Conversation`. """
17+
18+
_schema = ConversationMessageSchema()
19+
20+
conversation = None # type: str
21+
""" (str) Primary ID of Conversation object. """
22+
23+
created = None # type: datetime.datetime
24+
""" (datetime.datetime) Date of the Message creation. """
25+
26+
creator = None # type: User
27+
""" (:py:class:`.User`) :py:class:`.User` that created the message. """
28+
29+
text = None # type: str
30+
""" (str) Actual message. """
31+
32+
33+
class Conversation(BaseModel):
34+
""" Conversation. """
35+
36+
_schema = ConversationSchema()
37+
38+
instance_id = None # type: str
39+
""" (str) The id of object based on which discussion is made, e.g. listing request.
40+
It can be any object.
41+
"""
42+
43+
created = None # type: datetime.datetime
44+
""" (datetime.datetime) Date of the Conversation creation. """
45+
46+
topic = None # type: str
47+
""" (str) Conversation topic. """
48+
49+
messages = None # type: List[ConversationMessage]
50+
""" (List[:py:class:`.ConversationMessage`]) List of :py:class:`.ConversationMessage`
51+
objects.
52+
"""
53+
54+
creator = None # type: User
55+
""" (:py:class:`.User`) Creator of the conversation. """
56+
57+
def add_message(self, message, config=None):
58+
""" Adds a message to the conversation.
59+
60+
:param str message: Message to add.
61+
:param Config config: Configuration, or ``None`` to use the environment config (default).
62+
:return: The added message.
63+
:rtype: ConversationMessage
64+
:raises TypeError: Raised if the message cannot be deserialized.
65+
"""
66+
67+
from connect.resources.base import ApiClient
68+
response, _ = ApiClient(config, base_path='conversations/' + self.id + '/messages')\
69+
.post(json={'text': message})
70+
return ConversationMessage.deserialize(response)

connect/models/fulfillment.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from .asset import Asset
99
from .base import BaseModel
10+
from .conversation import Conversation
1011
from .marketplace import Contract, Marketplace
1112
from connect.models.schemas import FulfillmentSchema
1213

@@ -113,3 +114,23 @@ def needs_migration(self, migration_key='migration_info'):
113114
:rtype: bool
114115
"""
115116
return self.asset.get_param_by_id(migration_key) is not None
117+
118+
def get_conversation(self, config=None):
119+
"""
120+
:param Config config: Configuration, or ``None`` to use the environment config (default).
121+
:return: The conversation for this request, or ``None`` if there is none.
122+
:rtype: Conversation|None
123+
"""
124+
from connect.resources.base import ApiClient
125+
126+
client = ApiClient(config, base_path='conversations')
127+
response, _ = client.get(params={'instance_id': self.id})
128+
try:
129+
conversations = Conversation.deserialize(response)
130+
if conversations and conversations[0].id:
131+
response, _ = client.get(conversations[0].id)
132+
return Conversation.deserialize(response)
133+
else:
134+
return None
135+
except ValueError:
136+
return None

connect/models/schemas.py

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,6 @@ def make_object(self, data):
8585
return ContactInfo(**data)
8686

8787

88-
class AccountSchema(BaseSchema):
89-
name = fields.Str()
90-
external_id = fields.Str(allow_none=True)
91-
external_uid = fields.Str(allow_none=True)
92-
contact_info = fields.Nested(ContactInfoSchema)
93-
94-
@post_load
95-
def make_object(self, data):
96-
from connect.models import Account
97-
return Account(**data)
98-
99-
10088
class ValueChoiceSchema(Schema):
10189
value = fields.Str()
10290
label = fields.Str()
@@ -396,27 +384,27 @@ def make_object(self, data):
396384
return Template(**data)
397385

398386

399-
class TierSchema(BaseSchema):
387+
class TierAccountSchema(BaseSchema):
400388
name = fields.Str()
401389
contact_info = fields.Nested(ContactInfoSchema)
402390
external_id = fields.Str()
403391
external_uid = fields.Str()
404392

405393
@post_load
406394
def make_object(self, data):
407-
from connect.models import Tier
408-
return Tier(**data)
395+
from connect.models import TierAccount
396+
return TierAccount(**data)
409397

410398

411-
class TiersSchema(Schema):
412-
customer = fields.Nested(TierSchema)
413-
tier1 = fields.Nested(TierSchema)
414-
tier2 = fields.Nested(TierSchema)
399+
class TierAccountsSchema(Schema):
400+
customer = fields.Nested(TierAccountSchema)
401+
tier1 = fields.Nested(TierAccountSchema)
402+
tier2 = fields.Nested(TierAccountSchema)
415403

416404
@post_load
417405
def make_object(self, data):
418-
from connect.models import Tiers
419-
return Tiers(**data)
406+
from connect.models import TierAccounts
407+
return TierAccounts(**data)
420408

421409

422410
class ConnectionSchema(BaseSchema):
@@ -442,7 +430,7 @@ class AssetSchema(BaseSchema):
442430
)
443431
items = fields.Nested(ItemSchema, many=True)
444432
params = fields.Nested(ParamSchema, many=True)
445-
tiers = fields.Nested(TiersSchema)
433+
tiers = fields.Nested(TierAccountsSchema)
446434

447435
@post_load
448436
def make_object(self, data):
@@ -471,7 +459,7 @@ def make_object(self, data):
471459

472460
class TierConfigSchema(BaseSchema):
473461
name = fields.Str()
474-
account = fields.Nested(AccountSchema)
462+
account = fields.Nested(TierAccountSchema)
475463
product = fields.Nested(ProductSchema)
476464
tier_level = fields.Int()
477465
connection = fields.Nested(ConnectionSchema)
@@ -579,3 +567,28 @@ class UsageRecordSchema(BaseSchema):
579567
def make_object(self, data):
580568
from connect.models import UsageRecord
581569
return UsageRecord(**data)
570+
571+
572+
class ConversationMessageSchema(BaseSchema):
573+
conversation = fields.Str()
574+
created = fields.DateTime()
575+
creator = fields.Nested(UserSchema)
576+
text = fields.Str()
577+
578+
@post_load
579+
def make_object(self, data):
580+
from connect.models import ConversationMessage
581+
return ConversationMessage(**data)
582+
583+
584+
class ConversationSchema(BaseSchema):
585+
instance_id = fields.Str()
586+
created = fields.DateTime()
587+
topic = fields.Str()
588+
messages = fields.Nested(ConversationMessageSchema, many=True)
589+
creator = fields.Nested(UserSchema)
590+
591+
@post_load
592+
def make_object(self, data):
593+
from connect.models import Conversation
594+
return Conversation(**data)

connect/models/tier_config.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,41 @@
1313
from .marketplace import Activation
1414
from .parameters import Param
1515
from .product import Product
16-
from .schemas import AccountSchema, TemplateSchema, TierConfigSchema, TierConfigRequestSchema
16+
from connect.models.schemas import TemplateSchema, TierAccountSchema, \
17+
TierAccountsSchema, TierConfigSchema, TierConfigRequestSchema
1718

1819

19-
class Account(BaseModel):
20+
class TierAccount(BaseModel):
2021
""" Tier account. """
2122

22-
_schema = AccountSchema()
23+
_schema = TierAccountSchema()
2324

2425
name = None # type: str
25-
""" (str) Account name. """
26+
""" (str) Tier name. """
27+
28+
contact_info = None # type: ContactInfo
29+
""" (:py:class:`.ContactInfo`) Tier Contact Object. """
2630

2731
external_id = None # type: Optional[str]
2832
""" (str|None) Only in case of filtering by this field. """
33+
2934
external_uid = None # type: Optional[str]
3035
""" (str|None) Only in case of filtering by this field. """
3136

32-
contact_info = None # type: ContactInfo
33-
""" (:py:class:`.ContactInfo`) Contact. """
37+
38+
class TierAccounts(BaseModel):
39+
""" TierAccounts object. """
40+
41+
_schema = TierAccountsSchema()
42+
43+
customer = None # type: TierAccount
44+
""" (:py:class:`.TierAccount`) Customer Level TierAccount Object. """
45+
46+
tier1 = None # type: TierAccount
47+
""" (:py:class:`.TierAccount`) Level 1 TierAccount Object. """
48+
49+
tier2 = None # type: TierAccount
50+
""" (:py:class:`.TierAccount`) Level 2 TierAccount Object. """
3451

3552

3653
class Template(BaseModel):
@@ -50,8 +67,10 @@ class TierConfig(BaseModel):
5067
name = None # type: str
5168
""" (str) Tier configuration of account.name. """
5269

53-
account = None # type: Account
54-
""" (:py:class:`.Account`) Full tier account representation (same as in Asset). """
70+
account = None # type: TierAccount
71+
""" (:py:class:`.TierAccount`) Full tier account representation
72+
(same as in :py:class:`.Asset`).
73+
"""
5574

5675
product = None # type: Product
5776
""" (:py:class:`.Product`) Reference object to product (application). """
@@ -95,8 +114,8 @@ def get(cls, tier_id, product_id, config=None):
95114
response, _ = ApiClient(config, base_path='tier/config-requests').get(
96115
params={
97116
'status': 'approved',
98-
'configuration__product__id': product_id,
99-
'configuration__account__id': tier_id,
117+
'configuration.product.id': product_id,
118+
'configuration.account.id': tier_id,
100119
}
101120
)
102121
objects = TierConfigRequest.deserialize(response)

0 commit comments

Comments
 (0)