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.
- embed_client_dev-4.0.78/CONFIGURATION.md +358 -0
- embed_client_dev-4.0.78/LICENSE +21 -0
- embed_client_dev-4.0.78/MANIFEST.in +16 -0
- embed_client_dev-4.0.78/PKG-INFO +155 -0
- embed_client_dev-4.0.78/README.md +108 -0
- embed_client_dev-4.0.78/docs/SERVER_MODES_AND_CLIENT.md +49 -0
- embed_client_dev-4.0.78/docs/api_format.md +50 -0
- embed_client_dev-4.0.78/docs/client_integration_guide.md +303 -0
- embed_client_dev-4.0.78/docs/error_handling_complete.md +134 -0
- embed_client_dev-4.0.78/embed_client/__init__.py +36 -0
- embed_client_dev-4.0.78/embed_client/__main__.py +15 -0
- embed_client_dev-4.0.78/embed_client/_version.py +3 -0
- embed_client_dev-4.0.78/embed_client/adapter_config_factory.py +213 -0
- embed_client_dev-4.0.78/embed_client/adapter_config_normalizer.py +135 -0
- embed_client_dev-4.0.78/embed_client/adapter_generator_bridge.py +166 -0
- embed_client_dev-4.0.78/embed_client/auth.py +189 -0
- embed_client_dev-4.0.78/embed_client/cli.py +483 -0
- embed_client_dev-4.0.78/embed_client/cli_core.py +427 -0
- embed_client_dev-4.0.78/embed_client/client_factory.py +515 -0
- embed_client_dev-4.0.78/embed_client/client_factory_examples.py +375 -0
- embed_client_dev-4.0.78/embed_client/client_factory_helpers.py +59 -0
- embed_client_dev-4.0.78/embed_client/config.py +408 -0
- embed_client_dev-4.0.78/embed_client/config_defaults.py +77 -0
- embed_client_dev-4.0.78/embed_client/config_examples.py +228 -0
- embed_client_dev-4.0.78/embed_client/config_generator.py +652 -0
- embed_client_dev-4.0.78/embed_client/config_generator_cli.py +151 -0
- embed_client_dev-4.0.78/embed_client/config_presets.py +245 -0
- embed_client_dev-4.0.78/embed_client/config_validator.py +246 -0
- embed_client_dev-4.0.78/embed_client/config_validator_cli.py +141 -0
- embed_client_dev-4.0.78/embed_client/constants.py +52 -0
- embed_client_dev-4.0.78/embed_client/demo_cli.py +78 -0
- embed_client_dev-4.0.78/embed_client/demo_security_cli.py +206 -0
- embed_client_dev-4.0.78/embed_client/embed_file_output_validate.py +348 -0
- embed_client_dev-4.0.78/embed_client/embed_file_status_store.py +80 -0
- embed_client_dev-4.0.78/embed_client/embedding_client.py +1929 -0
- embed_client_dev-4.0.78/embed_client/embedding_client_helpers.py +105 -0
- embed_client_dev-4.0.78/embed_client/example_async_usage.py +357 -0
- embed_client_dev-4.0.78/embed_client/example_async_usage_demo.py +282 -0
- embed_client_dev-4.0.78/embed_client/example_async_usage_ru.py +340 -0
- embed_client_dev-4.0.78/embed_client/example_async_usage_ru_demo.py +313 -0
- embed_client_dev-4.0.78/embed_client/exceptions.py +122 -0
- embed_client_dev-4.0.78/embed_client/identifier_types.py +56 -0
- embed_client_dev-4.0.78/embed_client/json_embed_file_preflight.py +128 -0
- embed_client_dev-4.0.78/embed_client/local_json_embed_file.py +73 -0
- embed_client_dev-4.0.78/embed_client/md_embed_file_prep.py +197 -0
- embed_client_dev-4.0.78/embed_client/response_normalizer.py +160 -0
- embed_client_dev-4.0.78/embed_client/response_parsers.py +219 -0
- embed_client_dev-4.0.78/embed_client/security_cli.py +200 -0
- embed_client_dev-4.0.78/embed_client/security_cli_core.py +227 -0
- embed_client_dev-4.0.78/embed_client/ssl_examples.py +278 -0
- embed_client_dev-4.0.78/embed_client/ssl_manager.py +141 -0
- embed_client_dev-4.0.78/embed_client_dev.egg-info/PKG-INFO +155 -0
- embed_client_dev-4.0.78/embed_client_dev.egg-info/SOURCES.txt +103 -0
- embed_client_dev-4.0.78/embed_client_dev.egg-info/dependency_links.txt +1 -0
- embed_client_dev-4.0.78/embed_client_dev.egg-info/entry_points.txt +4 -0
- embed_client_dev-4.0.78/embed_client_dev.egg-info/requires.txt +20 -0
- embed_client_dev-4.0.78/embed_client_dev.egg-info/top_level.txt +1 -0
- embed_client_dev-4.0.78/examples/README.md +55 -0
- embed_client_dev-4.0.78/examples/__init__.py +1 -0
- embed_client_dev-4.0.78/examples/async_testing_client_example.py +95 -0
- embed_client_dev-4.0.78/examples/canonical_mtls_localhost_8001.py +255 -0
- embed_client_dev-4.0.78/examples/configs/http_simple.json +12 -0
- embed_client_dev-4.0.78/examples/configs/https_token.json +17 -0
- embed_client_dev-4.0.78/examples/configs/mtls_roles.json +29 -0
- embed_client_dev-4.0.78/examples/data/embed_file_json_array_sample.json +4 -0
- embed_client_dev-4.0.78/examples/embed_file_json_local.py +83 -0
- embed_client_dev-4.0.78/examples/security_examples.py +606 -0
- embed_client_dev-4.0.78/examples/security_examples_ru.py +614 -0
- embed_client_dev-4.0.78/pyproject.toml +127 -0
- embed_client_dev-4.0.78/setup.cfg +4 -0
- embed_client_dev-4.0.78/tests/test_adapter_integration.py +73 -0
- embed_client_dev-4.0.78/tests/test_adapter_phase1.py +166 -0
- embed_client_dev-4.0.78/tests/test_adapter_phase2.py +263 -0
- embed_client_dev-4.0.78/tests/test_all_security_modes.py +627 -0
- embed_client_dev-4.0.78/tests/test_async_client_adapter.py +84 -0
- embed_client_dev-4.0.78/tests/test_async_client_real.py +311 -0
- embed_client_dev-4.0.78/tests/test_async_client_real_fixtures.py +123 -0
- embed_client_dev-4.0.78/tests/test_async_client_stress.py +346 -0
- embed_client_dev-4.0.78/tests/test_async_client_stress_new.py +326 -0
- embed_client_dev-4.0.78/tests/test_async_client_stress_updated.py +326 -0
- embed_client_dev-4.0.78/tests/test_auth_manager.py +187 -0
- embed_client_dev-4.0.78/tests/test_canonical_mtls_example.py +145 -0
- embed_client_dev-4.0.78/tests/test_cli_embed_file_json.py +66 -0
- embed_client_dev-4.0.78/tests/test_cli_exit_codes_insecure.py +295 -0
- embed_client_dev-4.0.78/tests/test_client_factory.py +461 -0
- embed_client_dev-4.0.78/tests/test_client_factory_convenience.py +65 -0
- embed_client_dev-4.0.78/tests/test_client_factory_integration.py +115 -0
- embed_client_dev-4.0.78/tests/test_config.py +384 -0
- embed_client_dev-4.0.78/tests/test_config_explicit_host_not_overridden.py +34 -0
- embed_client_dev-4.0.78/tests/test_embed_file_aggregation_method.py +62 -0
- embed_client_dev-4.0.78/tests/test_embed_file_output_validate.py +147 -0
- embed_client_dev-4.0.78/tests/test_embed_immediate_mode.py +125 -0
- embed_client_dev-4.0.78/tests/test_example_async_usage.py +100 -0
- embed_client_dev-4.0.78/tests/test_input_limit_commands_client.py +232 -0
- embed_client_dev-4.0.78/tests/test_json_embed_file_preflight.py +63 -0
- embed_client_dev-4.0.78/tests/test_local_json_embed_file.py +100 -0
- embed_client_dev-4.0.78/tests/test_md_embed_file_prep.py +78 -0
- embed_client_dev-4.0.78/tests/test_security_matrix.py +421 -0
- embed_client_dev-4.0.78/tests/test_ssl_manager.py +58 -0
- embed_client_dev-4.0.78/tests/test_structured_terminal_error.py +477 -0
- embed_client_dev-4.0.78/tests/test_terminal_delivery_events.py +130 -0
- embed_client_dev-4.0.78/tests/test_vectorization_modes_client.py +245 -0
- embed_client_dev-4.0.78/tests/test_wait_for_job_poll_queue_shape.py +122 -0
- embed_client_dev-4.0.78/tests/test_wait_for_job_ws_fallback.py +113 -0
- 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
|