Contenido


Utilizar los servicios de Bluemix para crear una aplicación basada en el navegador para almacenar y buscar PDFs, Parte 1

Utilice los servicios de Conversión de Documentos y Extracción de Palabras Clave para convertir e indexar archivos

Comments

Contenido de la serie:

Este contenido es la parte # de # de la serie: Utilizar los servicios de Bluemix para crear una aplicación basada en el navegador para almacenar y buscar PDFs, Parte 1

Manténgase en contacto por contenidos adicionales de esta serie.

Este contenido es parte de la serie:Utilizar los servicios de Bluemix para crear una aplicación basada en el navegador para almacenar y buscar PDFs, Parte 1

Manténgase en contacto por contenidos adicionales de esta serie.

Si usted es como yo, ahora mismo probablemente tendrá cientos de documentos en su computadora. Documentos que ha creado, que le han debido revisar, que ha copiado como parte de diferentes proyectos... y la lista continúa. Los obtiene a través del email, en conversaciones de Slack y como descargas de sitio web... y cuantos más tiene, más crece su pajar y más difícil es encontrar las agujas que necesita, cuando las necesita.

Con los actuales servicios de Watson y Bluemix services, es posible crear una útil aplicación para el almacenamiento de documentos con total soporte para la búsqueda de palabras clave.

Aquí es donde este artículo entra en juego. En la Parte 1 de esta serie de dos partes, le muestro cómo crear una poderosa aplicación basada en el navegador para almacenar y buscar documentos, que hace más rápida y fácil la búsqueda de contenido relevante en su pajar de documentos. A través de este proceso, también le presento algunos servicios nuevos e interesantes de IBM® Watson y le guío a través del proceso de alojar la aplicación final en IBM Bluemix™.

¿Le parece interesante? ¡Siga leyendo!

Ejecutar la aplicaciónObtener el código en GitHub

La aplicación de ejemplo descrita en este artículo permite que los usuarios seleccionen y suban documentos PDF desde su computadora a un almacén de documentos online. Según se cargan los documentos, son escaneados de forma automática e inteligente en busca de palabras clave, y dichas palabras clave son extraídas y almacenadas en una base de datos. Más tarde, los usuarios pueden buscar por palabra clave para identificar y descargar rápidamente documentos que sean relevantes para sus necesidades. No hace falta decir que la aplicación está optimizada para móviles y se pueden utilizar apropiadamente en teléfonos inteligentes y en computadoras de escritorio.

En un segundo plano, la aplicación funciona coordinando varios servicios, algunos están disponibles directamente a través de IBM Bluemix y otros como servicios de terceros. Aquí tiene una lista breve:

Por el lado del cliente, para la aplicación estoy utilizando Bootstrap para crear una interfaz de usuario fácil de usar en móviles. Por el lado del servidor, estoy utilizando la microinfraestructura Slim PHP para gestionar el flujo de la aplicación y MongoDB para almacenar la lista de palabras clave. IBM Bluemix aloja la aplicación y conecta a los tres servicios enumerados previamente para procesar y almacenar los documentos.

Qué necesitará

Aquí se utilizan muchas tecnologías, así que aquí tiene lo que necesitará:

Nota: Cualquier aplicación que utilice el servicio AlchemyAPI debe cumplir los Términos y Condiciones de AlchemyAPI. De igual manera, cualquier aplicación que utilice los servicios Document Conversion y Object Storage debe cumplir todos los términos de utilización del servicio, como se describen en las páginas del catálogo de servicios. Antes de comenzar su proyecto, pase unos minutos leyendo estos requisitos y asegúrese de que su aplicación cumple con ellos.

Crear la aplicación básica

El primer paso es crear una aplicación básica que contenga la microinfraestructura Slim PHP y otras dependencias variadas, como OpenStack SDK para PHP y el cliente Guzzle HTTP, ambas son necesarias para interactuar con los variados servicios descritos anteriormente. Es posible descargar e instalar fácilmente estos servicios utilizando Composer, el administrador de dependencias PHP. Utilice este archivo de configuración de Composer, que deberá salvar en $APP_ROOT/composer.json donde $APP_ROOT hace referencia al directorio de su proyecto.

