Documentación de API de lectura de datos
Esta página trata sobre la creación de software para recuperar datos y metadatos de pruebas unitarias y de inspección de Instrumental. Se supone que tienes acceso a un proyecto instrumental que contiene datos.
Tabla de contenidos
Claves API
Para recuperar datos, necesitará una clave API con permisos de "lectura". Puede leer sobre las claves API y cómo obtenerlas en la página de claves API.
API de lectura de datos
Dominio/punto final
Realice una solicitud HTTPPOST
ahttps://api.instrumental.ai/api/v0/data
.
Trabaja con tus equipos de redes para desbloquear TCP en el puerto 443 (acceso HTTPS) para este dominio en cualquier red en la que se ejecute tu script. El dominio no tiene una dirección IP fija ni un rango de IP, por lo que el dominio en sí debe estar permitido. Si es necesario, Instrumental puede analizar la configuración de un proxy con una IP fija.
Las solicitudesdebentener los siguientes encabezados:
clave-api-instrumental: YOUR_API_KEY
tipo de contenido: aplicación/json
Por supuesto, reemplace YOUR_API_KEY
con su clave completa real (debe contener INST:V1
; no use solo el identificador que se muestra en el modal Claves API).
Límites predeterminados
Los clientes tienen un límite de velocidad de 50 solicitudes de ingesta rellenadas a una velocidad de 5 por segundo, compartidas entre todos los puntos finales de API de lectura. Esto permite cierta capacidad de ráfaga si necesita enviar más solicitudes durante un período breve. En algunas circunstancias, se pueden aplicar límites de tarifaspor sitio de fábrica. Si se excede el límite de tasa, las solicitudes se rechazarán con un error 429 Demasiadas solicitudes hasta que el depósito de límite de tasa se rellene lo suficiente para que lleguen nuevas solicitudes.
Las solicitudes pueden tener hasta 4 MB. Las solicitudes más grandes se rechazarán con un error 413 Demasiado grande . Es poco probable que esto suceda durante el uso normal, pero podría suceder si envía filtros con una gran cantidad de valores.
Si espera exceder estos límites, hable con su representante de Instrumental.
Solicitar
El punto final acepta un cuerpo JSON con esta estructura. Todos los campos son opcionales (pero si omite todos los campos, aún debe enviar un objeto JSON vacío{}
):
{
"formato": "UNIT_JSON",
"paginación": {
"count": 100,
"offsetPageId": "0123456789abcdef"
},
"filtros": {
"antes": "2022-05-25T00:26:02.901Z",
"after": "2022-04-25T00:26:02.901Z",
"serialNumbers": ["SN123"],
"stationNames": ["Finished Good"],
"fixtureNames": ["DFX-INST-0101"],
"lineNames": ["Línea 1"]
}
}
formato: UNIT_JSON
o UNIT_CSV
o INSPECTION_CSV
Indica cómo se formatearán los datos en la respuesta API (consulte la sección "Respuesta" a continuación). El formulario JSON (que es el predeterminado) es útil si desea hacer algo con la respuesta en el código. Los formatos CSV son útiles si desea que los archivos CSV estén disponibles para que los humanos los manipulen o, a veces, si desea cargar los datos a otro sistema que funcione con datos planos/tabulares.
paging.count: entero positivo
Aproximadamente cuántos registros se devolverán en la respuesta (el valor predeterminado es 100, máximo 1000). Para los formatos UNIT_JSON
y UNIT_CSV
, devolveremos esta cantidad de unidades a menos que haya menos unidades disponibles en la página solicitada. Para el formato INSPECTION_CSV
, agregamos inspecciones a la respuesta una unidad a la vez y nos detenemos cuando el número de inspecciones es mayor o igual al recuento especificado.
paging.offsetPageId: string
Cada solicitud tendrá un valor nextPageId
como parte de la respuesta, a menos que no haya más páginas para devolver (consulte la sección "Respuesta" a continuación). Pase ese valor a este parámetro para que la siguiente solicitud recupere la siguiente página de resultados. Asegúrese de que sus filtros no cambien entre solicitudes de páginas posteriores.
filtros
Cada filtro se aplica a la entidad especificada en el formato
. Para los formatos UNIT_JSON
y UNIT_CSV
, devolveremos todos los datos de cada unidad que coincida con los filtros, incluso si algunos de los datos de la unidad no coinciden con los filtros. Por ejemplo, dada una unidad con dos inspecciones, una el 2022-05-22 y otra el 2022-05-24, la solicitud { "format": "UNIT_CSV", "filters": { "before": "2022-05-23" } }
dará como resultado un registro de unidad que incluya ambas inspecciones. Para el formato INSPECTION_CSV
, devolveremos solo las inspecciones que coincidan con los filtros (en este ejemplo, solo la del 22 de mayo de 2022).
filters.before: cadena de fecha y hora ISO 8601
Solo se devolverán los registros con datos anteriores a esta fecha (exclusiva). La fecha debe estar en formatoISO 8601, es decir:“AAAA-MM-DDTHH:mm:ss.SSSZ”.
filters.after: cadena de fecha y hora ISO 8601
Solo se devolverán los registros con datos posteriores a esta fecha (exclusiva). La fecha debe estar en formatoISO 8601, es decir:“AAAA-MM-DDTHH:mm:ss.SSSZ”.
filters.serialNumbers: array[string]
Solo se devolverán los registros de las unidades que coincidan con estos números de serie. Los números de serie deben coincidir con los identificadores de Tiendas de instrumentos; este filtro no considera números de serie de conjuntos relacionados. Si no está seguro de qué número de serie de componente utiliza Instrumental para representar el ensamblaje final, inicie sesión en la aplicación web o consulte con su representante de Instrumental.
filters.stationNames: array[string]
Solo se devolverán registros con datos de estos nombres de estaciones.
filters.fixtureNames: array[string]
Solo se devolverán registros con datos de estos nombres de dispositivos.
filters.lineNames: array[string]
Solo se devolverán registros con datos de estas líneas.
Solicitud de ejemplo
Aquí hay una solicitud básica a través de cURL:
curl -v -XPOST --data '{"format": "UNIT_CSV"}' -H 'clave-api-instrumental: YOUR_API_KEY' -H 'tipo-contenido: aplicación/json' https://api.instrumental.ai/api/v0/data
Aquí está la misma solicitud en Python usando la solicitudes biblioteca:
solicitudes de importación
importar json
url = "https://api.instrumental.ai/api/v0/data"
json_data = json.dumps({ "format": "UNIT_CSV" })
headers = {
"content-type": "application/json",
"instrumental-api-key": "TU_API_KEY",
}
respuesta = request.post(url, data=json_data, headers=headers)
print(response.text)
print(response.status_code)
(Asegúrate de reemplazar YOUR_API_KEY
con tu clave API real si quieres probar esto).
Respuesta
Si la solicitud tiene éxito, la respuesta tendrá un código de estado HTTP de 200. Las solicitudes fallidas recibirán uno de los siguientes códigos de estado HTTP:
- 400: error al analizar el cuerpo de entrada o valores no válidos (por ejemplo, un valor negativo para
paging.count
) - 401 – Clave API no válida en el encabezado
- 413: la solicitud es demasiado grande; consulte la sección Límites predeterminados
- 429 – Límites de tasa excedidos; consulte la sección Límites predeterminados
- 500 – Error del servidor
El cuerpo de la respuesta para una solicitud exitosa (código de estado 200) depende del formato
especificado en la solicitud.
Para los formatos UNIT_CSV
y INSPECTION_CSV
, la respuesta tendrá el tipo de contenido text/csv
(puede guardarlo directamente en un archivo y abrirlo en Excel). Todos los mismos datos estarán presentes como en formato JSON (metadatos de unidad, marcas de tiempo, resultados de pruebas, etc.), pero presentados en una tabla plana. El valor que necesita pasar a offsetPageId
para obtener la siguiente página de resultados se devuelve en el Instrumental-Next-Page-Id
encabezado.
El formato UNIT_JSON
produce una respuesta como esta:
{
"unidades": [
{
"id": "0123456789abcdef",
"serialNumber": "SN123",
"buildName": "PVT",
"configName": "SKU1",
"subconjuntos": [
{
"serialNumber": "PCB456",
"relationshipName": "PCB",
"subassemblySerialNumbers": ["BATT789"]
},
{
"serialNumber": "BATT789",
"relationshipName": "Batería"
}
],
"lineName": "Línea 1",
"url": "https://app.instrumental.ai/explore/inspect?project=your-project&serial=SN123",
"data": [
{
"id": "123456789abcdef0",
"inspectionId": "23456789abcdef01",
"name": "Prueba de batería",
"value": {
"boolean": verdadero
},
"limits": {
"in.datatypes.measurementlimit.BooleanMeasurementLimit": {
"trueIsPassing": verdadero
}
}
},
{
"id": "3456789abcdef012",
"parentId": "123456789abcdef0",
"inspectionId": "23456789abcdef01",
"name": "Voltaje de la batería",
"value": {
"double": 3.791
},
"limits": {
"in.datatypes.measurementlimit.NumberMeasurementLimit": {
"passingUpperBound": 3.9,
"passingLowerBound": 3.75
}
}
},
{
"id": "456789abcdef0123",
"inspectionId": "56789abcdef01234",
"name": "Separación del gabinete 1",
"value": {
"dfx.schemas.api.searchdata.APISearchDataImageFeature": {
"value": 0.17,
"measuredFileId": "6789abcdef012345",
"featureType": "PERPENDICULAR"
}
}
},
{
"id": "789abcdef0123456",
"inspectionId": "56789abcdef01234",
"name": "Falta tornillo",
"value": {
"dfx.schemas.api.searchdata.APISearchDataMonitorResult": {
"pass": false,
"analyzedFileId": "6789abcdef012345",
"ejecutor": "ESTACIÓN"
}
}
}
],
"imageConfigs": {
"Color": "Azul",
"Bluetooth": "Sí"
},
"tags": ["Modificado por Joe"],
"files": [
{
"id": "6789abcdef012345",
"inspectionId": "56789abcdef01234",
"nombre": "Foto de PCB",
"tipo": "FOTO"
}
],
"inspecciones": [
{
"id": "23456789abcdef01",
"marca de tiempo": "2022-05-25T03:22:28.556Z",
"stationName": "Prueba final"
},
{
"id": "56789abcdef01234",
"timestamp": "2022-05-25T02:21:28.553Z",
"stationName": "PCB",
"subassemblySerialNumber": "PCB456"
}
]
}
],
"paging": {
"nextPageId": "89abcdef01234567"
}
}
Si la solicitud no es una forma válida, el cuerpo de la respuesta describirá lo que está mal. Por ejemplo, si intenta enviar una cadena a paging.count
en lugar de un número, es posible que vea un mensaje como este:
{"error":"No se pudo analizar el cuerpo de la solicitud con el formato JSON esperado.","reason":"ERROR :: /paging/count :: 1 no se puede convertir en entero"}
Si la solicitud es una forma válida pero los valores no son válidos, obtendrás un formato diferente:
{"code":"INVALID_INPUT","msg":"Valor negativo para el recuento"}
Orden de clasificación y paginación
Los resultados se ordenan aproximadamente por "los más recientes primero". En concreto, las inspecciones se clasifican en el siguiente orden:
- Inspecciones de imágenes y vídeos antes de las inspecciones de datos
- Marca de tiempo (el más reciente primero)
Las unidades se clasifican según el momento de su inspección más alta (por ejemplo, su inspección más reciente) según el orden anterior.
Puede pensar ennextPageId
/offsetPageId
como un hash de la última marca de tiempo + tipo de inspección visto en la página anterior. Las páginas siguientes básicamente usan esto para filtrar las páginas anteriores. Este filtrado se realiza en el momento de la solicitud, por lo que los resultados pueden ser inestables si los datos cambian. Específicamente, es posible perderse una unidad o inspección si llegan nuevos datos mientras busca, pero las unidades/inspecciones no aparecerán más de una vez.
Errores de revisión
Lassolicitudes de API que se autentican correctamente (es decir, que tienen un encabezado instrumental-api-key
válido y no tienen una tasa limitada) pero que fallan en otra validación (por ejemplo, el cuerpo de la solicitud no es válido) serán accesibles temporalmente para su depuración a través del modo de clave API. Puede leer más sobre esto en la página de claves API.