Migrar para a biblioteca cliente Python v0.25.1

A biblioteca cliente para Python v0.25.1 inclui algumas alterações significativas à forma como as bibliotecas cliente anteriores foram concebidas. Estas alterações podem ser resumidas da seguinte forma:

  • Consolidação de módulos em menos tipos

  • Substituir parâmetros não tipados por classes e enumerações fortemente tipadas

Este tópico fornece detalhes sobre as alterações que tem de fazer ao seu código Python para as bibliotecas cliente da API Cloud Vision de forma a usar a biblioteca cliente Python v0.25.1.

Executar versões anteriores da biblioteca cliente

Não tem de atualizar a sua biblioteca cliente Python para a versão 0.25.1. Se quiser continuar a usar uma versão anterior da biblioteca cliente Python e não quiser migrar o seu código, deve especificar a versão da biblioteca cliente Python usada pela sua app. Para especificar uma versão específica da biblioteca, edite o ficheiro requirements.txt, conforme mostrado:

google-cloud-vision==0.25

Módulos removidos

Os seguintes módulos foram removidos no pacote da biblioteca cliente Python v0.25.1.

  • google.cloud.vision.annotations

  • google.cloud.vision.batch

  • google.cloud.vision.client

  • google.cloud.vision.color

  • google.cloud.vision.crop_hint

  • google.cloud.vision.entity

  • google.cloud.vision.face

  • google.cloud.vision.feature

  • google.cloud.vision.geometry

  • google.cloud.vision.image

  • google.cloud.vision.likelihood

  • google.cloud.vision.safe_search

  • google.cloud.vision.text

  • google.cloud.vision.web

Alterações de código necessárias

Importações

Inclua o novo módulo google.cloud.vision.types para aceder aos novos tipos na biblioteca cliente Python v0.25.1.

O módulo types contém as novas classes necessárias para criar pedidos, como types.Image.

from google.cloud import vision

Além disso, o novo módulo google.cloud.vision.enums contém as enumerações úteis para analisar e compreender as respostas da API, como enums.Likelihood.UNLIKELY e enums.FaceAnnotation.Landmark.Type.LEFT_EYE.

Crie um cliente

A classe Client foi substituída pela classe ImageAnnotatorClient. Substitua as referências à turma Client por ImageAnnotatorClient.

Versões anteriores das bibliotecas cliente:

old_client = vision.Client()

Biblioteca cliente Python v0.25.1:

client = vision.ImageAnnotatorClient()

Construir objetos que representam conteúdo de imagem

Para identificar conteúdo de imagem a partir de um ficheiro local, de um URI do Google Cloud Storage ou de um URI da Web, use a nova classe Image.

Construir objetos que representam conteúdo de imagem a partir de um ficheiro local

O exemplo seguinte mostra a nova forma de representar conteúdo de imagem a partir de um ficheiro local.

Versões anteriores das bibliotecas cliente:

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

Construir objetos que representam conteúdo de imagem a partir de um URI

O exemplo seguinte mostra a nova forma de representar conteúdo de imagem a partir de um URI do Google Cloud Storage ou de um URI da Web. uri é o URI de um ficheiro de imagem no Google Cloud Storage ou na Web.

Versões anteriores das bibliotecas cliente:

image = old_client.image(source_uri=uri)

Biblioteca cliente Python v0.25.1:

image = vision.Image()
image.source.image_uri = uri

Fazer pedidos e processar respostas

Com a biblioteca cliente Python v.0.25.1, os métodos da API, como face_detection, pertencem ao objeto ImageAnnotatorClient, em vez dos objetos Image.

Os valores devolvidos são diferentes para vários métodos, conforme explicado abaixo.

Em particular, os vértices da caixa delimitadora são agora armazenados em bounding_poly.vertices, em vez de bounds.vertices. As coordenadas de cada vértice são armazenadas em vertex.x e vertex.y, em vez de vertex.x_coordinate e vertex.y_coordinate.

A alteração da caixa delimitadora afeta face_detection, logo_detection, text_detection, document_text_detection e crop_hints.

Fazer um pedido de deteção de caras e processar a resposta

As probabilidades de emoções são agora devolvidas como enumerações armazenadas em face.surprise_likelihood, em vez de face.emotions.surprise. Pode recuperar os nomes das etiquetas de probabilidade importando google.cloud.vision.enums.Likelihood.

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

faces = image.detect_faces()

for face in faces:
    print('anger: {}'.format(face.emotions.anger))
    print('joy: {}'.format(face.emotions.joy))
    print('surprise: {}'.format(face.emotions.surprise))

    vertices = (['({},{})'.format(bound.x_coordinate, bound.y_coordinate)
                for bound in face.bounds.vertices])

    print('face bounds: {}'.format(','.join(vertices)))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.face_detection(image=image)
