GET api update for image vector

This commit is contained in:
sriram
2026-09-18 17:50:14 +05:30
parent d6296bd1f0
commit bc786b1c49
6 changed files with 255 additions and 2 deletions

View File

@@ -11,6 +11,7 @@ product cards.
```
POST /api/search/image-vector JSON {vector[1024], text?, brand?, category?, top_k?, min_score?}
GET /api/search/image-vector query string: vector=<base64 or csv>&text=...&top_k=... (see "GET variant")
POST /api/search/image multipart file + the same optional fields as form fields
```
@@ -114,13 +115,57 @@ Every result is the full product card (`ProductOut`) plus `score` and
`text_overlap`. `detected_brand` is the brand the search was scoped to,
whether it came from `brand` or from the text.
## GET variant — the vector in the query string
For clients that can only issue a GET:
```
GET /api/search/image-vector?vector=<...>&text=...&brand=...&category=...&top_k=10&min_score=0
```
Same parameters, same ranking, same response as the POST. `vector` takes
either of two encodings, told apart by the presence of a comma:
| Encoding | Size in the URL | Works through |
|---|---|---|
| **base64** of 1024 little-endian float32, urlsafe alphabet, padding optional (recommended) | **5.5 KB** | every layer (Traefik, uvicorn, and the app domain's nginx with its 8 KB request-line cap) |
| comma-separated decimals, 5 dp (brackets / whitespace tolerated) | 8.3 KB raw, ~10.3 KB once commas are `%2C`-encoded | `mcp.nearle.ai.in` (Traefik → uvicorn, 64 KB); **not** the app domain (nginx `414`) |
Anything larger or more sensitive than that belongs in the POST body. GET
URLs also land in access logs in full (~6–10 KB per request).
```bash
# base64 (Python: struct.pack('<1024f', *v) → base64.urlsafe_b64encode)
curl -sG https://mcp.nearle.ai.in/api/search/image-vector --data-urlencode "vector=$B64" --data-urlencode "text=Britannia Marie Gold 300 g" -d top_k=5
# comma-separated
curl -sG https://mcp.nearle.ai.in/api/search/image-vector --data-urlencode "vector=0.03172,0.06823,-0.0223,...(1024 values)" -d top_k=5
```
Producing the base64 form:
```python
# Python
import base64, struct
b64 = base64.urlsafe_b64encode(struct.pack("<1024f", *vector)).decode().rstrip("=")
```
```dart
// Dart / Flutter - `vector` is the app's Float32List(1024) after L2 normalisation
final b64 = base64Url.encode(vector.buffer.asUint8List()).replaceAll('=', '');
// Float32List is little-endian on every platform Flutter ships to.
```
A malformed `vector` (wrong count, not a number, bad base64, all zeros)
is a 422 whose `detail` says which value or what length was wrong.
## Errors
| Code | Cause | What to do |
|---|---|---|
| 400 | `/image`: the upload is empty | send the file |
| 413 | `/image`: file over 8 MB | crop or downscale |
| 422 | wrong vector length, NaN, all zeros, `top_k` out of 1–50, `min_score` out of −1…1, undecodable image | `detail` names the field |
| 422 | wrong vector length, NaN, all zeros, unparseable GET `vector`, `top_k` out of 1–50, `min_score` out of −1…1, undecodable image | `detail` names the field |
| 503 | `/image`: this deployment has no embedding model | embed client-side and use `/image-vector`; `GET /api/health` → `image_vectors.model_present` says whether this can happen |
## Good to know