Como configurar um Jupyter Notebook para o Snowpark Scala

Este tópico explica como configurar um Jupyter Notebook para o Snowpark.

Neste tópico:

Como configurar Jupyter Notebooks para o desenvolvimento em Scala

Certifique-se de que Jupyter esteja configurado para usar o Scala. Por exemplo, você pode instalar o kernel Almond.

Nota

Ao usar coursier para instalar o kernel Almond, especifique uma versão do Scala suportada.

Como criar um novo Notebook em uma nova pasta

A biblioteca do Snowpark requer acesso ao diretório que contém as classes geradas pelo REPL do Scala. Se você está planejando usar vários notebooks, você deve usar um diretório de classes REPL separado para cada notebook.

Para facilitar a criação de um diretório de classes REPL separado para cada notebook, crie uma pasta separada para cada notebook:

  1. No painel do Notebook, clique em New » Folder para criar uma nova pasta para um notebook.

  2. Selecione a caixa de seleção ao lado da pasta, clique em Rename e atribua um novo nome para a pasta.

  3. Clique no link da pasta para navegar para a pasta.

  4. Clique em New » Scala para criar um novo notebook nessa pasta.

Como configurar o Jupyter Notebook para o Snowpark

Em seguida, configure o Jupyter Notebook para o Snowpark.

  1. Em uma nova célula, execute os seguintes comandos para definir uma variável para um diretório:

    val replClassPathObj = os.Path("replClasses", os.pwd)
    if (!os.exists(replClassPathObj)) os.makeDir(replClassPathObj)
    val replClassPath = replClassPathObj.toString()
    
    Copy

    Isso faz o seguinte:

    • Define uma variável os.Path e uma variável String para um diretório para classes geradas pelo REPL do Scala.

    • Cria esse diretório se ele ainda não existir.

    O REPL do Scala gera classes para o código Scala que você escreve, incluindo seu código que define UDFs. A biblioteca do Snowpark usa esse diretório para encontrar e carregar as classes para suas UDFs que são geradas pelo REPL.

    Nota

    Se você estiver usando vários notebooks, você precisará criar e configurar um diretório de classe REPL separado para cada notebook. Para simplificar, você pode simplesmente colocar cada notebook em uma pasta separada, como explicado em Como criar um novo Notebook em uma nova pasta.

  2. Execute os seguintes comandos em uma célula para configurar o compilador para o REPL do Scala:

    interp.configureCompiler(_.settings.outputDirs.setSingleOutput(replClassPath))
    interp.configureCompiler(_.settings.Yreplclassbased)
    interp.load.cp(replClassPathObj)
    
    Copy

    Isso faz o seguinte:

    • Configura o compilador para gerar classes para o REPL no diretório que você criou anteriormente.

    • Configura o compilador para inserir o código inserido no REPL em classes, e não em objetos.

    • Adiciona o diretório que você criou anteriormente como uma dependência do interpretador do REPL.

  3. Crie uma nova sessão no Snowpark e adicione o diretório de classes REPL que você criou anteriormente como uma dependência. Por exemplo:

    // Import the Snowpark library from Maven.
    import $ivy.`com.snowflake:snowpark:1.9.0`
    
    import com.snowflake.snowpark._
    import com.snowflake.snowpark.functions._
    
    val session = Session.builder.configs(Map(
        "URL" -> "https://<account_identifier>.snowflakecomputing.com",
        "USER" -> "<username>",
        "PASSWORD" -> "<password>",
        "ROLE" -> "<role_name>",
        "WAREHOUSE" -> "<warehouse_name>",
        "DB" -> "<database_name>",
        "SCHEMA" -> "<schema_name>"
    )).create
    
    // Add the directory for REPL classes that you created earlier.
    session.addDependency(replClassPath)

    Consulte Como criar uma sessão para o Snowpark Scala para obter uma explicação das chaves Map.

  4. Execute os seguintes comandos em uma célula para adicionar as classes de kernel Ammonite como dependências para sua UDF:

    def addClass(session: Session, className: String): String = {
      var cls1 = Class.forName(className)
      val resourceName = "/" + cls1.getName().replace(".", "/") + ".class"
      val url = cls1.getResource(resourceName)
      val path = url.getPath().split(":").last.split("!").head
      session.addDependency(path)
      path
    }
    addClass(session, "ammonite.repl.ReplBridge$")
    addClass(session, "ammonite.interp.api.APIHolder")
    addClass(session, "pprint.TPrintColors")
    
    Copy

    Nota

    Se você planeja criar UDFs que tenham dependências disponíveis através do Maven, você pode usar o método addClass definido acima para adicionar essas dependências:

    addClass(session, "<dependency_package>.<dependency_class>")
    
    Copy

    Se você precisar especificar uma dependência em um arquivo JAR, chame interp.load.cp para carregar o arquivo JAR para o intérprete do REPL e chame session.addDependency para adicionar o arquivo JAR como uma dependência para suas UDFs:

    interp.load.cp(os.Path(<path to jar file>/<jar file>))
    addDependency(<path to jar file>/<jar file>)
    
    Copy

Como verificar a configuração de seu Notebook Jupyter

Execute os seguintes comandos em uma célula para verificar se você pode definir e chamar uma função anônima definida pelo usuário (UDF):

class UDFCode extends Serializable {
  val appendLastNameFunc = (s: String) => {
    s"$s Johnson"
  }
}
// Define an anonymous UDF.
val appendLastNameUdf = udf((new UDFCode).appendLastNameFunc)
// Create a DataFrame that has a column NAME with a single row with the value "Raymond".
val df = session.sql("select 'Raymond' NAME")
// Call the UDF, passing in the values in the NAME column.
// Return a new DataFrame that has an additional column "Full Name" that contains the value returned by the UDF.
df.withColumn("Full Name", appendLastNameUdf(col("NAME"))).show()
Copy

Solução de problemas

value res<n> is not a member of ammonite.$sess.cmd<n>.wrapper.Helper

Se ocorrer o seguinte erro:

value res<n> is not a member of ammonite.$sess.cmd<n>.wrapper.Helper
Copy

Exclua o conteúdo do diretório contendo as classes do REPL (o diretório com o caminho especificado pela variável replClassPath) e reinicie o servidor do notebook.