チラシの商品名をLINE送信

チラシの商品名をLINE送信

ocr_list.py
でキーワードと一致した商品名の取得ができるので
これを
line_notify.pyにセットして送信するようにする

import json
from google.cloud import vision
import io

# 設定ファイルの読み込み
settings_json = open('settings.json', 'r', encoding='utf_8')
settings = json.load(settings_json)

# OCRで画像からテキストを抽出
def detect_text(image_paths):
    client = vision.ImageAnnotatorClient()

    all_text = ''

    for image_path in image_paths:
        with io.open(image_path, 'rb') as image_file:
            content = image_file.read()

        image = vision.Image(content=content)

        # document_text_detectionを使用して文書全体のテキストを取得
        response = client.document_text_detection(image=image)
        full_text_annotation = response.full_text_annotation

        # テキストの抽出
        all_text += full_text_annotation.text

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

    return all_text

# キーワード検索
def search_words(all_text):
    hitwords = []
    for keyword in settings["keywords"]:
        if keyword in all_text:
            hitwords.append(keyword)

    return hitwords

# 例として実行
if __name__ == "__main__":
    image_paths = ["images/combined_image_20240805.jpg"]
    extracted_text = detect_text(image_paths)
    hitwords = search_words(extracted_text)
    
    # ヒットしたキーワードのみを表示
    if hitwords:
        print("マッチしたキーワード:", ", ".join(hitwords))
    else:
        print("マッチしたキーワードはありませんでした。")

の中で

import requests
import os
from PIL import Image
from io import BytesIO
from utils import load_config, get_latest_directory, get_image_files

