Decoradores

Os decoradores do Cloud Endpoints Frameworks para Python descrevem a configuração da API, os métodos, os parâmetros e outros detalhes importantes que definem as propriedades e o comportamento do Endpoint.

Esta página descreve os decoradores disponíveis em detalhe. Para obter informações sobre a utilização dos decoradores para criar a sua API, consulte o seguinte:

Definir a API (@endpoints.api)

Pode fornecer vários argumentos a @endpoints.api para definir a sua API. A tabela seguinte descreve os argumentos disponíveis:

Argumentos @endpoints.api Descrição Exemplo
allowed_client_ids Obrigatório se a sua API usar autenticação. Lista de IDs de clientes para clientes autorizados a pedir tokens. Para mais informações, consulte o artigo IDs de clientes e públicos-alvo permitidos. allowed_client_ids=['1-web-apps.apps.googleusercontent.com','2-android-apps.apps.googleusercontent.com', endpoints.API_EXPLORER_CLIENT_ID]
api_key_required Opcional. Usado para restringir o acesso a pedidos que fornecem uma chave da API. api_key_required=True
audiences Obrigatório se a sua API exigir autenticação e se estiver a suportar clientes Android. Para tokens de ID da Google, pode ser uma lista de IDs de cliente em nome dos quais os tokens são pedidos. Se os tokens forem emitidos por fornecedores de autenticação de terceiros, como o Auth0, tem de ser um mapeamento de dicionário dos nomes dos emissores de autenticação para listas de públicos-alvo. Para mais informações, consulte o artigo IDs de clientes e públicos-alvo permitidos. audiences=['1-web-apps.apps.googleusercontent.com'] ou audiences={"auth0": ["aud-1.auth0.com", "aud-2.auth0.com"]}
base_path Opcional. Usado para publicar a sua API a partir do caminho especificado. Se especificar este argumento, também tem de alterar a secção handlers no ficheiro app.yaml. Consulte o artigo Publicar a sua API a partir de um caminho diferente.
canonical_name Opcional. Usado para especificar um nome diferente ou mais legível para a API na biblioteca cliente. Este nome é usado para gerar nomes na biblioteca de cliente. A API de back-end continua a usar o valor especificado na propriedade name.

Por exemplo, se a sua API tiver a propriedade name definida como dfaanalytics, pode usar esta propriedade para especificar um nome canónico de DFA Group Analytics. As classes de cliente geradas conteriam então o nome DfaGroupAnalytics.

Deve incluir os espaços relevantes entre os nomes, conforme mostrado. Estes são substituídos pela capitalização em camelo ou sublinhados adequados.
canonical_name='DFA Analytics'
description Uma breve descrição da API. Isto é exposto no serviço de deteção para descrever a sua API e também pode ser usado opcionalmente para gerar documentação, conforme descrito em Gerar bibliotecas de clientes. description='Sample API for a simple game'
documentation Opcional. O URL onde os utilizadores podem encontrar documentação sobre esta versão da API. Isto é apresentado no destaque "Saiba mais" do explorador de APIs na parte superior da página do explorador de APIs para permitir que os utilizadores saibam mais sobre o seu serviço. documentation='http://link_to/docs'
hostname O nome do anfitrião da sua aplicação do App Engine. A ferramenta de linha de comandos do Endpoints Frameworks usa o valor que especificar aqui quando gera um documento Discovery ou um documento OpenAPI. Se não especificar o nome do anfitrião aqui, tem de o especificar no campo application do ficheiro app.yaml ou especificar o ID do projeto quando implementar a sua aplicação do App Engine. hostname='your_app_id.appspot.com'
issuers Opcional. As configurações do emissor de JWT personalizadas. Este deve ser um mapeamento de dicionário dos nomes dos emissor para objetos endpoints.Issuer. issuers={"auth0": endpoints.Issuer("https://test.auth0.com", "https://test.auth0.com/.well-known/jwks.json")}
name Obrigatório. O nome da API, que é usado como prefixo para todos os métodos e caminhos da API. O name valor:
  • Tem de começar com uma letra minúscula.
  • Tem de corresponder à expressão regular [a-z]+[A-Za-z0-9], ou seja, o resto do nome pode consistir em letras maiúsculas e minúsculas ou números.
