A website looks more interesting with some images to liven up the text of articles, reviews, etc. Metro Publisher has a file library where we can store those images. The images have to be uploaded to the library before they can be used, for example, as the feature image for an article.
The library also allows uploads of files other than images, i.e. with a different MIME type. There is a size limit on files, depending on the MIME type. For example, we can add a PDF file detailing ways how people can advertise through our website.
So, in this chapter we want to add the following files to the library:
Files consist of two parts: the file metadata (e.g. file name, title and description) and the file itself. In order to add a file, we must first send the metadata as a PUT request to /{iid}/files/{uuid}. Once the file has been created, we can send a POST request to the same url to upload the file itself.
Let's start by adding an image taken during a trip to Rome. To add an image we send the image's metadata to PUT /{iid}/files/{uuid}:
>>> PUT("/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff",
... {'title': 'Rome at Night',
... 'filename': 'romeatnight.jpg',
... 'description': 'Night view of Rome',
... 'credits': '(c) 2012 Mike Meyers',
... 'created': '2012-08-28T09:00:00',
... 'modified': '2012-08-28T09:00:00'
... })
{'url': 'https://api.metropublisher.com/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff',
'uuid': 'ffffffff-ffff-ffff-ffff-ffffffffffff'}
Now that the image object has been added to the MP instance's file library, we can upload the actual file by sending a POST request to the same url, i.e. /{iid}/files/{uuid}:
>>> POST("/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff",
... REQUEST_BODY_CONTAINING_IMAGEDATA,
... content_type='image/jpeg')
{'download_url': 'https://api.metropublisher.com/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff/download/1346140800',
'url': 'https://api.metropublisher.com/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff',
'uuid': 'ffffffff-ffff-ffff-ffff-ffffffffffff'}
request body
The request body contains the file data, i.e. the file itself.
content_type
The request header must contain the 'Content-Type' field. The value of this field is the MIME type of the file, in this case 'image/jpeg'.
download_url [1]
The return value of the POST request contains a download_url [1].
Adding a file other than an image works just the same as above. As a PDF we'll add a "Media Kit" file with contact information and details for advertising:
>>> PUT("/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd",
... {'title': 'Media Kit 2012',
... 'filename': 'mediakit_2012.pdf',
... 'description': 'Our Media Kit 2012',
... 'created': '2012-01-04T10:00:00',
... 'modified': '2012-01-04T10:00:00'
... })
{'url': 'https://api.metropublisher.com/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd',
'uuid': 'ffffffff-dddd-dddd-dddd-dddddddddddd'}
>>> POST("/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd",
... REQUEST_BODY_CONTAINING_PDFDATA,
... content_type='application/pdf')
{'download_url': 'https://api.metropublisher.com/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd/download/1325667600',
'url': 'https://api.metropublisher.com/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd',
'uuid': 'ffffffff-dddd-dddd-dddd-dddddddddddd'}
content_type
In this case, the request header field 'Content-Type' has the value 'application/pdf' to specify that this is a PDF file.
>>> PUT("/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc",
... {'title': 'Some File',
... 'filename': 'somefile.xyz',
... 'created': '2012-01-04T10:00:00',
... 'modified': '2012-01-04T10:00:00'
... })
{'url': 'https://api.metropublisher.com/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc',
'uuid': 'ffffffff-cccc-cccc-cccc-cccccccccccc'}
>>> POST("/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc",
... REQUEST_BODY_CONTAINING_FILEDATA,
... content_type='unknown/mimetype')
{'download_url': 'https://api.metropublisher.com/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc/download/1325667600',
'url': 'https://api.metropublisher.com/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc',
'uuid': 'ffffffff-cccc-cccc-cccc-cccccccccccc'}
We've added three files to the MP instance now. We can retrieve a list of the files by sending a GET request to /{iid}/files:
>>> GET("/123/files")
{'items': [['https://api.metropublisher.com/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc'],
['https://api.metropublisher.com/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd'],
['https://api.metropublisher.com/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff']]}
This returns the API url for each of the three files. But, of course, this collection resource takes a few parameters to either get more information for each file or to filter which files are returned:
>>> GET("/123/files?groups=image-unknown&fields=title-url-mimetype-filename")
{'items': [['Rome at Night',
'https://api.metropublisher.com/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff',
'image/jpeg',
'romeatnight.jpg'],
['Some File',
'https://api.metropublisher.com/123/files/ffffffff-cccc-cccc-cccc-cccccccccccc',
'unknown/mimetype',
'somefile.xyz']]}
Here we used the fields parameter to get more information for each file:
We also used the groups parameter. This parameter allows us to filter for specific content type groups, in this case the groups images and unknown. The call to the GET /{iid}/files resource above only returns two files (instead of the three files available in the instance) because the MIME type of the third file does not belong to either the group image nor the group unknown. The third file is of the type application/pdf and therefore belongs to the group application.
Another parameter for this resource is mimetypes. With this parameter we can filter for specfic MIME types, such as 'application/pdf':
>>> GET("/123/files?mimetypes=application/pdf&fields=title-url-mimetype-filename")
{'items': [['Media Kit 2012',
'https://api.metropublisher.com/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd',
'application/pdf',
'mediakit_2012.pdf']]}
To retrieve a file's metadata, we send a GET request to the file resource /{iid}/files/{uuid}:
>>> GET("/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff")
{'byte_size': 315,
'created': '2012-08-28T09:00:00',
'credits': '(c) 2012 Mike Meyers',
'description': 'Night view of Rome',
'download_url': 'https://api.metropublisher.com/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff/download/1346140800',
'filename': 'romeatnight.jpg',
'mimetype': 'image/jpeg',
'modified': '2012-08-28T09:00:00',
'title': 'Rome at Night',
'uuid': 'ffffffff-ffff-ffff-ffff-ffffffffffff'}
This resource does not return the file data, i.e. we cannot use this resource to display the file itself. For that we need to send a GET request to the download_url [1] returned by the GET /{iid}/files/{uuid} resource:
>>> GET("/123/files/ffffffff-ffff-ffff-ffff-ffffffffffff/download/1346140800")
<200 OK image/jpeg body=b'\xff\xd8...\xd9'/315>
When downloading an image, we can specify the maximum width/height for the image by adding the parameters:
to the download url. That way we can downscale the image to fit into our application and save bandwidth:
>>> GET("/123/files/ffffffff-ffff-ffff-ffff-aaaaaaaaaaaa/download/1346140800")
<200 OK image/png body=b'\x89PNG\...\x82'/40999>
>>> GET("/123/files/ffffffff-ffff-ffff-ffff-aaaaaaaaaaaa/download/1346140800?h=120&w=300")
<200 OK image/png body=b'\x89PNG\...\x82'/7247>
The last number in the return values above shows the byte size of the image:
An image will only ever be downscaled, so if we send a maximum width/height that is larger than the size of the original image, the system will return the image in its original size.
The parameters w and h are not available for non-image files:
>>> GET("/123/files/ffffffff-dddd-dddd-dddd-dddddddddddd/download/1325667600?h=200&w=100")
{'error': 'bad_parameters',
'error_description': 'One or more of your incoming parameters failed validation, see info for details',
'error_info': {'h': "'h' parameter not available for files of type 'application/pdf'.",
'w': "'w' parameter not available for files of type 'application/pdf'."}}
[1] | (1, 2, 3) Warning The download_url of a file is not a constant url, i.e. it may change at any time. This url should not be stored in a remote system and should always be retrieved via the GET /{iid}/files/{uuid} resource. |