

# Tutorial: configuración de un cuaderno de Jupyter en JupyterLab para probar y depurar scripts ETL
<a name="dev-endpoint-tutorial-local-jupyter"></a>

En este tutorial, se conecta un bloc de notas Jupyter en JupyterLab que se ejecuta en su máquina local a un punto de enlace de desarrollo. Esto se hace para poder ejecutar, depurar y probar de forma interactiva los scripts de ETL (extracción, transformación y carga) de AWS Glue antes de implementarlos. Este tutorial utiliza enrutamiento de puertos Secure Shell (SSH) para conectar su máquina local a un punto de enlace de desarrollo de AWS Glue. Para obtener más información, consulte [Port forwarding (Enrutamiento de puertos)](https://en.wikipedia.org/wiki/Port_forwarding) en Wikipedia.

## Paso 1: instalar JupyterLab y Sparkmagic
<a name="dev-endpoint-tutorial-local-jupyter-install"></a>

Puede instalar JupyterLab con `conda` o `pip`. `conda` es un sistema de código abierto para la administración de paquetes y de entorno que se ejecuta en Windows, macOS y Linux. `pip` es el instalador del paquete para Python.

Si realizará la instalación en macOS, debe tener instalado Xcode para poder instalar Sparkmagic.

1. Instale JupyterLab, Sparkmagic y las extensiones relacionadas.

   ```
   $ conda install -c conda-forge jupyterlab
   $ pip install sparkmagic
   $ jupyter nbextension enable --py --sys-prefix widgetsnbextension
   $ jupyter labextension install @jupyter-widgets/jupyterlab-manager
   ```

1. Compruebe el directorio `sparkmagic` desde `Location`. 

   ```
   $ pip show sparkmagic | grep Location
   Location: /Users/username/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages
   ```

1. Cambie su directorio al devuelto para `Location`, e instale los kernels para Scala y PySpark.

   ```
   $ cd /Users/username/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages
   $ jupyter-kernelspec install sparkmagic/kernels/sparkkernel
   $ jupyter-kernelspec install sparkmagic/kernels/pysparkkernel
   ```

1. Descargue un archivo `config` de prueba. 

   ```
   $ curl -o ~/.sparkmagic/config.json https://raw.githubusercontent.com/jupyter-incubator/sparkmagic/master/sparkmagic/example_config.json
   ```

   En este archivo de configuración, puede configurar los parámetros relacionados con Spark como `driverMemory` y `executorCores`.

## Paso 2: inicie JupyterLab
<a name="dev-endpoint-tutorial-local-jupyter-start"></a>

Cuando inicia JupyterLab, su navegador web predeterminado se abre automáticamente y se muestra la URL `http://localhost:8888/lab/workspaces/{workspace_name}`.

```
$ jupyter lab
```

## Paso 3: inicie el enrutamiento de puertos SSH para conectarse a su punto de conexión de desarrollo
<a name="dev-endpoint-tutorial-local-jupyter-port-forward"></a>

A continuación, use el enrutamiento de puertos locales SSH para redireccionar un puerto local (aquí, `8998`) al destino remoto definido por AWS Glue (`169.254.76.1:8998`). 

1. Abra una ventana de terminal independiente que le proporcione acceso a SSH. En Microsoft Windows, puede usar el shell de BASH proporcionado por [Git for Windows (Git para Windows)](https://git-scm.com/downloads) o instale [Cygwin](https://www.cygwin.com/).

1. Ejecute el siguiente comando SSH, modificado de la siguiente manera:
   + Reemplace `private-key-file-path` por una ruta al archivo `.pem` que contiene la clave privada que se corresponde con la clave pública que usó para crear su punto de enlace de desarrollo.
   + Si redirecciona un puerto distinto de `8998`, reemplace `8998` por el número de puerto que usa realmente de forma local. La dirección, `169.254.76.1:8998`, es el puerto remoto y no la modifica el usuario.
   + Reemplace `dev-endpoint-public-dns` por la dirección DNS pública de su punto de enlace de desarrollo. Para encontrar esta dirección, diríjase a su punto de enlace de desarrollo en la consola de AWS Glue, elija el nombre y copie la **Public address (Dirección pública)** que se enumera en la página **Endpoint details (Detalles del punto de enlace)**.

   ```
   ssh -i private-key-file-path -NTL 8998:169.254.76.1:8998 glue@dev-endpoint-public-dns
   ```

   Lo más probable es que vea un mensaje de advertencia similar al siguiente:

   ```
   The authenticity of host 'ec2-xx-xxx-xxx-xx.us-west-2.compute.amazonaws.com (xx.xxx.xxx.xx)'
   can't be established.  ECDSA key fingerprint is SHA256:4e97875Brt+1wKzRko+JflSnp21X7aTP3BcFnHYLEts.
   Are you sure you want to continue connecting (yes/no)?
   ```

   Ingrese **yes** y deje la ventana de terminal abierta mientras usa JupyterLab. 

1. Compruebe que el enrutamiento de puertos SSH funciona correctamente con el punto de enlace de desarrollo.

   ```
   $ curl localhost:8998/sessions
   {"from":0,"total":0,"sessions":[]}
   ```

## Paso 4: ejecute un fragmento de script sencillo en un párrafo del bloc de notas
<a name="dev-endpoint-tutorial-local-jupyter-list-schema"></a>

Ahora su bloc de notas en JupyterLab debería funcionar con su punto de enlace de desarrollo. Escriba el siguiente fragmento de script en el bloc de notas y ejecútelo.

1. Compruebe que Spark se está ejecutando correctamente. El siguiente comando indica a Spark que calcule el `1` y luego imprima el valor.

   ```
   spark.sql("select 1").show()
   ```

1. Compruebe si la integración AWS Glue Data Catalog está funcionando. En el siguiente comando se muestran las tablas del Catálogo de datos.

   ```
   spark.sql("show tables").show()
   ```

1. Compruebe que un fragmento de script simple que use las bibliotecas de AWS Glue funcione.

   El script a continuación utiliza los metadatos de la tabla `persons_json` en AWS Glue Data Catalog para crear un `DynamicFrame` a partir de sus datos de ejemplo. A continuación, imprime el recuento de elementos y el esquema de estos datos. 

```
import sys
from pyspark.context import SparkContext
from awsglue.context import GlueContext
 
# Create a Glue context
glueContext = GlueContext(SparkContext.getOrCreate())
 
# Create a DynamicFrame using the 'persons_json' table
persons_DyF = glueContext.create_dynamic_frame.from_catalog(database="legislators", table_name="persons_json")
 
# Print out information about *this* data
print("Count:  ", persons_DyF.count())
persons_DyF.printSchema()
```

La salida del script es la siguiente.

```
 Count:  1961
 root
 |-- family_name: string
 |-- name: string
 |-- links: array
 |    |-- element: struct
 |    |    |-- note: string
 |    |    |-- url: string
 |-- gender: string
 |-- image: string
 |-- identifiers: array
 |    |-- element: struct
 |    |    |-- scheme: string
 |    |    |-- identifier: string
 |-- other_names: array
 |    |-- element: struct
 |    |    |-- note: string
 |    |    |-- name: string
 |    |    |-- lang: string
 |-- sort_name: string
 |-- images: array
 |    |-- element: struct
 |    |    |-- url: string
 |-- given_name: string
 |-- birth_date: string
 |-- id: string
 |-- contact_details: array
 |    |-- element: struct
 |    |    |-- type: string
 |    |    |-- value: string
 |-- death_date: string
```

## Solución de problemas
<a name="dev-endpoint-tutorial-local-jupyter-troubleshooting"></a>
+ Durante la instalación de JupyterLab, si su equipo está detrás de un proxy corporativo o firewall, es posible que encuentre errores HTTP y SSL debido a perfiles de seguridad personalizados administrados por departamentos de TI corporativos.

  El siguiente es un ejemplo de un error típico que se produce cuando `conda` no puede conectarse a sus propios repositorios:

  ```
  CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/main/win-64/current_repodata.json>
  ```

  Esto puede suceder porque su empresa puede bloquear conexiones a repositorios ampliamente utilizados en comunidades Python y JavaScript. Para obtener más información, consulte [Installation Problems (Problemas de instalación)](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html#installation-problems) en la página web de JupyterLab.
+ Si se encuentra ante un error de *connection refused (conexión rechazada)* al intentar conectar al punto de enlace de desarrollo, es posible que esté usando un punto de enlace de desarrollo que está desactualizado. Intente crear un nuevo punto de enlace de desarrollo y volver a conectarse.