Segurança de conteúdo de IA do Azure biblioteca de cliente para Python – versão 1.0.0
Segurança de conteúdo de IA do Azure deteta conteúdos gerados pelo utilizador e gerados por IA prejudiciais em aplicações e serviços. A Segurança do Conteúdo inclui APIs de texto e imagem que lhe permitem detetar material prejudicial:
- API de Análise de Texto: analisa o texto para conteúdo sexual, violência, ódio e auto-dano com níveis de multi-gravidade.
- API de Análise de Imagens: analisa imagens de conteúdo sexual, violência, ódio e auto-dano com níveis de multi-gravidade.
- APIs de Gestão de Listas de Texto: os classificadores de IA predefinidos são suficientes para a maioria das necessidades de segurança de conteúdo; no entanto, poderá ter de analisar os termos específicos do seu caso de utilização. Pode criar listas de bloqueios de termos a utilizar com a API de Texto.
Documentação
Estão disponíveis várias documentação para o ajudar a começar
Introdução
Pré-requisitos
- O Python 3.7 ou posterior é necessário para utilizar este pacote.
- Precisa de uma subscrição do Azure para utilizar este pacote.
- Um recurso Segurança de conteúdo de IA do Azure, se não existir nenhum recurso, pode criar um novo.
Instalar o pacote
pip install azure-ai-contentsafety
Autenticar o cliente
Obter o ponto final
Pode encontrar o ponto final do recurso de serviço Segurança de conteúdo de IA do Azure com o Portal do Azure ou a CLI do Azure:
# Get the endpoint for the Azure AI Content Safety service resource
az cognitiveservices account show --name "resource-name" --resource-group "resource-group-name" --query "properties.endpoint"
Criar um ContentSafetyClient/BlocklistClient com a chave de API
Para utilizar uma chave de API como parâmetro credential
.
Passo 1: obter a chave de API. A chave de API pode ser encontrada no Portal do Azure ou ao executar o seguinte comando da CLI do Azure :
az cognitiveservices account keys list --name "<resource-name>" --resource-group "<resource-group-name>"
Passo 2: passar a chave como uma cadeia para uma instância de
AzureKeyCredential
.from azure.core.credentials import AzureKeyCredential from azure.ai.contentsafety import ContentSafetyClient, BlocklistClient endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/" credential = AzureKeyCredential("<api_key>") content_safety_client = ContentSafetyClient(endpoint, credential) blocklist_client = BlocklistClient(endpoint, credential)
Criar um ContentSafetyClient/BlocklistClient com Microsoft Entra credencial de token de ID
Passo 1: Ativar Microsoft Entra ID para o recurso. Veja este documento Authenticate with Microsoft Entra ID (Autenticar com Microsoft Entra ID) para obter os passos para ativar Microsoft Entra ID do recurso.
Os passos principais são:
- Crie um recurso com um subdomínio personalizado.
- Crie o Principal de Serviço e atribua-lhe a função de Utilizador dos Serviços Cognitivos.
Passo 2: defina os valores do ID de cliente, do ID do inquilino e do segredo do cliente da aplicação Microsoft Entra como variáveis de ambiente:
AZURE_CLIENT_ID
,AZURE_TENANT_ID
,AZURE_CLIENT_SECRET
.DefaultAzureCredential utilizará os valores destas variáveis de ambiente.
from azure.identity import DefaultAzureCredential from azure.ai.contentsafety import ContentSafetyClient, BlocklistClient endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/" credential = DefaultAzureCredential() content_safety_client = ContentSafetyClient(endpoint, credential) blocklist_client = BlocklistClient(endpoint, credential)
Conceitos-chave
Funcionalidades disponíveis
Existem diferentes tipos de análise disponíveis neste serviço. A tabela seguinte descreve as APIs atualmente disponíveis.
Funcionalidade | Descrição |
---|---|
API de Análise de Texto | Analisa texto para conteúdo sexual, violência, ódio e auto-mutilação com níveis de multi-gravidade. |
API de Análise de Imagens | Analisa imagens de conteúdo sexual, violência, ódio e auto-mutilação com níveis de multi-gravidade. |
APIs de Gestão de Listas de Texto | Os classificadores de IA predefinidos são suficientes para a maioria das necessidades de segurança de conteúdo. No entanto, poderá ter de analisar os termos específicos do seu caso de utilização. Pode criar listas de bloqueios de termos a utilizar com a API de Texto. |
Categorias de danos
A Content Safety reconhece quatro categorias distintas de conteúdo censurável.
Categoria | Descrição |
---|---|
Ódio | Os danos relacionados com o ódio e a justiça referem-se a qualquer conteúdo que ataque ou utilize linguagem pejorativa ou discriminatória com referência a uma pessoa ou grupo de identidade com base em certos atributos diferenciadores destes grupos, incluindo, mas não se limitando à raça, etnia, nacionalidade, identidade e expressão de género, orientação sexual, religião, estatuto de imigração, estatuto de capacidade, aparência pessoal e tamanho do corpo. |
Sexual | Sexual descreve linguagem relacionada com órgãos anatómicos e genitais, relações românticas, atos retratados em termos eróticos ou afectuosos, gravidez, atos sexuais físicos, incluindo aqueles retratados como uma agressão ou um ato violento sexual forçado contra a sua vontade, prostituição, pornografia e abuso. |
Violência | A violência descreve a linguagem relacionada com ações físicas destinadas a ferir, ferir, danificar ou matar alguém ou algo assim; descreve armas, armas e entidades relacionadas, tais como fabricantes, associações, legislação, etc. |
Auto-dano | O auto-dano descreve a linguagem relacionada com ações físicas destinadas a magoar, ferir, danificar o corpo ou matar-se a si próprio. |
A classificação pode ser com várias etiquetas. Por exemplo, quando uma amostra de texto passa pelo modelo de moderação de texto, pode ser classificada como Conteúdo sexual e Violência.
Níveis de gravidade
Todas as categorias de danos que o serviço aplica também têm uma classificação de nível de gravidade. O nível de gravidade destina-se a indicar a gravidade das consequências de mostrar o conteúdo sinalizado.
Texto: a versão atual do modelo de texto suporta a escala de gravidade 0-7 completa. Por predefinição, a resposta irá produzir 4 valores: 0, 2, 4 e 6. Cada dois níveis adjacentes são mapeados para um único nível. Os utilizadores podem utilizar "outputType" no pedido e defini-lo como "EightSeverityLevels" para obter 8 valores na saída: 0,1,2,3,4,5,6,7. Pode consultar definições de níveis de gravidade de conteúdo de texto para obter detalhes.
- [0,1] -> 0
- [2,3] -> 2
- [4,5] -> 4
- [6,7] -> 6
Imagem: A versão atual do modelo de imagem suporta a versão cortada da escala de gravidade 0-7 completa. O classificador só devolve gravidades 0, 2, 4 e 6; cada dois níveis adjacentes são mapeados para um único nível. Pode consultar definições de níveis de gravidade de conteúdo de imagem para obter detalhes.
- [0,1] -> 0
- [2,3] -> 2
- [4,5] -> 4
- [6,7] -> 6
Gestão da lista de bloqueios de texto
As seguintes operações são suportadas para gerir a lista de bloqueios de texto:
- Criar ou modificar uma lista de bloqueios
- Listar todas as listas de bloqueios
- Obter uma lista de bloqueios por blocklistName
- Adicionar blocklistItems a uma lista de bloqueios
- Remover blocklistItems de uma lista de bloqueios
- Listar todos os blocklistItems numa lista de bloqueios por blocklistName
- Obter um blocklistItem numa lista de bloqueios por blocklistItemId e blocklistName
- Eliminar uma lista de bloqueios e todos os seus blocklistItems
Pode definir as listas de bloqueio que pretende utilizar quando analisar texto e, em seguida, pode obter o resultado da correspondência da lista de bloqueios da resposta devolvida.
Exemplos
A secção seguinte fornece vários fragmentos de código que abrangem algumas das tarefas mais comuns do serviço de Segurança de Conteúdos, incluindo:
Veja os dados de exemplo dos dados utilizados aqui. Para obter mais exemplos, veja exemplos.
Analisar texto
Analisar texto sem listas de bloqueio
import os
from azure.ai.contentsafety import ContentSafetyClient
from azure.ai.contentsafety.models import TextCategory
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.ai.contentsafety.models import AnalyzeTextOptions
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Content Safety client
client = ContentSafetyClient(endpoint, AzureKeyCredential(key))
# Construct a request
request = AnalyzeTextOptions(text="You are an idiot")
# Analyze text
try:
response = client.analyze_text(request)
except HttpResponseError as e:
print("Analyze text failed.")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
hate_result = next(item for item in response.categories_analysis if item.category == TextCategory.HATE)
self_harm_result = next(item for item in response.categories_analysis if item.category == TextCategory.SELF_HARM)
sexual_result = next(item for item in response.categories_analysis if item.category == TextCategory.SEXUAL)
violence_result = next(item for item in response.categories_analysis if item.category == TextCategory.VIOLENCE)
if hate_result:
print(f"Hate severity: {hate_result.severity}")
if self_harm_result:
print(f"SelfHarm severity: {self_harm_result.severity}")
if sexual_result:
print(f"Sexual severity: {sexual_result.severity}")
if violence_result:
print(f"Violence severity: {violence_result.severity}")
Analisar texto com listas de bloqueio
import os
from azure.ai.contentsafety import ContentSafetyClient
from azure.core.credentials import AzureKeyCredential
from azure.ai.contentsafety.models import AnalyzeTextOptions
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Content Safety client
client = ContentSafetyClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
input_text = "I h*te you and I want to k*ll you."
try:
# After you edit your blocklist, it usually takes effect in 5 minutes, please wait some time before analyzing with blocklist after editing.
analysis_result = client.analyze_text(
AnalyzeTextOptions(text=input_text, blocklist_names=[blocklist_name], halt_on_blocklist_hit=False)
)
if analysis_result and analysis_result.blocklists_match:
print("\nBlocklist match results: ")
for match_result in analysis_result.blocklists_match:
print(
f"BlocklistName: {match_result.blocklist_name}, BlockItemId: {match_result.blocklist_item_id}, "
f"BlockItemText: {match_result.blocklist_item_text}"
)
except HttpResponseError as e:
print("\nAnalyze text failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Analisar imagem
import os
from azure.ai.contentsafety import ContentSafetyClient
from azure.ai.contentsafety.models import ImageCategory
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.ai.contentsafety.models import AnalyzeImageOptions, ImageData
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
image_path = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "./sample_data/image.jpg"))
# Create a Content Safety client
client = ContentSafetyClient(endpoint, AzureKeyCredential(key))
# Build request
with open(image_path, "rb") as file:
request = AnalyzeImageOptions(image=ImageData(content=file.read()))
# Analyze image
try:
response = client.analyze_image(request)
except HttpResponseError as e:
print("Analyze image failed.")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
hate_result = next(item for item in response.categories_analysis if item.category == ImageCategory.HATE)
self_harm_result = next(item for item in response.categories_analysis if item.category == ImageCategory.SELF_HARM)
sexual_result = next(item for item in response.categories_analysis if item.category == ImageCategory.SEXUAL)
violence_result = next(item for item in response.categories_analysis if item.category == ImageCategory.VIOLENCE)
if hate_result:
print(f"Hate severity: {hate_result.severity}")
if self_harm_result:
print(f"SelfHarm severity: {self_harm_result.severity}")
if sexual_result:
print(f"Sexual severity: {sexual_result.severity}")
if violence_result:
print(f"Violence severity: {violence_result.severity}")
Gerir lista de bloqueios de texto
Criar ou atualizar a lista de bloqueios de texto
import os
from azure.ai.contentsafety import BlocklistClient
from azure.ai.contentsafety.models import TextBlocklist
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
blocklist_description = "Test blocklist management."
try:
blocklist = client.create_or_update_text_blocklist(
blocklist_name=blocklist_name,
options=TextBlocklist(blocklist_name=blocklist_name, description=blocklist_description),
)
if blocklist:
print("\nBlocklist created or updated: ")
print(f"Name: {blocklist.blocklist_name}, Description: {blocklist.description}")
except HttpResponseError as e:
print("\nCreate or update text blocklist failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Listar listas de bloqueios de texto
import os
from azure.ai.contentsafety import BlocklistClient
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
try:
blocklists = client.list_text_blocklists()
if blocklists:
print("\nList blocklists: ")
for blocklist in blocklists:
print(f"Name: {blocklist.blocklist_name}, Description: {blocklist.description}")
except HttpResponseError as e:
print("\nList text blocklists failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Obter lista de bloqueios de texto
import os
from azure.ai.contentsafety import BlocklistClient
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
try:
blocklist = client.get_text_blocklist(blocklist_name=blocklist_name)
if blocklist:
print("\nGet blocklist: ")
print(f"Name: {blocklist.blocklist_name}, Description: {blocklist.description}")
except HttpResponseError as e:
print("\nGet text blocklist failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Eliminar lista de bloqueios de texto
import os
from azure.ai.contentsafety import BlocklistClient
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
try:
client.delete_text_blocklist(blocklist_name=blocklist_name)
print(f"\nDeleted blocklist: {blocklist_name}")
except HttpResponseError as e:
print("\nDelete blocklist failed:")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Adicionar blockItems
import os
from azure.ai.contentsafety import BlocklistClient
from azure.ai.contentsafety.models import AddOrUpdateTextBlocklistItemsOptions, TextBlocklistItem
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
block_item_text_1 = "k*ll"
block_item_text_2 = "h*te"
block_items = [TextBlocklistItem(text=block_item_text_1), TextBlocklistItem(text=block_item_text_2)]
try:
result = client.add_or_update_blocklist_items(
blocklist_name=blocklist_name, options=AddOrUpdateTextBlocklistItemsOptions(blocklist_items=block_items)
)
for block_item in result.blocklist_items:
print(
f"BlockItemId: {block_item.blocklist_item_id}, Text: {block_item.text}, Description: {block_item.description}"
)
except HttpResponseError as e:
print("\nAdd block items failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Listar blockItems
import os
from azure.ai.contentsafety import BlocklistClient
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
try:
block_items = client.list_text_blocklist_items(blocklist_name=blocklist_name)
if block_items:
print("\nList block items: ")
for block_item in block_items:
print(
f"BlockItemId: {block_item.blocklist_item_id}, Text: {block_item.text}, "
f"Description: {block_item.description}"
)
except HttpResponseError as e:
print("\nList block items failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Obter blockItem
import os
from azure.ai.contentsafety import BlocklistClient
from azure.core.credentials import AzureKeyCredential
from azure.ai.contentsafety.models import TextBlocklistItem, AddOrUpdateTextBlocklistItemsOptions
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
block_item_text_1 = "k*ll"
try:
# Add a blockItem
add_result = client.add_or_update_blocklist_items(
blocklist_name=blocklist_name,
options=AddOrUpdateTextBlocklistItemsOptions(blocklist_items=[TextBlocklistItem(text=block_item_text_1)]),
)
if not add_result or not add_result.blocklist_items or len(add_result.blocklist_items) <= 0:
raise RuntimeError("BlockItem not created.")
block_item_id = add_result.blocklist_items[0].blocklist_item_id
# Get this blockItem by blockItemId
block_item = client.get_text_blocklist_item(blocklist_name=blocklist_name, blocklist_item_id=block_item_id)
print("\nGet blockitem: ")
print(
f"BlockItemId: {block_item.blocklist_item_id}, Text: {block_item.text}, Description: {block_item.description}"
)
except HttpResponseError as e:
print("\nGet block item failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Remover blockItems
import os
from azure.ai.contentsafety import BlocklistClient
from azure.core.credentials import AzureKeyCredential
from azure.ai.contentsafety.models import (
TextBlocklistItem,
AddOrUpdateTextBlocklistItemsOptions,
RemoveTextBlocklistItemsOptions,
)
from azure.core.exceptions import HttpResponseError
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
# Create a Blocklist client
client = BlocklistClient(endpoint, AzureKeyCredential(key))
blocklist_name = "TestBlocklist"
block_item_text_1 = "k*ll"
try:
# Add a blockItem
add_result = client.add_or_update_blocklist_items(
blocklist_name=blocklist_name,
options=AddOrUpdateTextBlocklistItemsOptions(blocklist_items=[TextBlocklistItem(text=block_item_text_1)]),
)
if not add_result or not add_result.blocklist_items or len(add_result.blocklist_items) <= 0:
raise RuntimeError("BlockItem not created.")
block_item_id = add_result.blocklist_items[0].blocklist_item_id
# Remove this blockItem by blockItemId
client.remove_blocklist_items(
blocklist_name=blocklist_name, options=RemoveTextBlocklistItemsOptions(blocklist_item_ids=[block_item_id])
)
print(f"\nRemoved blockItem: {add_result.blocklist_items[0].blocklist_item_id}")
except HttpResponseError as e:
print("\nRemove block item failed: ")
if e.error:
print(f"Error code: {e.error.code}")
print(f"Error message: {e.error.message}")
raise
print(e)
raise
Resolução de problemas
Geral
Segurança de conteúdo de IA do Azure biblioteca de cliente irá gerar exceções definidas no Azure Core. Os códigos de erro são definidos como abaixo:
Código de Erro | Motivos possíveis | Sugestões |
---|---|---|
InvalidRequestBody | Um ou mais campos no corpo do pedido não correspondem à definição da API. | 1. Verifique a versão da API que especificou na chamada à API. 2. Verifique a definição da API correspondente para a versão da API que selecionou. |
InvalidResourceName | O nome do recurso especificado no URL não cumpre os requisitos, como o nome da lista de bloqueios, o ID do termo da lista de bloqueios, etc. | 1. Verifique a versão da API que especificou na chamada à API. 2. Verifique se o nome especificado tem carateres inválidos de acordo com a definição da API. |
ResourceNotFound | O recurso que especificou no URL pode não existir, como o nome da lista de bloqueios. | 1. Verifique a versão da API que especificou na chamada à API. 2. Verifique novamente a existência do recurso especificado no URL. |
InternalError | Algumas situações inesperadas no lado do servidor foram acionadas. | 1. Poderá querer repetir algumas vezes após um pequeno período e ver que o problema volta a ocorrer. 2. Contacte o Suporte do Azure se este problema persistir. |
ServerBusy | O lado do servidor não consegue processar o pedido temporariamente. | 1. Poderá querer repetir algumas vezes após um pequeno período e ver que o problema volta a ocorrer. 2.Contacte o Suporte do Azure se este problema persistir. |
TooManyRequests | O RPS atual excedeu a quota do SKU atual. | 1. Verifique a tabela de preços para compreender a quota de RPS. 2.Contacte o Suporte do Azure se precisar de mais QPS. |
Registo
Esta biblioteca utiliza a biblioteca de registos padrão para registos.
As informações básicas sobre as sessões HTTP (URLs, cabeçalhos, etc.) são registadas ao INFO
nível.
O registo de nível detalhado DEBUG
, incluindo os corpos de pedido/resposta e cabeçalhos não retotados , pode ser ativado no cliente ou por operação com o logging_enable
argumento palavra-chave.
Veja a documentação completa do registo do SDK com exemplos aqui.
Configuração opcional
Os argumentos de palavra-chave opcionais podem ser transmitidos ao nível do cliente e por operação. A documentação de referência do azure-core descreve as configurações disponíveis para repetições, registos, protocolos de transporte e muito mais.
Passos seguintes
Documentação adicional
Para obter documentação mais extensa sobre a Segurança de Conteúdos do Azure, veja o Segurança de conteúdo de IA do Azure no docs.microsoft.com.
Contribuir
Agradecemos todas as contribuições e sugestões para este projeto. A maioria das contribuições requerem que celebre um Contrato de Licença de Contribuição (CLA) no qual se declare que tem o direito de conceder e que, na verdade, concede-nos os direitos para utilizar a sua contribuição. Para mais detalhes, visite https://cla.microsoft.com.
Quando submete um pedido Pull, um bot do CLA determina automaticamente se tem de fornecer um CLA e decorar o PR de forma adequada (por exemplo, etiqueta, comentário). Só tem de seguir as instruções fornecidas pelo bot. Apenas terá de fazer isto uma vez em todos os repositórios com o nosso CLA.
Este projeto adotou o Microsoft Open Source Code of Conduct (Código de Conduta do Microsoft Open Source). Para obter mais informações, veja a Code of Conduct FAQ (FAQ do Código de Conduta) ou envie um e-mail para opencode@microsoft.com com quaisquer perguntas ou comentários adicionais.
Azure SDK for Python