In this tutorial, we will cover how we can leverage Appwrite’s Cloud functions feature to execute certain tasks when certain events take place in the server. You can find a complete list of available system events here.
In this example, we will demonstrate how we can detect objects in an image that the user has uploaded. This could be useful if you’re building something like google photos where you would like to categorize photos based on objects in the image.
For the sake of this example, we will be using Cloudmersive's People and Object Detection API. A similar concept applies to other API providers like Google’s Vision API or Amazon’s Recognition API. So let’s get started.
The first step is to create a Cloudmersive account and obtain the free tier API Key. Now it's time to create your Cloud Function in the Appwrite Console. Head over to the Functions section of your console and select Add Function. You can give your function a funky new name and select the preferred environment. We will be using Python for this example.
The next step is to write the code that will be executed and upload it. Create a directory to hold your Cloud Function. Then create your main code file and a
$ mkdir cloud-functions-demo $ cd cloud-functions-demo $ touch main.py $ touch requirements.txt
We will be using two dependencies for this example
Add these to your
requirements.txt. We would typically perform a
pip install at this stage but that would install the libraries in the shared libraries path. We need the libraries to be installed in the same folder so that they can be packaged easily.
Run the following command to install the libraries inside the local
.appwrite directory. Appwrite’s Python environment will know how to autoload a file from that directory without any special configuration.
PIP_TARGET=./.appwrite pip install -r ./requirements.txt --upgrade --ignore-installed
Great. It’s time to start editing the
main.py file. We start by importing the relevant libraries.
from __future__ import print_function import time from pprint import pprint import json import os # For cloud vision API import cloudmersive_image_api_client from cloudmersive_image_api_client.rest import ApiException # Appwrite SDK from appwrite.client import Client from appwrite.services.storage import Storage
We will use a temporary file to access the image during the function execution. Let’s give this file a name. This is required because the Cloudmersive library expects a file path and not binary data as input.
FILENAME = "temp.jpg"
When a function is triggered by an event, we can obtain a lot of metadata about the event from some special environment variables that are set by Appwrite. A complete list is available here. In our case, we need the ID of the file that was uploaded in order to fetch it. Appwrite conveniently exposes this information as an environment variable named
APPWRITE_FUNCTION_EVENT_PAYLOAD. Let’s parse this JSON string to retrieve the file ID.
# Triggered by the storage.files.create event payload = json.loads(os.environ["APPWRITE_FUNCTION_EVENT_PAYLOAD"]) fileID = payload["$id"]
Now it’s time to set up the Appwrite SDK
# Setup appwrite client client = Client() client.set_endpoint('http://192.168.1.6/v1') # PRIVATE IP OF YOUR APPWRITE CONTAINER client.set_project('5fca866c65afc') # YOUR PROJECT ID client.set_key(os.environ["APPWRITE_KEY"])
Note: Within the Cloud Function, you cannot use localhost to refer to your Appwrite server, because localhost refers to your own runtime environment. You will have to find the private IP of your default network interface using ifconfig (usually eth0 in linux or en0 in macOS).
Using the SDK, lets fetch the image and save it:
# Get the image file storage = Storage(client) result = storage.get_file_preview(fileID) # Save the file to the container with open(FILENAME, "wb") as newFile: newFile.write(result)
We’re almost done. Now we will set up the Cloudmersive SDK and make our API request
# Configure API key authorization: Apikey configuration = cloudmersive_image_api_client.Configuration() configuration.api_key['Apikey'] = os.environ['API_KEY'] # create an instance of the API class api_instance = cloudmersive_image_api_client.RecognizeApi(cloudmersive_image_api_client.ApiClient(configuration)) image_file = FILENAME # file | Image file to perform the operation on. Common file formats such as PNG, JPEG are supported. try: # Detect objects including types and locations in an image api_response = api_instance.recognize_detect_objects(image_file) pprint(api_response) except ApiException as e: print("Exception when calling RecognizeApi->recognize_detect_objects: %s\n" % e)
Before we can package our cloud function, we need to ensure that our directory has the following structure.
. ├── .appwrite/ ├── main.py └── requirements.txt
We package the function by creating a tar file out of our folder.
$ cd .. $ tar -zcvf code.tar.gz cloud-functions-demo
We can now upload this tarfile to our function’s dashboard by selecting the Deploy Tag option. Our entry point command, in this case, would be:
$ python main.py
Note: You can also automate the code upload process using the Appwrite server SDK latest version and your CI server. In future versions, Appwrite will also support this process using a dedicated CLI tool, directly from your terminal.
Once created, we need to define a trigger for the function. In our case, we wish to trigger it whenever a new file is uploaded to the Appwrite server. So we would be interested in the
storage.files.create event. The trigger can be enabled under the Settings tab of the function.
Once the triggers are enabled, it’s time for our final step, Function Variables. Appwrite allows you to securely store secret keys using Appwrite Function Variables which will be available as environment variables to your program. The best part is that these keys are encrypted and stored securely on Appwrite’s internal DB. In this example, we have used two environment variables namely
API_KEY (Cloudmersive API Key) and
APPWRITE_KEY (Appwrite API Key) so let’s add them to the Function Variables. Don’t forget to click the Update option once you’re happy with your settings.
Great! We’re done with all the setup. All that’s left now is to test the Cloud Function.
Now it’s time to test your shiny new Cloud Function! Head over to the Storage section of Appwrite and create a new file by clicking on the ‘+’ button at the bottom right. Choose an image of your choice and click Create.
Your Cloud Function would now have been triggered. You can check it out by heading over to
Functions > Your Function Name > Logs
Once the execution is complete, you can check the response from the API.
And in a few simple steps, we successfully deployed our first Cloud Function. The possibilities with Cloud Functions are endless! Stay tuned for more Cloud Function ideas from the Appwrite Team.
- You can find the complete code sample and lots of other demos in our Cloud Functions Demo Repo.
- Check out Appwrite's Github Repo.
- Our Discord Server is the place to be if you ever get stuck.
- You can find all our Documentation here.