Para implementar várias APIs como parte de um único serviço, todos os nomes das APIs têm de corresponder à expressão regular [a-z][a-z0-9]{0,39}, ou seja, o nome tem de começar por uma letra minúscula, os restantes carateres têm de ser letras minúsculas ou números, e o comprimento máximo é de 40 carateres.
name='yourApi' ou name='yourapi'
limit_definitions Opcional. Usado para definir quotas para a sua API. Consulte limit_definitions para mais informações.
owner_domain Opcional. O nome do domínio da entidade proprietária da API. Usado em conjunto com owner_name para fornecer sugestões para nomear corretamente a biblioteca cliente quando é gerada para esta API. (O caminho da embalagem é o inverso do owner_domain e do package_path, se fornecidos. A predefinição é usar appid.apppost.com owner_domain='your-company.com'
owner_name Opcional. O nome da entidade proprietária da API. Usado em conjunto com owner_domain para fornecer sugestões para nomear corretamente a biblioteca cliente quando é gerada para esta API. owner_name='Your-Company'
package_path Opcional. É usado para definir o âmbito do "pacote" ao qual esta API pertence, com valores separados por / que especificam agrupamentos lógicos de APIs.

Por exemplo, especificar cloud/platform resulta no caminho da biblioteca cliente definido como cloud/platform/<ApiName> e no pacote da biblioteca cliente definido como cloud.plaform.<ApiName>.
package_path='cloud/platform'
scopes Se não for fornecido, a predefinição é o âmbito do email (https://www.googleapis.com/auth/userinfo.email), que é necessário para o OAuth. Pode substituir esta opção para especificar mais âmbitos do OAuth 2.0, se quiser. Também pode substituir os âmbitos especificados aqui para um método de API específico, especificando âmbitos diferentes no decorador @endpoints.method. No entanto, se definir mais do que um âmbito, tenha em atenção que a verificação do âmbito é aprovada se o token for gerado para qualquer um dos âmbitos especificados. Para exigir vários âmbitos, especifique uma única string com um espaço entre cada âmbito. scopes=['ss0', 'ss1 and_ss2']
title Opcional. O texto apresentado no API Explorer como o título da sua API e exposto nos serviços de descoberta e diretório. title='My Backend API'
version Obrigatório. Especifica a versão do Cloud Endpoints. Este valor aparece no caminho da API. Se especificar uma string de versão compatível com a norma SemVer, apenas o número da versão principal aparece no caminho da API quando implementa a API. Por exemplo, uma API denominada echo com a versão 2.1.0 teria um caminho semelhante a /echo/v2. Se atualizar a API echo para a versão 2.2.0 e implementar uma alteração retrocompatível, o caminho permanece /echo/v2. Isto permite-lhe atualizar o número da versão da API quando faz uma alteração compatível com versões anteriores sem interromper os caminhos existentes para os seus clientes. No entanto, se atualizar a API echo para a versão 3.0.0 (porque está a implementar uma alteração interruptiva), o caminho é alterado para /echo/v3. version='v1' ou version='2.1.0'

limit_definitions

Para definir quotas para a sua API, especifica o argumento opcional limit_definitions para @endpoints.api. Para configurar uma quota, também tem de:

  • Instale a versão 2.4.5 ou posterior da biblioteca Endpoints Frameworks.
  • Adicione o argumento metric_costs ao decorador de método para cada método ao qual quer aplicar uma quota.

Consulte o artigo Configurar quotas para ver todos os passos necessários para configurar uma quota.

Especifica uma lista de uma ou mais instâncias, semelhante ao seguinte:LimitDefinition

quota_limits = [
              endpoints.LimitDefinition(
                "name",
                "Display name",
                limit)
]

Cada instância de LimitDefinition tem de ter os seguintes valores:

Elemento Descrição
nome O nome do contador de pedidos da API. Normalmente, este é o tipo de pedido (por exemplo, "pedidos de leitura" ou "pedidos de gravação") que identifica exclusivamente a quota.
Nome a apresentar

O texto apresentado para identificar a quota no separador Quotas na página Endpoints > Serviços. Este texto também é apresentado aos consumidores da sua API na página Quotas de IAM e administrador e API e serviços. O nome a apresentar tem de ter um máximo de 40 carateres.

Para fins de legibilidade, o texto "por minuto por projeto" é automaticamente anexado ao nome a apresentar nas páginas de quotas. Para manter a consistência com os nomes a apresentar dos serviços Google indicados nas páginas de quotas que os consumidores da sua API veem, recomendamos o seguinte para o nome a apresentar:

  • Use "Pedidos" quando tiver apenas uma métrica.
  • Quando tem várias métricas, cada uma deve descrever o tipo de pedido e conter a palavra "pedidos" (por exemplo, "Pedidos de leitura" ou "Pedidos de gravação").
  • Use "Unidades de quota" em vez de "Pedidos" quando qualquer um dos custos desta quota for superior a 1.

limite Um valor inteiro que é o número máximo de pedidos por minuto por projeto de consumidor para a quota.

Exemplo

quota_limits = [
  endpoints.LimitDefinition('read-requests', 'Read Requests', 1000),
  endpoints.LimitDefinition('list-requests', 'List Requests', 100),
  endpoints.LimitDefinition('write-requests', 'Write Requests', 50)
]

@endpoints.api(name='bookstore',
               version='v1',
               limit_definitions=quota_limits)

IDs de clientes e públicos-alvo permitidos

Para a autenticação OAuth2, é emitida uma chave OAuth2 para um ID de cliente específico, o que significa que este ID de cliente pode ser usado para restringir o acesso às suas APIs. Quando regista aplicações Android na Google Cloud consola, cria um ID de cliente para as mesmas. Este ID do cliente é o que pede um token OAuth2 à Google para fins de autenticação. Quando a API de back-end está protegida por autenticação, é enviada uma chave de acesso OAuth2 e aberta pelos Frameworks de Endpoints para o App Engine. O ID de cliente é extraído da chave e, em seguida, o ID é comparado com a lista de IDs de clientes aceitáveis declarados do back-end (a lista allowed_client_ids).

A lista allowed_client_ids deve consistir em todos os IDs de clientes que obteve através da Google Cloud console para a Web, Android e outras apps de cliente. Isto significa que os clientes têm de ser conhecidos no momento da compilação da API. Se especificar uma lista vazia, nenhum cliente pode aceder à API.

Tenha em atenção que, em cada método API em que quer verificar a autenticação adequada, tem de chamar endpoints.get_current_user(). Consulte o artigo Autenticar utilizadores para mais informações.

Se usar o argumento allowed_client_ids e quiser testar chamadas autenticadas para a sua API usando o Explorador de APIs, tem de fornecer o respetivo ID de cliente na lista de allowed_client_ids especificando a constante endpoints.API_EXPLORER_CLIENT_ID. Tenha em atenção que, se allowed_client_ids contiver apenas endpoints.API_EXPLORER_CLIENT_ID e implementar a sua API, esta continua a ser publicamente detetável e acessível no Explorador de APIs.

Acerca dos públicos-alvo

A allowed_client_ids lista protege a API de back-end de clientes não autorizados. No entanto, é necessária uma proteção adicional para proteger os clientes, de modo que o respetivo token de autenticação funcione apenas para a API de back-end pretendida. Para clientes Android, este mecanismo é o argumento audiences, no qual especifica o ID do cliente da API de back-end.

Tenha em atenção que, quando cria um Google Cloud projeto da consola, é criado automaticamente um ID do cliente predefinido e nomeado para utilização pelo projeto. Quando carrega a sua API de back-end para o App Engine, este usa esse ID de cliente. Este é o ID de cliente Web mencionado na autorização da API.

Emissor de tokens de autenticação de terceiros

Se a sua aplicação aceitar tokens de autenticação que não sejam tokens de ID Google e forem emitidos por emissores externos, tem de definir corretamente os argumentos audiences e issuers em @endpoints.api para fornecer as informações sobre os emissores externos. Por exemplo:

@endpoints.api(
        audiences={'auth0': ['aud-1.auth0.com', 'aud-2.auth0.com']},
        issuers={'auth0': endpoints.Issuer('https://test.auth0.com',
                                           'https://test.auth0.com/.well-known/jwks.json')})
class GreetingApi(remote.Service):

Definir um método da API (@endpoints.method)

Pode definir as definições audiences, scopes e allowed_client_ids para toda a API através de @endpoints.api ou para um método através de @endpoints.method. Se estas definições forem especificadas ao nível da API e do método, a definição do método substitui a definição da API.

Para criar um método na sua API, decore o método Python correspondente com @endpoints.method, fornecendo argumentos para configurar a utilização do método. Por exemplo, especifica as classes de pedido e resposta Message a usar.

Os argumentos disponíveis estão listados na tabela seguinte:

@endpoints.method Argumentos Descrição Exemplo
allowed_client_ids Esta definição substitui o atributo equivalente especificado em @endpoints.api. Para mais informações, consulte o artigo IDs de clientes e públicos-alvo permitidos. ['1-web-apps.apps.googleusercontent.com', '2-android-apps.apps.googleusercontent.com']
api_key_required Opcional. Usado para restringir o acesso a pedidos que fornecem uma chave da API. api_key_required=True
audiences Substitui o argumento equivalente especificado em @endpoints.api. Para mais informações, consulte o artigo IDs de clientes e públicos-alvo permitidos. ['1-web-apps.apps.googleusercontent.com']
metric_costs Opcional. Indica que o método tem um limite de quota. Este é um dicionário com os seguintes pares de chave:valor:
  • name: um nome que especificou no argumento limit_definitions para o decorador da API.
  • cost: um número inteiro que especifica o custo de cada pedido. O custo permite que os métodos consumam a diferentes taxas a partir da mesma quota. Por exemplo, se uma quota tiver um limite de 1000 e um custo de 1, a aplicação de chamadas pode fazer 1000 pedidos por minuto antes de exceder o limite. Com um custo de 2 para a mesma quota, uma aplicação de chamadas só pode fazer 500 pedidos por minuto antes de exceder o limite.
metric_costs={'read-requests': 1}
http_method O método HTTP a usar. Se não definir esta opção, é usado o 'POST' por predefinição. 'GET'
name Um nome alternativo para este método. O name valor:
  • Tem de começar com letras minúsculas.
  • Tem de corresponder à expressão regular [a-z]+[A-Za-z0-9]*.
'yourApi'
path O caminho do URI para aceder a este método. Se não definir esta opção, é usado o nome do método Python. Se planear adicionar a gestão de APIs, não inclua uma barra invertida no final do caminho. 'yourapi/path'
Request Message turma A classe Google Protocol RPC Request Message a ser usada na chamada do método. Em alternativa, pode indicar o nome da classe. YourRequestClass
Response Message turma A classe Google Protocol RPC Response Message a ser usada na chamada do método. Em alternativa, pode indicar o nome da classe. YourResponseClass

Usar ResourceContainer para argumentos de caminho ou string de consulta

Se o pedido contiver argumentos de caminho ou de string de consulta, não pode usar uma classe Message simples, conforme descrito em Crie a API. Em alternativa, tem de usar uma classe ResourceContainer, da seguinte forma:

  1. Defina uma classe Message que tenha todos os argumentos transmitidos no corpo do pedido. Se não existirem argumentos no corpo do pedido, não precisa de definir uma classe Message: basta usar message_types.VoidMessage. Por exemplo:

    class Greeting(messages.Message):
        """Greeting that stores a message."""
    
        message = messages.StringField(1)
  2. Defina um ResourceContainer com a classe Message que definiu no passo anterior como o primeiro parâmetro. Especifique os argumentos do caminho e da string de consulta nos parâmetros subsequentes. Por exemplo:

    MULTIPLY_RESOURCE = endpoints.ResourceContainer(
        Greeting,
        times=messages.IntegerField(2, variant=messages.Variant.INT32, required=True),

    em que o primeiro argumento é a classe Message para os dados no corpo do pedido e times é um número esperado no caminho ou na string de consulta que acompanha o pedido.

  3. Forneça o ResourceContainer ao método que processa o pedido, no primeiro parâmetro, substituindo a classe Message de pedido que, de outra forma, seria fornecida nessa localização. Este fragmento mostra o ResourceContainer e o endpoints.method:

    # This ResourceContainer is similar to the one used for get_greeting, but
    # this one also contains a request body in the form of a Greeting message.
    MULTIPLY_RESOURCE = endpoints.ResourceContainer(
        Greeting,
        times=messages.IntegerField(2, variant=messages.Variant.INT32, required=True),
    )
    
    @endpoints.method(
        # This method accepts a request body containing a Greeting message
        # and a URL parameter specifying how many times to multiply the
        # message.
        MULTIPLY_RESOURCE,
        # This method returns a Greeting message.
        Greeting,
        path="greetings/multiply/{times}",
        http_method="POST",
        name="greetings.multiply",
    )
    def multiply_greeting(self, request):
        return Greeting(message=request.message * request.times)
    
  4. Adicione o parâmetro path, conforme mostrado, para incluir a sua API.

  5. Se o seu ResourceContainer tiver um argumento obrigatório, um pedido do cliente tem de o incluir numa string de consulta (por exemplo, yourApi?times=2) ou no caminho do URL (por exemplo, yourApi/2). No entanto, para que a sua API receba um valor de argumento através do caminho do URL, também tem de adicionar o nome do argumento ao caminho da API, conforme mostrado para o argumento {times} em path='yourApi/{times}.

O que se segue?