def resize_image_if_needed(image_data, max_size=3 * 1024 * 1024):
    if len(image_data) > max_size:
        image = Image.open(BytesIO(image_data))
        new_size = (image.width // 2, image.height // 2)
        image = image.resize(new_size, Image.LANCZOS)

        output = BytesIO()
        image_format = image.format if image.format else 'JPEG'
        image.save(output, format=image_format)
        return output.getvalue()
    return image_data

def send_line_notify(message, config_path='config.json'):
    # 設定ファイルを読み込む
    config = load_config(config_path)

    # 設定ファイルからトークンとディレクトリパスを取得
    token = config['token']
    base_path = config['image_file_path']

    # 最新のpredictディレクトリを取得
    latest_dir = get_latest_directory(base_path)
    image_files = get_image_files(latest_dir)

    url = 'https://notify-api.line.me/api/notify'

    headers = {'Authorization': f"Bearer {token}"}
    params = {'message': message}

    # 最新のpredictディレクトリ内の全ての画像ファイルに対してLINE Notify APIにリクエストを送信
    for image_file_path in image_files:
        with open(image_file_path, 'rb') as img_file:
            img_data = img_file.read()
            img_data = resize_image_if_needed(img_data)

            # ファイルデータをバイトデータとして用意
            files = {'imageFile': BytesIO(img_data)}
            files['imageFile'].name = os.path.basename(image_file_path)

            # LINE Notify APIにリクエストを送信
            res = requests.post(url, headers=headers, params=params, files=files)

            # レスポンスを出力
            print(f"File: {image_file_path}")
            print(res.status_code)
            print(res.text)

を呼び出し
hit words を line notifyで送信したい

その前に

import requests
import os
from PIL import Image
from io import BytesIO
from utils import load_config, get_latest_directory, get_image_files

def resize_image_if_needed(image_data, max_size=3 * 1024 * 1024):
    if len(image_data) > max_size:
        image = Image.open(BytesIO(image_data))
        new_size = (image.width // 2, image.height // 2)
        image = image.resize(new_size, Image.LANCZOS)

        output = BytesIO()
        image_format = image.format if image.format else 'JPEG'
        image.save(output, format=image_format)
        return output.getvalue()
    return image_data

def send_line_notify(message, config_path='config.json'):
    # 設定ファイルを読み込む
    config = load_config(config_path)

    # 設定ファイルからトークンとディレクトリパスを取得
    token = config['token']
    base_path = config['image_file_path']

    # 最新のpredictディレクトリを取得
    latest_dir = get_latest_directory(base_path)
    image_files = get_image_files(latest_dir)

    url = 'https://notify-api.line.me/api/notify'

    headers = {'Authorization': f"Bearer {token}"}
    params = {'message': message}

    # 最新のpredictディレクトリ内の全ての画像ファイルに対してLINE Notify APIにリクエストを送信
    for image_file_path in image_files:
        with open(image_file_path, 'rb') as img_file:
            img_data = img_file.read()
            img_data = resize_image_if_needed(img_data)

            # ファイルデータをバイトデータとして用意
            files = {'imageFile': BytesIO(img_data)}
            files['imageFile'].name = os.path.basename(image_file_path)

            # LINE Notify APIにリクエストを送信
            res = requests.post(url, headers=headers, params=params, files=files)

            # レスポンスを出力
            print(f"File: {image_file_path}")
            print(res.status_code)
            print(res.text)

で今回はyolov8は使ってないので
まずはテキストのみにする

import requests
import os
from utils import load_config

def send_line_notify(message, config_path='config.json'):
    # 設定ファイルを読み込む
    config = load_config(config_path)

    # 設定ファイルからトークンを取得
    token = config['token']

    url = 'https://notify-api.line.me/api/notify'

    headers = {'Authorization': f"Bearer {token}"}
    params = {'message': message}

    # LINE Notify APIにリクエストを送信
    res = requests.post(url, headers=headers, params=params)

    # レスポンスを出力
    print(res.status_code)
    print(res.text)

# 例として実行
if __name__ == "__main__":
    message = "マッチしたキーワード: サンプルキーワード"
    send_line_notify(message)

とりあえず main 部分は削除して
ocr_list.pyの中で呼び出したい

import json
from google.cloud import vision
import io
from line_notify import send_line_notify

# 設定ファイルの読み込み
def load_settings(file_path='settings.json'):
    with open(file_path, 'r', encoding='utf_8') as settings_json:
        return json.load(settings_json)

# OCRで画像からテキストを抽出
def detect_text(image_paths):
    client = vision.ImageAnnotatorClient()

    all_text = ''

    for image_path in image_paths:
        with io.open(image_path, 'rb') as image_file:
            content = image_file.read()

        image = vision.Image(content=content)

        # document_text_detectionを使用して文書全体のテキストを取得
        response = client.document_text_detection(image=image)
        full_text_annotation = response.full_text_annotation

        # テキストの抽出
        all_text += full_text_annotation.text

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

    return all_text

# キーワード検索
def search_words(all_text, keywords):
    hitwords = []
    for keyword in keywords:
        if keyword in all_text:
            hitwords.append(keyword)

    return hitwords

# 例として実行
if __name__ == "__main__":
    settings = load_settings()
    image_paths = ["images/combined_image_20240805.jpg"]
    extracted_text = detect_text(image_paths)
    hitwords = search_words(extracted_text, settings["keywords"])
    
    # ヒットしたキーワードをLINE Notifyで送信
    if hitwords:
        message = "マッチしたキーワード: " + ", ".join(hitwords)
        send_line_notify(message)
    else:
        print("マッチしたキーワードはありませんでした。")

これを実行したらLINEで送信されたのでOK

このままだとメッセージが分かりにくいので
マッチしたキーワードから
特売リスト
にメッセージを変更

そしてOCRした画像ファイルも一緒にLINE送信するように
line_notify.pyのソースを変更

import requests
import os
from utils import load_config

def send_line_notify(message, config_path='config.json'):
    # 設定ファイルを読み込む
    config = load_config(config_path)

    # 設定ファイルからトークンを取得
    token = config['token']

    url = 'https://notify-api.line.me/api/notify'

    headers = {'Authorization': f"Bearer {token}"}
    params = {'message': message}

    # LINE Notify APIにリクエストを送信
    res = requests.post(url, headers=headers, params=params)

    # レスポンスを出力
    print(res.status_code)
    print(res.text)

import requests
from utils import load_config
from io import BytesIO
from PIL import Image

def resize_image_if_needed(image_data, max_size=3 * 1024 * 1024):
    """
    画像が指定されたサイズを超える場合は、画像のサイズを縮小する。

    Args:
        image_data (bytes): 画像データ。
        max_size (int): 最大ファイルサイズ(バイト)。

    Returns:
        bytes: サイズ変更後の画像データ。
    """
    if len(image_data) > max_size:
        image = Image.open(BytesIO(image_data))
        new_size = (image.width // 2, image.height // 2)
        image = image.resize(new_size, Image.LANCZOS)

        output = BytesIO()
        image_format = image.format if image.format else 'JPEG'
        image.save(output, format=image_format)
        return output.getvalue()
    return image_data

def send_line_notify(message, image_path=None, config_path='config.json'):
    """
    LINE Notifyを使用してメッセージとオプションで画像を送信する関数。

    Args:
        message (str): 送信するメッセージ。
        image_path (str): 送信する画像のパス。
        config_path (str): 設定ファイルのパス。

    Returns:
        None
    """
    # 設定ファイルを読み込む
    config = load_config(config_path)

    # 設定ファイルからトークンを取得
    token = config['token']

    url = 'https://notify-api.line.me/api/notify'

    headers = {'Authorization': f"Bearer {token}"}
    params = {'message': message}

    # 画像がある場合は読み込み
    files = None
    if image_path:
        with open(image_path, 'rb') as img_file:
            img_data = img_file.read()
            img_data = resize_image_if_needed(img_data)
            files = {'imageFile': BytesIO(img_data)}
            files['imageFile'].name = os.path.basename(image_path)

    # LINE Notify APIにリクエストを送信
    res = requests.post(url, headers=headers, params=params, files=files)

    # レスポンスを出力
    print(res.status_code)
    print(res.text)

しかし

WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1723040085.190147 14567125 config.cc:230] gRPC experiments enabled: call_status_override_on_cancellation, event_engine_dns, event_engine_listener, http2_stats_fix, monitoring_experiment, pick_first_new, trace_record_callops, work_serializer_clears_time_cache
Traceback (most recent call last):
  File "/Users/snowpool/aw10s/store_adversting_list/ocr_list.py", line 57, in <module>
    send_line_notify(message,image_path)
  File "/Users/snowpool/aw10s/store_adversting_list/line_notify.py", line 54, in send_line_notify
    with open(image_path, 'rb') as img_file:
TypeError: expected str, bytes or os.PathLike object, not list

となる

send_line_notify関数は単一の画像パスを期待しているため、リストから1つずつ画像パスを取り出して送信する必要があります。

ソースを

import requests
from utils import load_config
from io import BytesIO
from PIL import Image
import os

def resize_image_if_needed(image_data, max_size=3 * 1024 * 1024):
    """
    画像が指定されたサイズを超える場合は、画像のサイズを縮小する。

    Args:
        image_data (bytes): 画像データ。
        max_size (int): 最大ファイルサイズ(バイト)。

    Returns:
        bytes: サイズ変更後の画像データ。
    """
    if len(image_data) > max_size:
        image = Image.open(BytesIO(image_data))
        new_size = (image.width // 2, image.height // 2)
        image = image.resize(new_size, Image.LANCZOS)

        output = BytesIO()
        image_format = image.format if image.format else 'JPEG'
        image.save(output, format=image_format)
        return output.getvalue()
    return image_data

def send_line_notify(message, image_paths=None, config_path='config.json'):
    """
    LINE Notifyを使用してメッセージとオプションで画像を送信する関数。
    複数の画像パスをリストとして受け取ることができます。

    Args:
        message (str): 送信するメッセージ。
        image_paths (list): 送信する画像のパスのリスト。
        config_path (str): 設定ファイルのパス。

    Returns:
        None
    """
    # 設定ファイルを読み込む
    config = load_config(config_path)

    # 設定ファイルからトークンを取得
    token = config['token']

    url = 'https://notify-api.line.me/api/notify'

    headers = {'Authorization': f"Bearer {token}"}
    params = {'message': message}

    # 画像がリストとして渡されている場合に対応
    if image_paths is not None:
        if not isinstance(image_paths, list):
            image_paths = [image_paths]

        for image_path in image_paths:
            if image_path is not None:
                with open(image_path, 'rb') as img_file:
                    img_data = img_file.read()
                    img_data = resize_image_if_needed(img_data)
                    files = {'imageFile': BytesIO(img_data)}
                    files['imageFile'].name = os.path.basename(image_path)

                    # LINE Notify APIにリクエストを送信
                    res = requests.post(url, headers=headers, params=params, files=files)

                    # レスポンスを出力
                    print(f"Sent {image_path}: {res.status_code} {res.text}")
    else:
        # 画像がない場合はメッセージのみ送信
        res = requests.post(url, headers=headers, params=params)
        print(f"Sent message: {res.status_code} {res.text}")

とすることで複数の画像に対応

リストに対応: image_paths引数がリスト型で渡されても対応できるようにしました。リストでない場合は、単一の画像パスとしてリストに変換して扱います。
画像のループ処理: 画像が渡された場合はループでそれぞれの画像をLINE Notifyに送信します。
画像なしの場合: 画像が渡されなかった場合は、メッセージのみを送信します。

Google Cloud Vision API の登録

Google Cloud Vision API の登録

https://cloud.google.com/vision/?hl=ja&_gl=1*1yrkeuh*_ga*NzQ0NTYyMjM5LjE2ODQxODU5MzA.*_ga_WH2QY8WWF5*MTcyMTE1MzQ3OS4yLjEuMTcyMTE1MzYyNS42LjAuMA..
でチュートリアル

料金については
https://cloud.google.com/vision/pricing?hl=ja#prices
を参考に
基本的に無料枠でできそう

プロジェクトを選択するのだが
Gmailと同じプロジェクトを選択する

Credentials.json
の中身を見ればOK

とりあえずデフォルトがこれなので
そのまま進める

APIとサービスを有効にする
をクリックし
cloud vision api
で検索

これでAPIを有効にする

多分認証のJSONファイルなので
権限などを増やしても変わらないはず

もしダメなら再度作成するだけ

とりあえずこれで進めてみる

Google colabでも実験できるのだが
Google drive へアップするときに
アップロード先のディレクトリがpublicに共有されていないことを確認すること
不安なら都度アップロードすればOK

とりあえずローカルで動かすのだが
Google Cloud SDK
が必要と chatgpt では言っている

本当か調べてみる

https://nikkie-ftnext.hatenablog.com/entry/ocr-with-google-vision-api-python-first-step
2024-01-03
GoogleのVision APIをPythonから呼び出して、画像内のテキストを検出する
に載っていた

サンプルコードを動かす前に準備が必要です。
「Google Cloud プロジェクトと認証のセットアップ」
* 大前提:Google Cloudのアカウント
* Google Cloudのプロジェクト1つ
* すでにあるものを選ぶ
* または、新規作成
* 余談:削除など管理したい場合は https://console.cloud.google.com/cloud-resource-manager から
* プロジェクトで課金が有効になっているか確認する
* 案内された別ドキュメントに従いました
* 直リンクは https://console.cloud.google.com/billing/linkedaccount?hl=ja&project=<選んだプロジェクトID> っぽいです
* 課金を有効にしますが、今回のサンプルコードの範囲内では無料で使える認識です
* 最初の 1,000 ユニット/月は無料

まではOK

次に
gcloudコマンドが使えるようにする設定が必要

https://cloud.google.com/docs/authentication/provide-credentials-adc?hl=ja#local-dev
の中の
gcloud CLI をインストールして初期化します。
をクリック

gcloud CLI をインストールする
https://cloud.google.com/sdk/docs/install?hl=ja
の中で
各種OSごとの
Google Cloud CLI 
のパッケージがダウンロードできるので
ここからダウンロード

私の場合 Macだけど
M1MacBookAir なので
macOS 64 ビット
(ARM64, Apple M1 silicon)
の方を選ぶ

google-cloud-cli-477.0.0-darwin-arm.tar.gz

をダウンロードしたら
展開して
ホームディレクトリに移動させる

Macの場合
圧縮ファイルをダブルクリックで展開できるので

 mv ~/Downloads/google-cloud-sdk .

でホームディレクトリ直下に移動

./google-cloud-sdk/install.sh

を実行したらエラーになるので

Reason: tried: '/opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/usr/local/lib/libssl.1.1.dylib' (no such file), '/usr/lib/libssl.1.1.dylib' (no such file, not in dyld cache)

で検索

Library not loaded: libssl.1.1.dylib (LoadError) 発生時の解決方法
によれば
OpenSSL@1.1のインストール
でOK

 brew install openssl@1.1

でインストールできるらしい

既にサポート終了しているはずと思い検索
「OpenSSL」にアップデート – 「同1.1.1」はサポート終了
https://www.security-next.com/149614

最初にchatgptでエラーの解決を調べた時にこの答えが出たけど
以前 YouTube live を再生するコードの時に
昔のライブラリ情報のインストールを提示され
ドツボにハマったことがあったので
念の為検索した

もうちょっと調べたら

PythonがOpenSSL周りのエラーで動かない

2024年05月24日
でこっちも同じ感じ

ただ

brew install openssl@1.1

を実行しても

brew install openssl@1.1

==> Auto-updating Homebrew...
Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with
HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
libgit2@1.7                              tdb
==> New Casks
avbeam                     jagex                      twingate
duplicateaudiofinder       sq-mixpad

You have 23 outdated formulae installed.

Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
    arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.

となるので

arch -arm64 brew install openssl@1.1

を実行

Warning: openssl@1.1 has been deprecated because it is not supported upstream!
==> Downloading https://ghcr.io/v2/homebrew/core/openssl/1.1/manifests/1.1.1w
######################################################################### 100.0%
==> Fetching openssl@1.1
==> Downloading https://ghcr.io/v2/homebrew/core/openssl/1.1/blobs/sha256:38619f
######################################################################### 100.0%
==> Pouring openssl@1.1--1.1.1w.arm64_sonoma.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /opt/homebrew/etc/openssl@1.1/certs

and run
  /opt/homebrew/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /opt/homebrew,
because this is an alternate version of another formula.

If you need to have openssl@1.1 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
  export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@1.1/lib/pkgconfig"
==> Summary
🍺  /opt/homebrew/Cellar/openssl@1.1/1.1.1w: 8,102 files, 18MB
==> Running `brew cleanup openssl@1.1`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

最後のメッセージが気になるので翻訳

openssl@1.1 は Keg 専用です。つまり、/opt/homebrew にシンボリックリンクされていません。
これは別の公式の代替バージョンであるためです。

PATH の最初に openssl@1.1 を含める必要がある場合は、次を実行します。
echo ‘export PATH=”/opt/homebrew/opt/openssl@1.1/bin:$PATH”‘ >> ~/.zshrc

コンパイラが openssl@1.1 を見つけるには、次の設定が必要になる場合があります。
エクスポート LDFLAGS=”-L/opt/homebrew/opt/openssl@1.1/lib”
エクスポート CPPFLAGS=”-I/opt/homebrew/opt/openssl@1.1/include”

pkg-config が openssl@1.1 を見つけるには、次の設定が必要になる場合があります。
import PKG_CONFIG_PATH=”/opt/homebrew/opt/openssl@1.1/lib/pkgconfig”
==> まとめ
🍺 /opt/homebrew/Cellar/openssl@1.1/1.1.1w: 8,102 ファイル、18MB
==> `brew cleanup openssl@1.1` を実行しています…
HOMEBREW_NO_INSTALL_CLEANUP を設定して、この動作を無効にします。
これらのヒントは HOMEBREW_NO_ENV_HINTS で非表示にします (「man brew」を参照)。

このため

export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@1.1/lib/pkgconfig"

の後に

 ./google-cloud-sdk/install.sh

を実行すると

Welcome to the Google Cloud CLI!

To help improve the quality of this product, we collect anonymized usage data
and anonymized stacktraces when crashes are encountered; additional information
is available at <https://cloud.google.com/sdk/usage-statistics>. This data is
handled in accordance with our privacy policy
<https://cloud.google.com/terms/cloud-privacy-notice>. You may choose to opt in this
collection now (by choosing 'Y' at the below prompt), or at any time in the
future by running the following command:

    gcloud config set disable_usage_reporting false

Do you want to help improve the Google Cloud CLI (y/N)?  

となる
メッセージを検索し

gcloud CLI をインストールする
を参考に
これは
N
でよいらしい

ちなみに日本語訳は
Google Cloud CLI へようこそ。

この製品の品質向上に役立てるため、当社は匿名化された使用状況データを収集します。
クラッシュが発生した場合は匿名化されたスタックトレース。追加情報
で入手できます。このデータは
弊社のプライバシーポリシーに従って取り扱われます
。これを選択することもできます
今すぐ (以下のプロンプトで「Y」を選択)、またはいつでも収集できます。
次のコマンドを実行して、将来のことを確認します。

gcloud config set disable_usage_reporting false

Google Cloud CLI の改善に協力したいと思いますか (y/N)?

どうやらデータ収集に同意するか
ということらしい

次に

Your current Google Cloud CLI version is: 477.0.0
The latest available version is: 484.0.0

┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                     Components                                                     │
├──────────────────┬──────────────────────────────────────────────────────┬──────────────────────────────┬───────────┤
│      Status      │                         Name                         │              ID              │    Size   │
├──────────────────┼──────────────────────────────────────────────────────┼──────────────────────────────┼───────────┤
│ Update Available │ BigQuery Command Line Tool                           │ bq                           │   1.7 MiB │
│ Update Available │ Cloud Storage Command Line Tool                      │ gsutil                       │  11.3 MiB │
│ Update Available │ Google Cloud CLI Core Libraries                      │ core                         │  19.1 MiB │
│ Not Installed    │ App Engine Go Extensions                             │ app-engine-go                │   4.5 MiB │
│ Not Installed    │ Appctl                                               │ appctl                       │  18.5 MiB │
│ Not Installed    │ Artifact Registry Go Module Package Helper           │ package-go-module            │   < 1 MiB │
│ Not Installed    │ Cloud Bigtable Command Line Tool                     │ cbt                          │  17.0 MiB │
│ Not Installed    │ Cloud Bigtable Emulator                              │ bigtable                     │   7.0 MiB │
│ Not Installed    │ Cloud Datastore Emulator                             │ cloud-datastore-emulator     │  36.2 MiB │
│ Not Installed    │ Cloud Firestore Emulator                             │ cloud-firestore-emulator     │  45.2 MiB │
│ Not Installed    │ Cloud Pub/Sub Emulator                               │ pubsub-emulator              │  63.7 MiB │
│ Not Installed    │ Cloud Run Proxy                                      │ cloud-run-proxy              │  11.3 MiB │
│ Not Installed    │ Cloud SQL Proxy v2                                   │ cloud-sql-proxy              │  13.2 MiB │
│ Not Installed    │ Google Container Registry's Docker credential helper │ docker-credential-gcr        │           │
│ Not Installed    │ Kustomize                                            │ kustomize                    │   7.4 MiB │
│ Not Installed    │ Log Streaming                                        │ log-streaming                │  11.9 MiB │
│ Not Installed    │ Minikube                                             │ minikube                     │  34.8 MiB │
│ Not Installed    │ Nomos CLI                                            │ nomos                        │  30.1 MiB │
│ Not Installed    │ On-Demand Scanning API extraction helper             │ local-extract                │  13.7 MiB │
│ Not Installed    │ Skaffold                                             │ skaffold                     │  22.8 MiB │
│ Not Installed    │ Terraform Tools                                      │ terraform-tools              │  63.6 MiB │
│ Not Installed    │ anthos-auth                                          │ anthos-auth                  │  20.9 MiB │
│ Not Installed    │ config-connector                                     │ config-connector             │  88.7 MiB │
│ Not Installed    │ enterprise-certificate-proxy                         │ enterprise-certificate-proxy │   8.3 MiB │
│ Not Installed    │ gcloud Alpha Commands                                │ alpha                        │   < 1 MiB │
│ Not Installed    │ gcloud Beta Commands                                 │ beta                         │   < 1 MiB │
│ Not Installed    │ gcloud app Java Extensions                           │ app-engine-java              │ 127.8 MiB │
│ Not Installed    │ gcloud app Python Extensions                         │ app-engine-python            │   5.0 MiB │
│ Not Installed    │ gcloud app Python Extensions (Extra Libraries)       │ app-engine-python-extras     │   < 1 MiB │
│ Not Installed    │ gke-gcloud-auth-plugin                               │ gke-gcloud-auth-plugin       │   4.0 MiB │
│ Not Installed    │ istioctl                                             │ istioctl                     │  24.8 MiB │
│ Not Installed    │ kpt                                                  │ kpt                          │  13.8 MiB │
│ Not Installed    │ kubectl                                              │ kubectl                      │   < 1 MiB │
│ Not Installed    │ kubectl-oidc                                         │ kubectl-oidc                 │  20.9 MiB │
│ Not Installed    │ pkg                                                  │ pkg                          │           │
│ Installed        │ Google Cloud CRC32C Hash Tool                        │ gcloud-crc32c                │   1.2 MiB │
└──────────────────┴──────────────────────────────────────────────────────┴──────────────────────────────┴───────────┘
To install or remove components at your current SDK version [477.0.0], run:
  $ gcloud components install COMPONENT_ID
  $ gcloud components remove COMPONENT_ID

To update your SDK installation to the latest version [484.0.0], run:
  $ gcloud components update


Modify profile to update your $PATH and enable shell command completion?

Do you want to continue (Y/n)?  

これを訳そうとしたけど
Google 翻訳は3900文字以上だとできなかった

To install or remove components at your current SDK version [477.0.0], run:
  $ gcloud components install COMPONENT_ID
  $ gcloud components remove COMPONENT_ID

To update your SDK installation to the latest version [484.0.0], run:
  $ gcloud components update


Modify profile to update your $PATH and enable shell command completion?

Do you want to continue (Y/n)?  

だけにして翻訳

現在の SDK バージョン [477.0.0] でコンポーネントをインストールまたは削除するには、次を実行します。
$ gcloud コンポーネントのインストール COMPONENT_ID
$ gcloud コンポーネントは COMPONENT_ID を削除します

SDK インストールを最新バージョン [484.0.0] に更新するには、次を実行します。
$ gcloud コンポーネントの更新

プロファイルを変更して $PATH を更新し、シェル コマンド補完を有効にしますか?

続行しますか (Y/n)?

これは
Y
でよいらしい

The Google Cloud SDK installer will now prompt you to update an rc file to bring
 the Google Cloud CLIs into your environment.

Enter a path to an rc file to update, or leave blank to use 
[/Users/snowpool/.zshrc]:  

の翻訳は

Google Cloud SDK インストーラは、rc ファイルを更新して、
Google Cloud CLI を環境に導入します。

更新する rc ファイルへのパスを入力するか、空白のままにして使用します
[/ユーザー/snowpool/.zshrc]:

これは
Enterキーにした

Backing up [/Users/snowpool/.zshrc] to [/Users/snowpool/.zshrc.backup].
[/Users/snowpool/.zshrc] has been updated.

==> Start a new shell for the changes to take effect.


Google Cloud CLI works best with Python 3.11 and certain modules.

Download and run Python 3.11 installer? (Y/n)?  

の翻訳は

[/Users/snowpool/.zshrc] を [/Users/snowpool/.zshrc.backup] にバックアップしています。
[/Users/snowpool/.zshrc]が更新されました。

==> 変更を有効にするために新しいシェルを開始します。

Google Cloud CLI は、Python 3.11 および特定のモジュールで最適に動作します。

Python 3.11 インストーラーをダウンロードして実行しますか? (はい/いいえ)?
なので
Y
にする

Running Python 3.11 installer, you may be prompted for sudo password...
Password:

となるので
Macのパスワードを入れる

あとは処理が自動で行われ

installer: Package name is Python
installer: Installing at base path /

installer: The install was successful.
Setting up virtual environment
Creating virtualenv...
Installing modules...
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 89.7/89.7 kB 2.4 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.0/59.0 kB 5.0 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.4/10.4 MB 7.2 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 163.0/163.0 kB 3.4 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.9/2.9 MB 7.4 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 182.4/182.4 kB 8.7 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 117.6/117.6 kB 6.5 MB/s eta 0:00:00
  Building wheel for crcmod (pyproject.toml) ... done


Updates are available for some Google Cloud CLI components.  To install them,
please run:
  $ gcloud components update

Virtual env enabled.

For more information on how to get started, please visit:
  https://cloud.google.com/sdk/docs/quickstarts

となる

source ~/.zshrc

を実行すれば

gcloud -v

が実行できるようになる

結果は

Google Cloud SDK 477.0.0
bq 2.1.4
core 2024.05.17
gcloud-crc32c 1.0.0
gsutil 5.29
Updates are available for some Google Cloud CLI components.  To install them,
please run:
  $ gcloud components update

次はgcloudの初期化をする