Cloudinary のパブリック ID ってなんだろう? API のオプションと合わせて解説
Guten Abend!ベルリンから伊藤です。
画像や動画のデジタルメディア管理・変換 SaaS、Cloudinaryを使うと、画像最適化が簡単に実現できます。
本稿では Cloudinary 上でファイルを一意に特定する名前である「public ID」について解説します。
Cloudinary におけるフォルダ
Cloudinary では S3 と同様キーバリュー形式でアセットが格納されているため、コンソールでは一般的なファイルエクスプローラー同様にフォルダとファイルという形式で確認することができますが、実体ではフォルダというものはありません。
「public ID」は、キー(フォルダ階層)とバリューを合わせたフルパスのことを指します。(例:test/animal/elephant
)そのため、同じファイル名 test.jpg でも異なるキー(≒フォルダ)であればフルパスが異なるので問題ありません。
fol1/test
fol2/test
パブリック ID の指定
パブリック ID には、画像や動画では拡張子を含めません。以下でも、JPGとPNGの3つの画像には名前に拡張子が含まれておらず、画像でも動画でもないアセット caption.vtt でのみ拡張子が含まれています。
デフォルトでは、コンソールでのアップロード時にランダムな文字列が付与されますが、設定でアップロードするファイル名をパブリックIDのバリューに使うよう指定することができます。
アップロード API のオプション
Upload API においても、パブリックIDを指定するか、それともランダムな文字列とするか、など各リクエストでオプションを指定することができます。
ドキュメントからパブリックIDに関するオプションパラメータをまとめると、以下の通りです。
パラメータ | タイプ | 説明 |
---|---|---|
file (必須) | String | アップロードするアセット (ローカルならローカルファイルパス) |
public_id | String | フォルダ配下ならスラッシュ区切りのフルパス; 指定しない場合は次に続くパラメータに基づく; 画像や動画には拡張子は含めないこと |
folder | String | アセットを配置するフォルダパス(キー); パブリックIDを指定する場合、パブリックID内でフルパスを指定する |
use_filename | Boolean | アップロードファイルの名前を使うかどうか; デフォルトは false で、 public_id を指定しない限りランダムな文字列が付与される |
unique_filename | Boolean | use_filename がtrue の場合に、必ず一意なファイル名とするためにファイル名末尾にランダムな文字列を付与するかどうか;これとoverwiteの両方が false で同じファイル名がアップロードされると、リクエストはエラーとなる;デフォルトは true |
overwrite | Boolean | 同じパブリックIDをもつ既存アセットを上書きするかどうか; デフォルトは true |
以下、適用した結果をPythonの実行例で紹介します。
public_id オプション
まず、パブリックIDを指定した場合、そのまま指定した値がパブリックIDとなります。
path = "/Users/mai/Pictures/Hoya-fishing.png" res = cloudinary.uploader.upload(file=path, public_id='ito-test/Hoya-fishing') print(res['public_id']) # ito-test/Hoya-fishing
このアセットの変換URLを取得する場合には、パブリックIDに上記の値を指定します。デフォルトでは、オリジナルのフォーマットで配信されるため、次の1つ目の例の場合は png 形式の画像が配信されます。一方、フォーマットを指定したい場合には、パブリックID内で末尾に拡張子を指定します。次の2つ目の例では、jpg 形式の画像が配信されます。
※f_auto
パラメータを付与すると、オリジナルや指定した以外の最適なフォーマットで配信される場合があります。
cloudinary.CloudinaryImage("ito-test/Hoya-fishing").image( height=60, width=60, crop="lpad", effect="contrast:-30", secure=True ) # '<img height="60" src="https://res.cloudinary.com/CLOUD-NAME/image/upload/c_lpad,e_contrast:-30,h_60,w_60/v1/ito-test/Hoya-fishing" width="60"/>' cloudinary.CloudinaryImage("ito-test/Hoya-fishing.jpg").image( height=60, width=60, crop="lpad", effect="contrast:-30", secure=True ) # '<img height="60" src="https://res.cloudinary.com/CLOUD-NAME/image/upload/c_lpad,e_contrast:-30,h_60,w_60/v1/ito-test/Hoya-fishing.jpg" width="60"/>'
folder、use_filename、unique_filname オプション
次に、残りのオプションをいろいろ組み合わせると以下のような結果になります。
- フォルダのみ指定した場合:指定したキー配下で、ファイル名はランダムな文字列
- フォルダとファイル名を使うよう指定した場合:指定したキー配下で、ファイル名は指定した値にランダムな文字列を加えたもの
- フォルダとファイル名とユニークファイル名(False)を指定した場合:指定したキー配下で、ファイル名は指定した値
path2 = "/Users/mai/Pictures/Hoya-king.png" res = cloudinary.uploader.upload(file=path2, folder = 'ito-test') print(res['public_id']) # ito-test/f5jykx2grtafeehxb4jw res = cloudinary.uploader.upload(file=path2, folder = 'ito-test', use_filename=True) print(res['public_id']) # ito-test/Hoya-king_j7jpnw res = cloudinary.uploader.upload(file=path2, folder = 'ito-test', use_filename=True, unique_filename=False) print(res['public_id']) # ito-test/Hoya-king
例外:public_id オプションに拡張子を含めた場合
上述の通り、拡張子は本来URLには含めないのでアンチパターンになりますが、含めてしまった場合にはどうなるのか、確認してみました。下記のようにアップロードAPIのパブリックID内で .png をつけてリクエストします。結果は、パブリックIDに拡張子が含まれます。
path = "/Users/mai/Pictures/Hoya-adventure.png" res = cloudinary.uploader.upload(file=path, public_id='ito-test/Hoya-adventure.png') print(res['public_id']) # ito-test/Hoya-adventure.png
この場合の変換URLがどうなるのか確認したところ、全く拡張子を付けない場合はやはりエラーになりましたが、拡張子を1つ付けた場合(この場合のパブリックID)でもエラーとなり、拡張子を2つ付けた場合([パブリックID].[拡張子])には画像が出力されました。
どうやら一番末尾の拡張子によって拡張子を明示的に指定したリクエストとみなし、それ以前の文字列をパブリックIDとして判断しているようです。2つ目のリクエストでは「ito-test/Hoya-adventure」がパブリックIDとされ、該当する結果がないとしてエラーとなったのでしょう。
cloudinary.CloudinaryImage("ito-test/Hoya-adventure").image( height=60, width=60, secure=True) # '<img height="60" src="https://res.cloudinary.com/CLOUD-NAME/image/upload/h_60,w_60/v1/ito-test/Hoya-adventure" width="60"/>' # ==> 404 エラー cloudinary.CloudinaryImage("ito-test/Hoya-adventure.png").image( height=60, width=60, secure=True) # '<img height="60" src="https://res.cloudinary.com/CLOUD-NAME/image/upload/h_60,w_60/v1/ito-test/Hoya-adventure.png" width="60"/>' # ==> 404 エラー cloudinary.CloudinaryImage("ito-test/Hoya-adventure.png.png").image( height=60, width=60, secure=True) # '<img height="60" src="https://res.cloudinary.com/CLOUD-NAME/image/upload/h_60,w_60/v1/ito-test/Hoya-adventure.png.png" width="60"/>' # ==> 200 画像出力
以上、少しでも Cloudinary 導入時の参考になれば幸いです!
クラスメソッドはCloudinaryのパートナーとして導入のお手伝いをさせていただいています。お気軽にこちらからお問い合わせください。こちらから無料でもサインアップいただけます。