embed-client-dev 4.0.78__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.
Files changed (105) hide show
  1. embed_client_dev-4.0.78/CONFIGURATION.md +358 -0
  2. embed_client_dev-4.0.78/LICENSE +21 -0
  3. embed_client_dev-4.0.78/MANIFEST.in +16 -0
  4. embed_client_dev-4.0.78/PKG-INFO +155 -0
  5. embed_client_dev-4.0.78/README.md +108 -0
  6. embed_client_dev-4.0.78/docs/SERVER_MODES_AND_CLIENT.md +49 -0
  7. embed_client_dev-4.0.78/docs/api_format.md +50 -0
  8. embed_client_dev-4.0.78/docs/client_integration_guide.md +303 -0
  9. embed_client_dev-4.0.78/docs/error_handling_complete.md +134 -0
  10. embed_client_dev-4.0.78/embed_client/__init__.py +36 -0
  11. embed_client_dev-4.0.78/embed_client/__main__.py +15 -0
  12. embed_client_dev-4.0.78/embed_client/_version.py +3 -0
  13. embed_client_dev-4.0.78/embed_client/adapter_config_factory.py +213 -0
  14. embed_client_dev-4.0.78/embed_client/adapter_config_normalizer.py +135 -0
  15. embed_client_dev-4.0.78/embed_client/adapter_generator_bridge.py +166 -0
  16. embed_client_dev-4.0.78/embed_client/auth.py +189 -0
  17. embed_client_dev-4.0.78/embed_client/cli.py +483 -0
  18. embed_client_dev-4.0.78/embed_client/cli_core.py +427 -0
  19. embed_client_dev-4.0.78/embed_client/client_factory.py +515 -0
  20. embed_client_dev-4.0.78/embed_client/client_factory_examples.py +375 -0
  21. embed_client_dev-4.0.78/embed_client/client_factory_helpers.py +59 -0
  22. embed_client_dev-4.0.78/embed_client/config.py +408 -0
  23. embed_client_dev-4.0.78/embed_client/config_defaults.py +77 -0
  24. embed_client_dev-4.0.78/embed_client/config_examples.py +228 -0
  25. embed_client_dev-4.0.78/embed_client/config_generator.py +652 -0
  26. embed_client_dev-4.0.78/embed_client/config_generator_cli.py +151 -0
  27. embed_client_dev-4.0.78/embed_client/config_presets.py +245 -0
  28. embed_client_dev-4.0.78/embed_client/config_validator.py +246 -0
  29. embed_client_dev-4.0.78/embed_client/config_validator_cli.py +141 -0
  30. embed_client_dev-4.0.78/embed_client/constants.py +52 -0
  31. embed_client_dev-4.0.78/embed_client/demo_cli.py +78 -0
  32. embed_client_dev-4.0.78/embed_client/demo_security_cli.py +206 -0
  33. embed_client_dev-4.0.78/embed_client/embed_file_output_validate.py +348 -0
  34. embed_client_dev-4.0.78/embed_client/embed_file_status_store.py +80 -0
  35. embed_client_dev-4.0.78/embed_client/embedding_client.py +1929 -0
  36. embed_client_dev-4.0.78/embed_client/embedding_client_helpers.py +105 -0
  37. embed_client_dev-4.0.78/embed_client/example_async_usage.py +357 -0
  38. embed_client_dev-4.0.78/embed_client/example_async_usage_demo.py +282 -0
  39. embed_client_dev-4.0.78/embed_client/example_async_usage_ru.py +340 -0
  40. embed_client_dev-4.0.78/embed_client/example_async_usage_ru_demo.py +313 -0
  41. embed_client_dev-4.0.78/embed_client/exceptions.py +122 -0
  42. embed_client_dev-4.0.78/embed_client/identifier_types.py +56 -0
  43. embed_client_dev-4.0.78/embed_client/json_embed_file_preflight.py +128 -0
  44. embed_client_dev-4.0.78/embed_client/local_json_embed_file.py +73 -0
  45. embed_client_dev-4.0.78/embed_client/md_embed_file_prep.py +197 -0
  46. embed_client_dev-4.0.78/embed_client/response_normalizer.py +160 -0
  47. embed_client_dev-4.0.78/embed_client/response_parsers.py +219 -0
  48. embed_client_dev-4.0.78/embed_client/security_cli.py +200 -0
  49. embed_client_dev-4.0.78/embed_client/security_cli_core.py +227 -0
  50. embed_client_dev-4.0.78/embed_client/ssl_examples.py +278 -0
  51. embed_client_dev-4.0.78/embed_client/ssl_manager.py +141 -0
  52. embed_client_dev-4.0.78/embed_client_dev.egg-info/PKG-INFO +155 -0
  53. embed_client_dev-4.0.78/embed_client_dev.egg-info/SOURCES.txt +103 -0
  54. embed_client_dev-4.0.78/embed_client_dev.egg-info/dependency_links.txt +1 -0
  55. embed_client_dev-4.0.78/embed_client_dev.egg-info/entry_points.txt +4 -0
  56. embed_client_dev-4.0.78/embed_client_dev.egg-info/requires.txt +20 -0
  57. embed_client_dev-4.0.78/embed_client_dev.egg-info/top_level.txt +1 -0
  58. embed_client_dev-4.0.78/examples/README.md +55 -0
  59. embed_client_dev-4.0.78/examples/__init__.py +1 -0
  60. embed_client_dev-4.0.78/examples/async_testing_client_example.py +95 -0
  61. embed_client_dev-4.0.78/examples/canonical_mtls_localhost_8001.py +255 -0
  62. embed_client_dev-4.0.78/examples/configs/http_simple.json +12 -0
  63. embed_client_dev-4.0.78/examples/configs/https_token.json +17 -0
  64. embed_client_dev-4.0.78/examples/configs/mtls_roles.json +29 -0
  65. embed_client_dev-4.0.78/examples/data/embed_file_json_array_sample.json +4 -0
  66. embed_client_dev-4.0.78/examples/embed_file_json_local.py +83 -0
  67. embed_client_dev-4.0.78/examples/security_examples.py +606 -0
  68. embed_client_dev-4.0.78/examples/security_examples_ru.py +614 -0
  69. embed_client_dev-4.0.78/pyproject.toml +127 -0
  70. embed_client_dev-4.0.78/setup.cfg +4 -0
  71. embed_client_dev-4.0.78/tests/test_adapter_integration.py +73 -0
  72. embed_client_dev-4.0.78/tests/test_adapter_phase1.py +166 -0
  73. embed_client_dev-4.0.78/tests/test_adapter_phase2.py +263 -0
  74. embed_client_dev-4.0.78/tests/test_all_security_modes.py +627 -0
  75. embed_client_dev-4.0.78/tests/test_async_client_adapter.py +84 -0
  76. embed_client_dev-4.0.78/tests/test_async_client_real.py +311 -0
  77. embed_client_dev-4.0.78/tests/test_async_client_real_fixtures.py +123 -0
  78. embed_client_dev-4.0.78/tests/test_async_client_stress.py +346 -0
  79. embed_client_dev-4.0.78/tests/test_async_client_stress_new.py +326 -0
  80. embed_client_dev-4.0.78/tests/test_async_client_stress_updated.py +326 -0
  81. embed_client_dev-4.0.78/tests/test_auth_manager.py +187 -0
  82. embed_client_dev-4.0.78/tests/test_canonical_mtls_example.py +145 -0
  83. embed_client_dev-4.0.78/tests/test_cli_embed_file_json.py +66 -0
  84. embed_client_dev-4.0.78/tests/test_cli_exit_codes_insecure.py +295 -0
  85. embed_client_dev-4.0.78/tests/test_client_factory.py +461 -0
  86. embed_client_dev-4.0.78/tests/test_client_factory_convenience.py +65 -0
  87. embed_client_dev-4.0.78/tests/test_client_factory_integration.py +115 -0
  88. embed_client_dev-4.0.78/tests/test_config.py +384 -0
  89. embed_client_dev-4.0.78/tests/test_config_explicit_host_not_overridden.py +34 -0
  90. embed_client_dev-4.0.78/tests/test_embed_file_aggregation_method.py +62 -0
  91. embed_client_dev-4.0.78/tests/test_embed_file_output_validate.py +147 -0
  92. embed_client_dev-4.0.78/tests/test_embed_immediate_mode.py +125 -0
  93. embed_client_dev-4.0.78/tests/test_example_async_usage.py +100 -0
  94. embed_client_dev-4.0.78/tests/test_input_limit_commands_client.py +232 -0
  95. embed_client_dev-4.0.78/tests/test_json_embed_file_preflight.py +63 -0
  96. embed_client_dev-4.0.78/tests/test_local_json_embed_file.py +100 -0
  97. embed_client_dev-4.0.78/tests/test_md_embed_file_prep.py +78 -0
  98. embed_client_dev-4.0.78/tests/test_security_matrix.py +421 -0
  99. embed_client_dev-4.0.78/tests/test_ssl_manager.py +58 -0
  100. embed_client_dev-4.0.78/tests/test_structured_terminal_error.py +477 -0
  101. embed_client_dev-4.0.78/tests/test_terminal_delivery_events.py +130 -0
  102. embed_client_dev-4.0.78/tests/test_vectorization_modes_client.py +245 -0
  103. embed_client_dev-4.0.78/tests/test_wait_for_job_poll_queue_shape.py +122 -0
  104. embed_client_dev-4.0.78/tests/test_wait_for_job_ws_fallback.py +113 -0
  105. embed_client_dev-4.0.78/tests/test_with_auth.py +260 -0
