konecty_sdk_python 2.1.1__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.
- KonectySdkPython/__init__.py +41 -0
- KonectySdkPython/cli/__init__.py +38 -0
- KonectySdkPython/cli/apply.py +555 -0
- KonectySdkPython/cli/backup.py +161 -0
- KonectySdkPython/cli/pull.py +309 -0
- KonectySdkPython/lib/__init__.py +43 -0
- KonectySdkPython/lib/client.py +950 -0
- KonectySdkPython/lib/exceptions.py +26 -0
- KonectySdkPython/lib/feature_types/__init__.py +46 -0
- KonectySdkPython/lib/feature_types/cross_module_query.py +78 -0
- KonectySdkPython/lib/feature_types/kpi.py +21 -0
- KonectySdkPython/lib/feature_types/query_json.py +242 -0
- KonectySdkPython/lib/file_manager.py +248 -0
- KonectySdkPython/lib/filters.py +155 -0
- KonectySdkPython/lib/http.py +95 -0
- KonectySdkPython/lib/model.py +88 -0
- KonectySdkPython/lib/serialization.py +13 -0
- KonectySdkPython/lib/services/__init__.py +5 -0
- KonectySdkPython/lib/services/aggregation.py +142 -0
- KonectySdkPython/lib/services/auth.py +105 -0
- KonectySdkPython/lib/services/base.py +63 -0
- KonectySdkPython/lib/services/change_user.py +64 -0
- KonectySdkPython/lib/services/comments.py +89 -0
- KonectySdkPython/lib/services/export.py +54 -0
- KonectySdkPython/lib/services/files.py +59 -0
- KonectySdkPython/lib/services/notifications.py +41 -0
- KonectySdkPython/lib/services/query.py +192 -0
- KonectySdkPython/lib/services/stream.py +133 -0
- KonectySdkPython/lib/services/subscriptions.py +26 -0
- KonectySdkPython/lib/settings.py +152 -0
- KonectySdkPython/lib/types.py +418 -0
- konecty_sdk_python-2.1.1.dist-info/METADATA +155 -0
- konecty_sdk_python-2.1.1.dist-info/RECORD +35 -0
- konecty_sdk_python-2.1.1.dist-info/WHEEL +4 -0
- konecty_sdk_python-2.1.1.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""Script para fazer backup dos documentos do MongoDB."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
import tarfile
|
|
6
|
+
import tempfile
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
from pymongo import MongoClient
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.progress import Progress
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.command(name="backup")
|
|
20
|
+
@click.option("--host", default="localhost", help="Host do MongoDB")
|
|
21
|
+
@click.option("--port", type=int, default=27017, help="Porta do MongoDB")
|
|
22
|
+
@click.option("--database", required=True, help="Nome do banco de dados")
|
|
23
|
+
@click.option("--output", default="backups", help="Diretório para salvar o backup")
|
|
24
|
+
@click.option("--username", help="Usuário do MongoDB")
|
|
25
|
+
@click.option("--password", help="Senha do MongoDB")
|
|
26
|
+
@click.option("--replicaset", help="Nome do ReplicaSet do MongoDB (ex: rs0)")
|
|
27
|
+
@click.option("--version", help="Rótulo de versão para o arquivo de backup")
|
|
28
|
+
@click.option("--mongo-url", help="URL do MongoDB")
|
|
29
|
+
def backup_command(
|
|
30
|
+
host: str,
|
|
31
|
+
port: int,
|
|
32
|
+
database: str,
|
|
33
|
+
output: str,
|
|
34
|
+
username: Optional[str],
|
|
35
|
+
password: Optional[str],
|
|
36
|
+
replicaset: Optional[str],
|
|
37
|
+
version: Optional[str],
|
|
38
|
+
mongo_url: Optional[str],
|
|
39
|
+
) -> None:
|
|
40
|
+
"""Gera backup dos documentos do MongoDB."""
|
|
41
|
+
asyncio.run(
|
|
42
|
+
_backup_command(
|
|
43
|
+
host=host,
|
|
44
|
+
port=port,
|
|
45
|
+
database=database,
|
|
46
|
+
output=output,
|
|
47
|
+
username=username,
|
|
48
|
+
password=password,
|
|
49
|
+
replicaset=replicaset,
|
|
50
|
+
version=version,
|
|
51
|
+
mongo_url=mongo_url,
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def _backup_command(
|
|
57
|
+
host: str,
|
|
58
|
+
port: int,
|
|
59
|
+
database: str,
|
|
60
|
+
output: str,
|
|
61
|
+
username: Optional[str],
|
|
62
|
+
password: Optional[str],
|
|
63
|
+
replicaset: Optional[str],
|
|
64
|
+
version: Optional[str],
|
|
65
|
+
mongo_url: Optional[str],
|
|
66
|
+
) -> None:
|
|
67
|
+
"""Internal async implementation of backup command."""
|
|
68
|
+
output_dir = Path(output).resolve()
|
|
69
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
70
|
+
|
|
71
|
+
# Gera nome do arquivo de backup
|
|
72
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
73
|
+
version_label = f"_{version}" if version else ""
|
|
74
|
+
backup_file = output_dir / f"backup_{timestamp}{version_label}.tar.gz"
|
|
75
|
+
|
|
76
|
+
uri = mongo_url
|
|
77
|
+
|
|
78
|
+
if not uri:
|
|
79
|
+
uri_params = []
|
|
80
|
+
if replicaset:
|
|
81
|
+
uri_params.extend(
|
|
82
|
+
[
|
|
83
|
+
f"replicaSet={replicaset}",
|
|
84
|
+
"directConnection=false",
|
|
85
|
+
"retryWrites=true",
|
|
86
|
+
"w=majority",
|
|
87
|
+
]
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
uri_suffix = f"?{'&'.join(uri_params)}" if uri_params else ""
|
|
91
|
+
|
|
92
|
+
if username and password:
|
|
93
|
+
uri = f"mongodb://{username}:{password}@{host}:{port}/admin{uri_suffix}"
|
|
94
|
+
else:
|
|
95
|
+
uri = f"mongodb://{host}:{port}{uri_suffix}"
|
|
96
|
+
|
|
97
|
+
client = MongoClient(
|
|
98
|
+
uri,
|
|
99
|
+
serverSelectionTimeoutMS=30000,
|
|
100
|
+
connectTimeoutMS=20000,
|
|
101
|
+
socketTimeoutMS=20000,
|
|
102
|
+
maxPoolSize=1,
|
|
103
|
+
)
|
|
104
|
+
db = client[database]
|
|
105
|
+
collection = db["MetaObjects"]
|
|
106
|
+
|
|
107
|
+
# Cria diretório temporário
|
|
108
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
109
|
+
temp_path = Path(temp_dir)
|
|
110
|
+
|
|
111
|
+
# Busca todos os documentos
|
|
112
|
+
documents = list(collection.find({"type": {"$in": ["composite", "document"]}}))
|
|
113
|
+
|
|
114
|
+
with Progress() as progress:
|
|
115
|
+
task = progress.add_task("[cyan]Gerando backup...", total=len(documents))
|
|
116
|
+
|
|
117
|
+
# Processa cada documento
|
|
118
|
+
for doc in documents:
|
|
119
|
+
doc_path = temp_path / doc["name"]
|
|
120
|
+
doc_path.mkdir(parents=True, exist_ok=True)
|
|
121
|
+
|
|
122
|
+
# Salva documento principal
|
|
123
|
+
doc_file = doc_path / "document.json"
|
|
124
|
+
doc_file.write_text(json.dumps(doc, indent=2))
|
|
125
|
+
|
|
126
|
+
# Busca documentos relacionados
|
|
127
|
+
related = list(collection.find({"document": doc["name"]}))
|
|
128
|
+
|
|
129
|
+
for rel in related:
|
|
130
|
+
rel_type = rel["type"]
|
|
131
|
+
type_path = doc_path / rel_type
|
|
132
|
+
type_path.mkdir(exist_ok=True)
|
|
133
|
+
|
|
134
|
+
rel_file = type_path / f"{rel['name']}.json"
|
|
135
|
+
rel_file.write_text(json.dumps(rel, indent=2))
|
|
136
|
+
|
|
137
|
+
progress.update(task, advance=1)
|
|
138
|
+
|
|
139
|
+
# Cria arquivo tar.gz
|
|
140
|
+
with tarfile.open(backup_file, "w:gz") as tar:
|
|
141
|
+
tar.add(temp_dir, arcname="metadata")
|
|
142
|
+
|
|
143
|
+
client.close()
|
|
144
|
+
console.print(
|
|
145
|
+
f"[green]Backup concluído com sucesso:[/green] [cyan]{backup_file}[/cyan]"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def main():
|
|
150
|
+
"""Entry point for the CLI."""
|
|
151
|
+
import asyncio
|
|
152
|
+
import sys
|
|
153
|
+
|
|
154
|
+
if sys.platform == "win32":
|
|
155
|
+
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
156
|
+
|
|
157
|
+
backup_command()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
if __name__ == "__main__":
|
|
161
|
+
main()
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""Script para extrair dados do MongoDB e gerar arquivos JSON."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, List, Literal, Optional, TypedDict, Union, cast
|
|
7
|
+
|
|
8
|
+
import black
|
|
9
|
+
import click
|
|
10
|
+
import inquirer
|
|
11
|
+
from pymongo import MongoClient
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.progress import Progress
|
|
14
|
+
from rich.table import Table
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DocFiles(TypedDict):
|
|
18
|
+
document: List[Path]
|
|
19
|
+
view: List[Path]
|
|
20
|
+
list: List[Path]
|
|
21
|
+
pivot: List[Path]
|
|
22
|
+
access: List[Path]
|
|
23
|
+
hook: List[Path]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class RelatedResults(TypedDict):
|
|
27
|
+
view: List[str]
|
|
28
|
+
list: List[str]
|
|
29
|
+
pivot: List[str]
|
|
30
|
+
access: List[str]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MongoFilter(TypedDict, total=False):
|
|
34
|
+
document: str
|
|
35
|
+
type: str
|
|
36
|
+
name: str
|
|
37
|
+
or_conditions: List[Dict[str, str]]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class MongoCondition(TypedDict, total=False):
|
|
41
|
+
type: str
|
|
42
|
+
name: str
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
MongoQuery = Dict[str, Union[str, List[MongoCondition]]]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
DocType = Literal["document", "view", "list", "pivot", "access", "hook"]
|
|
49
|
+
MetaType = Literal["view", "list", "pivot", "access"]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
console = Console()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def format_code(name: str, code: str) -> str:
|
|
56
|
+
"""Formata o código JavaScript usando black."""
|
|
57
|
+
try:
|
|
58
|
+
return black.format_str(code, mode=black.Mode())
|
|
59
|
+
except Exception as error:
|
|
60
|
+
console.print(f"[red]Erro ao formatar código {name}[/red]: {str(error)}")
|
|
61
|
+
return code
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
async def write_file(file_path: str, content: str) -> None:
|
|
65
|
+
"""Escreve conteúdo em um arquivo, criando diretórios se necessário."""
|
|
66
|
+
try:
|
|
67
|
+
path = Path(file_path)
|
|
68
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
69
|
+
path.write_text(content)
|
|
70
|
+
except Exception as error:
|
|
71
|
+
console.print(f"[red]Erro ao escrever arquivo {file_path}[/red]: {str(error)}")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@click.command(name="pull")
|
|
75
|
+
@click.option("--host", default="localhost", help="Host do MongoDB")
|
|
76
|
+
@click.option("--port", type=int, default=27017, help="Porta do MongoDB")
|
|
77
|
+
@click.option("--database", default="default", help="Nome do banco de dados")
|
|
78
|
+
@click.option("--output", default="metadata", help="Diretório para salvar os metadados")
|
|
79
|
+
@click.option("--username", help="Usuário do MongoDB")
|
|
80
|
+
@click.option("--password", help="Senha do MongoDB")
|
|
81
|
+
@click.option("--replicaset", help="Nome do ReplicaSet do MongoDB (ex: rs0)")
|
|
82
|
+
@click.option("--document", help="Nome do documento para baixar")
|
|
83
|
+
@click.option("--view", help="Nome da view específica para extrair")
|
|
84
|
+
@click.option("--list", "list_param", help="Nome da lista específica para extrair")
|
|
85
|
+
@click.option("--pivot", help="Nome do pivot específico para extrair")
|
|
86
|
+
@click.option("--access", help="Nome do access específica para extrair")
|
|
87
|
+
@click.option("--hook", help="Nome do hook específico para extrair")
|
|
88
|
+
@click.option("--mongo-url", help="URL do MongoDB")
|
|
89
|
+
@click.option(
|
|
90
|
+
"--all",
|
|
91
|
+
"extract_all",
|
|
92
|
+
is_flag=True,
|
|
93
|
+
help="Extrair todas as collections sem perguntar",
|
|
94
|
+
)
|
|
95
|
+
def pull_command(
|
|
96
|
+
host: str,
|
|
97
|
+
port: int,
|
|
98
|
+
database: str,
|
|
99
|
+
output: str,
|
|
100
|
+
username: Optional[str],
|
|
101
|
+
password: Optional[str],
|
|
102
|
+
replicaset: Optional[str],
|
|
103
|
+
document: Optional[str],
|
|
104
|
+
view: Optional[str],
|
|
105
|
+
list_param: Optional[str],
|
|
106
|
+
pivot: Optional[str],
|
|
107
|
+
access: Optional[str],
|
|
108
|
+
hook: Optional[str],
|
|
109
|
+
extract_all: bool,
|
|
110
|
+
mongo_url: Optional[str],
|
|
111
|
+
) -> None:
|
|
112
|
+
"""Baixa metadados do MongoDB."""
|
|
113
|
+
asyncio.run(
|
|
114
|
+
_pull_command(
|
|
115
|
+
host=host,
|
|
116
|
+
port=port,
|
|
117
|
+
database=database,
|
|
118
|
+
output=output,
|
|
119
|
+
username=username,
|
|
120
|
+
password=password,
|
|
121
|
+
replicaset=replicaset,
|
|
122
|
+
document=document,
|
|
123
|
+
view=view,
|
|
124
|
+
list_param=list_param,
|
|
125
|
+
pivot=pivot,
|
|
126
|
+
access=access,
|
|
127
|
+
hook=hook,
|
|
128
|
+
extract_all=extract_all,
|
|
129
|
+
mongo_url=mongo_url,
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
async def _pull_command(
|
|
135
|
+
host: str,
|
|
136
|
+
port: int,
|
|
137
|
+
database: str,
|
|
138
|
+
output: str,
|
|
139
|
+
username: Optional[str],
|
|
140
|
+
password: Optional[str],
|
|
141
|
+
replicaset: Optional[str],
|
|
142
|
+
document: Optional[str],
|
|
143
|
+
view: Optional[str],
|
|
144
|
+
list_param: Optional[str],
|
|
145
|
+
pivot: Optional[str],
|
|
146
|
+
access: Optional[str],
|
|
147
|
+
hook: Optional[str],
|
|
148
|
+
mongo_url: Optional[str],
|
|
149
|
+
extract_all: bool,
|
|
150
|
+
) -> None:
|
|
151
|
+
"""Internal async implementation of pull command."""
|
|
152
|
+
output_dir = Path(output).resolve()
|
|
153
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
|
|
155
|
+
uri = mongo_url
|
|
156
|
+
|
|
157
|
+
if not uri:
|
|
158
|
+
uri_params = []
|
|
159
|
+
if replicaset:
|
|
160
|
+
uri_params.extend(
|
|
161
|
+
[
|
|
162
|
+
f"replicaSet={replicaset}",
|
|
163
|
+
"directConnection=false",
|
|
164
|
+
"retryWrites=true",
|
|
165
|
+
"w=majority",
|
|
166
|
+
]
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
uri_suffix = f"?{'&'.join(uri_params)}" if uri_params else ""
|
|
170
|
+
|
|
171
|
+
if username and password:
|
|
172
|
+
uri = f"mongodb://{username}:{password}@{host}:{port}/admin{uri_suffix}"
|
|
173
|
+
else:
|
|
174
|
+
uri = f"mongodb://{host}:{port}{uri_suffix}"
|
|
175
|
+
|
|
176
|
+
client = MongoClient(
|
|
177
|
+
uri,
|
|
178
|
+
serverSelectionTimeoutMS=30000,
|
|
179
|
+
connectTimeoutMS=20000,
|
|
180
|
+
socketTimeoutMS=20000,
|
|
181
|
+
maxPoolSize=1,
|
|
182
|
+
)
|
|
183
|
+
db = client[database]
|
|
184
|
+
collection = db["MetaObjects"]
|
|
185
|
+
|
|
186
|
+
table = Table(title="Resultados da Extração")
|
|
187
|
+
table.add_column("Documento")
|
|
188
|
+
table.add_column("Hook")
|
|
189
|
+
table.add_column("View")
|
|
190
|
+
table.add_column("List")
|
|
191
|
+
table.add_column("Pivot")
|
|
192
|
+
table.add_column("Access")
|
|
193
|
+
|
|
194
|
+
if document is None and not extract_all:
|
|
195
|
+
document_names = list(
|
|
196
|
+
collection.find(
|
|
197
|
+
{"type": {"$in": ["composite", "document"]}}, {"name": 1}
|
|
198
|
+
).sort("name", 1)
|
|
199
|
+
)
|
|
200
|
+
if not document_names:
|
|
201
|
+
console.print("[red]Nenhum documento encontrado.[/red]")
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
document_names = [doc["name"] for doc in document_names]
|
|
205
|
+
document_names.append("Todos")
|
|
206
|
+
|
|
207
|
+
questions = [
|
|
208
|
+
inquirer.List(
|
|
209
|
+
"document",
|
|
210
|
+
message="Selecione o documento para extrair",
|
|
211
|
+
choices=document_names,
|
|
212
|
+
)
|
|
213
|
+
]
|
|
214
|
+
answers = inquirer.prompt(questions)
|
|
215
|
+
if not answers:
|
|
216
|
+
return
|
|
217
|
+
document = "all" if answers["document"] == "Todos" else answers["document"]
|
|
218
|
+
elif extract_all:
|
|
219
|
+
document = "all"
|
|
220
|
+
|
|
221
|
+
filter_query: Dict[str, Any] = {"type": {"$in": ["composite", "document"]}}
|
|
222
|
+
if document != "all":
|
|
223
|
+
filter_query["name"] = document
|
|
224
|
+
|
|
225
|
+
documents = list(collection.find(filter_query).sort("name", 1))
|
|
226
|
+
|
|
227
|
+
with Progress() as progress:
|
|
228
|
+
task = progress.add_task("[cyan]Extraindo metadados...", total=len(documents))
|
|
229
|
+
|
|
230
|
+
for doc in documents:
|
|
231
|
+
doc_path = output_dir / doc["name"]
|
|
232
|
+
doc_path.mkdir(parents=True, exist_ok=True)
|
|
233
|
+
|
|
234
|
+
# Processando hooks
|
|
235
|
+
hook_results = []
|
|
236
|
+
if "validationData" in doc:
|
|
237
|
+
await write_file(
|
|
238
|
+
str(doc_path / "hook" / "validationData.json"),
|
|
239
|
+
json.dumps(doc["validationData"], indent=2),
|
|
240
|
+
)
|
|
241
|
+
hook_results.append("✓ validationData")
|
|
242
|
+
|
|
243
|
+
for script_type in [
|
|
244
|
+
"scriptBeforeValidation",
|
|
245
|
+
"validationScript",
|
|
246
|
+
"scriptAfterSave",
|
|
247
|
+
]:
|
|
248
|
+
if script_type in doc:
|
|
249
|
+
formatted = format_code(f"{script_type}.js", doc[script_type])
|
|
250
|
+
await write_file(
|
|
251
|
+
str(doc_path / "hook" / f"{script_type}.js"), formatted
|
|
252
|
+
)
|
|
253
|
+
hook_results.append(f"✓ {script_type}")
|
|
254
|
+
|
|
255
|
+
# Processando views, lists, pivots e access
|
|
256
|
+
related_results: RelatedResults = {
|
|
257
|
+
"view": [],
|
|
258
|
+
"list": [],
|
|
259
|
+
"pivot": [],
|
|
260
|
+
"access": [],
|
|
261
|
+
}
|
|
262
|
+
for type_name, param in [
|
|
263
|
+
("view", extract_all or view),
|
|
264
|
+
("list", extract_all or list_param),
|
|
265
|
+
("pivot", extract_all or pivot),
|
|
266
|
+
("access", extract_all or access),
|
|
267
|
+
]:
|
|
268
|
+
if param is not None:
|
|
269
|
+
condition = {"type": type_name}
|
|
270
|
+
if not extract_all:
|
|
271
|
+
condition["name"] = param
|
|
272
|
+
related_metas = list(collection.find(condition).sort("_id", 1))
|
|
273
|
+
for meta in related_metas:
|
|
274
|
+
meta_type = cast(MetaType, meta["type"])
|
|
275
|
+
if meta_type in ("view", "list", "pivot", "access"):
|
|
276
|
+
await write_file(
|
|
277
|
+
str(doc_path / meta_type / f"{meta['name']}.json"),
|
|
278
|
+
json.dumps(meta, indent=2),
|
|
279
|
+
)
|
|
280
|
+
related_results[meta_type].append(f"✓ {meta['name']}")
|
|
281
|
+
|
|
282
|
+
table.add_row(
|
|
283
|
+
doc["name"],
|
|
284
|
+
"\n".join(hook_results),
|
|
285
|
+
"\n".join(related_results["view"]),
|
|
286
|
+
"\n".join(related_results["list"]),
|
|
287
|
+
"\n".join(related_results["pivot"]),
|
|
288
|
+
"\n".join(related_results["access"]),
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
progress.update(task, advance=1)
|
|
292
|
+
|
|
293
|
+
console.print(table)
|
|
294
|
+
client.close()
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def main():
|
|
298
|
+
"""Entry point for the CLI."""
|
|
299
|
+
import asyncio
|
|
300
|
+
import sys
|
|
301
|
+
|
|
302
|
+
if sys.platform == "win32":
|
|
303
|
+
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
304
|
+
|
|
305
|
+
pull_command()
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
if __name__ == "__main__":
|
|
309
|
+
main()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Konecty SDK Python - A Python SDK for interacting with Konecty platform
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .client import KonectyClient, KonectyDict, KonectyFilter, KonectyFindParams
|
|
6
|
+
from .file_manager import FileManager
|
|
7
|
+
from .model import KonectyModelGenerator
|
|
8
|
+
from .settings import fill_settings, fill_settings_sync
|
|
9
|
+
from .types import Address as KonectyAddress
|
|
10
|
+
from .types import (
|
|
11
|
+
KonectyBaseModel,
|
|
12
|
+
KonectyDateTime,
|
|
13
|
+
KonectyEmail,
|
|
14
|
+
KonectyLabel,
|
|
15
|
+
KonectyLookup,
|
|
16
|
+
KonectyPersonName,
|
|
17
|
+
KonectyPhone,
|
|
18
|
+
KonectyUpdateId,
|
|
19
|
+
KonectyUser,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"KonectyClient",
|
|
24
|
+
"KonectyModel",
|
|
25
|
+
"FileManager",
|
|
26
|
+
"KonectyModelGenerator",
|
|
27
|
+
"fill_settings",
|
|
28
|
+
"fill_settings_sync",
|
|
29
|
+
"KonectyAddress",
|
|
30
|
+
"KonectyBaseModel",
|
|
31
|
+
"KonectyDateTime",
|
|
32
|
+
"KonectyEmail",
|
|
33
|
+
"KonectyLabel",
|
|
34
|
+
"KonectyLookup",
|
|
35
|
+
"KonectyPersonName",
|
|
36
|
+
"KonectyPhone",
|
|
37
|
+
"KonectyUser",
|
|
38
|
+
"KonectyModel",
|
|
39
|
+
"KonectyFilter",
|
|
40
|
+
"KonectyFindParams",
|
|
41
|
+
"KonectyDict",
|
|
42
|
+
"KonectyUpdateId",
|
|
43
|
+
]
|