#この記事は
CloudinaryのUpload APIを使って、画像をアップロードする の続きで、CloudinaryのAdmin APIとSearch APIを試します。
環境の準備などは、前記事を参照でお願いします。
#Admin API & Search APIとは
Admin API
Admin APIは、Cloudinaryの設定面を管理画面の代わりに操作できるAPIです。設定周りだけでなく、動画や画像(総じてAssetアセット)の操作もできます。Admin APIは1時間あたりの呼び出し回数に制限があります。
Search API
Search APIは、Cloudinary内に蓄積されたアセットをLuceneのようなクエリーを書いて検索するAPIです。さまざまなファイルの属性(ファイル名だけでなくタグ、登録・更新の時間、補足の説明など)を検索対象にして探すことができます。
APIのsearchメソッドはAdmin APIの一部なので、利用回数はAdminAPIと共有されます。認証方法、ページネーション、エラーハンドリングなどはAdmin APIと同じなので、ドキュメントを見るべし。
##Admin APIで操作可能なオブジェクト
Admin APIでは、以下のものが操作可能です。(一部不明点あり)
###Resources
アセットの操作ができます。アセットの検索する、情報を参照する、更新する、削除するなどの操作です。
メインの機能になります。
機能 | 説明 |
---|---|
Get resources | アセットを検索 |
Get resources by tag | アセットをタグで検索 |
Get resources by context | アセットをコンテキストで検索 |
Get resources in moderation queues | 一時保留になっている画像を探す |
Get the details of a single resource | 1つのアセットの詳細を取る |
Search for resources | アセットを検索する(Search API) |
Update details of an existing resource | アセットの情報を更新する |
Restore resources | バックアップからリストア |
Update access mode | access modeを更新 |
Delete resources | 複数のアセットを削除 |
Delete resources by tags | タグを指定してアセットを削除 |
###Transformations
変換を作ったり消したりできます。管理画面のここに表示される一覧のことです。
###Upload mappings
URLで外部リソースを取り込むマッピングを作ったり消したり。APIでわざわざやらないような気もする。
###Upload presets
アップロードしたときに変換されるプリセットを作ったり消したり。これも、APIでわざわざやらないような気もする。
###Metadata fields
Cloudinaryで管理する全てのアセットに、共通のメタデータを定義する機能をAPIでやるのですね。
コンソールだと、設定メニューの右側にあるリンクから行ける機能です。
型を決めて、メタデータの箱を登録すると、各アセットにメタデータを登録できるようになると。(使うかな。。)
###Folders
フォルダを作ったり消したり
###Adaptive streaming profiles
(。´・ω・)ん?これはなんだ?
https://cloudinary.com/documentation/admin_api#adaptive_streaming_profiles
###Tags
画像にタグをつけるのではなくて、システム内のタグの種類を見るだけ。
###Usage
システムの利用状況(プラン、StorageやBandwidth)を確認する
###Ping
いきてますかー?
詳細はこちらに。
https://cloudinary.com/documentation/admin_api
#SDKに頼らずにHTTPSで直接実行してみる
Admin APIは、API Key
とAPI Secret
だけで接続することができます。Upload APIのように、パラメータから複雑な手順で生成するsignatureは不要です。使い方さえ覚えてしまえば、PostManやVS CodeのHTTP Clientでも実行可能です。
##Admin APIの接続先
APIはAPIキーとAPIシークレットをURLに埋める形で作ります。最後のアクション部分を変えることで呼び出す処理が変わります。
Admin APIのURLのパターン
https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<CLOUD_NAME>/<ACTION>
自分の環境のURL
https://378xxx:eyhxxx@api.cloudinary.com/v1_1/kanaxx/
レスポンスヘッダーにAPIの実行回数に関する情報が含まれています。Headerから残り回数を読み取って残りが少なくなったら待機するか、エラーコードでエラー処理をするのか、どちらか実装しておきましょう。
上限が超えたときには、420: Rate limited.
になります。
X-FeatureRateLimit-Limit: 500
X-FeatureRateLimit-Remaining: 498
X-FeatureRateLimit-Reset: Sat, 18 Apr 2020 10:00:00 GMT
APIの実行回数は、時計の針が00分になるときに、全てリセットされる仕組みです。
##コード
Admin APIの中で簡単な/usage
Actionにリクエストを投げ込むPHPです。
<?php
//各自設定
$cloudName='kanaxx';
$resourceType = 'image';
$apiKey = '37826219xxx';
$apiSecret = 'eyhlvE3t16l1WYxxx';
$api = "https://{$apiKey}:{$apiSecret}@api.cloudinary.com/v1_1/{$cloudName}/";
$usage = $api . '/usage';
// 以下、API実行部分
$ch = curl_init();
// オプションを設定
curl_setopt($ch, CURLOPT_URL, $usage);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
// API実行
$json = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo 'Response Code:' . $code . PHP_EOL;
echo $json . PHP_EOL;
$result = json_decode($json, true);
var_dump($result);
難しくないですね。
response code=200でないときだけ、ちゃんと対応をしましょう。
#SDKを使う
前回同様、PHPのSDKを使ってCloudinaryをコントロールしてみます。管理コンソールでやればよさそうなものをやってもしょうがないので、画像の操作系だけやってみます。
$api = new \Cloudinary\Api();
//1.使用量の確認
$usage = $api->usage();
//データ全体
var_export($usage);
//細かくみるなら、こんな感じで
echo 'plan = ' . $usage['plan'] . PHP_EOL;
echo 'storage = ' . $usage['storage']['usage'] . PHP_EOL;
echo PHP_EOL;
//2.簡易な検索機能で画像を探す。
$resources = $api->resources([
'max_results' => 10,
'resource_type '=>'image',
'type'=>'upload',
'prefix'=>'upload-test/test'
]);
var_export($resources);
//各リソースは、'resource'キーに配列が入っている
foreach($resources['resources'] as $r){
echo $r['public_id'] . PHP_EOL;
}
echo PHP_EOL;
//3.画像を1件だけ探すと情報がたくさんとれる。単数形なので注意
$resource = $api->resource('upload-test/test4_l8ro1n');
var_export($resource);
echo PHP_EOL;
//4.Cloudinary内のタグ一覧
$tags = $api->tags(['max_results'=>500]);
var_export($tags['tags']);
##実行結果
SDKで実行したときは、PHPのオブジェクトにラップされて戻ってきます。
resources(複数形)の戻り
array (
'public_id' => 'upload-test/test01',
'format' => 'png',
'version' => 1586779187,
'resource_type' => 'image',
'type' => 'upload',
'created_at' => '2020-04-13T11:59:47Z',
'bytes' => 1530,
'width' => 150,
'height' => 150,
'access_mode' => 'public',
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/v1586779187/upload-test/test01.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/v1586779187/upload-test/test01.png',
)
resource(単数)呼び出しの戻り方
array(
'public_id' => 'upload-test/test4_l8ro1n',
'format' => 'png',
'version' => 1587268817,
'resource_type' => 'image',
'type' => 'upload',
'created_at' => '2020-04-19T04:00:17Z',
'bytes' => 1433,
'width' => 150,
'height' => 150,
'backup' => true,
'access_mode' => 'public',
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/v1587268817/upload-test/test4_l8ro1n.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/v1587268817/upload-test/test4_l8ro1n.png',
'next_cursor' => '38cb428ee5bce2c43ae9db1442eecf8579d95eebc82715ce87a4686467b70d23',
'derived' => array (
0 =>
array (
'transformation' => 't_media_lib_thumb',
'format' => 'png',
'bytes' => 1139,
'id' => 'f00301b389c96f5ea828a696ae8a3f48',
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/t_media_lib_thumb/v1587268817/upload-test/test4_l8ro1n.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/t_media_lib_thumb/v1587268817/upload-test/test4_l8ro1n.png',
),
1 =>
array (
'transformation' => 'a_hflip,w_200/a_45,g_south_west,l_pop_gazouha_image_desu,w_70',
'format' => 'png',
'bytes' => 6549,
'id' => '6de1174745014ab48bca093fce6b6b58',
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/a_hflip,w_200/a_45,g_south_west,l_pop_gazouha_image_desu,w_70/v1587268817/upload-test/test4_l8ro1n.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/a_hflip,w_200/a_45,g_south_west,l_pop_gazouha_image_desu,w_70/v1587268817/upload-test/test4_l8ro1n.png',
),
2 =>
array (
'transformation' => 'bo_3px_solid_blue,r_max,w_120',
'format' => 'png',
'bytes' => 3548,
'id' => '662d3f6e8f9d759708128812e97cb073',
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/bo_3px_solid_blue,r_max,w_120/v1587268817/upload-test/test4_l8ro1n.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/bo_3px_solid_blue,r_max,w_120/v1587268817/upload-test/test4_l8ro1n.png',
),
3 =>
array (
'transformation' => 'bo_2px_solid_red,w_100',
'format' => 'png',
'bytes' => 1172,
'id' => 'e66d0e2d6304f57cd008ddb141bc07cd',
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/bo_2px_solid_red,w_100/v1587268817/upload-test/test4_l8ro1n.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/bo_2px_solid_red,w_100/v1587268817/upload-test/test4_l8ro1n.png',
),
),
))
Admin APIの2つのリソース系のメソッドの大きな違いは、Get the details of a single resource(単一public_id
を指定)は、deliveredの画像の一覧が取れることですね。deliveredのリソースとは、元画像を元にして変換して増殖した分ということです。
#Search API SDK
Search APIはAdmin APIの一部なのに、Admin APIと使い方が違います。しかも、PHP-SDKの公式マニュアルも微妙に間違えていたので注意です。
//https://cloudinary.com/documentation/search_api#syntax
//↓コンパイルエラーです
result = \Cloudinary\search->execute();
SDKのソースを調べてみましたが、new Search()
で一度インスタンス化すれば使えそうです。
$search
インスタンスは内部にexpression()
やmax_results()
などのメソッドチェーンで渡した条件が保持されているので、インスタンスを使いまわすときには気を付けましょう。同一条件でページネーションしていくケース以外では、使いまわさないほうがよさそうです。
例1と例2で使いまわすと痛い目に合います。(1件しか取れななくて1時間くらいハマりました)
##SearchAPIのサンプルコード
<?php
require_once "vendor/autoload.php";
\Cloudinary::config([
"cloud_name" => "kanaxx", "secure" => true,
"api_key" => "37826219xxx", "api_secret" => "eyhlvE3t16l1WYgdxxx",
]);
//例1. public_idを指定して検索
//public_id=aだと完全一致、public_id:aだと部分一致
$result = (new \Cloudinary\Search())
->max_results(10)
->expression('public_id=upload-test/test4_l8ro1n')
->execute();
var_export($result);
echo PHP_EOL;
//例2. 一番新しい画像を探す (order by created_at desc limit 1)
//Search APIだとMatch件数が取れるので、expressionを指定しないクエリーなし画像の総数が分かる
$search = new \Cloudinary\Search();
$result = $search
->max_results(1)
->sort_by('created_at','desc')
->execute();
var_export($result);
echo PHP_EOL;
//例3. フォルダ配下にあるファイルを検索
//pagenationのカーソルを使うためにmax=10で実行
$search = new \Cloudinary\Search();
//基本的な条件だけ先に組み立てておいて
$search->expression('folder=upload-test AND filename=api*')
->max_results(10)
->sort_by('created_at','desc');
$next = '';
$no = 0;
do{
//カーソルの値を足してから、execute
//この場合だけは、$searchインスタンスを使いまわしてよい。
$result = $search->next_cursor($next)->execute();
$resources = $result['resources']??[];
echo count($resources) . '/' . $result['total_count'] . PHP_EOL;
$next = $result['next_cursor']??'';
echo 'next cursor ==>' . $next . PHP_EOL;
//画像の一覧
foreach($resources as $resource){
$no++;
echo $no . ' ' . $resource['public_id'] .'|'. $resource['created_at'] . PHP_EOL;
}
}while($next != '');
##実行結果
###例1
1件だけ取れるので、total_count=1
で、resources
配列に値が入ってきます。
Cloudinary\Api\Response::__set_state(array(
'total_count' => 1,
'time' => 116,
'resources' =>
array (
0 =>
array (
'public_id' => 'upload-test/test4_l8ro1n',
'folder' => 'upload-test',
'filename' => 'test4_l8ro1n',
'format' => 'png',
'version' => 1587268817,
'resource_type' => 'image',
'type' => 'upload',
'created_at' => '2020-04-19T04:00:17+00:00',
'uploaded_at' => '2020-04-19T04:00:17+00:00',
'bytes' => 1433,
'backup_bytes' => 1433,
'width' => 150,
'height' => 150,
'aspect_ratio' => 1.0,
'pixels' => 22500,
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/v1587268817/upload-test/test4_l8ro1n.png',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/v1587268817/upload-test/test4_l8ro1n.png',
'status' => 'active',
'access_mode' => 'public',
'access_control' => NULL,
'etag' => 'e3ae356ead1e954aa25ff8fe77e344b3',
'created_by' =>
array (
'access_key' => '378262191665246',
),
'uploaded_by' =>
array (
'access_key' => '378262191665246',
),
),
),
))
###例2の
total_count=448件のうち、一番新しい画像が1つだけ返ってきます。
array(
'total_count' => 448,
'time' => 785,
'next_cursor' => 'f9f3441bf70cb7a277280e548b4a824ae34db3c441d2106674a7f3955a140748ecdd7b525feaf9ce0efcfaeba7926664',
'resources' =>
array (
0 =>
array (
'public_id' => 'upload-test/api-context3',
'folder' => 'upload-test',
'filename' => 'api-context3',
'format' => 'jpg',
'version' => 1587475767,
'resource_type' => 'image',
'type' => 'upload',
'created_at' => '2020-04-21T13:29:27+00:00',
'uploaded_at' => '2020-04-21T13:29:27+00:00',
'bytes' => 2639,
'backup_bytes' => 2639,
'width' => 150,
'height' => 150,
'aspect_ratio' => 1.0,
'pixels' => 22500,
'url' => 'http://res.cloudinary.com/kanaxx/image/upload/v1587475767/upload-test/api-context3.jpg',
'secure_url' => 'https://res.cloudinary.com/kanaxx/image/upload/v1587475767/upload-test/api-context3.jpg',
'status' => 'active',
'access_mode' => 'public',
'access_control' => NULL,
'etag' => 'ef01d44d8742ad19cd34739f4ed25b9d',
'created_by' =>
array (
'access_key' => '378262191665246',
),
'uploaded_by' =>
array (
'access_key' => '378262191665246',
),
),
),
))
###例3
全部で12件の結果を10件刻みで取得しました。next_cursorがemptyになったらbreakします。sort_by指定をしているので、新しい順に並んで取れます。
件数:12
next cursor ==>1bcfc7ba149c49ba483be2ccd755ed6e393aea3b6ed3708781dd309e6c7cc211cde9171c341dd21ea30f0dba4e5e0e34
1 upload-test/api-context3|2020-04-21T13:29:27+00:00
2 upload-test/api-context2|2020-04-21T13:29:21+00:00
3 upload-test/api-context1|2020-04-21T13:29:12+00:00
4 upload-test/api-accessmode02|2020-04-20T23:53:35+00:00
5 upload-test/api-accessmode03|2020-04-20T23:51:08+00:00
6 upload-test/api-accessmode01|2020-04-20T23:40:00+00:00
7 upload-test/api-tag03|2020-04-20T16:56:33+00:00
8 upload-test/api-tag02|2020-04-20T16:44:01+00:00
9 upload-test/api-tag01|2020-04-20T16:43:24+00:00
10 upload-test/api-test03|2020-04-20T16:39:15+00:00
件数:12
next cursor ==>
11 upload-test/api-test02|2020-04-20T16:38:20+00:00
12 upload-test/api-test01|2020-04-20T16:37:47+00:00
#Admin APIとUpload APIの重複操作
今回、APIを調べていてAdmin API
とUpload API
でどちらでもできるものがあったので、整理しておきます。Upload APIは回数制限がないので、どちらでもできるのであればUpload APIでやるほうがよさそうです。
操作 | Admin API | Upload API | memo |
---|---|---|---|
画像登録 | x | o | |
名前変更 | x | o | |
画像の削除 | 複数 | 1つずつ | |
画像の検索 | o | x | resource / search の2種類あり |
情報取得 | o | x | resource / resources で取得する情報に差があり |
Tag操作 | 1つの画像に複数のタグを設定 | 複数の画像に1つのタグを設定 | |
Context操作 | 1つの画像に設定 | 複数の画像に設定 | |
AccessMode変更 | x | upload時に設定 | RESTではできるのにSDKに実装されていない |
#まとめ
Cloudinaryファンとして、2つのAPIの使い方を簡単に書いてみましたけど、まぁ、あまり出番がないかもですねぇ。