select-ai 1.2.0rc3__py3-none-any.whl
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.
- select_ai/__init__.py +66 -0
- select_ai/_abc.py +82 -0
- select_ai/_enums.py +14 -0
- select_ai/_validations.py +123 -0
- select_ai/action.py +23 -0
- select_ai/agent/__init__.py +25 -0
- select_ai/agent/core.py +511 -0
- select_ai/agent/sql.py +82 -0
- select_ai/agent/task.py +521 -0
- select_ai/agent/team.py +590 -0
- select_ai/agent/tool.py +1129 -0
- select_ai/async_profile.py +648 -0
- select_ai/base_profile.py +265 -0
- select_ai/conversation.py +295 -0
- select_ai/credential.py +135 -0
- select_ai/db.py +191 -0
- select_ai/errors.py +113 -0
- select_ai/feedback.py +19 -0
- select_ai/privilege.py +135 -0
- select_ai/profile.py +579 -0
- select_ai/provider.py +195 -0
- select_ai/sql.py +111 -0
- select_ai/summary.py +61 -0
- select_ai/synthetic_data.py +90 -0
- select_ai/vector_index.py +642 -0
- select_ai/version.py +8 -0
- select_ai-1.2.0rc3.dist-info/METADATA +129 -0
- select_ai-1.2.0rc3.dist-info/RECORD +31 -0
- select_ai-1.2.0rc3.dist-info/WHEEL +5 -0
- select_ai-1.2.0rc3.dist-info/licenses/LICENSE.txt +35 -0
- select_ai-1.2.0rc3.dist-info/top_level.txt +1 -0
select_ai/provider.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2025, Oracle and/or its affiliates.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at
|
|
5
|
+
# http://oss.oracle.com/licenses/upl.
|
|
6
|
+
# -----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import List, Optional, Union
|
|
10
|
+
|
|
11
|
+
from select_ai._abc import SelectAIDataClass
|
|
12
|
+
from select_ai._validations import enforce_types
|
|
13
|
+
|
|
14
|
+
from .db import async_cursor, cursor
|
|
15
|
+
from .sql import (
|
|
16
|
+
DISABLE_AI_PROFILE_DOMAIN_FOR_USER,
|
|
17
|
+
ENABLE_AI_PROFILE_DOMAIN_FOR_USER,
|
|
18
|
+
GRANT_PRIVILEGES_TO_USER,
|
|
19
|
+
REVOKE_PRIVILEGES_FROM_USER,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
OPENAI = "openai"
|
|
23
|
+
COHERE = "cohere"
|
|
24
|
+
AZURE = "azure"
|
|
25
|
+
OCI = "oci"
|
|
26
|
+
GOOGLE = "google"
|
|
27
|
+
ANTHROPIC = "anthropic"
|
|
28
|
+
HUGGINGFACE = "huggingface"
|
|
29
|
+
AWS = "aws"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class Provider(SelectAIDataClass):
|
|
34
|
+
"""
|
|
35
|
+
Base class for AI Provider
|
|
36
|
+
|
|
37
|
+
To create an object of Provider class, use any one of the concrete AI
|
|
38
|
+
provider implementations
|
|
39
|
+
|
|
40
|
+
:param str embedding_model: The embedding model, also known as a
|
|
41
|
+
transformer. Depending on the AI provider, the supported embedding models
|
|
42
|
+
vary
|
|
43
|
+
:param str model: The name of the LLM being used to generate
|
|
44
|
+
responses
|
|
45
|
+
:param str provider_name: The name of the provider being used
|
|
46
|
+
:param str provider_endpoint: Endpoint URL of the AI provider being used
|
|
47
|
+
:param str region: The cloud region of the Gen AI cluster
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
embedding_model: Optional[str] = None
|
|
52
|
+
model: Optional[str] = None
|
|
53
|
+
provider_name: Optional[str] = None
|
|
54
|
+
provider_endpoint: Optional[str] = None
|
|
55
|
+
region: Optional[str] = None
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def create(cls, *, provider_name: Optional[str] = None, **kwargs):
|
|
59
|
+
for subclass in cls.__subclasses__():
|
|
60
|
+
if subclass.provider_name == provider_name:
|
|
61
|
+
return subclass(**kwargs)
|
|
62
|
+
return cls(**kwargs)
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def key_alias(cls, k):
|
|
66
|
+
return {"provider": "provider_name", "provider_name": "provider"}.get(
|
|
67
|
+
k, k
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def keys(cls):
|
|
72
|
+
return {
|
|
73
|
+
"provider",
|
|
74
|
+
"provider_name",
|
|
75
|
+
"embedding_model",
|
|
76
|
+
"model",
|
|
77
|
+
"region",
|
|
78
|
+
"provider_endpoint",
|
|
79
|
+
"azure_deployment_name",
|
|
80
|
+
"azure_embedding_deployment_name",
|
|
81
|
+
"azure_resource_name",
|
|
82
|
+
"oci_apiformat",
|
|
83
|
+
"oci_compartment_id",
|
|
84
|
+
"oci_endpoint_id",
|
|
85
|
+
"oci_runtimetype",
|
|
86
|
+
"aws_apiformat",
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass
|
|
91
|
+
class AzureProvider(Provider):
|
|
92
|
+
"""
|
|
93
|
+
Azure specific attributes
|
|
94
|
+
|
|
95
|
+
:param str azure_deployment_name: Name of the Azure OpenAI Service
|
|
96
|
+
deployed model.
|
|
97
|
+
:param str azure_embedding_deployment_name: Name of the Azure OpenAI
|
|
98
|
+
deployed embedding model.
|
|
99
|
+
:param str azure_resource_name: Name of the Azure OpenAI Service resource
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
provider_name: str = AZURE
|
|
103
|
+
azure_deployment_name: Optional[str] = None
|
|
104
|
+
azure_embedding_deployment_name: Optional[str] = None
|
|
105
|
+
azure_resource_name: Optional[str] = None
|
|
106
|
+
|
|
107
|
+
def __post_init__(self):
|
|
108
|
+
super().__post_init__()
|
|
109
|
+
self.provider_endpoint = f"{self.azure_resource_name}.openai.azure.com"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@dataclass
|
|
113
|
+
class OpenAIProvider(Provider):
|
|
114
|
+
"""
|
|
115
|
+
OpenAI specific attributes
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
provider_name: str = OPENAI
|
|
119
|
+
provider_endpoint: Optional[str] = "api.openai.com"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass
|
|
123
|
+
class OCIGenAIProvider(Provider):
|
|
124
|
+
"""
|
|
125
|
+
OCI Gen AI specific attributes
|
|
126
|
+
|
|
127
|
+
:param str oci_apiformat: Specifies the format in which the API expects
|
|
128
|
+
data to be sent and received. Supported values are 'COHERE' and 'GENERIC'
|
|
129
|
+
:param str oci_compartment_id: Specifies the OCID of the compartment you
|
|
130
|
+
are permitted to access when calling the OCI Generative AI service
|
|
131
|
+
:param str oci_endpoint_id: This attributes indicates the endpoint OCID
|
|
132
|
+
of the Oracle dedicated AI hosting cluster
|
|
133
|
+
:param str oci_runtimetype: This attribute indicates the runtime type of
|
|
134
|
+
the provided model. The supported values are 'COHERE' and 'LLAMA'
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
provider_name: str = OCI
|
|
138
|
+
oci_apiformat: Optional[str] = None
|
|
139
|
+
oci_compartment_id: Optional[str] = None
|
|
140
|
+
oci_endpoint_id: Optional[str] = None
|
|
141
|
+
oci_runtimetype: Optional[str] = None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@dataclass
|
|
145
|
+
class CohereProvider(Provider):
|
|
146
|
+
"""
|
|
147
|
+
Cohere AI specific attributes
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
provider_name: str = COHERE
|
|
151
|
+
provider_endpoint = "api.cohere.ai"
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@dataclass
|
|
155
|
+
class GoogleProvider(Provider):
|
|
156
|
+
"""
|
|
157
|
+
Google AI specific attributes
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
provider_name: str = GOOGLE
|
|
161
|
+
provider_endpoint = "generativelanguage.googleapis.com"
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@dataclass
|
|
165
|
+
class HuggingFaceProvider(Provider):
|
|
166
|
+
"""
|
|
167
|
+
HuggingFace specific attributes
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
provider_name: str = HUGGINGFACE
|
|
171
|
+
provider_endpoint = "api-inference.huggingface.co"
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass
|
|
175
|
+
class AWSProvider(Provider):
|
|
176
|
+
"""
|
|
177
|
+
AWS specific attributes
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
provider_name: str = AWS
|
|
181
|
+
aws_apiformat: Optional[str] = None
|
|
182
|
+
|
|
183
|
+
def __post_init__(self):
|
|
184
|
+
super().__post_init__()
|
|
185
|
+
self.provider_endpoint = f"bedrock-runtime.{self.region}.amazonaws.com"
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@dataclass
|
|
189
|
+
class AnthropicProvider(Provider):
|
|
190
|
+
"""
|
|
191
|
+
Anthropic specific attributes
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
provider_name: str = ANTHROPIC
|
|
195
|
+
provider_endpoint = "api.anthropic.com"
|
select_ai/sql.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2025, Oracle and/or its affiliates.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at
|
|
5
|
+
# http://oss.oracle.com/licenses/upl.
|
|
6
|
+
# -----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
GRANT_PRIVILEGES_TO_USER = """
|
|
9
|
+
DECLARE
|
|
10
|
+
TYPE array_t IS VARRAY(4) OF VARCHAR2(60);
|
|
11
|
+
v_packages array_t;
|
|
12
|
+
BEGIN
|
|
13
|
+
v_packages := array_t(
|
|
14
|
+
'DBMS_CLOUD',
|
|
15
|
+
'DBMS_CLOUD_AI',
|
|
16
|
+
'DBMS_CLOUD_AI_AGENT',
|
|
17
|
+
'DBMS_CLOUD_PIPELINE'
|
|
18
|
+
);
|
|
19
|
+
FOR i in 1..v_packages.count LOOP
|
|
20
|
+
EXECUTE IMMEDIATE
|
|
21
|
+
'GRANT EXECUTE ON ' || v_packages(i) || ' TO {0}';
|
|
22
|
+
END LOOP;
|
|
23
|
+
END;
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
REVOKE_PRIVILEGES_FROM_USER = """
|
|
27
|
+
DECLARE
|
|
28
|
+
TYPE array_t IS VARRAY(4) OF VARCHAR2(60);
|
|
29
|
+
v_packages array_t;
|
|
30
|
+
BEGIN
|
|
31
|
+
v_packages := array_t(
|
|
32
|
+
'DBMS_CLOUD',
|
|
33
|
+
'DBMS_CLOUD_AI',
|
|
34
|
+
'DBMS_CLOUD_AI_AGENT',
|
|
35
|
+
'DBMS_CLOUD_PIPELINE'
|
|
36
|
+
);
|
|
37
|
+
FOR i in 1..v_packages.count LOOP
|
|
38
|
+
EXECUTE IMMEDIATE
|
|
39
|
+
'REVOKE EXECUTE ON ' || v_packages(i) || ' FROM {0}';
|
|
40
|
+
END LOOP;
|
|
41
|
+
END;
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
ENABLE_AI_PROFILE_DOMAIN_FOR_USER = """
|
|
45
|
+
BEGIN
|
|
46
|
+
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
|
|
47
|
+
host => :host,
|
|
48
|
+
ace => xs$ace_type(privilege_list => xs$name_list('http'),
|
|
49
|
+
principal_name => :user,
|
|
50
|
+
principal_type => xs_acl.ptype_db)
|
|
51
|
+
);
|
|
52
|
+
END;
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
DISABLE_AI_PROFILE_DOMAIN_FOR_USER = """
|
|
56
|
+
BEGIN
|
|
57
|
+
DBMS_NETWORK_ACL_ADMIN.REMOVE_HOST_ACE(
|
|
58
|
+
host => :host,
|
|
59
|
+
ace => xs$ace_type(privilege_list => xs$name_list('http'),
|
|
60
|
+
principal_name => :user,
|
|
61
|
+
principal_type => xs_acl.ptype_db)
|
|
62
|
+
);
|
|
63
|
+
END;
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
GET_USER_AI_PROFILE_ATTRIBUTES = """
|
|
67
|
+
SELECT attribute_name, attribute_value
|
|
68
|
+
FROM USER_CLOUD_AI_PROFILE_ATTRIBUTES
|
|
69
|
+
WHERE profile_name = :profile_name
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
GET_USER_AI_PROFILE = """
|
|
73
|
+
SELECT profile_name, description
|
|
74
|
+
FROM USER_CLOUD_AI_PROFILES
|
|
75
|
+
WHERE profile_name = :profile_name
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
LIST_USER_AI_PROFILES = """
|
|
80
|
+
SELECT profile_name, description
|
|
81
|
+
FROM USER_CLOUD_AI_PROFILES
|
|
82
|
+
WHERE REGEXP_LIKE(profile_name, :profile_name_pattern, 'i')
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
LIST_USER_VECTOR_INDEXES = """
|
|
86
|
+
SELECT v.index_name, v.description
|
|
87
|
+
FROM USER_CLOUD_VECTOR_INDEXES v
|
|
88
|
+
WHERE REGEXP_LIKE(v.index_name, :index_name_pattern, 'i')
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
GET_USER_VECTOR_INDEX_ATTRIBUTES = """
|
|
92
|
+
SELECT attribute_name, attribute_value
|
|
93
|
+
FROM USER_CLOUD_VECTOR_INDEX_ATTRIBUTES
|
|
94
|
+
WHERE INDEX_NAME = :index_name
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
LIST_USER_CONVERSATIONS = """
|
|
98
|
+
SELECT conversation_id,
|
|
99
|
+
conversation_title,
|
|
100
|
+
description,
|
|
101
|
+
retention_days
|
|
102
|
+
from USER_CLOUD_AI_CONVERSATIONS
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
GET_USER_CONVERSATION_ATTRIBUTES = """
|
|
106
|
+
SELECT conversation_title,
|
|
107
|
+
description,
|
|
108
|
+
retention_days
|
|
109
|
+
from USER_CLOUD_AI_CONVERSATIONS
|
|
110
|
+
WHERE conversation_id = :conversation_id
|
|
111
|
+
"""
|
select_ai/summary.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2025, Oracle and/or its affiliates.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at
|
|
5
|
+
# http://oss.oracle.com/licenses/upl.
|
|
6
|
+
# -----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
from select_ai._abc import SelectAIDataClass
|
|
12
|
+
from select_ai._enums import StrEnum
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Style(StrEnum):
|
|
16
|
+
|
|
17
|
+
PARAGRAPH = "paragraph"
|
|
18
|
+
LIST = "list"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ChunkProcessingMethod(StrEnum):
|
|
22
|
+
|
|
23
|
+
ITERATIVE_REFINEMENT = "iterative_refinement"
|
|
24
|
+
MAP_REDUCE = "map_reduce"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ExtractivenessLevel(StrEnum):
|
|
28
|
+
|
|
29
|
+
LOW = "low"
|
|
30
|
+
MEDIUM = "medium"
|
|
31
|
+
HIGH = "high"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class SummaryParams(SelectAIDataClass):
|
|
36
|
+
"""
|
|
37
|
+
Customize summary generation using these parameters
|
|
38
|
+
|
|
39
|
+
:param int min_words: approximate minimum number of words the generated
|
|
40
|
+
summary is expected to contain.
|
|
41
|
+
|
|
42
|
+
:param int max_words: approximate maximum number of words the generated
|
|
43
|
+
summary is expected to contain.
|
|
44
|
+
|
|
45
|
+
:param select_ai.summary.Style summary_style: Specifies the format
|
|
46
|
+
style for the summary
|
|
47
|
+
|
|
48
|
+
:param select_ai.summary.ChunkProcessingMethod chunk_processing_method:
|
|
49
|
+
When the text exceeds the token limit that the LLM can process, it must
|
|
50
|
+
be split into manageable chunks
|
|
51
|
+
|
|
52
|
+
:param select_ai.summary.ExtractivenessLevel extractiveness_level:
|
|
53
|
+
Determines how closely the summary follows the original wording
|
|
54
|
+
of the input
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
min_words: Optional[int] = None
|
|
58
|
+
max_words: Optional[int] = None
|
|
59
|
+
summary_style: Optional[Style] = None
|
|
60
|
+
chunk_processing_method: Optional[ChunkProcessingMethod] = None
|
|
61
|
+
extractiveness_level: Optional[ExtractivenessLevel] = None
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2025, Oracle and/or its affiliates.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at
|
|
5
|
+
# http://oss.oracle.com/licenses/upl.
|
|
6
|
+
# -----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import List, Mapping, Optional
|
|
11
|
+
|
|
12
|
+
from select_ai._abc import SelectAIDataClass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class SyntheticDataParams(SelectAIDataClass):
|
|
17
|
+
"""Optional parameters to control generation of synthetic data
|
|
18
|
+
|
|
19
|
+
:param int sample_rows: number of rows from the table to use as a sample
|
|
20
|
+
to guide the LLM in data generation
|
|
21
|
+
|
|
22
|
+
:param bool table_statistics: Enable or disable the use of table
|
|
23
|
+
statistics information. Default value is False
|
|
24
|
+
|
|
25
|
+
:param str priority: Assign a priority value that defines the number of
|
|
26
|
+
parallel requests sent to the LLM for generating synthetic data.
|
|
27
|
+
Tasks with a higher priority will consume more database resources and
|
|
28
|
+
complete faster. Possible values are: HIGH, MEDIUM, LOW
|
|
29
|
+
|
|
30
|
+
:param bool comments: Enable or disable sending comments to the LLM to
|
|
31
|
+
guide data generation. Default value is False
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
sample_rows: Optional[int] = None
|
|
36
|
+
table_statistics: Optional[bool] = False
|
|
37
|
+
priority: Optional[str] = "HIGH"
|
|
38
|
+
comments: Optional[bool] = False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class SyntheticDataAttributes(SelectAIDataClass):
|
|
43
|
+
"""Attributes to control generation of synthetic data
|
|
44
|
+
|
|
45
|
+
:param str object_name: Table name to populate synthetic data
|
|
46
|
+
:param List[Mapping] object_list: Use this to generate synthetic data
|
|
47
|
+
on multiple tables
|
|
48
|
+
:param str owner_name: Database user who owns the referenced object.
|
|
49
|
+
Default value is connected user's schema
|
|
50
|
+
:param int record_count: Number of records to generate
|
|
51
|
+
:param str user_prompt: User prompt to guide generation of synthetic data
|
|
52
|
+
For e.g. "the release date for the movies should be in 2019"
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
object_name: Optional[str] = None
|
|
57
|
+
object_list: Optional[List[Mapping]] = None
|
|
58
|
+
owner_name: Optional[str] = None
|
|
59
|
+
params: Optional[SyntheticDataParams] = None
|
|
60
|
+
record_count: Optional[int] = None
|
|
61
|
+
user_prompt: Optional[str] = None
|
|
62
|
+
|
|
63
|
+
def __post_init__(self):
|
|
64
|
+
if self.params and not isinstance(self.params, SyntheticDataParams):
|
|
65
|
+
raise TypeError(
|
|
66
|
+
"'params' must be an object of" " type SyntheticDataParams'"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def dict(self, exclude_null=True):
|
|
70
|
+
attributes = {}
|
|
71
|
+
for k, v in self.__dict__.items():
|
|
72
|
+
if v is not None or not exclude_null:
|
|
73
|
+
if isinstance(v, SyntheticDataParams):
|
|
74
|
+
attributes[k] = v.json(exclude_null=exclude_null)
|
|
75
|
+
elif isinstance(v, List):
|
|
76
|
+
attributes[k] = json.dumps(v)
|
|
77
|
+
else:
|
|
78
|
+
attributes[k] = v
|
|
79
|
+
return attributes
|
|
80
|
+
|
|
81
|
+
def prepare(self):
|
|
82
|
+
if self.object_name and self.object_list:
|
|
83
|
+
raise ValueError("Both object_name and object_list cannot be set")
|
|
84
|
+
|
|
85
|
+
if not self.object_name and not self.object_list:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
"One of object_name and object_list should be set"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return self.dict()
|