@@ -0,0 +1,358 @@
1
+ # Embed-Client Configuration Reference
2
+
3
+ Complete reference for embed-client configuration structure. **`ClientConfig`** loads and merges JSON; **`ConfigValidator`** enforces field rules; **`ClientConfigGenerator`** (CLI **`embed-config-generator`**) emits JSON for all deploy modes. See **[CLI_README.md](CLI_README.md)** for generator and validator commands.
4
+
5
+ Author: Vasiliy Zdanovskiy
6
+ email: vasilyvz@gmail.com
7
+
8
+ ## Recommended local integration (mTLS, port 8001)
9
+
10
+ For a **localhost:8001** embedding service with **mutual TLS**, use the same certificate layout as the repository test bundle:
11
+
12
+ - **Client certificate / key:** `mtls_certificates/client/embedding-service.crt`, `mtls_certificates/client/embedding-service.key`
13
+ - **CA certificate:** `mtls_certificates/ca/ca.crt`
14
+
15
+ A validated configuration dict matching this layout is built by **`build_mtls_localhost_8001_config()`** in [`examples/canonical_mtls_localhost_8001.py`](examples/canonical_mtls_localhost_8001.py). Typical fields:
16
+
17
+ - **`protocol`:** `"mtls"`
18
+ - **`server`:** `host` **`localhost`**, **`port`** **`8001`**
19
+ - **`auth.method`:** **`certificate`** with **`auth.certificate`** paths mirroring **`ssl`** certificate paths
20
+ - **`ssl.enabled`:** **`true`**, **`verify_mode`:** **`CERT_REQUIRED`** (or as required by your environment), **`cert_file`**, **`key_file`**, **`ca_cert_file`** under **`mtls_certificates/client/`** and **`mtls_certificates/ca/`**
21
+
22
+ Pass the dict to **`EmbeddingClient.from_config_dict(...)`** or write it to a JSON file and use **`EmbeddingClient.from_config_file(...)`**.
23
+
24
+ ## Configuration Structure
25
+
26
+ All embed-client configurations follow a unified structure with all fields present. Fields that are not applicable for a specific security mode are set to `null`.
27
+
28
+ ### Complete Configuration Schema
29
+
30
+ ```json
31
+ {
32
+ "server": {
33
+ "host": "string (required, default: 'localhost')",
34
+ "port": "integer (required, default: 8001)",
35
+ "base_url": "string (optional, auto-generated)"
36
+ },
37
+ "client": {
38
+ "timeout": "float (optional, default: 30.0)"
39
+ },
40
+ "protocol": "string (required, one of: 'http', 'https', 'mtls')",
41
+ "auth": {
42
+ "method": "string (required, one of: 'none', 'api_key', 'jwt', 'certificate', 'basic')",
43
+ "api_key": {
44
+ "key": "string (optional, can be null)",
45
+ "header": "string (optional, default: 'X-API-Key')"
46
+ },
47
+ "jwt": {
48
+ "username": "string (optional, required for jwt method)",
49
+ "password": "string (optional, required for jwt method)",
50
+ "secret": "string (optional, required for jwt method)",
51
+ "expiry_hours": "integer (optional, default: 24)"
52
+ },
53
+ "certificate": {
54
+ "enabled": "boolean (required, true for mtls, false otherwise)",
55
+ "cert_file": "string (optional, required for mtls, null for http)",
56
+ "key_file": "string (optional, required for mtls, null for http)",
57
+ "ca_cert_file": "string (optional, required for mtls, null for http)"
58
+ },
59
+ "basic": {
60
+ "username": "string (optional, required for basic method)",
61
+ "password": "string (optional, required for basic method)"
62
+ }
63
+ },
64
+ "ssl": {
65
+ "enabled": "boolean (required, true for https/mtls, false for http)",
66
+ "verify": "boolean (optional, default: true for https/mtls, false for http)",
67
+ "verify_mode": "string (optional, 'CERT_REQUIRED' for mtls, 'CERT_NONE' for https)",
68
+ "check_hostname": "boolean (optional, default: false)",
69
+ "check_expiry": "boolean (optional, default: false)",
70
+ "cert_file": "string (optional, required for mtls, optional for https, null for http)",
71
+ "key_file": "string (optional, required for mtls, optional for https, null for http)",
72
+ "ca_cert_file": "string (optional, required for mtls, optional for https, null for http)",
73
+ "crl_file": "string (optional, can be null for all protocols)",
74
+ "client_cert_required": "boolean (optional, true for mtls, false otherwise)"
75
+ },
76
+ "security": {
77
+ "enabled": "boolean (optional, default: false)",
78
+ "roles_enabled": "boolean (optional, default: false)",
79
+ "roles_file": "string (optional, can be null)",
80
+ "tokens": "object (optional, dictionary of tokens for token-based auth)",
81
+ "roles": "object (optional, dictionary of roles and permissions)"
82
+ },
83
+ "logging": {
84
+ "enabled": "boolean (optional, default: false)",
85
+ "level": "string (optional, default: 'INFO')",
86
+ "format": "string (optional, default log format)"
87
+ },
88
+ "timeout": "integer (optional, default: 30)",
89
+ "retry_attempts": "integer (optional, default: 3)",
90
+ "retry_delay": "integer (optional, default: 1)"
91
+ }
92
+ ```
93
+
94
+ ## Field Requirements by Protocol
95
+
96
+ ### HTTP Protocol
97
+
98
+ - **protocol**: `"http"` (required)
99
+ - **server.host**: Required (default: `"localhost"`)
100
+ - **server.port**: Required (default: `8001`)
101
+ - **auth.method**: `"none"` or `"api_key"` or `"jwt"` or `"basic"`
102
+ - **auth.api_key.key**: Optional (can be `null`)
103
+ - **auth.certificate.cert_file**: Must be `null` (not used)
104
+ - **auth.certificate.key_file**: Must be `null` (not used)
105
+ - **auth.certificate.ca_cert_file**: Must be `null` (not used)
106
+ - **ssl.enabled**: `false` (required)
107
+ - **ssl.cert_file**: Must be `null` (not used)
108
+ - **ssl.key_file**: Must be `null` (not used)
109
+ - **ssl.ca_cert_file**: Must be `null` (not used)
110
+ - **ssl.crl_file**: Optional (can be `null`)
111
+
112
+ ### HTTPS Protocol
113
+
114
+ - **protocol**: `"https"` (required)
115
+ - **server.host**: Required (default: `"localhost"`)
116
+ - **server.port**: Required (default: `8001`)
117
+ - **auth.method**: `"none"` or `"api_key"` or `"jwt"` or `"basic"`
118
+ - **auth.api_key.key**: Optional (can be `null`)
119
+ - **auth.certificate.cert_file**: Optional (can be `null`)
120
+ - **auth.certificate.key_file**: Optional (can be `null`)
121
+ - **auth.certificate.ca_cert_file**: Optional (can be `null`)
122
+ - **ssl.enabled**: `true` (required)
123
+ - **ssl.cert_file**: Optional (can be `null`)
124
+ - **ssl.key_file**: Optional (can be `null`)
125
+ - **ssl.ca_cert_file**: Optional (can be `null`)
126
+ - **ssl.crl_file**: Optional (can be `null`)
127
+
128
+ ### mTLS Protocol
129
+
130
+ - **protocol**: `"mtls"` (required)
131
+ - **server.host**: Required (default: `"localhost"`)
132
+ - **server.port**: Required (default: `8001`)
133
+ - **auth.method**: `"certificate"` (required)
134
+ - **auth.api_key.key**: Optional (can be `null`, not used for mTLS auth)
135
+ - **auth.certificate.cert_file**: **Required** (must be provided)
136
+ - **auth.certificate.key_file**: **Required** (must be provided)
137
+ - **auth.certificate.ca_cert_file**: **Required** (must be provided)
138
+ - **ssl.enabled**: `true` (required)
139
+ - **ssl.cert_file**: **Required** (must be provided)
140
+ - **ssl.key_file**: **Required** (must be provided)
141
+ - **ssl.ca_cert_file**: **Required** (must be provided)
142
+ - **ssl.crl_file**: Optional (can be `null`)
143
+ - **ssl.client_cert_required**: `true` (required)
144
+
145
+ ## Configuration Examples
146
+
147
+ ### HTTP Configuration
148
+
149
+ ```json
150
+ {
151
+ "server": {
152
+ "host": "localhost",
153
+ "port": 8001
154
+ },
155
+ "protocol": "http",
156
+ "auth": {
157
+ "method": "none",
158
+ "api_key": {
159
+ "key": null
160
+ },
161
+ "certificate": {
162
+ "enabled": false,
163
+ "cert_file": null,
164
+ "key_file": null,
165
+ "ca_cert_file": null
166
+ }
167
+ },
168
+ "ssl": {
169
+ "enabled": false,
170
+ "cert_file": null,
171
+ "key_file": null,
172
+ "ca_cert_file": null,
173
+ "crl_file": null
174
+ }
175
+ }
176
+ ```
177
+
178
+ ### HTTPS with Token Configuration
179
+
180
+ ```json
181
+ {
182
+ "server": {
183
+ "host": "localhost",
184
+ "port": 8443
185
+ },
186
+ "protocol": "https",
187
+ "auth": {
188
+ "method": "api_key",
189
+ "api_key": {
190
+ "key": "your-api-key-here"
191
+ },
192
+ "certificate": {
193
+ "enabled": false,
194
+ "cert_file": null,
195
+ "key_file": null,
196
+ "ca_cert_file": null
197
+ }
198
+ },
199
+ "ssl": {
200
+ "enabled": true,
201
+ "verify_mode": "CERT_NONE",
202
+ "cert_file": "/path/to/cert.crt",
203
+ "key_file": null,
204
+ "ca_cert_file": "/path/to/ca.crt",
205
+ "crl_file": null
206
+ }
207
+ }
208
+ ```
209
+
210
+ ### mTLS Configuration
211
+
212
+ ```json
213
+ {
214
+ "server": {
215
+ "host": "localhost",
216
+ "port": 8443
217
+ },
218
+ "protocol": "mtls",
219
+ "auth": {
220
+ "method": "certificate",
221
+ "api_key": {
222
+ "key": null
223
+ },
224
+ "certificate": {
225
+ "enabled": true,
226
+ "cert_file": "/path/to/client.crt",
227
+ "key_file": "/path/to/client.key",
228
+ "ca_cert_file": "/path/to/ca.crt"
229
+ }
230
+ },
231
+ "ssl": {
232
+ "enabled": true,
233
+ "verify_mode": "CERT_REQUIRED",
234
+ "cert_file": "/path/to/client.crt",
235
+ "key_file": "/path/to/client.key",
236
+ "ca_cert_file": "/path/to/ca.crt",
237
+ "crl_file": "/path/to/crl.pem",
238
+ "client_cert_required": true
239
+ }
240
+ }
241
+ ```
242
+
243
+ ## Environment variables
244
+
245
+ - **`EMBED_CLIENT_MAX_JSON_BLOCK_BYTES`** — Optional positive integer: maximum UTF-8 byte length of each string item when validating a local JSON file before **`embed_file`** (`json_array`). If unset, the default is 1 MiB (see **`embed_client.constants.DEFAULT_MAX_JSON_EMBED_BLOCK_BYTES`**). For Markdown/plain text produced by **`prepare-embed-file-json`**, each string is one **paragraph block** after splitting the body **only** on **`\n\n`** (no automatic re-split of oversized paragraphs). Validation runs locally on the client; uploading the validated file uses the same adapter HTTP transport and authentication as JSON-RPC requests to the service. For the CLI entry points, see **`CLI_README.md`** (**`embed-file-json`**, **`prepare-embed-file-json`**) and **`docs/SERVER_MODES_AND_CLIENT.md`** (local upload vs server path).
246
+
247
+ ## Default Values
248
+
249
+ When creating a configuration, the following default values are used if not specified:
250
+
251
+ - **server.host**: `"localhost"`
252
+ - **server.port**: `8001`
253
+ - **client.timeout**: `30.0`
254
+ - **protocol**: Determined by SSL settings (`"http"`, `"https"`, or `"mtls"`)
255
+ - **auth.method**: `"none"`
256
+ - **auth.api_key.key**: `null`
257
+ - **auth.certificate.enabled**: `false` (except for mTLS where it's `true`)
258
+ - **ssl.enabled**: `false` (except for HTTPS/mTLS where it's `true`)
259
+ - **ssl.crl_file**: `null` (optional for all protocols)
260
+
261
+ ## Field Semantics
262
+
263
+ ### Protocol Field
264
+
265
+ The `protocol` field is **always present** in all configurations and indicates the transport protocol:
266
+ - `"http"`: Plain HTTP without encryption
267
+ - `"https"`: HTTPS with server certificate verification
268
+ - `"mtls"`: Mutual TLS with client and server certificates
269
+
270
+ ### Token Field
271
+
272
+ The `auth.api_key.key` field is **always present** but can be `null`:
273
+ - For HTTP/HTTPS with token authentication: contains the API key
274
+ - For HTTP/HTTPS without authentication: `null`
275
+ - For mTLS: `null` (certificate-based authentication is used)
276
+
277
+ ### Certificate Fields
278
+
279
+ Certificate fields behavior:
280
+ - **For HTTP**: All certificate fields (`cert_file`, `key_file`, `ca_cert_file`) must be `null`
281
+ - **For HTTPS**: Certificate fields are optional (can be `null` or provided)
282
+ - **For mTLS**: Certificate fields are **required** and must be provided
283
+
284
+ ### CRL Field
285
+
286
+ The `ssl.crl_file` field is **always present** but optional:
287
+ - Can be `null` for all protocols
288
+ - If provided, must point to a valid Certificate Revocation List file
289
+ - Used for checking if certificates have been revoked
290
+
291
+ ## Configuration Generator
292
+
293
+ Use `embed-config-generator` CLI tool to generate configurations:
294
+
295
+ ```bash
296
+ # Generate HTTP config
297
+ embed-config-generator --mode http --host localhost --port 8001 --output config.json
298
+
299
+ # Generate HTTPS config with certificates
300
+ embed-config-generator --mode https --host localhost --port 8443 \
301
+ --cert-file /path/to/cert.crt --ca-cert-file /path/to/ca.crt --output config.json
302
+
303
+ # Generate mTLS config with all certificates and CRL
304
+ embed-config-generator --mode mtls --host localhost --port 8443 \
305
+ --cert-file /path/to/client.crt --key-file /path/to/client.key \
306
+ --ca-cert-file /path/to/ca.crt --crl-file /path/to/crl.pem --output config.json
307
+ ```
308
+
309
+ ## Configuration Validator
310
+
311
+ Use `embed-config-validator` CLI tool to validate configurations:
312
+
313
+ ```bash
314
+ # Validate single config
315
+ embed-config-validator --file config.json
316
+
317
+ # Validate all configs in directory
318
+ embed-config-validator --dir ./configs --verbose
319
+ ```
320
+
321
+ ## Integration with Server
322
+
323
+ When embedding the client into a server, create a separate configuration section:
324
+
325
+ ```json
326
+ {
327
+ "server": {
328
+ "host": "localhost",
329
+ "port": 8001
330
+ },
331
+ "embed_client": {
332
+ "protocol": "mtls",
333
+ "server": {
334
+ "host": "embedding-service.example.com",
335
+ "port": 8443
336
+ },
337
+ "auth": {
338
+ "method": "certificate",
339
+ "certificate": {
340
+ "enabled": true,
341
+ "cert_file": "/path/to/client.crt",
342
+ "key_file": "/path/to/client.key",
343
+ "ca_cert_file": "/path/to/ca.crt"
344
+ }
345
+ },
346
+ "ssl": {
347
+ "enabled": true,
348
+ "cert_file": "/path/to/client.crt",
349
+ "key_file": "/path/to/client.key",
350
+ "ca_cert_file": "/path/to/ca.crt",
351
+ "crl_file": "/path/to/crl.pem"
352
+ }
353
+ }
354
+ }
355
+ ```
356
+
357
+ This allows the server to have its own configuration while the client has a separate, validated configuration section.
358
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Vasiliy Zdanovskiy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,16 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CONFIGURATION.md
4
+ include pyproject.toml
5
+ recursive-include examples *.py *.md *.json
6
+ recursive-include docs *.md
7
+ recursive-include configs *.json
8
+ recursive-exclude * __pycache__
9
+ recursive-exclude * *.py[co]
10
+ recursive-exclude * .pytest_cache
11
+ recursive-exclude * .git*
12
+ recursive-exclude * .venv
13
+ recursive-exclude * tests
14
+ recursive-exclude * mtls_certificates
15
+ recursive-exclude * logs
16
+ recursive-exclude * test_environment
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: embed-client-dev
3
+ Version: 4.0.78
4
+ Summary: Async client for the Embedding Service API. Canonical class: EmbeddingClient (JSON-RPC via mcp-proxy-adapter >=8.10).
5
+ Author-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/maverikod/ai-embed
8
+ Project-URL: Repository, https://github.com/maverikod/ai-embed
9
+ Project-URL: Documentation, https://github.com/maverikod/ai-embed/tree/main/client#readme
10
+ Project-URL: Bug Tracker, https://github.com/maverikod/ai-embed/issues
11
+ Project-URL: Configuration Reference, https://github.com/maverikod/ai-embed/blob/main/client/CONFIGURATION.md
12
+ Keywords: embedding,async,client,api,authentication,ssl,tls,mtls,config,generator,validator,configuration
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
24
+ Classifier: Topic :: Security
25
+ Classifier: Topic :: System :: Networking
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: mcp-proxy-adapter>=8.11.14
30
+ Requires-Dist: mcp_security_framework>=2.3.2
31
+ Provides-Extra: scripts
32
+ Requires-Dist: pydantic>=2.0.0; extra == "scripts"
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest; extra == "test"
35
+ Requires-Dist: pytest-asyncio; extra == "test"
36
+ Requires-Dist: pytest-xdist; extra == "test"
37
+ Requires-Dist: pytest-timeout; extra == "test"
38
+ Provides-Extra: dev
39
+ Requires-Dist: pytest; extra == "dev"
40
+ Requires-Dist: pytest-asyncio; extra == "dev"
41
+ Requires-Dist: pytest-xdist; extra == "dev"
42
+ Requires-Dist: pytest-timeout; extra == "dev"
43
+ Requires-Dist: black; extra == "dev"
44
+ Requires-Dist: flake8; extra == "dev"
45
+ Requires-Dist: mypy; extra == "dev"
46
+ Dynamic: license-file
47
+
48
+ # embed-client
49
+
50
+ Python **async** client bundled with the Embedding Service in this repository's
51
+ `client/` directory. The canonical public client is **`EmbeddingClient`** (JSON-RPC
52
+ via **`mcp-proxy-adapter`**). The distribution and import names are unchanged.
53
+
54
+ ```python
55
+ from embed_client import EmbeddingClient
56
+ ```
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install embed-client
62
+ ```
63
+
64
+ Editable development checkout:
65
+
66
+ ```bash
67
+ git clone https://github.com/maverikod/ai-embed.git
68
+ cd ai-embed
69
+ pip install -e ./client
70
+ ```
71
+
72
+ ## Canonical real-server E2E (localhost:8001, mTLS)
73
+
74
+ The repository ships a **runnable** end-to-end tour of the public API against **localhost:8001** with **mTLS**, using certificates under **`mtls_certificates/`** (see **`mtls_certificates/README.md`** if present).
75
+
76
+ | Artifact | Path |
77
+ |----------|------|
78
+ | Example script | [`examples/canonical_mtls_localhost_8001.py`](examples/canonical_mtls_localhost_8001.py) |
79
+ | Live integration | Set **`RUN_CANONICAL_MTLS_E2E=1`** to perform real network calls (otherwise dry run / config check) |
80
+ | Optional `embed_file` | Set **`CANONICAL_EMBED_FILE_SERVER_PATH`** to a **server-visible** file path to include **`embed_file`** in the tour |
81
+ | Tests | [`tests/test_canonical_mtls_example.py`](tests/test_canonical_mtls_example.py) |
82
+
83
+ ```bash
84
+ python examples/canonical_mtls_localhost_8001.py
85
+ RUN_CANONICAL_MTLS_E2E=1 python examples/canonical_mtls_localhost_8001.py
86
+ ```
87
+
88
+ ## Minimal usage
89
+
90
+ ```python
91
+ import asyncio
92
+ from embed_client import EmbeddingClient
93
+
94
+ async def main() -> None:
95
+ async with EmbeddingClient.from_base_url_port("http://localhost", 8001) as client:
96
+ h = await client.health()
97
+ print("health:", h)
98
+ data = await client.embed(["hello"], error_policy="continue", wait=True)
99
+ print("embed keys:", list(data.keys()) if isinstance(data, dict) else type(data))
100
+
101
+ if __name__ == "__main__":
102
+ asyncio.run(main())
103
+ ```
104
+
105
+ Public queue-oriented helpers include **`embed`**, **`wait_for_job`**, **`job_status`**, **`list_queued_commands`**, **`cmd`**, optional **`embed_file`**, plus introspection (**`list_commands`**, **`models`**, **`default_model`**, **`fetch_openapi_schema`**, **`http_get`**, **`timing_stats`**) and TLS helpers **`is_mtls_enabled`**, **`get_ssl_config`**. See **`embed_client/embedding_client.py`** for the full list.
106
+
107
+ **`embed_file` vs local JSON without shared server disk:** use **`embed_file`** with a server-visible **`input_file`** when the input already exists on the service host. For a **`json_array`** file that exists only on the client machine (no shared filesystem), use the CLI **`embed-file-json`** subcommand (or **`embed_file_from_local_json_file`**) so the client validates, uploads through the adapter, resolves **`storage_path`** via **`get_upload_session`**, then runs **`embed_file`** with that path and **`format=json_array`**. For Markdown sources (e.g. with YAML front matter), run **`prepare-embed-file-json`** first to emit a valid **`json_array`** (array of strings): the body is split **only** on blank lines (**`\n\n`**) into paragraph-sized strings, with per-paragraph UTF-8 size limits and **no** automatic oversize split — oversized paragraphs require editing the source or raising the byte cap; then **`embed-file-json`**. Add **`--show-progress`** to stream server WebSocket/status lines to stderr during the job wait (see **`CLI_README.md`**).
108
+
109
+ **Providers (server 4.0.46+):** the full model id is provider + model. **`embed`** and **`embed_file`** take an optional **`provider`** (`"local"` = the server's own model, or a live macsc provider id such as `"openai"`); it is sent only when not `None`. There is no `backend` argument any more (a `TypeError` is raised for `backend=`); the `backend` field of results and `models()` entries is still returned. **`default_model()`** returns exactly `{model, dimension, provider}`; **`models()`** returns `{use_own_model, default: {provider, model}, external: {configured, service}, models: [...]}` with entries `{name, provider, dimension, supported_dimensions, max_tokens, backend, residency (local)}`.
110
+
111
+ Resolution order (server): provider given -> must be known, model omitted -> the default model of that provider (it must be the default provider's, else `UNKNOWN_MODEL`); provider and model omitted -> the default pair; provider omitted and model given -> the default provider first (if it lists the model it is used and macsc is not consulted for a local default), else the other providers are searched: exactly one offers it -> used, several -> `PROVIDER_REQUIRED`, none -> `UNKNOWN_MODEL`. Dimension omitted -> the entry's default; given -> must satisfy `supported_dimensions` else `UNSUPPORTED_DIMENSION`.
112
+
113
+ Error codes (`error.data.code` / `error.data.kind`, surfaced unchanged): `-32602` `UNKNOWN_PROVIDER`, `UNKNOWN_MODEL`, `UNSUPPORTED_DIMENSION`, `PROVIDER_REQUIRED`; `-32003` `EXTERNAL_UNAVAILABLE`, `EXTERNAL_UPSTREAM_FAILURE`, `EXTERNAL_BAD_RESPONSE`, `EXTERNAL_INVALID_REQUEST`; `-32001` `MODEL_LOADING` (retry); `-32004` `OWN_MODEL_DISABLED`; `-32005` `GPU_DISABLED`; `-32603` `MODEL_LOAD_FAILED`, `NO_GPU_AVAILABLE`. **`model_offload()`** moves the resident local model VRAM -> RAM (pinned against the GPU watcher) and **`model_load(model=None, device=None, wait=None)`** moves it back (`wait=False` returns at once while the load continues, `wait=True` blocks until it is in VRAM); neither takes a provider. Refusals of `model_offload`/`model_load`/`default_model` arrive as **`EmbedAPIError`** carrying the server error object. Every embed result carries `provider`, `model`, `dimension` and `backend`; external results also carry `usage`.
114
+
115
+ **Input-limit table (server input_limit_* commands):** **`input_limit_add(provider, model, max_input_tokens, tokenizer, max_inputs_per_request=None, max_total_tokens_per_request=None, source=None)`** adds a manual row (`-32602` `INPUT_LIMIT_EXISTS`, `LOCAL_LIMIT_FROM_MODEL`); **`input_limit_delete(provider, model)`** removes a row (`-32602` `INPUT_LIMIT_NOT_FOUND`); **`input_limit_update(provider, model, *, <named cells>)`** changes only the cells passed explicitly (`None` sends null, which only the three nullable cells accept; `-32602` `INPUT_LIMIT_NOT_FOUND`, `INPUT_LIMIT_EMPTY_UPDATE`, `LOCAL_LIMIT_FROM_MODEL`); **`input_limit_list(provider=None)`** returns `{rows: [...]}` sorted by `(provider, model)` with each row's `origin` (`module` | `manual`). Mutating commands may also return `-32603` `INPUT_LIMIT_PERSIST_FAILED`. Refusals arrive as **`EmbedAPIError`**. The client does not validate these parameters.
116
+
117
+ ## Documentation
118
+
119
+ - **[CONFIGURATION.md](CONFIGURATION.md)** — JSON config schema, protocols, validation
120
+ - **[CLI_README.md](CLI_README.md)** — `embed-config-generator`, `embed-config-validator`, `embed-vectorize`
121
+ - **[docs/api_format.md](docs/api_format.md)** — JSON-RPC shapes for `embed` and `embed_file` (server path vs upload)
122
+ - **[examples/README.md](examples/README.md)** — example index (canonical mTLS first)
123
+ - **[docs/SERVER_MODES_AND_CLIENT.md](docs/SERVER_MODES_AND_CLIENT.md)** — security modes vs client behavior (short summary; not full matrix)
124
+
125
+ ## Security modes
126
+
127
+ The server supports multiple HTTP/HTTPS/mTLS and auth combinations. For deploy-time verification expectations, see the project deploy rule; for field-level mapping, see **CONFIGURATION.md** and **docs/SERVER_MODES_AND_CLIENT.md**.
128
+
129
+ ## Development and tests
130
+
131
+ The original client test modules are preserved under `client/tests/`; the shared
132
+ project pipeline owns executable acceptance from the repository root.
133
+
134
+ ```bash
135
+ python -m pipeline
136
+ ```
137
+
138
+ ### Release
139
+
140
+ The server and client read one version from `embed_client/_version.py` here.
141
+ The root `../build.sh` builds the client wheel and sdist, checks their metadata,
142
+ publishes only the client to PyPI and pushes the server image to Docker Hub on
143
+ every successful run. It accepts no arguments or skip options and invokes no
144
+ pipeline. Run the shared pipeline separately before releasing the candidate.
145
+
146
+ For isolated package artifacts without publishing, run `python -m build client`
147
+ from the repository root. This is packaging only, not service acceptance.
148
+
149
+ ## License
150
+
151
+ MIT License
152
+
153
+ ## Author
154
+
155
+ **Vasiliy Zdanovskiy** — vasilyvz@gmail.com
@@ -0,0 +1,108 @@
1
+ # embed-client
2
+
3
+ Python **async** client bundled with the Embedding Service in this repository's
4
+ `client/` directory. The canonical public client is **`EmbeddingClient`** (JSON-RPC
5
+ via **`mcp-proxy-adapter`**). The distribution and import names are unchanged.
6
+
7
+ ```python
8
+ from embed_client import EmbeddingClient
9
+ ```
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install embed-client
15
+ ```
16
+
17
+ Editable development checkout:
18
+
19
+ ```bash
20
+ git clone https://github.com/maverikod/ai-embed.git
21
+ cd ai-embed
22
+ pip install -e ./client
23
+ ```
24
+
25
+ ## Canonical real-server E2E (localhost:8001, mTLS)
26
+
27
+ The repository ships a **runnable** end-to-end tour of the public API against **localhost:8001** with **mTLS**, using certificates under **`mtls_certificates/`** (see **`mtls_certificates/README.md`** if present).
28
+
29
+ | Artifact | Path |
30
+ |----------|------|
31
+ | Example script | [`examples/canonical_mtls_localhost_8001.py`](examples/canonical_mtls_localhost_8001.py) |
32
+ | Live integration | Set **`RUN_CANONICAL_MTLS_E2E=1`** to perform real network calls (otherwise dry run / config check) |
33
+ | Optional `embed_file` | Set **`CANONICAL_EMBED_FILE_SERVER_PATH`** to a **server-visible** file path to include **`embed_file`** in the tour |
34
+ | Tests | [`tests/test_canonical_mtls_example.py`](tests/test_canonical_mtls_example.py) |
35
+
36
+ ```bash
37
+ python examples/canonical_mtls_localhost_8001.py
38
+ RUN_CANONICAL_MTLS_E2E=1 python examples/canonical_mtls_localhost_8001.py
39
+ ```
40
+
41
+ ## Minimal usage
42
+
43
+ ```python
44
+ import asyncio
45
+ from embed_client import EmbeddingClient
46
+
47
+ async def main() -> None:
48
+ async with EmbeddingClient.from_base_url_port("http://localhost", 8001) as client:
49
+ h = await client.health()
50
+ print("health:", h)
51
+ data = await client.embed(["hello"], error_policy="continue", wait=True)
52
+ print("embed keys:", list(data.keys()) if isinstance(data, dict) else type(data))
53
+
54
+ if __name__ == "__main__":
55
+ asyncio.run(main())
56
+ ```
57
+
58
+ Public queue-oriented helpers include **`embed`**, **`wait_for_job`**, **`job_status`**, **`list_queued_commands`**, **`cmd`**, optional **`embed_file`**, plus introspection (**`list_commands`**, **`models`**, **`default_model`**, **`fetch_openapi_schema`**, **`http_get`**, **`timing_stats`**) and TLS helpers **`is_mtls_enabled`**, **`get_ssl_config`**. See **`embed_client/embedding_client.py`** for the full list.
59
+
60
+ **`embed_file` vs local JSON without shared server disk:** use **`embed_file`** with a server-visible **`input_file`** when the input already exists on the service host. For a **`json_array`** file that exists only on the client machine (no shared filesystem), use the CLI **`embed-file-json`** subcommand (or **`embed_file_from_local_json_file`**) so the client validates, uploads through the adapter, resolves **`storage_path`** via **`get_upload_session`**, then runs **`embed_file`** with that path and **`format=json_array`**. For Markdown sources (e.g. with YAML front matter), run **`prepare-embed-file-json`** first to emit a valid **`json_array`** (array of strings): the body is split **only** on blank lines (**`\n\n`**) into paragraph-sized strings, with per-paragraph UTF-8 size limits and **no** automatic oversize split — oversized paragraphs require editing the source or raising the byte cap; then **`embed-file-json`**. Add **`--show-progress`** to stream server WebSocket/status lines to stderr during the job wait (see **`CLI_README.md`**).
61
+
62
+ **Providers (server 4.0.46+):** the full model id is provider + model. **`embed`** and **`embed_file`** take an optional **`provider`** (`"local"` = the server's own model, or a live macsc provider id such as `"openai"`); it is sent only when not `None`. There is no `backend` argument any more (a `TypeError` is raised for `backend=`); the `backend` field of results and `models()` entries is still returned. **`default_model()`** returns exactly `{model, dimension, provider}`; **`models()`** returns `{use_own_model, default: {provider, model}, external: {configured, service}, models: [...]}` with entries `{name, provider, dimension, supported_dimensions, max_tokens, backend, residency (local)}`.
63
+
64
+ Resolution order (server): provider given -> must be known, model omitted -> the default model of that provider (it must be the default provider's, else `UNKNOWN_MODEL`); provider and model omitted -> the default pair; provider omitted and model given -> the default provider first (if it lists the model it is used and macsc is not consulted for a local default), else the other providers are searched: exactly one offers it -> used, several -> `PROVIDER_REQUIRED`, none -> `UNKNOWN_MODEL`. Dimension omitted -> the entry's default; given -> must satisfy `supported_dimensions` else `UNSUPPORTED_DIMENSION`.
65
+
66
+ Error codes (`error.data.code` / `error.data.kind`, surfaced unchanged): `-32602` `UNKNOWN_PROVIDER`, `UNKNOWN_MODEL`, `UNSUPPORTED_DIMENSION`, `PROVIDER_REQUIRED`; `-32003` `EXTERNAL_UNAVAILABLE`, `EXTERNAL_UPSTREAM_FAILURE`, `EXTERNAL_BAD_RESPONSE`, `EXTERNAL_INVALID_REQUEST`; `-32001` `MODEL_LOADING` (retry); `-32004` `OWN_MODEL_DISABLED`; `-32005` `GPU_DISABLED`; `-32603` `MODEL_LOAD_FAILED`, `NO_GPU_AVAILABLE`. **`model_offload()`** moves the resident local model VRAM -> RAM (pinned against the GPU watcher) and **`model_load(model=None, device=None, wait=None)`** moves it back (`wait=False` returns at once while the load continues, `wait=True` blocks until it is in VRAM); neither takes a provider. Refusals of `model_offload`/`model_load`/`default_model` arrive as **`EmbedAPIError`** carrying the server error object. Every embed result carries `provider`, `model`, `dimension` and `backend`; external results also carry `usage`.
67
+
68
+ **Input-limit table (server input_limit_* commands):** **`input_limit_add(provider, model, max_input_tokens, tokenizer, max_inputs_per_request=None, max_total_tokens_per_request=None, source=None)`** adds a manual row (`-32602` `INPUT_LIMIT_EXISTS`, `LOCAL_LIMIT_FROM_MODEL`); **`input_limit_delete(provider, model)`** removes a row (`-32602` `INPUT_LIMIT_NOT_FOUND`); **`input_limit_update(provider, model, *, <named cells>)`** changes only the cells passed explicitly (`None` sends null, which only the three nullable cells accept; `-32602` `INPUT_LIMIT_NOT_FOUND`, `INPUT_LIMIT_EMPTY_UPDATE`, `LOCAL_LIMIT_FROM_MODEL`); **`input_limit_list(provider=None)`** returns `{rows: [...]}` sorted by `(provider, model)` with each row's `origin` (`module` | `manual`). Mutating commands may also return `-32603` `INPUT_LIMIT_PERSIST_FAILED`. Refusals arrive as **`EmbedAPIError`**. The client does not validate these parameters.
69
+
70
+ ## Documentation
71
+
72
+ - **[CONFIGURATION.md](CONFIGURATION.md)** — JSON config schema, protocols, validation
73
+ - **[CLI_README.md](CLI_README.md)** — `embed-config-generator`, `embed-config-validator`, `embed-vectorize`
74
+ - **[docs/api_format.md](docs/api_format.md)** — JSON-RPC shapes for `embed` and `embed_file` (server path vs upload)
75
+ - **[examples/README.md](examples/README.md)** — example index (canonical mTLS first)
76
+ - **[docs/SERVER_MODES_AND_CLIENT.md](docs/SERVER_MODES_AND_CLIENT.md)** — security modes vs client behavior (short summary; not full matrix)
77
+
78
+ ## Security modes
79
+
80
+ The server supports multiple HTTP/HTTPS/mTLS and auth combinations. For deploy-time verification expectations, see the project deploy rule; for field-level mapping, see **CONFIGURATION.md** and **docs/SERVER_MODES_AND_CLIENT.md**.
81
+
82
+ ## Development and tests
83
+
84
+ The original client test modules are preserved under `client/tests/`; the shared
85
+ project pipeline owns executable acceptance from the repository root.
86
+
87
+ ```bash
88
+ python -m pipeline
89
+ ```
90
+
91
+ ### Release
92
+
93
+ The server and client read one version from `embed_client/_version.py` here.
94
+ The root `../build.sh` builds the client wheel and sdist, checks their metadata,
95
+ publishes only the client to PyPI and pushes the server image to Docker Hub on
96
+ every successful run. It accepts no arguments or skip options and invokes no
97
+ pipeline. Run the shared pipeline separately before releasing the candidate.
98
+
99
+ For isolated package artifacts without publishing, run `python -m build client`
100
+ from the repository root. This is packaging only, not service acceptance.
101
+
102
+ ## License
103
+
104
+ MIT License
105
+
106
+ ## Author
107
+
108
+ **Vasiliy Zdanovskiy** — vasilyvz@gmail.com