L'API Blobstore permet à votre application de diffuser des objets de données, appelés blobs, beaucoup plus volumineux que la taille autorisée pour les objets dans le service Datastore. Les blobs sont particulièrement utiles pour la diffusion de fichiers de grande taille, tels que des fichiers vidéo ou image, ainsi que pour l'importation de fichiers de données volumineux. Les blobs sont générés lors de l'importation d'un fichier via une requête HTTP. Pour ce faire, vos applications présentent généralement à l'utilisateur un formulaire avec un champ d'importation de fichier. Une fois ce formulaire envoyé, le blobstore crée un blob à partir du contenu du fichier et renvoie une référence opaque au blob, appelée clé blob, que vous pouvez ensuite utiliser pour diffuser le blob. L'application peut diffuser la valeur complète du blob en réponse à une demande d'utilisateur. Elle peut aussi lire directement la valeur à l'aide d'une interface de type fichier de streaming.
Présentation du Blobstore
App Engine inclut le service Blobstore, qui permet aux applications de diffuser des objets de données limités uniquement par la quantité de données pouvant être importées ou téléchargées via une seule connexion HTTP. Ces objets sont appelés valeurs Blobstore ou objets blob.
Les valeurs Blobstore sont diffusées en tant que réponses par des gestionnaires de requêtes et créées en tant qu'importations via des formulaires Web. Les applications ne créent pas directement de données blob. En effet, les blobs sont créés indirectement, par un formulaire Web envoyé ou par une autre requête HTTP POST
.
Les valeurs Blobstore peuvent être diffusées auprès de l'utilisateur et sont accessibles par l'application dans un flux de type fichier, à l'aide de l'API Blobstore.
Pour inviter un utilisateur à importer une valeur Blobstore, votre application présente un formulaire Web avec un champ d'importation de fichier. L'application génère l'URL d'action du formulaire en appelant l'API Blobstore. Le navigateur de l'utilisateur importe le fichier directement dans le Blobstore via l'URL générée. Blobstore stocke ensuite le blob, réécrit la requête de manière à inclure la clé blob et la transmet à un chemin d'accès dans votre application. Un gestionnaire de requêtes situé sur ce chemin dans votre application peut alors procéder au traitement approfondi du formulaire.
Pour diffuser un blob, votre application définit un en-tête sur la réponse sortante et App Engine remplace la réponse par la valeur du blob.
Une fois créés, les objets blob ne peuvent pas être modifiés. Cependant, ils peuvent être supprimés. Chaque blob est associé à un enregistrement d'informations, stocké dans le datastore. Cet enregistrement fournit des détails, tels que la date de création et le type de contenu de ce blob. Vous pouvez utiliser la clé blob pour récupérer des enregistrements d'informations sur les blobs et interroger leurs propriétés.
Une application peut lire une valeur de Blobstore portion par portion, à l'aide d'un appel d'API.
La taille de chaque portion est limitée par la taille maximale d'une valeur renvoyée par l'API.
Cela correspond à un peu moins de 32 Mo et à la constante google.appengine.ext.blobstore.MAX_BLOB_FETCH_SIZE
dans Python.
Une application ne peut créer ou modifier des valeurs Blobstore que par le biais des fichiers importés par l'utilisateur.
Utilisation du Blobstore
Les applications peuvent utiliser le Blobstore pour accepter l'importation des fichiers volumineux par les utilisateurs et pour diffuser ces fichiers. Une fois importés, les fichiers sont appelés des objets blob. Les applications n'accèdent pas directement aux blobsElles utilisent plutôt les blobs via des entités d'informations de blobs
(représentées par la classe BlobInfo
) dans le datastore.
L'utilisateur crée un blob en soumettant un formulaire HTML qui inclut un ou plusieurs champs de saisie de fichiers. Votre application
appelle
blobstore.create_upload_url()
pour destination (action) de ce formulaire, en transmettant à la fonction le chemin d'URL d'un gestionnaire dans votre application. Lorsque l'utilisateur envoie le formulaire, son navigateur transfère directement les fichiers indiqués au service Blobstore. Le service Blobstore réécrit la requête de l'utilisateur et stocke les données des fichiers importés, en les remplaçant par une ou plusieurs clés blob correspondantes. Il transmet ensuite la requête ainsi modifiée au gestionnaire au chemin d'URL que vous avez fourni à la fonction
blobstore.create_upload_url()
.
Ce gestionnaire peut procéder à un traitement supplémentaire en fonction de la clé blob.
L'application peut lire des portions d'une valeur Blobstore à l'aide d'uneinterface de diffusion de type fichier. Consultez la classe BlobReader
.
Importer un blob
Pour créer et importer un objet blob, suivez la procédure suivante :
1. Créez une URL d'importation
Appelez
blobstore.create_upload_url()
pour créer une URL d'importation pour le formulaire destiné à l'utilisateur, en transmettant le chemin d'accès de l'application à charger lorsque la requête POST
du formulaire est terminée.
Il existe une version asynchrone, create_upload_url_async()
. Elle permet au code de votre application de continuer à s'exécuter pendant que Blobstore génère l'URL d'importation.
2. Créez un formulaire d'importation
Le formulaire doit inclure un champ d'importation de fichiers et le enctype
du formulaire doit être défini sur multipart/form-data
. Lorsque l'utilisateur envoie le formulaire, la requête POST
est traitée par l'API Blobstore, ce qui entraîne la création du blob. L'API crée également un enregistrement d'informations pour le blob et le stocke dans le datastore. Elle transmet ensuite la requête réécrite à votre application au chemin fourni en tant que clé blob.
3. Implémentez le gestionnaire d'importation
Dans ce gestionnaire, vous pouvez stocker la clé blob avec le reste du modèle de données de l'application. La clé blob elle-même reste accessible à partir de l'entité d'informations sur le blob dans le datastore. Notez qu'une fois que l'utilisateur a soumis le formulaire et que votre gestionnaire a été appelé, le blob a déjà été sauvegardé et les informations associées ajoutées au datastore. Si votre application ne souhaite pas conserver le blob, vous devez le supprimer immédiatement pour éviter qu'il ne devienne orphelin.
Pour toutes les applications Flask, les appels passés aux méthodes dans la classeBlobstoreUploadHandler
nécessitent le dictionnaire request.environ dictionary
(requête importée à partir du module Flask). Si votre application est une application WSGI sans framework Web, utilisez le paramètre environ
dans la méthode get_uploads()
.
Lorsque le service Blobstore réécrit la requête de l'utilisateur, le corps des parties MIME des fichiers importés est vidé, et la clé blob est ajoutée en tant qu'en-tête de la partie MIME.
Tous les autres champs et parties du formulaire sont préservés et transmis au gestionnaire de transferts.
Si vous ne spécifiez pas de type de contenu, le Blobstore tentera de l'inférer à partir de l'extension du fichier. Si cela n'est pas possible, le type de contenu application/octet-stream
est affecté au blob nouvellement créé.
Diffuser un blob
Pour diffuser des blobs, vous devez inclure un gestionnaire de téléchargement de blob en tant que chemin d'accès dans votre application.
L'application diffuse un blob en définissant un en-tête dans la réponse sortante. Si vous utilisez Flask, la classe BlobstoreDownloadHandler
nécessite le dictionnaire request.environ
(requête importée à partir du module Flask). Si votre application est une application WSGI sans framework Web, utilisez le paramètre environ
dans les méthodes send_blob()
.
.
Les blobs peuvent être transmis à partir de n'importe quelle URL d'application. Pour diffuser un blob dans votre application, vous devez mettre un en-tête spécial dans la réponse contenant la clé blob. App Engine remplace le corps de la réponse par le contenu du blob.
Plages d'octets des objets blob
Le Blobstore permet de diffuser uniquement une partie d'une grande valeur, plutôt que la totalité de cette valeur, en réponse à une requête. Pour diffuser une valeur partielle, l'en-tête X-AppEngine-BlobRange
doit être inclus dans la réponse sortante. Sa valeur correspond à une plage d'octets HTTP standard. La numérotation des octets est basée sur zéro. Un champ X-AppEngine-BlobRange
vide indique à l'API d'ignorer l'en-tête de plage et de diffuser le blob dans son intégralité.
Exemples de plages :
0-499
: diffuse les 500 premiers octets de la valeur (octets 0 à 499 inclus).500-999
: diffuse 500 octets à partir du 501e octet.500-
: diffuse tous les octets à partir du 501e octet, jusqu'à la fin de la valeur.-500
: diffuse les 500 derniers octets de la valeur.
Si la plage d'octets est valide pour la valeur Blobstore, le Blobstore envoie au client un code d'état 206
Partial
Content
ainsi que la plage d'octets requise. Si la plage n'est pas valide pour la valeur, le Blobstore envoie 416
Requested
Range
Not
Satisfiable
.
Le Blobstore n'accepte pas plusieurs plages d'octets dans une même requête (par exemple, 100-199,200-299
), qu'elles se chevauchent ou non.
Exemple d'application complète
Consultez l'exemple d'application Flask dans le guide API Blobstore pour Python 3.
Utiliser le service Images avec le Blobstore
Le service Images peut utiliser une valeur Blobstore comme source d'une transformation. La taille de l'image source est limitée par la taille maximale d'une valeur Blobstore. Le service Images renvoie encore l'image transformée à l'application. Par conséquent, l'image transformée doit être inférieure à 32 mégaoctets. Cela est utile pour créer des vignettes des photos volumineuses transférées par les utilisateurs. Pour en savoir plus sur l'utilisation du service Images avec les valeurs Blobstore, consultez la Documentation du service Images
Utiliser l'API Blobstore avec Cloud Storage
Vous pouvez exploiter l'API Blobstore pour stocker des blobs dans Cloud Storage plutôt que dans Blobstore. Vous devez configurer un bucket comme décrit dans la documentation de Cloud Storage, spécifier le bucket et le nom de fichier dans
blobstore.create_upload_url
paramètre gs_bucket_name
.
Dans le gestionnaire d'importation, vous devez traiter les métadonnées FileInfo et stocker explicitement le nom de fichier Cloud Storage nécessaire à la récupération ultérieure du blob.
Vous pouvez également diffuser des objets Cloud Storage à l'aide de l'API Blobstore.
Si vous souhaitez une solution de stockage d'objets plus moderne, envisagez de migrer du service Blobstore d'App Engine vers Cloud Storage.
Utiliser BlobReader
Une application peut lire des données à partir de valeurs Blobstore à l'aide d'une interface semblable à un objet file
Python. Cette interface peut commencer à lire une valeur à n'importe quelle position d'octet, et utilise plusieurs appels de service ainsi que la mise en mémoire tampon. L'application peut ainsi accéder à l'intégralité de la valeur malgré la limite de taille d'une réponse à un appel de service.
La classe BlobReader
peut utiliser l'une des trois valeurs suivantes comme argument pour son constructeur :
L'objet implémente les méthodes de fichier courantes pour lire la valeur. L'application ne peut pas modifier la valeur Blobstore, car elle ne met pas en œuvre les méthodes de fichier pour l'écriture.
Envoyer des requêtes asynchrones
Une application peut appeler certaines fonctions Blobstore qui s'exécutent en arrière-plan.
Le service Blobstore traite la requête pendant que l'application effectue d'autres tâches. Pour envoyer la requête, l'application appelle une fonction asynchrone. Celle-ci renvoie immédiatement un objet RPC représentant la requête. Lorsque l'application a besoin du résultat de la requête, elle appelle la méthode get_result()
de l'objet RPC.
Si le service n'a pas terminé la requête lorsque l'application appelle get_result()
, la méthode attend que la requête soit terminée (ou que le délai ait expiré, ou qu'une erreur se produise). La méthode renvoie l'objet du résultat ou génère une exception si une erreur s'est produite lors de l'exécution de la requête. Par exemple, cet extrait de code
upload_url = blobstore.create_upload_url('/upload')
slow_operation()
self.response.out.write("""<form action="%s" method="POST"
enctype="multipart/form-data">""" % upload_url)
devient
upload_url_rpc = blobstore.create_upload_url_async('/upload')
slow_operation()
upload_url = upload_url_rpc.get_result()
self.response.out.write("""<form action="%s" method="POST"
enctype="multipart/form-data">""" % upload_url)
Dans cet exemple, l'application exécute le code slow_operation()
en même temps que le service Blobstore génère l'URL d'importation.
Quotas et limites
L'espace utilisé pour les valeurs Blobstore est décompté dans le quota Stored Data (billable) (Données stockées (facturables)). Les entités d'informations de blob dans le datastore sont comptabilisées dans les limites associées au datastore. Sachez que Cloud Storage est un service payant qui vous sera facturé selon la grille tarifaire de Cloud Storage.
Pour en savoir plus sur les quotas de sécurité à l'échelle du système, consultez la rubrique Quotas.
Outre les quotas de sécurité à l'échelle du système, les limites suivantes s'appliquent spécifiquement à l'utilisation du Blobstore :
- La taille maximale des données Blobstore lisibles par l'application avec un seul appel d'API est de 32 mégaoctets.
- Le nombre maximal de fichiers importables dans un seul formulaire POST est de 500.