Gerenciamento do Snowpark Container Services (incluindo funções de serviço) com Python¶
Você pode usar Python para gerenciar o Snowpark Container Services, um serviço de contêiner totalmente gerenciado por meio do qual você pode implantar, gerenciar e dimensionar aplicativos em contêineres. Para obter uma visão geral do Snowpark Container Services, consulte Sobre Snowpark Container Services.
Com o Snowflake Python APIs, é possível gerenciar pools de computação, repositórios de imagens e serviços.
Pré-requisitos¶
Os exemplos neste tópico pressupõem que você tenha adicionado código para se conectar ao Snowflake e criar um objeto Root
a partir do qual usar o Snowflake Python APIs.
Por exemplo, o seguinte código usa parâmetros de conexão definidos em um arquivo de configuração para criar uma conexão com o Snowflake:
from snowflake.core import Root
from snowflake.snowpark import Session
session = Session.builder.config("connection_name", "myconnection").create()
root = Root(session)
Usando o objeto Session
resultante, o código cria um objeto Root
para usar os tipos e métodos de API. Para obter mais informações, consulte Conexão ao Snowflake com o Snowflake Python APIs.
Gerenciamento de pools de computação¶
Você pode gerenciar pools de computação, que são coleções de nós de máquinas virtuais (VM) nos quais o Snowflake executa seus trabalhos e serviços do Snowpark Container Services.
O Snowflake Python APIs representa pools de computação com dois tipos separados:
ComputePool
: expõe as propriedades de um pool de computação, como seu warehouse, nós máximo e mínimo e configurações de retomada automática e suspensão automática.ComputePoolResource
: expõe métodos para executar ações em pools de computação, como buscar um objetoComputePool
correspondente e suspender, retomar e parar pools.
Para obter mais informações sobre pools de computação, consulte Snowpark Container Services: como trabalhar com pools de computação.
Criação de um pool de computação¶
Você pode criar um pool de computação chamando o método ComputePoolCollection.create
, passando um objeto ComputePool
que representa o pool de computação que você deseja criar.
Para criar um pool de computação, primeiro crie um objeto ComputePool
que especifique propriedades do pool, como as seguintes:
Nome do pool de computação
Número máximo e mínimo de nós que o pool conterá
Nome da família de instâncias que identifica o tipo de máquina a ser provisionada para nós no pool
Se o pool deve ser retomado automaticamente quando um serviço ou trabalho é enviado a ele
O código no exemplo a seguir cria um objeto ComputePool
que representa um pool nomeado my_compute_pool
:
from snowflake.core.compute_pool import ComputePool
compute_pool = ComputePool(name="my_compute_pool", min_nodes=1, max_nodes=2, instance_family="CPU_X64_XS", auto_resume=False)
root.compute_pools.create(compute_pool)
O código então cria o banco de pool de computação passando o objeto ComputePool
para o método ComputePoolCollection.create
.
Como obter detalhes do pool de computação¶
Você pode obter informações sobre um pool de computação chamando o método ComputePoolResource.fetch
, que retorna um objeto ComputePool
.
O código no exemplo a seguir obtém informações sobre um pool chamado my_compute_pool
:
compute_pool = root.compute_pools["my_compute_pool"].fetch()
print(compute_pool.to_dict())
Listagem de pools de computação¶
Você pode listar pools de computação usando o método iter
, que retorna um iterador PagedIter
.
O código no exemplo a seguir lista pools de computação cujos nomes começam com my
:
compute_pools = root.compute_pools.iter(like="my%")
for compute_pool in compute_pools:
print(compute_pool.name)
Execução de operações de pool de computação¶
Você pode executar operações comuns de pool de computação,—como suspender, retomar e interromper pools—com um objeto ComputePoolResource
, que você pode obter usando o método ComputePool.fetch
.
O código no exemplo a seguir suspende, retoma e interrompe o pool de computação my_compute_pool
:
compute_pool_res = root.compute_pools["my_compute_pool"]
compute_pool_res.suspend()
compute_pool_res.resume()
compute_pool_res.stop_all_services()
O código usa o método Root.compute_pools
para criar um objeto ComputePool
que representa o pool de computação. Do objeto ComputePool
, ele busca um objeto ComputePoolResource
com o qual executará operações de pool de computação.
Gerenciamento de repositórios de imagens¶
Você pode gerenciar repositórios de imagens, que armazenam imagens de aplicativos executados em serviços de contêiner.
Um repositório de imagens é um objeto no nível do esquema. Ao criar ou referenciar um repositório, você faz isso no contexto de seu esquema.
O Snowflake Python APIs representa repositórios de imagens com dois tipos separados:
ImageRepository
: expõe as propriedades de um repositório de imagens, como banco de dados e nomes de esquema, URL do repositório e proprietário.ImageRepositoryResource
: Expõe métodos que podem ser usados para buscar um objetoImageRepository
correspondente e descartar o recurso do repositório de imagens.
Para obter mais informações sobre repositórios de imagens, consulte Snowpark Container Services: como trabalhar com um registro e repositório de imagens.
Criação de um repositório de imagens¶
Para criar um repositório de imagens, primeiro crie um objeto ImageRepository
que especifique o nome do repositório.
O código no exemplo a seguir cria um objeto ImageRepository
que representa um repositório nomeado my_repo
:
from snowflake.core.image_repository import ImageRepository
my_repo = ImageRepository("my_repo")
root.databases["my_db"].schemas["my_schema"].image_repositories.create(my_repo)
O código então cria o repositório de imagens passando o objeto ImageRepository
para o método ImageRepositoryCollection.create
, criando o repositório de imagens no banco de dados my_db
e no esquema my_schema
.
Como obter detalhes do repositório de imagens¶
Você pode obter informações sobre um repositório de imagens chamando o método ImageRepositoryResource.fetch
, que retorna um objeto ImageRepository
.
O código no exemplo a seguir obtém um objeto ImageRepository
que representa o repositório de imagens my_repo
e então imprime o nome do proprietário do repositório:
my_repo_res = root.databases["my_db"].schemas["my_schema"].image_repositories["my_repo"]
my_repo = my_repo_res.fetch()
print(my_repo.owner)
Listagem do repositórios de imagens¶
Você pode listar os repositórios de imagens em um esquema especificado usando o método iter
, que retorna um iterador PagedIter
dos objetos ImageRepository
.
O código no exemplo a seguir lista os nomes dos repositórios no banco de dados my_db
e no esquema my_schema
:
repo_list = root.databases["my_db"].schemas["my_schema"].image_repositories.iter()
for repo_obj in repo_list:
print(repo_obj.name)
Descarte de um repositório de imagens¶
É possível descartar um repositório de imagens usando o método ImageRepositoryResource.drop
.
O código no exemplo a seguir descarta o repositório my_repo
:
my_repo_res = root.databases["my_db"].schemas["my_schema"].image_repositories["my_repo"]
my_repo_res.drop()
Gerenciamento de serviços e funções de serviço¶
Você pode gerenciar serviços, que executam contêineres de aplicativos até serem interrompidos. O Snowflake reinicia um serviço automaticamente se o contêiner de serviço parar. Dessa forma, o serviço funciona efetivamente de forma ininterrupta.
Um serviço é um objeto no nível do esquema. Ao criar ou referenciar um serviço, você faz isso no contexto de seu esquema.
O Snowflake Python APIs representa serviços com dois tipos distintos:
Service
: expõe as propriedades de um serviço, como especificação, instâncias mínimas e máximas e nome do banco de dados e do esquema.ServiceResource
: expõe métodos que você pode usar para buscar um objetoService
correspondente, suspender e retomar o serviço e excluir seu status.
Para obter mais informações sobre serviços, consulte Snowpark Container Services: como trabalhar com serviços.
Criação de um serviço¶
Para criar um serviço, você executa o método services.create
, passando um objeto Service
que representa o serviço que deseja criar.
Você cria um serviço a partir de um arquivo de especificação de serviço .yaml
que foi transferido por upload para um estágio. Para obter mais informações sobre a criação de uma especificação do serviço, consulte Referência de especificação de serviço.
Carregamento da especificação¶
Se você estiver criando um serviço a partir de uma especificação que ainda não foi carregada em um estágio, poderá fazer upload da especificação usando um objeto FileOperation do Snowpark.
O código no exemplo a seguir usa o método FileOperation.put
para fazer upload de uma especificação como um arquivo:
session.file.put("/local_location/my_service_spec.yaml", "@my_stage")
O código no exemplo a seguir usa o método FileOperation.put_stream
para fazer upload de uma especificação como uma cadeia de caracteres:
service_spec_string = """
// Specification as a string.
"""
session.file.put_stream(StringIO(sepc_in_string), "@my_stage/my_service_spec.yaml")
Criação do serviço¶
Para criar um serviço a partir de uma especificação preparada, primeiro crie um objeto Service
que especifique propriedades de serviço como estas:
Nome do serviço
Número máximo e mínimo de instâncias de serviço que o Snowflake pode criar
Pool de computação ao qual o serviço deve ser adicionado
Localização do estágio e nome da especificação
O código no exemplo a seguir cria um objeto Service
que representa um serviço nomeado my_service
a partir de uma especificação em @my_stage/my_service_spec.yaml
:
from snowflake.core.service import Service, ServiceSpec
my_service = Service(name="my_service", min_instances=1, max_instances=2, compute_pool="my_compute_pool", spec=ServiceSpec("@my_stage/my_service_spec.yaml"))
root.databases["my_db"].schemas["my_schema"].services.create(my_service)
O código então cria o serviço passando o objeto Service
para o método ServiceCollection.create
, criando o serviço no banco de dados my_db
e no esquema my_schema
.
Você também pode criar um serviço a partir de uma especificação fornecida como texto inline, conforme mostrado no exemplo a seguir. A função ServiceSpec
aceita um único argumento da cadeia de caracteres spec
. Se a sequência começar com @
, a função interpreta e valida como um caminho de arquivo de estágio. Caso contrário, a cadeia de caracteres é passada como texto inline.
from textwrap import dedent
from snowflake.core.service import Service, ServiceSpec
spec_text = dedent(f"""\
spec:
containers:
- name: hello-world
image: repo/hello-world:latest
endpoints:
- name: hello-world-endpoint
port: 8080
public: true
""")
my_service = Service(name="my_service", min_instances=1, max_instances=2, compute_pool="my_compute_pool", spec=ServiceSpec(spec_text))
root.databases["my_db"].schemas["my_schema"].services.create(my_service)
Criação de uma função de serviço¶
Depois que o serviço estiver instalado e funcionando, você poderá criar uma função de serviço que se comunique com o ponto de extremidade do servidor. Uma função de serviço é uma função definida pelo usuário (UDF) que você cria e associa a um serviço no Snowpark Container Services. Para obter mais informações, consulte Funções de serviço: como usar um serviço de uma consulta SQL.
O código no exemplo a seguir cria uma UDF nomeada my-udf
que especifica o serviço hello-world
e o ponto de extremidade hello-world-endpoint
que você definiu anteriormente:
from snowflake.core import CreateMode
from snowflake.core.function import FunctionArgument, ServiceFunction
root.databases["my_db"].schemas["my_schema"].functions.create(
ServiceFunction(
name="my-udf",
arguments=[
FunctionArgument(name="input", datatype="TEXT")
],
returns="TEXT",
service="hello-world",
endpoint="'hello-world-endpoint'",
path="/hello-world-path",
max_batch_rows=5,
),
mode = CreateMode.or_replace
)
Invocação de uma função de serviço¶
Depois que a função de serviço for criada, será possível invocar a função para testá-la.
O código no exemplo a seguir invoca a função de serviço my-udf
que você criou anteriormente:
result = root.databases["my_db"].schemas["my_schema"].functions["my-udf(TEXT)"].execute_function(["test"])
print(result)
Como obter detalhes do serviço¶
Você pode obter informações sobre um serviço do Snowflake chamando o método ServiceResource.fetch
, que retorna um objeto Service
.
O código no exemplo a seguir obtém informações sobre um serviço nomeado my_service
:
my_service = root.databases["my_db"].schemas["my_schema"].services["my_service"].fetch()
Listagem de serviços¶
Você pode listar os serviços em um esquema especificado usando o método iter
, que retorna um iterador PagedIter
dos objetos Service
.
O código no exemplo a seguir lista serviços cujos nomes começam com my
:
services = root.databases["my_db"].schemas["my_schema"].services.iter(like="my%")
for service_obj in services:
print(service_obj.name)
Execução de operações de serviço¶
Você pode realizar operações de serviço comuns,—como suspender, retomar e obter o status do serviço—com um objeto ServiceResource
.
O código no exemplo a seguir suspende e retoma o serviço my_service
e também obtém o status do serviço:
my_service_res = root.databases["my_db"].schemas["my_schema"].services["my_service"]
my_service_res.suspend()
my_service_res.resume()
status = my_service_res.get_service_status(10)