{
    "require": {
        "php-opencloud/openstack": "*",
        "slim/slim": "*",
        "slim/php-view": "*",
        "guzzlehttp/guzzle": "~6.0"
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

Instale Slim y los otros componentes necesarios utilizando Composer con el comando:

  shell> php composer.phar install

Después, cree los directorios $APP_ROOT/public para todos los archivos accesibles por la web, $APP_ROOT/views para todas las vistas y $APP_ROOT/config.php para la información de la configuración. Deberá acabar con una estructura de directorio parecida a esta:

Figura 1. Estructura de archivos de la aplicación
Application file structure

También deberá añadir la información de la conexión de su MongoDB al archivo $APP_ROOT/config.php siguiendo el ejemplo de abajo:

<?php
$config['settings']['db']['uri'] = "mongodb://USERNAME:PASSWORD@HOST:PORT/DATABASE";

Para facilitar el acceso a la aplicación, es posible definir un nuevo alojamiento virtual en el entorno de desarrollo y apuntar su raíz de documentos a $APP_ROOT. Este paso, aunque es opcional, se recomienda porque crea una réplica parecida al entorno de desarrollo del objetivo de Bluemix.

Para establecer un alojamiento virtual identificado para la aplicación en Apache, abra el archivo de configuración de Apache (httpd.conf or httpd-vhosts.conf) y añada estas líneas:

NameVirtualHost 127.0.0.1
<VirtualHost 127.0.0.1>
    DocumentRoot "/var/www/pdf-keyword-search/public"
    ServerName pdf-keyword-search.localhost
</VirtualHost>

Estas líneas definen un alojamiento virtual nuevo http://pdf-keyword-search.localhost/, cuya raíz del documento corresponde a $APP_ROOT (recuerde actualizarlo para reflejar sus propios ajustes locales). Reinicie el servidor web para activar estos ajustes nuevos. Observe que puede tener que actualizar el servidor DNS local de su red para comunicarle el nuevo alojamiento.

Después, añada al directorio $APP_ROOT/public un archivo .htaccess con los siguientes ajustes:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

Después, establezca el script para el control principal de la aplicación. Este script carga la infraestructura Slim e inicia la aplicación Slim. También contiene devoluciones de llamada para todas las rutas de la aplicación, cada devolución de llamada define el código que se va a ejecutar cuando la ruta coincide con una solicitud entrante.

Cree el script en $APP_ROOT/public/index.php con el siguiente contenido:

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Client;

// establece un amplio límite de tiempo para la cuenta
// para cargas y tiempo de procesado de archivos grandes
set_time_limit(6000);

// incluye el autocargador y la configuración
require '../vendor/autoload.php';
require '../config.php';

// inicia la aplicación
$app = new \Slim\App($config);

// inicia el contenedor de inyección de dependencias
$container = $app->getContainer();

// añade el representador de vistas
$container['view'] = function ($container) {
  return new \Slim\Views\PhpRenderer("../views/");
};

$app->run();

Este script carga todas las clases necesarias y el archivo de configuración. Después inicia un nuevo objeto de la aplicación Slim y un contenedor de inyección de dependencias (DI), y añade el representador de la vista PHP al contenedor DI.

También tiene que construir una interfaz de usuario básica que pueda ser utilizada por las diferentes vistas representadas por la aplicación. Aquí tiene un ejemplo, que se utiliza para todas las vistas de la aplicación mostradas en las subsiguientes porciones de código:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Documents</title>
    <link rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"
    >
    <!-- corrector de HTML5 y Respond.js para la compatibilidad con IE8 de los elementos
      y consultas de media de HTML5 -->
    <!-- AVISO: Respond.js no funciona al ver la página
      a través del archivo:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js">
      </script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js">
      </script>
    <![endif]-->    
  </head>
  <body>

    <div class="container">
      <div class="panel panel-default">
        <div class="panel-heading clearfix">
          <h4 class="pull-left">Documents</h4>
        </div>
      </div>  
      

      <div>
          <!-- área de contenido principal -->
      </div>
    </div>

    <div class="container">
          <!-- área del pie de página -->
    </div>

  </body>
</html>

Esta vista instala Bootstrap desde un CDN y define una página Bootstrap básica que contiene una cabecera, un área de contenido principal y un pie de página.

Con todas las partes en su sitio, ahora puede comenzar a construir la propia aplicación.

Cree un formulario de carga de archivos

Slim trabaja mediante la definición de devoluciones de llamadas del router para los métodos y extremos del HTTP. Esto se logra simplemente llamando al método HTTP correspondiente get() para solicitudes GET, post() para solicitudes POST y así, y pasando la ruta del URL a ser emparejado como primer argumento para el método. El segundo argumento para el método es una función que especifica las acciones a llevar a cabo cuando la ruta coincide con una solicitud entrante.

Para ver esto en acción, cree un formulario de carga de archivos con el que los usuarios pueden subir documentos. Comience definiendo una ruta /add y la función correspondiente para la devolución de la llamada añadiendo el código de abajo a $APP_ROOT/public/index.php:

<?php
// Inicio de la aplicación Slim - recortado
// Formulario de carga
$app->get('/add', function (Request $request, Response $response) {
  $response = $this->view->render($response, 'add.phtml', 
    array('router' => $this->router));
  return $response;
})->setName('add');

En resumen, esto dice a Slim que responda a las solicitudes GET para el extremo del URL /add con el contenido del script de la vista add.phtml. Ese script de la vista, ubicado en $APP_ROOT/views/add.phtml, debería contener un código HTML, necesario para el formulario de carga de archivos, parecido a este:

<?php if (!isset($_POST['submit'])): ?>
<div>
  <form method="post" enctype="multipart/form-data" 
    action="<?php echo $data['router']->pathFor('add'); ?>">
    <input type="hidden" name="MAX_FILE_SIZE" value="300000000" />
    <div class="form-group">
      <label for="upload">File</label>
      <span class="btn btn-default btn-file">
        <input type="file" name="upload" />
      </span>
    </div>  
    <div class="form-group">
      <label for="body">Description</label>
      <textarea name="description" id="description" 
        class="form-control" rows="3"></textarea>
    </div>
  <div class="form-group">
    <button type="submit" name="submit" 
      class="btn btn-primary">Add</button>
  </div>          
  </form>
</div>
<?php endif; ?>

Esto define un formulario PHP básico para la carga de archivos (observe el tipo de codificación multipart/form-data y la variable oculta MAX_FILE_SIZE ). Incluye un campo de carga de archivos y un campo de descripción adicional para el texto especificado por el usuario.

Y ahora, cuando accede a http://pdf-keyword-search.localhost/add en su navegador, debería ver algo parecido esto:

Figura 2. Formulario de carga de archivos
File upload form
File upload form

La infraestructura para cargar archivos ya está completa. El paso siguiente es procesarlos, lo que requiere aprender más acerca de dos servicios clave: el servicio Watson Document Conversion y el servicio AlchemyAPI.

Entender y configurar el servicio Document Conversion

El procesado de un documento subido consta de cuatro pasos:

  1. Convertirlo del formato PDF a texto normalizado
  2. Analizar el texto para extraer las palabras clave
  3. Almacenar las palabras clave
  4. Almacenar el PDF cargado

El servicio de Document Conversion se ocupa de los primeros pasos. Parte del Watson Developer Cloud, brinda una API para convertir un documento de un formato a otro. Los casos de uso habituales incluyen limpiar el código de marcado HTML incorrecto y procesar el contenido a unidades JSON-formatted Answer que pueden ser usadas con otros servicios de Watson.

El servicio Document Conversion acepta como entrada documentos HTML, PDF o Microsoft Word (para este artículo, asumiré que todos los documentos son PDF) y devuelve un HTML normalizado o una versión de texto sin formato que es más fácil de analizar. Acepta las solicitudes POST hechas al extremo del servicio https://gateway.watsonplatform.net/document-conversion/api/v1. Todas las solicitudes POST deben contener el documento que va a ser convertido, como cuerpo del POST junto con un arreglo con formato JSON que indica que el formato requerido para la salida.

Para ver cómo funciona esto, inicie en Bluemix una nueva instancia del servicio Document Conversion. Inicie sesión en cuenta de Bluemix. Busque y seleccione el servicio Document Conversion .

Revise la descripción del servicio y haga clic para iniciarlo. Asegúrese de que el campo "Conectar a" se ha establecido a "Dejar independiente" y que está utilizando el "Plan Estándar". Inicialmente, esta instancia del servicio se ejecutará en un estado independiente; esto permite que la aplicación sea desarrollada localmente con la propia instancia del servicio alojada remotamente en Bluemix.

Figura 3. Inicio del servicio Document Conversion
Document Conversion service initialization
Document Conversion service initialization

Una vez hecho, se inicia la instancia del servicio y se le presenta una página de información del servicio. Despliegue la barra de navegación de la izquierda y haga clic en el enlace "Credenciales del Servicio" para ver el nombre de usuario y la contraseña de la instancia del servicio. Anote esas credenciales junto con el nombre del servicio, ya que las necesitará en los siguientes pasos.

Figura 4. Credenciales del servicio Document Conversion
Document Conversion service credentials
Document Conversion service credentials

Ahora puede probar el servicio Document Conversion, mediante la utilización de un cliente de REST como Postman para enviarle una solicitud de muestra. La imagen de abajo muestra un ejemplo de solicitud y respuesta.

Figura 5. Solicitud/respuesta de muestra para el servicio Document Conversion
Sample request and response for Document Conversion service
Sample request and response for Document Conversion service

Este también es un buen momento para copiar las credenciales de su servicio Document Conversion a la aplicación PHP. Edite el archivo $APP_ROOT/config.php y añádale las credenciales siguiendo el ejemplo de abajo:

<?php
$config['settings']['document-conversion']['user'] = "USERNAME";
$config['settings']['document-conversion']['pass'] = "PASSWORD";

Entender y configurar el servicio AlchemyAPI Keyword Extraction

Por supuesto, convertir el documento PDF al texto sin formato es sólo el comienzo. El siguiente paso es enviar la salida de texto sin formato al servicio AlchemyAPI para su análisis y extracción de palabras clave. Es posible acceder a este servicio desde el catálogo de Bluemix (como se muestra en la sección anterior) o de forma independiente mediante la solicitud de una clave de API utilizando el sitio web de AlchemyAPI.

El servicio AlchemyAPI utiliza el procesado del lenguaje natural para analizar semánticamente el texto no estructurado y devolver información sobre el mismo. Esta información puede estar relacionada con sentimientos o emociones (en el caso en el que el texto sea positivo, negativo o neutral) o como puede ser una lista de palabras clave, relaciones o conceptos extraídos que después pueden ser enlazados a noticias o a otras fuentes de información. Es un servicio increíblemente poderoso que hay que tener en el kit de herramientas cuando se trabaja con contenido de texto de cualquier tipo.

El servicio AlchemyAPI funciona aceptando las solicitudes POST que se hacen al extremo del servicio http://gateway-a.watsonplatform.net/calls/text/TextGetRankedKeywords. Todas las solicitudes POST deben contener la clave de AlchemyAPI, junto con el texto a analizar y el formato requerido para la respuesta, como un arreglo de parámetros del formulario.

Aquí hay un ejemplo de acceso a la API con un cliente de REST:

Figura 6. Solicitud/respuesta de muestra para el servicio AlchemyAPI
Sample request and response for AlchemyAPI service
Sample request and response for AlchemyAPI service

Una vez que ha tenido la oportunidad de verificar que funciona, actualice el archivo $APP_ROOT/config.php con su clave de API:

<?php
$config['settings']['alchemy']['apikey'] = "APIKEY";

Extraer las palabras clave de los documentos subidos

Una vez que ha entendido cómo funcionan los servicios Document Conversion y AlchemyAPI, es el momento de escribir el código de la aplicación que los une y guardar las palabras clave generadas en la base de datos MongoDB. Comience utilizando el contenedor DI de Slim para crear en el archivo $APP_ROOT/public/index.php las rutinas de inicio para cada servicio, además de su conexión a la base de datos MongoDB:

<?php
// Inicio de la aplicación Slim - recortado

// inicia el contenedor de inyección de dependencias
$container = $app->getContainer();

// Añade el cliente PHP de Mongo
$container['db'] = function ($container) {
  $config = $container->get('settings');
  $dbn = substr(parse_url($config['db']['uri'], PHP_URL_PATH), 1);
  $mongo = new MongoClient($config['db']['uri'], 
    array("connectTimeoutMS" => 30000));
  return $mongo->selectDb($dbn);
};

// Añade el cliente de la API de Alchemy
$container['extractor'] = function ($container) {
  $config = $container->get('settings');
  return new Client(array(
    'base_uri' => 'http://gateway-a.watsonplatform.net/calls/',
    'timeout'  => 6000,
  ));
};

// añade el cliente de conversión de documentos de Watson
$container['converter'] = function ($container) {
  $config = $container->get('settings');
  return new Client(array(
    'base_uri' => 'https://gateway.watsonplatform.net/document-conversion/api/',
    'timeout'  => 6000,
    'auth' => array($config['document-conversion']['user'], 
      $config['document-conversion']['pass'])
  ));
};

En el código de arriba, se crea un objeto de Guzzle Client para los servicios Document Conversion y AlchemyAPI, iniciados con el extremo y las credenciales del servicio, cuando sean necesarios. De forma similar, se inicia un objeto de MongoClient para la interacción de la base de datos de MongoDB utilizando una extensión MongoDB de PHP. Los extremos y las credenciales del servicio se obtienen de $APP_ROOT/config.php .

Después, defina una devolución de la llamada para que se encargue de las solicitudes POST hechas al extremo /add responsable de manejar las cargas de archivos PHP. Lo primero que hace esta devolución de llamada es verificar si una carga de archivo es válida y, si la encuentra, la procesa. Aquí está el código:

<?php
// Inicio de la aplicación Slim - recortado

// carga el procesador
$app->post('/add', function (Request $request, Response $response) {

  // obtiene la configuración
  $config = $this->get('settings');


  try {
    // Verifica para encontrar una carga de archivo válida
    if (empty($_FILES['upload']['name'])) {
      throw new Exception('No se ha cargado ningún archivo');
    }

    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $type = $finfo->file($_FILES['upload']['tmp_name']);
    if ($type != 'application/pdf') {
      throw new Exception('El formato del archivo no es válido');
    }

    // convierte a texto el PDF subido
    // conecta con la API de conversión de documentos de Watson
    // transfiere el archivo cargado para su conversión a formato de texto
    $apiResponse = $this->converter->post(
      'v1/convert_document?version=2015-12-15', array('multipart' => array(
        array('name' => 'config',
          'contents' => '{"conversion_target":"normalized_text"}'),
        array('name' => 'file',
          'contents' => fopen($_FILES['upload']['tmp_name'], 'r'))
    )));
    
    // almacena la respuesta
    $text = (string)$apiResponse->getBody();
    unset($apiResponse);

    // extrae las palabras clave del texto
    // conecta con Watson/Alchemy API para la extracción de las palabras clave
    // transfiere el contenido del texto para la extracción de las palabras clave
    // solicita la salida de JSON
    $apiResponse = $this->extractor->post(
      'text/TextGetRankedKeywords', array('form_params' => array(
        'apikey' => $config['alchemy']['apikey'],
        'text' => strip_tags($text),
        'outputMode' => 'json'
    )));

    // procesa la respuesta
    // crea el arreglo de las palabras clave
    $body = $apiResponse->getBody();
    $data = json_decode($body);
    $keywords = array();
    foreach ($data->keywords as $k) {
      $keywords[] = $k->text;
    }

    // guarda las palabras clave en MongoDB
    $collection = $this->db->docs;
    $q = trim($_FILES['upload']['name']);
    $params = $request->getParams();
    $result = $collection->findOne(array('name' => $q));
    $doc = new stdClass;
    if (count($result) > 0) {
      $doc->_id = $result['_id'];
    }
    $doc->name = trim($_FILES['upload']['name']);
    $doc->keywords = $keywords;
    $doc->description = trim(strip_tags($params['description']));
    $doc->updated = time();
    $collection->save($doc);
    
    $response = $this->view->render($response, 'add.phtml', 
      array('keywords' => $keywords, 
        'object' => trim($_FILES['upload']['name']), 
        'router' => $this->router));
    return $response;
    
  } catch (ClientException $e) {
    // en el caso de excepción de Guzzle
    // muestra el contenido de la respuesta HTTP
    throw new Exception($e->getResponse());
  }

});

Aquí hay mucho, así que revisémoslo paso a paso:

  • Las primeras líneas de código verifican si el archivo fue, de hecho, subido y si lo fue, verifica que el archivo es un documento PDF. Si alguna de esas condiciones no se cumple, se genera una excepción.
  • Considerando una carga de PDF válida, envía una solicitud POST al servicio Document Conversion que incluye el archivo cargado. Si tiene éxito, la respuesta es una versión en texto sin formato normalizado del PDF almacenado en $text .
  • Una vez que está disponible la versión del contenido del PDF el texto sin formato, envía una solicitud POST al servicio AlchemyAPI. Esta solicitud contiene la versión del PDF en texto sin formato, la clave de AlchemyAPI y el formato solicitado de salida (JSON). Si tiene éxito, la respuesta es una lista de palabras clave en código JSON, clasificadas por su puntuación.
  • Utilice el cliente de MongoDB para guardar las palabras clave en la base de datos. Lo primero que hace el código es verificar si ya existe un documento MongoDB para dicho archivo, utilizando el nombre del archivo como identificador. Si no encuentra un documento de MongoDB con el mismo nombre del archivo, crea un objeto de MongoDocument nuevo que contiene las propiedades para el archivo llamado (name), la descripción del archivo (description), la fecha y la hora (updated) y la lista de palabras clave (keywords). Si descubre que ya existe un documento MongoDB con el mismo nombre del archivo (por ejemplo, si es una actualización de un documento PDF ya existente), se recupera el actual documento de MongoDB y se actualizan sus propiedades con la nueva información. Después este resultado se guarda en la colección docs de la base de datos.

Una vez se hayan completado esos pasos, la devolución de la llamada pasa al script de vista un mensaje de éxito y una lista de las palabras clave que se han extraído y guardado. Aquí se muestra a lo que se parece el script de vista revisado, ubicado en $APP_ROOT/views/add.phtml, después de ser ajustado por este cambio:

<?php if (!isset($_POST['submit'])): ?>
<div>
  <form method="post" enctype="multipart/form-data"
    action="<?php echo $data['router']->pathFor('add'); ?>">
    <input type="hidden" name="MAX_FILE_SIZE" value="300000000" />
    <div class="form-group">
      <label for="upload">File</label>
      <span class="btn btn-default btn-file">
        <input type="file" name="upload" />
      </span>
    </div>
    <div class="form-group">
      <label for="body">Description</label>
      <textarea name="description" id="description"
        class="form-control" rows="3"></textarea>
    </div>
  <div class="form-group">
    <button type="submit" name="submit"
      class="btn btn-primary">Add</button>
  </div>
  </form>
</div>
<?php else: ?>
<div>
  <div class="alert alert-success">
    <strong>¡Funcionó!</strong> Su documento se añadió
      <strong><?php echo $data['object']; ?></strong>.
      <a role="button" class="btn btn-primary"
      href="<?php echo $data['router']->pathFor('add'); ?>">
      ¿Añadir otro?</a>
  </div>
  <div>
   Se extrajeron y almacenaron las siguientes palabras clave:
    <ul>
    <?php foreach ($data['keywords'] as $k): ?>
      <li><?php echo $k; ?></li>
    <?php endforeach; ?>
    </ul>
  </div>
</div>
<p>Esta operación utilizó los datos generados a través de los servicios
  <a href="http://www.ibm.com/smarterplanet/us/en/ibmwatson/">
  IBM Watson</a> and <a href="https://www.alchemyapi.com/">
  AlchemyAPI</a>.</p>
<?php endif; ?>

Como demuestra el código de arriba, el script de vista simplemente itera por la listas de palabras clave y las muestra, junto con un breve mensaje de éxito.

Para ver esto en acción, vuelva en su navegador a http://pdf-keyword-search.localhost/add e intente subir un archivo PDF. Si todo va bien, su archivo PDF será convertido, analizado y guardado y usted verá un mensaje de éxito:

Figura 7. Resultados de la carga del archivo
File upload results
File upload results

Conclusión

Si usted es observador se habrá dado cuenta que al principio del Paso 3, yo escribí cuatro etapas en el procesado de la carga de un archivo. El código que ha visto hasta ahora se ocupa de las tres primeras etapas, pero todavía falta una: guardar el archivo PDF actual. En la Parte 2 de esta serie de artículos, le presento la parte que falta, el servicio IBM Bluemix Object Storage que brinda la infraestructura escalable y basada en la nube para el almacenamiento y la recuperación de archivos.

También le acompaño a través del proceso de construir una interfaz de búsqueda para la aplicación, así puede empezar a usarla para encontrar documentos que coincidan con las palabras claves de su búsqueda. Finalmente, le muestro cómo desplegar todo en IBM Bluemix, para que pueda obtener sus documentos en cualquier momento y desde cualquier lugar. ¡Asegúrese de volver por ello!


Recursos para Descargar


Temas relacionados


Comentarios

Inicie Sesión o Regístrese para agregar comentarios.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Cognitive computing
ArticleID=1035940
ArticleTitle=Utilizar los servicios de Bluemix para crear una aplicación basada en el navegador para almacenar y buscar PDFs, Parte 1: Utilice los servicios de Conversión de Documentos y Extracción de Palabras Clave para convertir e indexar archivos
publish-date=08152016