faces = response.face_annotations

# Names of likelihood from google.cloud.vision.enums
likelihood_name = (
    "UNKNOWN",
    "VERY_UNLIKELY",
    "UNLIKELY",
    "POSSIBLE",
    "LIKELY",
    "VERY_LIKELY",
)
print("Faces:")

for face in faces:
    print(f"anger: {likelihood_name[face.anger_likelihood]}")
    print(f"joy: {likelihood_name[face.joy_likelihood]}")
    print(f"surprise: {likelihood_name[face.surprise_likelihood]}")

    vertices = [
        f"({vertex.x},{vertex.y})" for vertex in face.bounding_poly.vertices
    ]

    print("face bounds: {}".format(",".join(vertices)))

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção de etiquetas e processar a resposta

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

labels = image.detect_labels()

for label in labels:
    print(label.description)

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.label_detection(image=image)
labels = response.label_annotations
print("Labels:")

for label in labels:
    print(label.description)

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção de pontos de referência e processar a resposta

Versões anteriores das bibliotecas cliente::

A latitude e a longitude das localizações de pontos de referência estão agora armazenadas em location.lat_lng.latitude e location.lat_lng.longitude, em vez de location.latitude e location.longitude.

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

landmarks = image.detect_landmarks()

for landmark in landmarks:
    print(landmark.description, landmark.score)
    for location in landmark.locations:
        print('Latitude'.format(location.latitude))
        print('Longitude'.format(location.longitude))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.landmark_detection(image=image)
landmarks = response.landmark_annotations
print("Landmarks:")

