{"openapi":"3.1.0","info":{"title":"Vehicle ReID service","description":"Формирование цифрового признака ТС и поиск по галерее. OCR и ввод номера не применяются; область пластины остаётся частью кадра.","version":"0.2.0"},"paths":{"/api/demo":{"get":{"tags":["client"],"summary":"Demo Catalog","description":"Available approved examples, empty when the local dataset is absent.","operationId":"demo_catalog_api_demo_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoCatalog"}}}}}}},"/api/demo/{example_id}/image":{"get":{"tags":["client"],"summary":"Demo Image","operationId":"demo_image_api_demo__example_id__image_get","parameters":[{"name":"example_id","in":"path","required":true,"schema":{"type":"string","title":"Example Id"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/materials":{"get":{"tags":["client"],"summary":"Material Catalog","description":"List only files actually installed by the reviewed delivery bundle.","operationId":"material_catalog_api_materials_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MaterialCatalog"}}}}}}},"/materials/{material_id}":{"get":{"tags":["client"],"summary":"Material File","operationId":"material_file_materials__material_id__get","parameters":[{"name":"material_id","in":"path","required":true,"schema":{"type":"string","title":"Material Id"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health":{"get":{"tags":["service"],"summary":"Health","description":"Состояние сервиса: модель в памяти, доступность и наполнение хранилища.","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Api Health Get"}}}}}}},"/api/version":{"get":{"tags":["service"],"summary":"Version","description":"Версия сервиса, состав конвейера и численные параметры.","operationId":"version_api_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Version Api Version Get"}}}}}}},"/api/embed":{"post":{"tags":["inference"],"summary":"Embed","description":"Извлечь вектор признака ТС из изображения по bbox (тот же конвейер,\nчто и в пакетном прогоне).","operationId":"embed_api_embed_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_embed_api_embed_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search":{"post":{"tags":["inference"],"summary":"Search","description":"Найти в галерее кандидатов на то же ТС; при отсутствии уверенного\nсовпадения — пустой ответ (режим отказа).","operationId":"search_api_search_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_search_api_search_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search/vector":{"post":{"tags":["inference"],"summary":"Search By Vector","description":"Поиск кандидатов по готовому вектору (например, из /api/embed).","operationId":"search_by_vector_api_search_vector_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ui/state":{"get":{"tags":["client"],"summary":"Ui State","description":"Всё, что тонкому клиенту нужно знать до первого запроса.\n\nОдин вызов вместо трёх: клиент должен уметь объяснить пользователю, почему\nпоиск сейчас не выполнить (хранилище не поднято, галерея не загружена),\nи знать, доступны ли картинки и объяснения.","operationId":"ui_state_api_ui_state_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UIState"}}}}}}},"/api/gallery/{gallery_id}/crop":{"get":{"tags":["client"],"summary":"Gallery Crop","description":"Изображение объекта галереи: сам объект или кадр целиком с рамкой.\n\nНужен клиенту, чтобы показывать кандидатов картинками, а не строками\nидентификаторов. Рамка берётся из того же payload, по которому шёл поиск.","operationId":"gallery_crop_api_gallery__gallery_id__crop_get","parameters":[{"name":"gallery_id","in":"path","required":true,"schema":{"type":"string","title":"Gallery Id"}},{"name":"view","in":"query","required":false,"schema":{"type":"string","pattern":"^(crop|frame)$","description":"crop — объект, frame — весь кадр","default":"crop","title":"View"},"description":"crop — объект, frame — весь кадр"},{"name":"size","in":"query","required":false,"schema":{"type":"integer","maximum":1600,"minimum":64,"description":"длинная сторона результата","default":320,"title":"Size"},"description":"длинная сторона результата"}],"responses":{"200":{"description":"кроп объекта галереи или кадр с рамкой","content":{"image/jpeg":{}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/explain":{"post":{"tags":["client"],"summary":"Explain","description":"На что модель смотрела, сопоставляя запрос с этим кандидатом.\n\nНе приближение и не Grad-CAM: голова сети после глобального пулинга\nаффинна, поэтому косинус раскладывается по позициям карты признаков ТОЧНО,\nза один прогон сети (вывод и проверки — 04-solution/explainability/).\nВозвращаются обе карты и невязка разложения — оператор видит и картинку,\nи меру её достоверности.\n\nРаботает на ПЕРВОЙ модели конвейера (OSNet-AIN, config.MODEL_PATH) — это\nзафиксировано осознанно: разложение опирается на аффинную голову именно\nеё графа, а возвращаемый cos — на шкале признаков OSNet, а не на шкале\nпоиска (d1_j48: whitening-ансамбль). На выдачу поиска не влияет: отдельный\nметод, отдельная сессия, вызывается только по явному действию оператора.","operationId":"explain_api_explain_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_explain_api_explain_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplainResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Body_embed_api_embed_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"кадр JPEG/PNG"},"x":{"type":"integer","title":"X"},"y":{"type":"integer","title":"Y"},"w":{"type":"integer","title":"W"},"h":{"type":"integer","title":"H"}},"type":"object","required":["file","x","y","w","h"],"title":"Body_embed_api_embed_post"},"Body_explain_api_explain_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"кадр запроса JPEG/PNG"},"x":{"type":"integer","title":"X"},"y":{"type":"integer","title":"Y"},"w":{"type":"integer","title":"W"},"h":{"type":"integer","title":"H"},"gallery_id":{"type":"string","title":"Gallery Id","description":"кандидат из /api/search"}},"type":"object","required":["file","x","y","w","h","gallery_id"],"title":"Body_explain_api_explain_post"},"Body_search_api_search_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"кадр JPEG/PNG"},"x":{"type":"integer","title":"X"},"y":{"type":"integer","title":"Y"},"w":{"type":"integer","title":"W"},"h":{"type":"integer","title":"H"},"top_k":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Top K","default":10},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold"}},"type":"object","required":["file","x","y","w","h"],"title":"Body_search_api_search_post"},"Candidate":{"properties":{"gallery_id":{"type":"string","title":"Gallery Id","description":"image_id объекта галереи"},"confidence":{"type":"number","title":"Confidence","description":"косинусная близость, [-1, 1]"}},"type":"object","required":["gallery_id","confidence"],"title":"Candidate"},"DemoBox":{"properties":{"x":{"type":"integer","title":"X"},"y":{"type":"integer","title":"Y"},"w":{"type":"integer","title":"W"},"h":{"type":"integer","title":"H"}},"type":"object","required":["x","y","w","h"],"title":"DemoBox"},"DemoCatalog":{"properties":{"examples":{"items":{"$ref":"#/components/schemas/DemoExample"},"type":"array","title":"Examples"}},"type":"object","required":["examples"],"title":"DemoCatalog"},"DemoExample":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"bbox":{"$ref":"#/components/schemas/DemoBox"},"image_url":{"type":"string","title":"Image Url"}},"type":"object","required":["id","label","bbox","image_url"],"title":"DemoExample"},"EmbedResponse":{"properties":{"dim":{"type":"integer","title":"Dim"},"embedding":{"items":{"type":"number"},"type":"array","title":"Embedding","description":"L2-нормированный вектор признака"}},"type":"object","required":["dim","embedding"],"title":"EmbedResponse"},"ExplainResponse":{"properties":{"gallery_id":{"type":"string","title":"Gallery Id"},"cos":{"type":"number","title":"Cos","description":"близость пары запрос-кандидат"},"grid":{"items":{"type":"integer"},"type":"array","title":"Grid","description":"размер карты признаков [H, W]"},"query":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Query","description":"вклад позиций карты ЗАПРОСА в cos, в единицах близости"},"gallery":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Gallery","description":"то же со стороны кандидата"},"bias":{"additionalProperties":{"type":"number"},"type":"object","title":"Bias","description":"свободный член разложения"},"residual":{"additionalProperties":{"type":"number"},"type":"object","title":"Residual","description":"невязка «сумма вкладов + свободный член − cos»; разложение точное, ожидается уровень округления float32"},"ms":{"type":"number","title":"Ms","description":"время расчёта пары на сервере"}},"type":"object","required":["gallery_id","cos","grid","query","gallery","bias","residual","ms"],"title":"ExplainResponse","description":"Точное разложение косинуса по позициям карты признаков (13x13)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"MaterialCatalog":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MaterialItem"},"type":"array","title":"Items"},"deployment_status":{"type":"string","title":"Deployment Status"}},"type":"object","required":["items","deployment_status"],"title":"MaterialCatalog"},"MaterialItem":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"url":{"type":"string","title":"Url"},"bytes":{"type":"integer","title":"Bytes"},"sha256":{"type":"string","title":"Sha256"}},"type":"object","required":["id","label","url","bytes","sha256"],"title":"MaterialItem"},"SearchResponse":{"properties":{"refusal":{"type":"boolean","title":"Refusal","description":"true — уверенного совпадения нет, список пуст"},"threshold":{"type":"number","title":"Threshold","description":"применённый порог отказа"},"best_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Confidence","description":"близость лучшего кандидата до порога (видна и при отказе)"},"candidates":{"items":{"$ref":"#/components/schemas/Candidate"},"type":"array","title":"Candidates"}},"type":"object","required":["refusal","threshold","best_confidence","candidates"],"title":"SearchResponse"},"UIState":{"properties":{"service":{"type":"string","title":"Service"},"model":{"type":"string","title":"Model"},"score_scale":{"type":"string","title":"Score Scale"},"default_threshold":{"type":"number","title":"Default Threshold"},"storage_reachable":{"type":"boolean","title":"Storage Reachable"},"gallery_points":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gallery Points"},"images_available":{"type":"boolean","title":"Images Available","description":"каталог кадров смонтирован — можно показывать кропы"},"explain_available":{"type":"boolean","title":"Explain Available","description":"разложение близости по областям доступно"}},"type":"object","required":["service","model","score_scale","default_threshold","storage_reachable","gallery_points","images_available","explain_available"],"title":"UIState","description":"Состояние для тонкого клиента одним запросом."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VectorQuery":{"properties":{"vector":{"items":{"type":"number"},"type":"array","title":"Vector","description":"вектор признака размерности 512"},"top_k":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Top K","default":10},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold","description":"порог отказа; по умолчанию — порог сервиса"}},"type":"object","required":["vector"],"title":"VectorQuery"}}}}