Storage
Appwrite Storage allows you to manage files in your project. You can use it to store images, videos, documents, and other files for your projects. It provides APIs to upload, download, delete, and list files. Not only that Appwrite storage service provides APIs to manipulate images. Using the preview endpoint, you can crop, resize, rotate, add borders and border-radius and select the desired output format for your image. The preview API also allows you to change your image's quality, format, or compression, including WebP support for maximum optimization of your network bandwidth.
Buckets
Storage buckets are similar to collections in the Databases service. The difference is buckets also provide more power to decide what kinds of files, what sizes you want to allow in that bucket, whether or not to encrypt the files, scan with antivirus, and more. Let's look at how we can create a bucket and configure it to your needs.
Create Bucket
You can create your bucket from your Appwrite project's dashboard, using any of our server-side SDKs, or directly using our REST API authenticated using an API Key. To create a bucket from the Appwrite Console, access your Storage dashboard from your project's left navigation panel. Click Add Bucket button and choose your bucket's name. You can also set a custom ID for your bucket instead of an auto-generated ID for convenience. This will create a new bucket and take you to its settings page, where you can configure various options for your bucket.
You can manage your buckets programmatically using one of Appwrite's Server SDKs or REST API paired with an API Key. You can manage files with both Server and Client side.
Permissions
The Storage Service allows you to configure permissions at both the bucket level and the file level. When a user has the appropriate type of access permissions granted at either the bucket or the file level, they will be able to access the file. If the permission field is left empty, no one can access the file.
File Level Permissions
File level permissions grant access to individual files. File level permissions are only enabled if File Security is enabled in the settings of your bucket.
Bucket Level Permissions
Bucket level permissions apply to every file in the bucket.
More Bucket Configurations
Storage buckets have many configuration options, including the type and maximum size of files in the bucket, whether encryption or anti-virus is enabled, and the compression algorithm to use. If you look at the bucket settings or the REST API example above, you can find these configurations. Let's look at what those are:
Parameter | Description |
---|---|
allowedFileExtensions | This parameter allows you to provide a list of file extensions that will be accepted into the bucket. |
maximumFileSize | This parameter allows you to set the maximum size of a file that a bucket accepts. The buckets will accept any file less than or equal to the size provided here. |
encryption | This parameter allows you to configure whether or not the files inside the bucket will be encrypted. We don't encrypt files bigger than 20MB. |
antivirus | This parameter allows you to configure whether or not the files being added inside the bucket be scanned by antivirus. We don't scan files bigger than 20MB. |
You can learn more about storage buckets and APIs you can use to manage storage buckets from our Storage documentation. Now that we know how to create and configure buckets for our applications, let's look at how to manage files using the storage service.
Create File
After you create a bucket or have navigated to bucket details, you can access the Files tab so you can upload, view, delete and update files in the bucket using the Appwrite project's dashboard. You can also perform all those operations from Appwrite's client SDK, server SDKs, and REST APIs as long as you have the proper permission.
When you are in the Files tab, you can click Add File and select a file to upload. If the bucket is configured to accept the file type and size you are uploading, your file will be uploaded, and you will see the file in the list of files.
You can also upload files programmatically using our SDKs:
-
Web
import { Client, Storage } from "appwrite"; const client = new Client() .setEndpoint('https://cloud.appwrite.io/v1') .setProject('[PROJECT_ID]'); const storage = new Storage(client); const promise = storage.createFile( '[BUCKET_ID]', ID.unique(), document.getElementById('uploader').files[0] ); promise.then(function (response) { console.log(response); // Success }, function (error) { console.log(error); // Failure });
-
Flutter
import 'package:appwrite/appwrite.dart'; void main() { // Init SDK final client = Client() .setEndpoint('https://cloud.appwrite.io/v1') .setProject('[PROJECT_ID]'); final storage = Storage(client); final file = await storage.createFile( bucketId: '[BUCKET_ID]', fileId: ID.unique(), file: InputFile.fromPath(path: './path-to-files/image.jpg', filename: 'image.jpg'), ); }
-
Android
import io.appwrite.Client import io.appwrite.services.Storage suspend fun main() { val client = Client(applicationContext) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint .setProject("[PROJECT_ID]") // Your project ID val storage = Storage(client) val file = storage.createFile( bucketId = "[BUCKET_ID]", fileId = ID.unique(), file = File("./path-to-files/image.jpg"), ) }
-
Apple
import Appwrite func main() async throws { let client = Client() .setEndpoint("https://cloud.appwrite.io/v1") .setProject("[PROJECT_ID]") let storage = Storage(client) let file = try await storage.createFile( bucketId: "[BUCKET_ID]", fileId: ID.unique(), file: InputFile.fromBuffer(yourByteBuffer, filename: "image.jpg", mimeType: "image/jpeg" ) ) }
-
GraphQL
POST /v1/storage/buckets/{bucketId}/files HTTP/1.1 Content-Type: multipart/form-data; boundary="cec8e8123c05ba25" Content-Length: *Length of your entity body in bytes* X-Appwrite-Project: [PROJECT_ID] --cec8e8123c05ba25 Content-Disposition: form-data; name="operations" { "query": "mutation CreateFile($bucketId: String!, $fileId: String!, $file: InputFile!) { storageCreateFile(bucketId: $bucketId, fileId: $fileId, file: $file) { id } }", "variables": { "bucketId": "[BUCKET_ID]", "fileId": "[FILE_ID]", "file": null } } --cec8e8123c05ba25 Content-Disposition: form-data; name="map" { "0": ["variables.file"] } --cec8e8123c05ba25 Content-Disposition: form-data; name="0"; filename="file.txt" Content-Type: text/plain File content. --cec8e8123c05ba25--
When you are trying to upload any files above 5MB, you will need to upload them in chunks for better reliability and performance. If you're using an Appwrite SDK, this is handled automatically. If you're not using an SDK, you can learn more about file handling in the REST API docs.
File Input
Every language and platform handles file inputs differently. This section documents the expected input type of each SDK. Where applicable, Appwrite provides a InputFile
class to accept multiple file sources, like paths, buffers, streams, or plain text.
Client SDK
-
Web
The Appwrite Web SDK expects a File object for file creation. This is most commonly associated with DOM file inputs.
For example, for the input tag
<input type="file" id="uploader" />
, you would call create file like this:const promise = storage.createFile( '[BUCKET_ID]', ID.unique(), document.getElementById('uploader').files[0] );
-
Flutter
The Appwrite Flutter SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(path: [PATH], filename: [NAME], contentType: [MIME TYPE])
Used to upload files from a provided path, filename
andcontentType
are optional. Used for Flutter apps on mobile and desktop.InputFile.fromBytes(bytes: [BYTE LIST], filename: [NAME], contentType: [MIME TYPE])
Used to upload files from a byte list, contentType
is optional. Used for Flutter apps on web -
Android
The Appwrite Android SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(path: String)
Used to upload files from a provided path. InputFile.fromFile(file: File)
Used to upload files from a File object. InputFile.fromBytes(bytes: ByteArray, filename: String, mimeType: String)
Used to upload files from a ByteArray object. Specify the file MIME type using the mimeType
param. -
Apple
The Appwrite Apple SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(_ path: String)
Used to upload files from a provided path. InputFile.fromData(_ data: Data, filename: String, mimeType: String)
Used to upload files from a Data object. Specify the file MIME type using the mimeType
param.InputFile.fromBuffer(_ buffer: ByteBuffer, filename: String, mimeType: String)
Used to upload files from a NIO Buffer object. Specify the file MIME type using the mimeType
param.
Server SDK
-
Node.js
The Appwrite NodeJS SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(filePath, filename)
Used to upload files from a provided path. InputFile.fromBuffer(buffer, filename)
Used to upload files from a Buffer object. InputFile.fromBlob(blob, filename)
Used to upload files from a Blob object. InputFile.fromStream(stream, filename, size)
Used to upload files from a Readable Stream object. InputFile.fromPlainText(content, filename)
Used to upload files in plain text. Expects a string encoded in UTF-8. -
PHP
The Appwrite PHP SDK expects an
InputFile
class for file inputs.Method Description InputFile.withPath(string $path, ?string $mimeType = null, ?string $filename = null)
Used to upload files from a provided path. InputFile.withData(string $data, ?string $mimeType = null, ?string $filename = null)
Used to upload files from a string. -
Python
The Appwrite Python SDK expects an
InputFile
class for file inputs.Method Description InputFile.from_path(path)
Used to upload files from a provided path. InputFile.from_bytes(bytes)
Used to upload files from an array of bytes. -
Ruby
The Appwrite Ruby SDK expects an
InputFile
class for file inputs.Method Description InputFile.from_path(path)
Used to upload files from a provided path. InputFile.from_string(string)
Used to upload files from a String. InputFile.from_bytes(bytes)
Used to upload files from an array of bytes. -
Deno
The Appwrite Deno SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(filePath, filename)
Used to upload files from a provided path. InputFile.fromBuffer(buffer, filename)
Used to upload files from a Uint8Array object. InputFile.fromPlainText(content, filename)
Used to upload files in plain text. Expects a string encoded in UTF-8. -
Dart
The Appwrite Dart SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(path: [PATH], filename: [NAME], contentType: [MIME TYPE])
Used to upload files from a provided path, filename
andcontentType
are optional.InputFile.fromBytes(bytes: [BYTE LIST], filename: [NAME], contentType: [MIME TYPE])
Used to upload files from a byte list, contentType
is optional. -
Kotlin
The Appwrite Kotlin SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(path: String)
Used to upload files from a provided path. InputFile.fromFile(file: File)
Used to upload files from a File object. InputFile.fromBytes(bytes: ByteArray, filename: String, mimeType: String)
Used to upload files from a ByteArray object. Specify the file MIME type using the mimeType
param. -
Swift
The Appwrite Swift SDK expects an
InputFile
class for file inputs.Method Description InputFile.fromPath(_ path: String)
Used to upload files from a provided path. InputFile.fromData(_ data: Data, filename: String, mimeType: String)
Used to upload files from a Data object. Specify the file MIME type using the mimeType
param.InputFile.fromBuffer(_ buffer: ByteBuffer, filename: String, mimeType: String)
Used to upload files from a NIO Buffer object. Specify the file MIME type using the mimeType
param.
Image Manipulation
Another great built-in feature of Appwrite is the image manipulation feature. With Appwrite Storage's preview endpoint you can manipulate resolution, add borders and the border-radius, add background-color, set the opacity for the image, and get the image in the appropriate output format.
This enables a wide range of possibilities! You can manipulate images resolution to display appropriately on responsive websites. You can also adjust the image border, background color, and border-radius to match the theming of your application. The Appwrite Storage also allows you to change the format and compression of your images for network transfer optimization and to help you speed your application. You can do all that without caring about how the image was originally uploaded.
Below you can find all the different parameters offered by the preview endpoint to manipulate the image.
Parameter | Description |
---|---|
height | Set the height of the output image in pixels, the image will be resized keeping the aspect ratio intact. Accepts integer between 0-4000 |
width | Set the width of the output image in pixels, the image will be resized keeping the aspect ratio intact. Accepts integer between 0-4000 |
gravity | The gravity while cropping the image providing either width, height or both. Accepts any of: center, top-left, top, top-right, left, right, bottom-left, bottom, bottom-right |
quality | Set the quality of the output image. Accepts integer between 0-100, where 100 is the highest quality. |
borderWidth | Set a border with given width in pixels to the output image. Accepts integer between 0-100 |
borderColor | Set a border-color for the output image. Accepts any valid Hex color value without the leading #. |
borderRadius | Set a border-radius in pixels. Accepts an integer between 0-4000. |
opacity | Set opacity for the output image. Accepts a float value between 0-1, where 0 makes it transparent. Only works with output format supporting alpha channel like png. |
rotation | Rotate the output image by a degree. Accepts an integer between -360 to 360. |
background | Set a background-color. Accepts any valid Hex color value without the leading #. Only works with output format supporting alpha channel like png. |
output | Set the output image format. If not provided, will use the original image's format. Supported formats are: jpg, jpeg, png, gif and webp |
Downloading and Streaming with Range
Appwrite supports streamed downloads using the HTTP range header to gracefully handle large files. If you are using our SDKs or console, nothing is different. Even if you want to download the whole file at once, even if you use the REST endpoint directly, there isn't any difference. However, if you want to get only a part of a file from storage, you can supply the range header and the server will respond with an appropriate chunk of the file.