for landmark in landmarks:
    print(landmark.description)
    for location in landmark.locations:
        lat_lng = location.lat_lng
        print(f"Latitude {lat_lng.latitude}")
        print(f"Longitude {lat_lng.longitude}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção de logótipo e processar a resposta

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

logos = image.detect_logos()

for logo in logos:
    print(logo.description, logo.score)

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.logo_detection(image=image)
logos = response.logo_annotations
print("Logos:")

for logo in logos:
    print(logo.description)

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção da Pesquisa Segura e processar a resposta

As probabilidades da Pesquisa segura são agora devolvidas como enumerações. Pode recuperar os nomes das etiquetas de probabilidade importando google.cloud.vision.enums.Likelihood.

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

safe = image.detect_safe_search()
print('Safe search:')
print('adult: {}'.format(safe.adult))
print('medical: {}'.format(safe.medical))
print('spoofed: {}'.format(safe.spoof))
print('violence: {}'.format(safe.violence))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.safe_search_detection(image=image)
safe = response.safe_search_annotation

# Names of likelihood from google.cloud.vision.enums
likelihood_name = (
    "UNKNOWN",
    "VERY_UNLIKELY",
    "UNLIKELY",
    "POSSIBLE",
    "LIKELY",
    "VERY_LIKELY",
)
print("Safe search:")

print(f"adult: {likelihood_name[safe.adult]}")
print(f"medical: {likelihood_name[safe.medical]}")
print(f"spoofed: {likelihood_name[safe.spoof]}")
print(f"violence: {likelihood_name[safe.violence]}")
print(f"racy: {likelihood_name[safe.racy]}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção de texto e processar a resposta

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

texts = image.detect_text()

for text in texts:
    print('\n"{}"'.format(text.description))

    vertices = (['({},{})'.format(bound.x_coordinate, bound.y_coordinate)
                for bound in text.bounds.vertices])

    print('bounds: {}'.format(','.join(vertices)))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.text_detection(image=image)
texts = response.text_annotations
print("Texts:")

for text in texts:
    print(f'\n"{text.description}"')

    vertices = [
        f"({vertex.x},{vertex.y})" for vertex in text.bounding_poly.vertices
    ]

    print("bounds: {}".format(",".join(vertices)))

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção de texto de documentos e processar a resposta

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

document = image.detect_full_text()

for page in document.pages:
    for block in page.blocks:
        block_words = []
        for paragraph in block.paragraphs:
            block_words.extend(paragraph.words)

        block_symbols = []
        for word in block_words:
            block_symbols.extend(word.symbols)

        block_text = ''
        for symbol in block_symbols:
            block_text = block_text + symbol.text

        print('Block Content: {}'.format(block_text))
        print('Block Bounds:\n {}'.format(block.bounding_box))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.document_text_detection(image=image)

for page in response.full_text_annotation.pages:
    for block in page.blocks:
        print(f"\nBlock confidence: {block.confidence}\n")

        for paragraph in block.paragraphs:
            print("Paragraph confidence: {}".format(paragraph.confidence))

            for word in paragraph.words:
                word_text = "".join([symbol.text for symbol in word.symbols])
                print(
                    "Word text: {} (confidence: {})".format(
                        word_text, word.confidence
                    )
                )

                for symbol in word.symbols:
                    print(
                        "\tSymbol: {} (confidence: {})".format(
                            symbol.text, symbol.confidence
                        )
                    )

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de propriedades de imagens e processar a resposta

As informações de cor dominante são agora armazenadas em props.dominant_colors.colors, em vez de props.colors.

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

props = image.detect_properties()

for color in props.colors:
    print('fraction: {}'.format(color.pixel_fraction))
    print('\tr: {}'.format(color.color.red))
    print('\tg: {}'.format(color.color.green))
    print('\tb: {}'.format(color.color.blue))
    print('\ta: {}'.format(color.color.alpha))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.image_properties(image=image)
props = response.image_properties_annotation
print("Properties:")

for color in props.dominant_colors.colors:
    print(f"fraction: {color.pixel_fraction}")
    print(f"\tr: {color.color.red}")
    print(f"\tg: {color.color.green}")
    print(f"\tb: {color.color.blue}")
    print(f"\ta: {color.color.alpha}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de deteção na Web e processar a resposta

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

notes = image.detect_web()

if notes.pages_with_matching_images:
    print('\n{} Pages with matching images retrieved')

    for page in notes.pages_with_matching_images:
        print('Score : {}'.format(page.score))
        print('Url   : {}'.format(page.url))

if notes.full_matching_images:
    print ('\n{} Full Matches found: '.format(
           len(notes.full_matching_images)))

    for image in notes.full_matching_images:
        print('Score:  {}'.format(image.score))
        print('Url  : {}'.format(image.url))

if notes.partial_matching_images:
    print ('\n{} Partial Matches found: '.format(
           len(notes.partial_matching_images)))

    for image in notes.partial_matching_images:
        print('Score: {}'.format(image.score))
        print('Url  : {}'.format(image.url))

if notes.web_entities:
    print ('\n{} Web entities found: '.format(len(notes.web_entities)))

    for entity in notes.web_entities:
        print('Score      : {}'.format(entity.score))
        print('Description: {}'.format(entity.description))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()

image = vision.Image(content=content)

response = client.web_detection(image=image)
annotations = response.web_detection

if annotations.best_guess_labels:
    for label in annotations.best_guess_labels:
        print(f"\nBest guess label: {label.label}")

if annotations.pages_with_matching_images:
    print(
        "\n{} Pages with matching images found:".format(
            len(annotations.pages_with_matching_images)
        )
    )

    for page in annotations.pages_with_matching_images:
        print(f"\n\tPage url   : {page.url}")

        if page.full_matching_images:
            print(
                "\t{} Full Matches found: ".format(len(page.full_matching_images))
            )

            for image in page.full_matching_images:
                print(f"\t\tImage url  : {image.url}")

        if page.partial_matching_images:
            print(
                "\t{} Partial Matches found: ".format(
                    len(page.partial_matching_images)
                )
            )

            for image in page.partial_matching_images:
                print(f"\t\tImage url  : {image.url}")

if annotations.web_entities:
    print("\n{} Web entities found: ".format(len(annotations.web_entities)))

    for entity in annotations.web_entities:
        print(f"\n\tScore      : {entity.score}")
        print(f"\tDescription: {entity.description}")

if annotations.visually_similar_images:
    print(
        "\n{} visually similar images found:\n".format(
            len(annotations.visually_similar_images)
        )
    )

    for image in annotations.visually_similar_images:
        print(f"\tImage url    : {image.url}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Fazer um pedido de sugestões de recorte e processar a resposta

Versões anteriores das bibliotecas cliente::

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()

image = old_client.image(content=content)

hints = image.detect_crop_hints(aspect_ratios=[1.77])

for n, hint in enumerate(hints):
    print('\nCrop Hint: {}'.format(n))

    vertices = (['({},{})'.format(bound.x_coordinate, bound.y_coordinate)
                for bound in hint.bounds.vertices])

    print('bounds: {}'.format(','.join(vertices)))

Biblioteca cliente Python v0.25.1:

with open(path, "rb") as image_file:
    content = image_file.read()
image = vision.Image(content=content)

crop_hints_params = vision.CropHintsParams(aspect_ratios=[1.77])
image_context = vision.ImageContext(crop_hints_params=crop_hints_params)

response = client.crop_hints(image=image, image_context=image_context)
hints = response.crop_hints_annotation.crop_hints

for n, hint in enumerate(hints):
    print(f"\nCrop Hint: {n}")

    vertices = [
        f"({vertex.x},{vertex.y})" for vertex in hint.bounding_poly.vertices
    ]

    print("bounds: {}".format(",".join(vertices)))

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

Tenha em atenção que os formatos têm de ser transmitidos através de um CropHintsParams e um ImageContext.