inlineDataとfileDataについては、以下のAPIリファレンスに記載されています。
Google Gemini APIにfileDataを渡すためには、あらかじめGoogle Cloud Storageにファイルをアップロードしておく必要があります。Autonomous Databaseでは、パッケージDBMS_CLOUDを使って、Google Cloud Storageの操作を行うことができます。
Oracle CorporationのPrincipal Product ManagerのCan Tuzlaさんによる以下の記事を参考にして、Google Cloud Storageのバケットに画像または動画ファイルをアップロードするAPEXアプリケーションを作成してみます。
Access GCP Resources from Your Autonomous Database
https://blogs.oracle.com/datawarehousing/post/access-gcp-resources-from-your-autonomous-database
作成したアプリケーションは以下のように動作します。
最初に説明が必要ですが、GoogleのGemini APIのfileDataとしてGoogle Cloud Storage上のファイルを扱う場合(gs:で始まるURIでないとエラーが発生するためGoogle Cloud Storage上のファイル以外は扱えない模様)、Gemini APIの認証にAPIキーは使えません。これはAPIキーではGoogle Cloud Storageにアクセスできないためです。また、呼び出し先もVertex AIである必要があるようです。
以上より、Gemini APIでfileDataを扱うにはVertex AI Gemini APIを呼び出すためのサービス・アカウントが必須です。それであれば、Gemini APIを呼び出すために作成したサービス・アカウントにGoogle Cloud Storageを操作するロールを追加すれば(Gemini APIからファイルを参照する必要があるため、サービス・アカウントにファイルの参照権限は必須です)、ブログ記事にある手順で、別途サービス・アカウントを作る必要はありません。
DBMS_CLOUDでは、Google Cloud Storageを操作するためにXML APIを使っている模様ですが(APIのエンドポイントがXML APIのエンドポイントです)、Gemini APIを呼び出すために作成したサービス・アカウントであれば、より柔軟に扱えるObject Storage JSON APIを呼び出すこともできます。
以上の理由により、Gemini APIで扱うファイルを操作するためにDBMS_CLOUDは使わないことにしました。とはいえ実際にAPEXアプリケーションを作って動作を確認しているので、DBMS_CLOUDを使ったGoogle Cloud Storageを操作するAPEXアプリケーションの作成手順を紹介します。
前置きが長くなりましたが、以下より作業手順です。Google Cloud Platformのサービス・アカウントの作成、バケットの作成や権限付与については、元にしたブログ記事をほとんどそのまま踏襲します。
最初にGCPのサービス・アカウントを有効にします。APEXのワークスペース・スキーマはパッケージDBMS_CLOUD_ADMINの実行権限はなく、また、与えるべきでもないため、このプロシージャの呼び出しはユーザーADMINで実施します。引数usernameとして、APEXのワークスペース・スキーマを与えます。今回の例ではWKSP_APEXDEVを指定しています。
ユーザーADMINでデータベース・アクションにサインインし、SQLより以下のコマンドを実行します。
BEGIN
DBMS_CLOUD_ADMIN.ENABLE_PRINCIPAL_AUTH(
provider => 'GCP'
,username => 'WKSP_APEXDEV');
END;
/
select * from cloud_integrations where param_name like 'gcp%';
PARAM_NAMEがgcp_service_accountのPARAM_VALUEが、GCPのサービス・アカウントのメールになります。この値を安全に保存しておきます。
異なるAPEXワークスペース・スキーマに対してDBMS_CLOUD_ADMIN.ENABLE_PRINCIPAL_AUTHを実行しても、サービス・アカウントのメールは同じになるようです。ENABLE_PRINCIPAL_AUTHが呼び出されているスキーマでは、GCPにアクセスする際に使用するクリデンシャルであるGCP$PAが作成されています。
Cloud Storageにバケットを作成します。
Google CloudのコンソールよりCloud Storageを開き、サイド・メニューのバケットより作成を実行します。
バケットに名前を付けます。今回はmy-gemini-data-1234としています。
続行をクリックします。
続行をクリックします。
ストレージ・クラスはStandard、オブジェクトのアクセス制御は、公開アクセスを防止し、かつアクセス制御は均一(バケット単位での制御 )、保護ツールはなしです。
作成をクリックします。
公開アクセスの設定の確認が求められるので、このバケットに対する公開アクセス禁止を適用するにチェックが入っていることを確認します。
確認をクリックします。
バケットが作成され、詳細画面が開きます。
権限のタブを開き、アクセス権を付与をクリックします。
保存をクリックします。
Oracle APEXからアクセスをしてみます。以下のテストはこちらの記事で、AWSのS3にアクセスした際に使用したものとほぼ同じです。
SQLワークショップのSQLコマンドより、ファイルのアップロードを行ってみます。
バケットmy-gemini-data-1234にファイルtest.txtをアップロードしてみます。
declare
l_resp dbms_cloud_types.resp;
l_blob blob;
l_clob clob;
begin
l_clob := 'my first upload';
l_blob := apex_util.clob_to_blob(l_clob);
l_resp := dbms_cloud.send_request(
credential_name => 'GCP$PA'
,uri => 'https://my-gemini-data-1234.storage.googleapis.com/test.txt'
,method => 'PUT'
,body => l_blob
);
end;
バケットmy-gemini-data-1234の内容を一覧します。ファイルtest.txtがアップロードされていることが確認できます。
select * from dbms_cloud.list_objects(
credential_name => 'GCP$PA'
,location_uri => 'https://my-gemini-data-1234.storage.googleapis.com/'
)
declare
l_resp dbms_cloud_types.resp;
l_clob clob;
begin
l_resp := dbms_cloud.send_request(
credential_name => 'GCP$PA'
,uri => 'https://my-gemini-data-1234.storage.googleapis.com/test.txt'
,method => 'GET'
);
l_clob := dbms_cloud.get_response_text(
resp => l_resp
);
dbms_output.put_line(l_clob);
end;
ファイルtest.txtを削除します。
begin
dbms_cloud.send_request(
credential_name => 'GCP$PA'
,uri => 'https://my-gemini-data-1234.storage.googleapis.com/test.txt'
,method => 'DELETE'
);
end;
再度、バケット内のファイルをリストします。データが見つかりませんと返されます。
Oracle APEXのワークスペースよりGoogle Cloud Storageにアクセスできることが確認できたので、これよりAPEXのアプリケーションを作成します。
アプリケーション・ビルダーより作成を開始し、名前をSample Google Cloud Storage Accessとした空のアプリケーションを作成します。
置換文字列としてG_BUCKET_NAME、置換値にGCPに作成したバケットの名前を設定します。
バケット内のファイルを対話モード・レポートで一覧します。ファイルのアップロードや削除はフォームに実装します。
ページの作成を開始します。
対話モード・レポートを選択します。
対話モード・レポートのページの名前はFilesとします。フォーム・ページを含めるをオンにし、フォーム・ページ名はFileとします。
データ・ソースのソース・タイプをSQL問合せに変更し、SQL SELECT文を入力に以下を記述します。ウィザードにSQL文を記述する際は置換文字列が使えないため、localtion_uriのバケット名は直書きします。これは、ページの作成後に置き換えます。また、列OBJECT_NAMEを主キー列としますが、その場合、列が非表示項目になるため列IDを追加しています。
select object_name id, object_name, bytes, checksum, created, last_modified
from dbms_cloud.list_objects(
credential_name => 'GCP$PA'
,location_uri => 'https://my-gemini-data-1234.storage.googleapis.com/'
)
ナビゲーションはデフォルトのままとし、ブラッドクラムの使用、ナビゲーションの使用ともにオンとします。
次へ進みます。
主キー列1にID (Varchar2)を選択します。
ページの作成をクリックします。
ページが作成されます。
対話モード・レポートのソースのSQL問合せを、バケット名として置換文字列G_BUCKET_NAMEを使用するように変更します。
select object_name id, object_name, bytes, checksum, created, last_modified
from dbms_cloud.list_objects(
credential_name => 'GCP$PA'
,location_uri => 'https://' || :G_BUCKET_NAME || '.storage.googleapis.com/'
)
ページ・デザイナでフォームのページを開き、ファイルのアップロードを実装します。
ファイルを選択するページ・アイテムとしてP2_FILESを作成します。ページ・アイテムのタイプはファイルのアップロードです。ラベルはFilesとします。
ストレージのタイプは表APEX_APPLICATION_TEMP_FILES、ファイルをパージするタイミングはリクエストの終わり、複数ファイルの許可をオンにします。
セッション・ステートのストレージはリクエストごと(メモリーのみ)、また、このページ・アイテムはファイルをアップロードするときのみ表示するため、サーバー側の条件のタイプとしてアイテムはNULLを選択し、アイテムとしてP3_IDを指定します。
ページ・アイテムP3_OBJECT_NAME、P3_BYTES、P3_CHECKSUM、P3_CREATED、P3_LAST_MODIFIEDはファイルをアップロードする際には表示は不要です。
これらのページ・アイテムをすべて選択し、サーバー側の条件のタイプとしてアイテムはNULLではないを選択し、アイテムにP3_IDを指定します。
左ペインでプロセス・ビューを開き、デフォルトで作成されているプロセスプロセス・フォームFileをコメント・アウトします。
このプロセスの代わりに、ファイルをアップロードするプロセスと削除するプロセスを作成します。更新は今回実装しません。
プロセスを作成します。
識別の名前はUpload Files、タイプはコードの実行を選択し、ソースのPL/SQLコードとして以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_uri varchar2(32767); | |
begin | |
for r in ( | |
select * from apex_application_temp_files | |
where name in ( | |
select column_value from apex_string.split(:P3_FILES,':') | |
) | |
) | |
loop | |
l_uri := 'https://' || :G_BUCKET_NAME || '.storage.googleapis.com/' | |
|| utl_url.escape(r.filename, false, 'AL32UTF8'); | |
dbms_cloud.send_request( | |
credential_name => 'GCP$PA' | |
,uri => l_uri | |
,method => 'PUT' | |
,body => r.blob_content | |
); | |
end loop; | |
end; |
サーバー側の条件のボタン押下時にCREATEを指定します。
ファイルを削除するプロセスを作成します。
識別の名前はDelete File、タイプはコードを実行です。ソースのPL/SQLコードとして以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_uri varchar2(32767); | |
begin | |
l_uri := 'https://' || :G_BUCKET_NAME || '.storage.googleapis.com/' | |
|| utl_url.escape(:P3_ID, false, 'AL32UTF8'); | |
dbms_cloud.send_request( | |
credential_name => 'GCP$PA' | |
,uri => l_uri | |
,method => 'DELETE' | |
); | |
end; |
サーバー側の条件のボタン押下時にDELETEを指定します。
以上でアプリケーションは完成です。実行すると記事の先頭にあるGIF動画のように動作します。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-google-cloud-storage-access.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完