embed-client-dev 4.0.78__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.
- embed_client/__init__.py +36 -0
- embed_client/__main__.py +15 -0
- embed_client/_version.py +3 -0
- embed_client/adapter_config_factory.py +213 -0
- embed_client/adapter_config_normalizer.py +135 -0
- embed_client/adapter_generator_bridge.py +166 -0
- embed_client/auth.py +189 -0
- embed_client/cli.py +483 -0
- embed_client/cli_core.py +427 -0
- embed_client/client_factory.py +515 -0
- embed_client/client_factory_examples.py +375 -0
- embed_client/client_factory_helpers.py +59 -0
- embed_client/config.py +408 -0
- embed_client/config_defaults.py +77 -0
- embed_client/config_examples.py +228 -0
- embed_client/config_generator.py +652 -0
- embed_client/config_generator_cli.py +151 -0
- embed_client/config_presets.py +245 -0
- embed_client/config_validator.py +246 -0
- embed_client/config_validator_cli.py +141 -0
- embed_client/constants.py +52 -0
- embed_client/demo_cli.py +78 -0
- embed_client/demo_security_cli.py +206 -0
- embed_client/embed_file_output_validate.py +348 -0
- embed_client/embed_file_status_store.py +80 -0
- embed_client/embedding_client.py +1929 -0
- embed_client/embedding_client_helpers.py +105 -0
- embed_client/example_async_usage.py +357 -0
- embed_client/example_async_usage_demo.py +282 -0
- embed_client/example_async_usage_ru.py +340 -0
- embed_client/example_async_usage_ru_demo.py +313 -0
- embed_client/exceptions.py +122 -0
- embed_client/identifier_types.py +56 -0
- embed_client/json_embed_file_preflight.py +128 -0
- embed_client/local_json_embed_file.py +73 -0
- embed_client/md_embed_file_prep.py +197 -0
- embed_client/response_normalizer.py +160 -0
- embed_client/response_parsers.py +219 -0
- embed_client/security_cli.py +200 -0
- embed_client/security_cli_core.py +227 -0
- embed_client/ssl_examples.py +278 -0
- embed_client/ssl_manager.py +141 -0
- embed_client_dev-4.0.78.dist-info/METADATA +155 -0
- embed_client_dev-4.0.78.dist-info/RECORD +48 -0
- embed_client_dev-4.0.78.dist-info/WHEEL +5 -0
- embed_client_dev-4.0.78.dist-info/entry_points.txt +4 -0
- embed_client_dev-4.0.78.dist-info/licenses/LICENSE +21 -0
- embed_client_dev-4.0.78.dist-info/top_level.txt +1 -0
embed_client/cli_core.py
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core implementation of the embed-client CLI.
|
|
3
|
+
|
|
4
|
+
Provides the `VectorizationCLI` class and configuration helpers used by the
|
|
5
|
+
user-facing `embed_client.cli` entry point.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import sys
|
|
15
|
+
import time
|
|
16
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
17
|
+
|
|
18
|
+
from embed_client.embedding_client import EmbeddingClient
|
|
19
|
+
from embed_client.client_factory import ClientFactory
|
|
20
|
+
from embed_client.config import ClientConfig
|
|
21
|
+
from embed_client.constants import DEFAULT_POLL_INTERVAL
|
|
22
|
+
from embed_client.embed_file_output_validate import (
|
|
23
|
+
EmbedFileJobPerfReport,
|
|
24
|
+
format_perf_report_lines,
|
|
25
|
+
format_validation_checklist_lines,
|
|
26
|
+
validate_embed_file_job_result,
|
|
27
|
+
)
|
|
28
|
+
from embed_client.exceptions import EmbedClientError
|
|
29
|
+
from embed_client.json_embed_file_preflight import iter_json_array_block_texts
|
|
30
|
+
from embed_client.response_parsers import extract_embeddings
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _embed_file_ws_progress_stderr(msg: Dict[str, Any]) -> None:
|
|
34
|
+
"""Print one WebSocket/status JSON object per line to stderr (embed_file wait)."""
|
|
35
|
+
print(json.dumps(msg, ensure_ascii=False), file=sys.stderr, flush=True)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class VectorizationCLI:
|
|
39
|
+
"""CLI application for text vectorization using embed-client library.
|
|
40
|
+
|
|
41
|
+
This class encapsulates the core logic of the `embed-vectorize` command,
|
|
42
|
+
including connection management, health checks, embedding requests, and
|
|
43
|
+
queue operations. It relies exclusively on `EmbeddingClient`
|
|
44
|
+
and related helpers from the embed-client package.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
"""Initialize a new VectorizationCLI instance."""
|
|
49
|
+
self.client: Optional[EmbeddingClient] = None
|
|
50
|
+
|
|
51
|
+
async def connect(
|
|
52
|
+
self,
|
|
53
|
+
config: Optional[ClientConfig] = None,
|
|
54
|
+
config_dict: Optional[Dict[str, Any]] = None,
|
|
55
|
+
) -> bool:
|
|
56
|
+
"""Connect to the embedding service using provided configuration.
|
|
57
|
+
|
|
58
|
+
The client is created via `ClientFactory` or directly from a
|
|
59
|
+
`ClientConfig` / configuration dictionary. All low-level transport and
|
|
60
|
+
authentication details are handled by the embed-client library.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
config: Optional `ClientConfig` instance.
|
|
64
|
+
config_dict: Optional raw configuration dictionary.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
True if connection was established successfully, False otherwise.
|
|
68
|
+
"""
|
|
69
|
+
try:
|
|
70
|
+
if config is not None:
|
|
71
|
+
self.client = EmbeddingClient.from_config(config)
|
|
72
|
+
elif config_dict is not None:
|
|
73
|
+
from embed_client.embedding_client import (
|
|
74
|
+
embedding_client_from_config_dict,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
self.client = embedding_client_from_config_dict(config_dict)
|
|
78
|
+
else:
|
|
79
|
+
# Use ClientFactory.from_environment() as fallback
|
|
80
|
+
self.client = ClientFactory.from_environment()
|
|
81
|
+
|
|
82
|
+
await self.client.__aenter__()
|
|
83
|
+
return True
|
|
84
|
+
except Exception as exc: # noqa: BLE001
|
|
85
|
+
print(f"❌ Failed to connect: {exc}", file=sys.stderr)
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
async def disconnect(self) -> None:
|
|
89
|
+
"""Close the underlying client connection if it exists."""
|
|
90
|
+
if self.client is not None:
|
|
91
|
+
await self.client.close()
|
|
92
|
+
|
|
93
|
+
async def health_check(self) -> bool:
|
|
94
|
+
"""Perform a health check against the embedding service."""
|
|
95
|
+
try:
|
|
96
|
+
assert self.client is not None
|
|
97
|
+
result = await self.client.health()
|
|
98
|
+
print(json.dumps(result, indent=2))
|
|
99
|
+
return True
|
|
100
|
+
except Exception as exc: # noqa: BLE001
|
|
101
|
+
print(f"❌ Health check failed: {exc}", file=sys.stderr)
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
async def get_models(self) -> bool:
|
|
105
|
+
"""Fetch and print available embedding models from the service."""
|
|
106
|
+
try:
|
|
107
|
+
assert self.client is not None
|
|
108
|
+
result = await self.client.models()
|
|
109
|
+
print(json.dumps(result, indent=2))
|
|
110
|
+
return True
|
|
111
|
+
except Exception as exc: # noqa: BLE001
|
|
112
|
+
print(f"❌ Failed to get models: {exc}", file=sys.stderr)
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
async def get_timing_stats(self, file_path: Optional[str] = None) -> bool:
|
|
116
|
+
"""Fetch and print timing statistics from the service."""
|
|
117
|
+
try:
|
|
118
|
+
assert self.client is not None
|
|
119
|
+
result = await self.client.timing_stats(file_path=file_path)
|
|
120
|
+
print(json.dumps(result, indent=2))
|
|
121
|
+
return True
|
|
122
|
+
except Exception as exc: # noqa: BLE001
|
|
123
|
+
print(f"❌ Failed to get timing stats: {exc}", file=sys.stderr)
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
async def embed_file_local_json(
|
|
127
|
+
self,
|
|
128
|
+
json_path: str,
|
|
129
|
+
*,
|
|
130
|
+
max_block_bytes: Optional[int] = None,
|
|
131
|
+
upload_filename: Optional[str] = None,
|
|
132
|
+
wait_timeout: Optional[float] = None,
|
|
133
|
+
download_to: Optional[str] = None,
|
|
134
|
+
skip_download: bool = False,
|
|
135
|
+
model: Optional[str] = None,
|
|
136
|
+
dimension: Optional[int] = None,
|
|
137
|
+
device: Optional[str] = None,
|
|
138
|
+
error_policy: str = "continue",
|
|
139
|
+
show_progress: bool = False,
|
|
140
|
+
) -> bool:
|
|
141
|
+
"""Local JSON array file → adapter upload → ``embed_file`` (json_array)."""
|
|
142
|
+
try:
|
|
143
|
+
assert self.client is not None
|
|
144
|
+
on_ws: Optional[Callable[[Dict[str, Any]], None]] = None
|
|
145
|
+
if show_progress:
|
|
146
|
+
on_ws = _embed_file_ws_progress_stderr
|
|
147
|
+
ef_kw: Dict[str, Any] = {
|
|
148
|
+
"max_block_bytes": max_block_bytes,
|
|
149
|
+
"upload_filename": upload_filename,
|
|
150
|
+
"wait": True,
|
|
151
|
+
"download_to": download_to,
|
|
152
|
+
"skip_download": skip_download,
|
|
153
|
+
"model": model,
|
|
154
|
+
"dimension": dimension,
|
|
155
|
+
"device": device,
|
|
156
|
+
"error_policy": error_policy,
|
|
157
|
+
"on_ws_event": on_ws,
|
|
158
|
+
}
|
|
159
|
+
if wait_timeout is not None:
|
|
160
|
+
ef_kw["wait_timeout"] = int(wait_timeout)
|
|
161
|
+
blocks = iter_json_array_block_texts(json_path)
|
|
162
|
+
t0 = time.perf_counter()
|
|
163
|
+
result = await self.client.embed_file_from_local_json_file(
|
|
164
|
+
json_path,
|
|
165
|
+
**ef_kw,
|
|
166
|
+
)
|
|
167
|
+
elapsed = time.perf_counter() - t0
|
|
168
|
+
perf = EmbedFileJobPerfReport(
|
|
169
|
+
total_seconds=elapsed, block_count=len(blocks)
|
|
170
|
+
)
|
|
171
|
+
for ln in format_perf_report_lines(perf):
|
|
172
|
+
print(ln, file=sys.stderr, flush=True)
|
|
173
|
+
try:
|
|
174
|
+
vreport = validate_embed_file_job_result(
|
|
175
|
+
blocks, result, rpc_dimension=dimension
|
|
176
|
+
)
|
|
177
|
+
except EmbedClientError as ve:
|
|
178
|
+
print(f"❌ embed_file output validation: {ve}", file=sys.stderr)
|
|
179
|
+
print(json.dumps(result, indent=2))
|
|
180
|
+
return False
|
|
181
|
+
for ln in format_validation_checklist_lines(vreport):
|
|
182
|
+
print(ln, file=sys.stderr, flush=True)
|
|
183
|
+
if not vreport.ok:
|
|
184
|
+
print("❌ embed_file output validation failed.", file=sys.stderr)
|
|
185
|
+
print(json.dumps(result, indent=2))
|
|
186
|
+
return False
|
|
187
|
+
print(json.dumps(result, indent=2))
|
|
188
|
+
return True
|
|
189
|
+
except Exception as exc: # noqa: BLE001
|
|
190
|
+
print(f"❌ embed-file-json failed: {exc}", file=sys.stderr)
|
|
191
|
+
return False
|
|
192
|
+
|
|
193
|
+
async def vectorize_texts(
|
|
194
|
+
self,
|
|
195
|
+
texts: List[str],
|
|
196
|
+
output_format: str = "json",
|
|
197
|
+
show_full_data: bool = False,
|
|
198
|
+
timeout: Optional[float] = None,
|
|
199
|
+
model: Optional[str] = None,
|
|
200
|
+
dimension: Optional[int] = None,
|
|
201
|
+
error_policy: str = "continue",
|
|
202
|
+
device: Optional[str] = None,
|
|
203
|
+
) -> Optional[List[List[float]]]:
|
|
204
|
+
"""Vectorize texts using the high-level `embed` helper.
|
|
205
|
+
|
|
206
|
+
Notes:
|
|
207
|
+
- Default ``error_policy=\"continue\"`` so per-item errors are
|
|
208
|
+
exposed via ``data[\"results\"][i][\"error\"]``.
|
|
209
|
+
- All input validation is delegated to the server.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
texts: List of input texts to embed.
|
|
213
|
+
output_format: One of ``\"json\"``, ``\"csv\"``, or ``\"vectors\"``.
|
|
214
|
+
show_full_data: If True, print full embedding payload instead of
|
|
215
|
+
only vectors.
|
|
216
|
+
timeout: Maximum time to wait for vectorization completion in seconds.
|
|
217
|
+
If None, return immediately without waiting.
|
|
218
|
+
If 0, wait indefinitely (no timeout).
|
|
219
|
+
If > 0, wait up to specified seconds.
|
|
220
|
+
model: Optional model name (server-side).
|
|
221
|
+
dimension: Optional expected vector dimension (server-side).
|
|
222
|
+
error_policy: "continue" or "fail_fast" (default: "continue").
|
|
223
|
+
device: Optional device: "auto", "cpu", "cuda", "cuda:0" (server-side).
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
A list of embedding vectors on success (possibly empty when
|
|
227
|
+
`show_full_data` is True and no plain vectors are available),
|
|
228
|
+
or ``None`` on failure.
|
|
229
|
+
"""
|
|
230
|
+
try:
|
|
231
|
+
assert self.client is not None
|
|
232
|
+
|
|
233
|
+
wt = 60 if timeout is None else int(timeout)
|
|
234
|
+
data = await self.client.embed(
|
|
235
|
+
texts,
|
|
236
|
+
model=model,
|
|
237
|
+
dimension=dimension,
|
|
238
|
+
error_policy=error_policy,
|
|
239
|
+
device=device,
|
|
240
|
+
wait=True,
|
|
241
|
+
wait_timeout=wt,
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
if show_full_data:
|
|
245
|
+
if output_format == "json":
|
|
246
|
+
print(json.dumps(data, indent=2))
|
|
247
|
+
return data.get("embeddings") or []
|
|
248
|
+
embeddings = data.get("embeddings") or []
|
|
249
|
+
if output_format == "csv":
|
|
250
|
+
self._print_csv(embeddings)
|
|
251
|
+
elif output_format == "vectors":
|
|
252
|
+
self._print_vectors(embeddings)
|
|
253
|
+
return embeddings
|
|
254
|
+
|
|
255
|
+
embeddings = data.get("embeddings")
|
|
256
|
+
if embeddings is None:
|
|
257
|
+
# Fallback to response_parsers for legacy-style responses
|
|
258
|
+
wrapped: Dict[str, Any] = {"result": {"success": True, "data": data}}
|
|
259
|
+
embeddings = extract_embeddings(wrapped)
|
|
260
|
+
|
|
261
|
+
if output_format == "json":
|
|
262
|
+
print(json.dumps(embeddings, indent=2))
|
|
263
|
+
elif output_format == "csv":
|
|
264
|
+
self._print_csv(embeddings)
|
|
265
|
+
elif output_format == "vectors":
|
|
266
|
+
self._print_vectors(embeddings)
|
|
267
|
+
|
|
268
|
+
return embeddings
|
|
269
|
+
except Exception as exc: # noqa: BLE001
|
|
270
|
+
print(f"❌ Vectorization failed: {exc}", file=sys.stderr)
|
|
271
|
+
return None
|
|
272
|
+
|
|
273
|
+
def _print_csv(self, embeddings: List[List[float]]) -> None:
|
|
274
|
+
"""Print embeddings in CSV format."""
|
|
275
|
+
for idx, embedding in enumerate(embeddings):
|
|
276
|
+
print(f"text_{idx}," + ",".join(map(str, embedding)))
|
|
277
|
+
|
|
278
|
+
def _print_vectors(self, embeddings: List[List[float]]) -> None:
|
|
279
|
+
"""Print embeddings as human-readable vectors."""
|
|
280
|
+
for idx, embedding in enumerate(embeddings):
|
|
281
|
+
print(f"Text {idx}: [{', '.join(map(str, embedding))}]")
|
|
282
|
+
|
|
283
|
+
async def get_help(self, command: Optional[str] = None) -> bool:
|
|
284
|
+
"""Fetch help information from the embedding service."""
|
|
285
|
+
try:
|
|
286
|
+
assert self.client is not None
|
|
287
|
+
if command:
|
|
288
|
+
result = await self.client.cmd("help", params={"command": command})
|
|
289
|
+
else:
|
|
290
|
+
result = await self.client.cmd("help")
|
|
291
|
+
print(json.dumps(result, indent=2))
|
|
292
|
+
return True
|
|
293
|
+
except Exception as exc: # noqa: BLE001
|
|
294
|
+
print(f"❌ Help request failed: {exc}", file=sys.stderr)
|
|
295
|
+
return False
|
|
296
|
+
|
|
297
|
+
async def get_commands(self) -> bool:
|
|
298
|
+
"""List all available commands from the embedding service."""
|
|
299
|
+
try:
|
|
300
|
+
assert self.client is not None
|
|
301
|
+
result = await self.client.list_commands()
|
|
302
|
+
print(json.dumps(result, indent=2))
|
|
303
|
+
return True
|
|
304
|
+
except Exception as exc: # noqa: BLE001
|
|
305
|
+
print(f"❌ Commands request failed: {exc}", file=sys.stderr)
|
|
306
|
+
return False
|
|
307
|
+
|
|
308
|
+
async def queue_list(
|
|
309
|
+
self, status: Optional[str] = None, limit: Optional[int] = None
|
|
310
|
+
) -> bool:
|
|
311
|
+
"""List queued commands."""
|
|
312
|
+
try:
|
|
313
|
+
assert self.client is not None
|
|
314
|
+
result = await self.client.list_queued_commands(status=status, limit=limit)
|
|
315
|
+
print(json.dumps(result, indent=2))
|
|
316
|
+
return True
|
|
317
|
+
except Exception as exc: # noqa: BLE001
|
|
318
|
+
print(f"❌ Failed to list queue: {exc}", file=sys.stderr)
|
|
319
|
+
return False
|
|
320
|
+
|
|
321
|
+
async def queue_status(self, job_id: str) -> bool:
|
|
322
|
+
"""Get the status of a specific job."""
|
|
323
|
+
try:
|
|
324
|
+
assert self.client is not None
|
|
325
|
+
result = await self.client.job_status(job_id)
|
|
326
|
+
print(json.dumps(result, indent=2))
|
|
327
|
+
return True
|
|
328
|
+
except Exception as exc: # noqa: BLE001
|
|
329
|
+
print(f"❌ Failed to get job status: {exc}", file=sys.stderr)
|
|
330
|
+
return False
|
|
331
|
+
|
|
332
|
+
async def queue_cancel(self, job_id: str) -> bool:
|
|
333
|
+
"""Cancel a queued or running job."""
|
|
334
|
+
try:
|
|
335
|
+
assert self.client is not None
|
|
336
|
+
result = await self.client.cancel_command(job_id)
|
|
337
|
+
print(json.dumps(result, indent=2))
|
|
338
|
+
return True
|
|
339
|
+
except Exception as exc: # noqa: BLE001
|
|
340
|
+
print(f"❌ Failed to cancel job: {exc}", file=sys.stderr)
|
|
341
|
+
return False
|
|
342
|
+
|
|
343
|
+
async def queue_wait(
|
|
344
|
+
self,
|
|
345
|
+
job_id: str,
|
|
346
|
+
timeout: float = 60.0,
|
|
347
|
+
poll_interval: float = DEFAULT_POLL_INTERVAL,
|
|
348
|
+
) -> bool:
|
|
349
|
+
"""Wait for completion of a specific job."""
|
|
350
|
+
try:
|
|
351
|
+
assert self.client is not None
|
|
352
|
+
result = await self.client.wait_for_job(
|
|
353
|
+
job_id, timeout=timeout, poll_interval=poll_interval
|
|
354
|
+
)
|
|
355
|
+
print(json.dumps(result, indent=2))
|
|
356
|
+
return True
|
|
357
|
+
except Exception as exc: # noqa: BLE001
|
|
358
|
+
print(f"❌ Failed to wait for job: {exc}", file=sys.stderr)
|
|
359
|
+
return False
|
|
360
|
+
|
|
361
|
+
async def queue_logs(self, job_id: str) -> bool:
|
|
362
|
+
"""Fetch logs for a specific job."""
|
|
363
|
+
try:
|
|
364
|
+
assert self.client is not None
|
|
365
|
+
result = await self.client.get_job_logs(job_id)
|
|
366
|
+
print(json.dumps(result, indent=2))
|
|
367
|
+
return True
|
|
368
|
+
except Exception as exc: # noqa: BLE001
|
|
369
|
+
print(f"❌ Failed to get job logs: {exc}", file=sys.stderr)
|
|
370
|
+
return False
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def create_config_from_args(args: Any) -> Dict[str, Any]:
|
|
374
|
+
"""Create a configuration dictionary from parsed CLI arguments.
|
|
375
|
+
|
|
376
|
+
This helper mirrors the shape of the JSON configuration files used by
|
|
377
|
+
`ClientConfig` and `ClientFactory`, allowing the CLI to construct a
|
|
378
|
+
`ClientConfig` instance without requiring callers to manage JSON files.
|
|
379
|
+
|
|
380
|
+
The ``--insecure`` (``--no-check-hostname``) flag maps to
|
|
381
|
+
``ssl.check_hostname = False``, which the library propagates as
|
|
382
|
+
``check_hostname=False`` to both the HTTPS transport and the WebSocket
|
|
383
|
+
(wss) SSL context. Default (no flag) keeps strict TLS verification.
|
|
384
|
+
"""
|
|
385
|
+
insecure = bool(getattr(args, "insecure", False))
|
|
386
|
+
config: Dict[str, Any] = {
|
|
387
|
+
"server": {"host": args.host, "port": args.port},
|
|
388
|
+
"auth": {"method": "none"},
|
|
389
|
+
"ssl": {"enabled": False, "check_hostname": not insecure},
|
|
390
|
+
"client": {"timeout": getattr(args, "timeout", 30.0)},
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
# Add authentication if specified
|
|
394
|
+
if getattr(args, "api_key", None):
|
|
395
|
+
config["auth"]["method"] = "api_key"
|
|
396
|
+
config["auth"]["api_keys"] = {"user": args.api_key}
|
|
397
|
+
if getattr(args, "api_key_header", None):
|
|
398
|
+
config["auth"]["api_key_header"] = args.api_key_header
|
|
399
|
+
elif getattr(args, "jwt_secret", None):
|
|
400
|
+
config["auth"]["method"] = "jwt"
|
|
401
|
+
config["auth"]["jwt"] = {
|
|
402
|
+
"secret": args.jwt_secret,
|
|
403
|
+
"username": getattr(args, "jwt_username", ""),
|
|
404
|
+
"password": getattr(args, "jwt_password", ""),
|
|
405
|
+
}
|
|
406
|
+
elif getattr(args, "basic_username", None):
|
|
407
|
+
config["auth"]["method"] = "basic"
|
|
408
|
+
config["auth"]["basic"] = {
|
|
409
|
+
"username": args.basic_username,
|
|
410
|
+
"password": getattr(args, "basic_password", ""),
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
# Add SSL if specified
|
|
414
|
+
if (
|
|
415
|
+
getattr(args, "ssl", False)
|
|
416
|
+
or getattr(args, "cert_file", None)
|
|
417
|
+
or getattr(args, "key_file", None)
|
|
418
|
+
):
|
|
419
|
+
config["ssl"]["enabled"] = True
|
|
420
|
+
if getattr(args, "cert_file", None):
|
|
421
|
+
config["ssl"]["cert_file"] = args.cert_file
|
|
422
|
+
if getattr(args, "key_file", None):
|
|
423
|
+
config["ssl"]["key_file"] = args.key_file
|
|
424
|
+
if getattr(args, "ca_cert_file", None):
|
|
425
|
+
config["ssl"]["ca_cert_file"] = args.ca_cert_file
|
|
426
|
+
|
|
427
|
+
return config
|