> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/sdks/backend-sdk/ocr/installation/installation_instructions.md).

# Instalación y despliegue del servicio

## 1. Instalación y despliegue

El servicio está dockerizado, y existe una imagen Docker en un repositorio de Facephi. Para poder descargar la imagen debe iniciar sesión de la siguiente manera:

```
docker login facephicorp.jfrog.io
user: username
pass: token
```

Descargue la imagen:

```bash
docker pull facephicorp.jfrog.io/docker-pro-fphi/facephi-ocr-service:#VERSION#
```

Donde `#VERSION#` es el número de versión que queremos descargar (p. ej. `6.8.2`).

## 2. docker-compose

Una forma de desplegar el servicio es crear un fichero `docker-compose.yml` con el siguiente contenido:

```yaml
version: '3.7'

services:
  ocr-service:
    image: facephicorp.jfrog.io/docker-pro-fphi/facephi-ocr-service:#VERSION#
    container_name: facephi-ocr-service
    ports:
      - "6982:6982"
    environment:
      # Optional JWT protection
      # - FACEPHI_OCR_REST_AUTH_ENABLED=true
      # - FACEPHI_OCR_REST_AUTH_JWT_SECRET=shared-secret
      # - FACEPHI_OCR_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER=true
      # - FACEPHI_OCR_REST_AUTH_ACCEPT_API_KEY_HEADER=false
      # - FACEPHI_OCR_REST_AUTH_API_KEY_HEADER_NAME=x-api-key
    volumes:
      - ~/facephi_ocr_license:/service/license
      - ~/facephi_ocr_configuration:/service/config
      - ~/facephi_ocr_logs:/service/logs
      - ~/facephi_ocr_custom_templates:/service/custom_templates
```

Observe el volumen que se monta en el contenedor. Este volumen se utiliza para almacenar el fichero de licencia. El volumen `facephi_ocr_configuration` es opcional, pero permite configurar el servicio. Consulte la sección `2.2 Service`. El volumen `facephi_ocr_logs` es opcional, pero permite guardar los logs en el almacenamiento local, evitando perderlos cuando el contenedor Docker se detiene. El volumen `facephi_ocr_custom_templates` es opcional, pero permite añadir plantillas de documentos personalizadas. Puede copiar sus plantillas personalizadas en esta carpeta y luego configurar el servicio para que las utilice. Consulte la sección `3.2 Service`.

Ejecute el siguiente comando, dentro de la carpeta donde se encuentra el fichero docker-compose.yml, para desplegar el servicio:

```bash
docker compose up
```

## 3. Configuración de la licencia

Para utilizar este servicio, necesita disponer de un fichero de licencia válido.

El fichero de licencia podría contener la siguiente información:

```init
LICENSE_TYPE=         # License type, can be MACHINE, SHARED or LOCAL
LICENSE_BEHAVIOUR=    # License behaviour, can be ONLINE or OFFLINE
LICENSE_KEY=          # License key
LICENSE_ID=           # Product ID
LICENSE_DATA=         # Product data
LICENSE_URLS=         # Comma-separated license server URLs. Only needed if LICENSE_TYPE is LOCAL
LICENSE_PATH_OFFLINE= # Local file with data for offline activation. Only needed if LICENSE_TYPE=MACHINE and LICENSE_BEHAVIOUR=OFFLINE
```

El fichero de licencia puede pasarse como parámetro al servicio. Por defecto, el servicio buscará un fichero llamado `/service/license/license.lic`. En el caso del contenedor Docker, el fichero de configuración podría ubicarse en un volumen montado en `/service/license`.

Para poder conectar con nuestros servidores de licencias, debe añadir a las reglas de su firewall las siguientes reglas:

| IP           | Puerto | Tipo   |
| ------------ | ------ | ------ |
| 52.223.22.71 | 443    | TCP/IP |
| 35.71.188.31 | 443    | TCP/IP |
| 75.2.113.112 | 443    | TCP/IP |
| 99.83.149.57 | 443    | TCP/IP |

A continuación, añada las siguientes URLs a su lista blanca:

* <https://api.cryptlex.com:443>
* <https://api.eu.cryptlex.com:443>

## 4. Configuración del servicio

El fichero de configuración podría contener la siguiente información por defecto:

```json
{
    "port": 6982,                     # Service port number.

    # The number of used by the REST service, 1 by default.
    # If the value is set to 0, the number of threads is autodetected.
    "number_of_threads": 1,

    "connection_timeout": 60,         # The lifetime of the connection without read or write.

    # Set the maximum number of requests that can be served through one keep-alive connection.
    # After the maximum number of requests are made, the connection is closed.
    # The default value of 0 means no limit.
    "keep_alive_request_number": 0,

    # The maximum size of the body allowed in the requests in Mb. The default value of 100 Mb.
    "client_max_body_size": 100,

    "logger_path": "./logs",         # Set the path to store log files.
    "logger_level": "trace",         # Possible values are [trace|debug|info|warning|error|critical|off].
    "logger_rotation": "daily",      # Possible values are [hourly|daily].
    "logger_max_files": 31,          # The default value of 0 means no limit.

    "auth_enabled": false,          # Enable JWT protection for non-public endpoints.
    "auth_jwt_secret": "",         # Shared secret used to validate HS256 JWT tokens.
    "auth_accept_authorization_header": true,
    "auth_accept_api_key_header": false,
    "auth_api_key_header_name": "x-api-key",

    # Folder containing the models, templates and other and resources.
    "config_path": "data",

    # Path to the folder that contains the templates.
    "templates_path": "data/templates",

    # Version of the document interpreter to use. 1 legacy version, 2 new version. By default, it is set to 1.
    "document_interpreter_version": 1,

    # By default, it is 0 (use legacy output format). If 1, use universal one.
    "document_interpreter_use_universal": 0,

    # The number of threads in the pool for processing document images in parallel.
    # By default, it is set to 2. If the value is set to 0, the number of threads is autodetected.
    "processor_threads_pool_size": 2,

    # The number of threads in the flow pool for processing inferences in parallel when executing the pipeline.
    "pipeline_threads_pool_size": 1,

    # The number of threads in the pool for creating interpreters in parallel.
    "global_threads_pool_size": 1,

    # Maximum number of threads used during inference. If 0, use as many threads as cores.
    "max_inference_threads": 0,

    # Number of OCR regions of interest that can be processed concurrently.
    "ocr_latin_batch_size": 1,

    # Multi service configuration
    "multi_service_base_url": "http://localhost", # Base URL of the remote multi service.
    "multi_service_api_key": "fake_key",          # API key for authenticating with the remote multi service.
    "multi_service_connection_timeout": 10000,    # Connection timeout in milliseconds for requests to the remote multi service.
    "multi_service_request_timeout": 60000,       # Request timeout in milliseconds for requests to the remote multi service.
    "multi_service_max_retries": 3,               # Maximum number of retries to the remote multi service.
    "multi_service_verify_ssl": true              # Whether to verify SSL certificates when connecting to the remote multi service.
}
```

El fichero de configuración puede pasarse como parámetro al servicio. Por defecto, el servicio buscará un fichero llamado `/service/config/config.json`. En el caso del contenedor Docker, el fichero de configuración podría ubicarse en un volumen montado en `/service/config`.

Todos los parámetros son opcionales. Si algún parámetro no está presente, se utilizará el valor por defecto en su lugar.

La autenticación JWT es opcional y está deshabilitada por defecto. Los ajustes de arranque anteriores también pueden proporcionarse mediante variables de entorno con el prefijo `FACEPHI_OCR_REST_AUTH_`:

* `FACEPHI_OCR_REST_AUTH_ENABLED`
* `FACEPHI_OCR_REST_AUTH_JWT_SECRET`
* `FACEPHI_OCR_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER`
* `FACEPHI_OCR_REST_AUTH_ACCEPT_API_KEY_HEADER`
* `FACEPHI_OCR_REST_AUTH_API_KEY_HEADER_NAME`

Cuando el JWT está habilitado, `GET /api/v1/version` y `GET /api/v1/health` permanecen públicos. El resto de los endpoints requieren un JWT válido mediante `Authorization: Bearer <jwt>` o la cabecera de API key configurada.

Los ajustes de arranque de JWT se aplican únicamente cuando el servicio se inicia. `GET /api/v1/config` no expone estos campos y `POST /api/v1/config` rechaza los intentos de modificarlos.

### 4.1. `document_interpreter_version`

Existen dos intérpretes distintos disponibles para el procesamiento de documentos de identidad y documentos de extranjería.

Estos intérpretes se diferencian en los siguientes aspectos:

* Países admitidos
* Formato de salida
* Campos disponibles

#### Países admitidos

Versión 1:

* Argentina (ARG)
* México (MEX)

La versión 2 admite oficialmente un conjunto más amplio de países, entre ellos:

* Argentina (ARG)
* Bolivia (BOL)
* Brasil (BRA)
* Canadá (CAN)
* Chile (CHL)
* Colombia (COL)
* Costa Rica (CRI)
* República Dominicana (DOM)
* Ecuador (ECU)
* El Salvador (SLV)
* Guatemala (GTM)
* Honduras (HND)
* Jordania (JOR)
* México (MEX)
* Nicaragua (NIC)
* Nigeria (NGA)
* Panamá (PAN)
* Paraguay (PRY): PRY I v3, PRY I v2
* Perú (PER): PER I v5, PER I v2
* Sudáfrica (ZAF)
* Corea del Sur (KOR)
* España (ESP)
* Uganda (UGA)
* Uruguay (URY)
* Vietnam (VNM)

#### Formato de salida

Cada versión estructura sus datos de salida de forma diferente.

La versión 1 organiza los datos extraídos utilizando las claves `front` y `back` para distinguir entre el anverso y el reverso del documento:

```json
{
    "back": {
        "Address": "REDACTED",
        ...
    },
    "front": {
        "DateOfBirth": "01/09/1972",
        ...
    }
}
```

La versión 2, por su parte, utiliza una estructura anidada bajo la clave `reader`, con identificadores numéricos para representar cada cara del documento (0 para el anverso y 1 para el reverso), junto con claves de tipo ruta más detalladas:

```json
{
    "reader": {
        "0/MRZ/DateOfBirth": "01/09/1972",
        ...
        "1/ML/Address": "Redacted",
        ...
    }
}
```

La versión 2 también admite la salida universal (`document_interpreter_use_universal=1`)

#### Campos disponibles

Además de las variaciones en la estructura de datos, puede haber diferencias en los propios campos. Algunos campos pueden existir solo en un formato y, aunque un campo aparezca en todos los formatos, su contenido puede cambiar.
