From 01585c2c88c226efb73036ef378427839d4c5013 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" Appwrite uses emails and SMS messages to perform user invite, user verification, login, and reset password. Emails and SMS messages can be customized to fit your app's design and voice. You can customize email and SMS templates in the Appwrite console. The built-in email service does not support custom email templates. Configure a custom SMTP server to enable custom email templates. Appwrite uses emails and SMS messages to perform user invite, user verification, login, and reset password. Emails and SMS messages can be customized to fit your app's design and voice. You can customize email and SMS templates in the Appwrite console. The built-in email service does not support custom email templates. Configure a custom SMTP server to enable custom email templates. The built-in email service does not support custom email templates. Configure a custom SMTP server to enable custom email templates. Appwrite uses emails and SMS messages to perform user invite, user verification, login, and reset password. Emails and SMS messages can be customized to fit your app's design and voice. Appwrite uses emails messages to perform user invite, user verification, login, and reset password. Emails messages can be customized to fit your app's design and voice. You can customize email and SMS templates in the Appwrite console. You can customize email templates in the Appwrite console. The built-in email service does not support custom email templates. Configure a custom SMTP server to enable custom email templates. You can customize the email emplates for account verification, magic-url authentication, password resets, and user invites. Each email templates has the following components that you can customize. In Client and Server SDKs, you will find a Permission class with helper methods for each role described below. [TODO: @damodar are these variables accessible only in the Message tempalte or also the other components?] [TODO: @damodar are these variables accessible only in the Message tempalte or also the other components?] Variables can be used in email templates to dynamically format unique emails for each reader. These variables can only be accessed in the Message field of the email template. You can customize the SMS emplates used for phone verification and login. Variables can be used in SMS templates to dynamically format unique messages for each reader. Appwrite uses emails messages to perform user invite, user verification, login, and reset password. Emails messages can be customized to fit your app's design and voice. Appwrite uses email and SMS messages to communicate with users to perform authentication actions. Emails and SMS messages can be customized to fit your app's design and voice. Each Appwrite project can have its own set of unique templates. Templates also support localization, every template can be written in multiple languages and served depending on the [TODO: @dlohani] You can customize email templates in the Appwrite console. You can customize email templates for each of your projects in the Appwrite console. The built-in email service does not support custom email templates. Configure a custom SMTP server to enable custom email templates. You can customize the email emplates for account verification, magic-url authentication, password resets, and user invites. Each email templates has the following components that you can customize. In Client and Server SDKs, you will find a Permission class with helper methods for each role described below. You can customize the SMS emplates used for phone verification and login. The Appwrite API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded or JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. The Appwrite API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded or JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. Specifications for the Appwrite API are available in multiple formats, including Open API 3 for clients or servers and Swagger2 for clients or servers. Appwrite Functions allow you to extend and customize your Appwrite server functionality by executing your custom code. Appwrite can execute your custom code in response to any Appwrite system event like account creation, user login, or document update. You can also schedule your functions or start them manually by triggering your function from an HTTP endpoint using the Appwrite client or server APIs. Appwrite Functions run in a secure, isolated Docker container. By default, Appwrite supports multiple runtimes for different languages that you can use to run your code. The quickest way to get started with Appwrite Functions is using the Appwrite CLI. The CLI comes with starter code and some simple commands to quickly create and deploy your functions. Once you have the CLI installed and setup with an Appwrite project, create your first function using: Give your function a name and choose your runtime. This will create a new starter function in the current directory and also add it to your You can now head over to your Appwrite Dashboard, navigate to the Function settings and execute your function. You can find the status of your execution under the Logs tab. Feel free to modify and play around with the starter code and use the The following sections will dive deeper into some more terminology and advanced concepts which can be useful when writing your function from scratch. When writing your own Appwrite Function, you must export the code in certain ways depending on the language. This varies between languages so refer to the examples below. Installing Dependencies Include a Installing Dependencies Include a Installing Dependencies Include a Installing Dependencies Include a Installing Dependencies No special steps are required for Deno, Appwrite handles everything! Installing Dependencies Include a With Swift, your entrypoint can be empty since Appwrite automatically infers it from the location of your main() function. Just ensure that your cloud function has a single declaration of main() across your source files. Installing Dependencies Include a Installing Dependencies Include a Installing Dependencies Include a Installing Dependencies Include a Installing Dependencies Include a When your function is called, you receive two parameters, a The response object has two functions, Before you can deploy your function, you will need to create a new function from your Appwrite project's dashboard. Access the Function settings from your project's left navigation panel. Click the 'Add Function' button and choose a function name and runtime. In your Functions settings page, you can also set your function event triggers, CRON schedule, and set secure function variables for your function. Once you've written your function, you can now deploy it using the Appwrite CLI, the Appwrite Server API or manually from the Appwrite console. The command above accepts three parameters: You can also create new code deployments using the Appwrite server API You can also upload your functions to be deployed using the Appwrite console. The example below shows a simple Node.JS function, but the same idea applies to any other language. First, navigate inside the folder that contains your dependency file. Package your code files into the Next, navigate to your Appwrite console and upload the function. Deployments needs to be built before they can be activated. This is automatically done after creating a deployment and the time taken can vary depending on the runtime. If a build fails for any reason, the deployment's status is set to failed and you won't be able to activate it. You can however retry a build if you think it was caused by an external factor using the Retry Button on the Appwrite Dashboard or Retry Build endpoint with the To find more details about a deployment and reasons for its failure, you can use the Get Deployment endpoint using the Deployments that have been built successfully are marked as ready and can be activated and executed. Compiled runtimes such as Rust and Swift take much longer to build however yield better performance over their interpreted counterparts such as Node. Besides setting a schedule or allowing your function to listen to Appwrite's system events, you can also manually execute your cloud functions from your Appwrite console or API. To execute a function from the Appwrite console, click the Execute Now button on your function's overview page. To execute a function from the API, send a POST request to the function execution endpoint. The function execution endpoint is available from both Appwrite client and server APIs. To execute your function from the server API, you need an API key with 'execution.write' scope. Executing the function from the client API requires the current user to have execution permission for the function. You can change the execution permission from the function's settings page in the Appwrite console, by default no user, team, or role has this permission. Appwrite supports scheduled function executions. You can schedule executions using cron expressions in the settings of your function. Cron supports recurring executions as frequently as every minute. Here are some cron expressions for common intervals. Appwrite Functions can be executed using Client or Server SDKs. Client SDKs must be authenticated with an account that has been granted execution permissions on the function's settings page. Server SDKs require an API key with the correct scopes. The Functions Service APIs are rate limited to 60 calls per minute per account when using a Client SDK. Learn more about rate limiting. The response size of a Cloud Function is limited to 1MB. Responses larger than 1MB should be handled using Appwrite's Databases or Storage service. Each execution has a default timeout of 15 seconds to prevent hanging functions from blocking resources. This timeout can be configured per function on a function's settings page or in Library folders such as You can use the ignore property in your The example configuration above would not deploy the folder Alternatively, you can add a If you need to use a Appwrite provides multiple code runtimes to execute your custom functions. Each runtime uses a Docker image tied to a specific language version to provide a safe, isolated playground to run your team's code. Below is a list of supported Cloud Functions runtimes. The Appwrite team continually adds support for new runtimes. By default, the following runtimes are enabled: Function variables supplied by Appwrite in addition to your own defined function variables that you can access from your function code. These variables give you information about your execution runtime environment. version >= 0.8.0 version >= 0.8.0 version >= 0.8.0 version >= 0.8.0 version < 0.8.0 (deprecated) version < 0.8.0 (deprecated) version < 0.8.0 (deprecated) Appwrite Server SDKs require an API key, an endpoint, and a project ID for authentication. Appwrite passes in your project ID with the function variable If you are running a local Appwrite instance, you will need to pass in the machine's public IP instead of You can integrate Appwrite Functions with other Appwrite services by using the appropriate Server SDK for your runtime. You can find starter code for your function's runtime in the Appwrite Function Starter repository. To initialize a Server SDK in a function, you need to provide your Appwrite endpoint and an API key in the Variables tab of your Function. The ID of your Appwrite project is passed in automatically as You can monitor your function execution usage stats and logs from your Appwrite console. To access your functions usage stats and logs, click the Usage tab in your function dashboard. The usage screen in your console will allow you to track the number of execution and your function CPU usage time. You can also review a detailed log of your function execution history, including the function exit code, output log, and error log. There are many Cloud Function demos and examples created by the Appwrite team and community in multiple coding languages. These examples are available at our examples repository on GitHub. You can also submit your examples by submitting a pull-request.
+ Appwrite Functions let you extend Appwrite by adding your own code and logic.
+ You can think of them as code snippets that are triggered by server events, webhooks, scheduled executions, or user invokation.
+ Each function will have their own URL, execute in their own isolated container, and have their own configurable environment variables and permissions.
+ With these features, Appwrite Functions unlock limitless potential to expand Appwrite's capabilities with custom logic and integrations.
+
+ The quickest way to experience Appwrite functions is to [TODO: @matej What's a good example to show to give devs an idea of what Appwrite Functions workflow is like?]
+
+ To fully harness the power of Appwrite Functions, explore the following features.
+
+ If you need to integrate Appwrite with a third-party API or add a function for common utilities,
+ there might already be a function template made by the Appwrite community that fits your needs.
+ Function templates are Appwrite Functions repositories that you can clone and add to your Appwrite instance.
+
+Learn more about using function templates
+
+ Appwrite Functions are designed to be maintainable and fit into a familiar development workflow.
+ You can deploy them from a GitHub repository branch or using the Appwrite CLI.
+
+Learn more about using deploying functions
+
+Appwrite Functions can be executed directly through a request to the API, or triggered by events, webhooks, or scheduled executions.
+This flexible execution models unlocks many potential usecases for Appwrite functions.
+Explore using Appwrite Functions to execute a complex routine of logic, or execute background tasks on a schedule.
+
+Learn more about using executing functions
+
+Writing Appwrite Functions should feel familiar to writing controllers in an HTTP server.
+In your function, you'll receive a request object, add transformations and logic, then return a response.
+Almost anything can be executed as code in an Appwrite Function.
+Customize Templates
+Custom SMTP Server Required
+
+
+Email Templates
+
+Email Template Syntax
+Email Template Components
+
+
+SMS Templates
+
+SMS Template Syntax
+SMS Template Components
\ No newline at end of file
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 998d36cfe..0265e8178 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -106,6 +106,7 @@ $cols = [
Customize Templates
+Customize Templates
Custom SMTP Server Required
-
-Email Templates
+Email Templates
+Add a SMTP provider
+Email Template Syntax
+Email Template Components
-Email Template Syntax
-Email Template Components
+SMS Templates
-SMS Templates
-
-SMS Template Syntax
-SMS Template Components
\ No newline at end of file
+SMS Template Syntax
+SMS Template Components
\ No newline at end of file
From 0c444f7d0daebcdfdfa61004e41fb0ccf7cbdbbb Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" Customize Templates
-Custom SMTP Server Required
-
Email Templates
-Add a SMTP provider
-Email Template Syntax
-Email Template Components
+Email Template Components
+Permission Types
+
+
+
+
+
+
+
+ Component
+ Description
+
+
+ Sender name
+ [TODO: @damodar where is this used?].
+
+
+ Sender email
+ [TODO: @damodar which part of this can be configured? Does it have to do with the SMTP configuration?].
+
+
+ Reply to
+ [TODO: @damodar Where is this displayed, if empty is no reply?].
+
+
+ Subject
+ The title of the email.
+
+
+
+Message
+ The body of the email. You can find the variables available in the Email Template Syntax section.
+ Email Template Syntax
+SMS Templates
-
-SMS Template Syntax
-SMS Template Components
\ No newline at end of file
+
+
+
\ No newline at end of file
From 703d2c36971b877dd078d864520a7bd4b0d1454e Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
+
+
+
+ Component
+ Description
+
+
+
+ {{project}}The project name.
+
+
+
+ {{team}}Thee project team's name.
+
+
+
+
+ {{user}}The name of the uer receiving the email.
+ Email Templates
@@ -29,15 +29,15 @@
Sender name
- [TODO: @damodar where is this used?].
+ Readers will see this as display name of the sender.
Sender email
- [TODO: @damodar which part of this can be configured? Does it have to do with the SMTP configuration?].
+ Readers will see this as the displayed email of the sender. This must be a valid email for the SMTP provider your configured.
Reply to
- [TODO: @damodar Where is this displayed, if empty is no reply?].
+ Readers will reply to this email adress instead of the sender address. You can leave this field empty if unused.
Subject
@@ -50,7 +50,7 @@
Email Template Syntax
-
From 5b880ecc121613a21871b9e854fd041cf29fd7c4 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
+
+The name of the uer receiving the email.
+SMS Templates
+SMS Template Components
+
+
+
+
+
+
+
+
+ Component
+ Description
+
+
+
+Message
+ The body of the SMS message. You can find the variables available in the SMS Template Syntax section.
+ SMS Template Syntax
+
+
+
\ No newline at end of file
From 455b4bf9972413d4b934838422fb2a27c43e230f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
+
+
+
+ Component
+ Description
+
+
+
+ {{project}}The project name.
+
+
+
+ {{team}}Thee project team's name.
+
+
+
+ {{user}}The name of the uer receiving the email.
+
+
+
+ {{passcode}}The secret code sent to users for phone verification or authentication.
+
@@ -99,7 +103,7 @@
-
@@ -70,7 +70,11 @@
Component
+ Variable
Description
+
- {{user}}The name of the uer receiving the email.
+ The name of the user receiving the email.
+
+
+ {{redirect}}The URL for the user to complete the email template's action.
\ No newline at end of file
+
+
+
-
From a0ebf266a8ef920bb9e3555c99fe3c2e549803c1 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" Component
+ Variable
Description
+
+
-
- Customize Templates
-Custom SMTP Server Required
Email Template Components
Permission Types
-
+
@@ -79,6 +86,9 @@
Email Template Components
+[TODO: @dlohani once we're ready, let's do examples for each type of template (maybe also what it would look like rendered)]
+
SMS Templates
SMS Template Components
@@ -125,4 +135,11 @@
The secret code sent to users for phone verification or authentication.
-SMS Template Components
+[TODO: @dlohani once we're ready, let's do examples for each type of template (maybe also what it would look like rendered)]
+
+Localization
+[TODO: @dlohani short description of how it's decided which language's template is sent]
+[TODO: @dlohani Maybe example of a template in two languages? (maybe also what it would look like rendered)]
diff --git a/app/views/docs/main.phtml b/app/views/docs/main.phtml
index 8c4db0f2e..373d4ab51 100644
--- a/app/views/docs/main.phtml
+++ b/app/views/docs/main.phtml
@@ -94,7 +94,7 @@ $getSpecsUrl = function($type, $platform) use ($latestVersion) {
API References
- SMS Template Components
+SMS Template Examples
[TODO: @dlohani once we're ready, let's do examples for each type of template (maybe also what it would look like rendered)]
Localization
From 601dd293f7df9e8dbe891dd357322c8051b80f56 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" Email Template Components
+Email Template Examples
[TODO: @dlohani once we're ready, let's do examples for each type of template (maybe also what it would look like rendered)]
SMS Templates
From 4537a2b71a802db213009df5b741a45d2f374aed Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" Getting Started
-
-
-appwrite init functionappwrite.json file. Go ahead and deploy your function using :
-appwrite deploy functionappwrite deploy command to instantly deploy your changes to the Appwrite server. Writing your own Function
-
-
-
-
-
-Node.js
-
- module.exports = async (req, res) => {
- const payload =
- req.payload ||
- 'No payload provided. Add custom data when executing function.';
-
- const secretKey =
- req.variables.SECRET_KEY ||
- 'SECRET_KEY variable not found. You can set it in Function settings.';
-
- const randomNumber = Math.random();
-
- const trigger = req.variables.APPWRITE_FUNCTION_TRIGGER;
-
- res.json({
- message: 'Hello from Appwrite!',
- payload,
- secretKey,
- randomNumber,
- trigger,
- });
-};package.json file along with your function, and Appwrite handles the rest! The best practice is to make sure that the node_modules folder is not a part of your tarball.PHP
-
- <?php
-
-return function ($req, $res) {
- $payload =
- $req['payload'] ?:
- 'No payload provided. Add custom data when executing function.';
-
- $secretKey =
- $req['variables']['SECRET_KEY'] ?:
- 'SECRET_KEY variable not found. You can set it in Function settings.';
-
- $randomNumber = \mt_rand() / \mt_getrandmax();
-
- $trigger = $req['variables']['APPWRITE_FUNCTION_TRIGGER'];
-
- $res->json([
- 'message' => 'Hello from Appwrite!',
- 'payload' => $payload,
- 'secretKey' => $secretKey,
- 'randomNumber' => $randomNumber,
- 'trigger' => $trigger,
- ]);
-};composer.json file along with your function, make sure to require autoload.php from vendor folder, and Appwrite handles the rest!. The best practice is to make sure that the vendor directory is not a part of your tarball. Python
-
- import random
-
-def main(req, res):
- payload = req.payload or 'No payload provided. Add custom data when executing function.'
-
- secretKey = req.variables.get(
- 'SECRET_KEY',
- 'SECRET_KEY variable not found. You can set it in Function settings.'
- )
-
- randomNumber = random.random()
-
- trigger = req.variables['APPWRITE_FUNCTION_TRIGGER']
-
- return res.json({
- 'message': 'Hello from Appwrite!',
- 'payload': payload,
- 'secretKey': secretKey,
- 'randomNumber': randomNumber,
- 'trigger': trigger,
- })requirements.txt file with your function, Appwrite handles the rest!Ruby
-
- def main(req, res)
- payload =
- !req.payload.empty? ? req.payload :
- 'No payload provided. Add custom data when executing function.'
-
- secretKey =
- req.variables['SECRET_KEY'] ||
- 'SECRET_KEY variable not found. You can set it in Function settings.'
-
- randomNumber = rand()
-
- trigger = req.variables['APPWRITE_FUNCTION_TRIGGER']
-
- return res.json({
- :message => 'Hello from Appwrite!',
- :payload => payload,
- :secretKey => secretKey,
- :randomNumber => randomNumber,
- :trigger => trigger,
- })
-endGemfile with your function, Appwrite handles the rest!Deno
-
- export default async function (req: any, res: any) {
- const payload =
- req.payload ||
- 'No payload provided. Add custom data when executing function.';
-
- const secretKey =
- req.variables.SECRET_KEY ||
- 'SECRET_KEY variable not found. You can set it in Function settings.';
-
- const randomNumber = Math.random();
-
- const trigger = req.variables.APPWRITE_FUNCTION_TRIGGER;
-
- res.json({
- message: 'Hello from Appwrite!',
- payload,
- secretKey,
- randomNumber,
- trigger,
- });
-};Dart
-
- import 'dart:math';
-import 'dart:async';
-
-Future <void> start(final req, final res) async {
- final payload =
- !req.payload?.isEmpty ? req.payload :
- 'No payload provided. Add custom data when executing function.';
-
- final secretKey =
- req.variables['SECRET_KEY'] ??
- 'SECRET_KEY variable not found. You can set it in Function settings.';
-
- final randomNumber = new Random().nextDouble();
-
- final trigger = req.variables['APPWRITE_FUNCTION_TRIGGER'];
-
- res.json({
- 'message': 'Hello from Appwrite!',
- 'payload': payload,
- 'secretKey': secretKey,
- 'randomNumber': randomNumber,
- 'trigger': trigger,
- });
-}pubspec.yaml file with your function- Appwrite handles the rest!Swift
-
- func main(req: RequestValue, res: RequestResponse) throws -> RequestResponse {
- let payload = req.payload.isEmpty
- ? "No payload provided. Add custom data when executing function"
- : req.payload
-
- let secretKey = req.variables["SECRET_KEY"]
- ?? "SECRET_KEY variable not found. You can set it in Function settings."
-
- let randomNumber = Double.random(in: 0...1)
-
- let trigger = req.variables["APPWRITE_FUNCTION_TRIGGER"]
-
- return res.json(data: [
- "message": "Hello from Appwrite!",
- "payload": payload,
- "secretKey": secretKey,
- "randomNumber": randomNumber,
- "trigger": trigger,
- ])
-}Package.swift file with your function, Appwrite handles the rest!.NET
-
- public async TaskFunction.csproj file with your function, Appwrite handles the rest!Kotlin
-
- import kotlin.random.Random
-
-@Throws(Exception::class)
-fun main(req: RuntimeRequest, res: RuntimeResponse): RuntimeResponse {
-
- val payload = if (req.payload.isEmpty()) "No payload provided. Add custom data when executing function." else req.payload
-
- val secretKey = req.variables["SECRET_KEY"] ?: "SECRET_KEY variable not found. You can set it in Function settings."
-
- val randomNumber = Random.nextDouble(0.0, 1.0)
-
- val trigger = req.variables["APPWRITE_FUNCTION_TRIGGER"]
-
- return res.json(mapOf(
- "message" to "Hello from Appwrite!",
- "payload" to payload,
- "secretKey" to secretKey,
- "randomNumber" to randomNumber,
- "trigger" to trigger
- ))
-}deps.gradle file with your function, Appwrite handles the rest!Java
-
- import java.util.Map;
-import java.util.HashMap;
-
-public RuntimeResponse main(RuntimeRequest req, RuntimeResponse res) throws Exception {
-
- String payload = (req.getPayload().isEmpty())
- ? "No payload provided. Add custom data when executing function."
- : req.getPayload();
-
- Mapdeps.gradle file with your function, Appwrite handles the rest!C++
-
- #include <iostream>
-#include <string>
-
-static RuntimeResponse &main(const RuntimeRequest &req, RuntimeResponse &res) {
-
- std::string payload = req.payload.empty() ?
- "No payload provided. Add custom data when executing function." :
- req.payload;
-
- std::string secretKey = req.variables.get("SECRET_KEY", "SECRET_KEY variable not found. You can set it in Function settings.").asString();
-
- double randomNumber = ((double) rand() / (RAND_MAX));
-
- std::string trigger = req.variables["APPWRITE_FUNCTION_TRIGGER"].asString();
-
- Json::Value response;
- response["message"] = "Hello from Appwrite!";
- response["payload"] = payload;
- response["secretKey"] = secretKey;
- response["randomNumber"] = randomNumber;
- response["trigger"] = trigger;
-
- return res.json(response);
-}CMakeLists.txt file with your function, Appwrite handles the rest!request and a response object. The request object contains all data that was sent to the function including function variables. A schema of the request object can be found below and is the same for all runtimes.
-
-
-
-
-
-
-
- Property
- Description
-
-
- headers
- An object containing all the request headers.
-
-
- payload
- A JSON string containing the data when you created the execution.
-
-
-
-variables
- An object containing all the function variables. This includes variables automatically added by Appwrite.
- send() and json() that can be used to send data back to the client. The types and implementation of these functions vary depending on runtime due to all languages being slightly different. You can check out implementation in the specific languages to learn more about them. The schema of the response object can be found below:
-
-
-
-
-
-
-
- Function
- Description
-
-
- send(text, status)
- Function to return a text response. Status code defaults to 200
-
-
-
-json(obj, status)
- Function to return a JSON response. Status code defaults to 200
- Create your Function
-
-Deploy Your Function
-
-
-
-
-Unix
-
-
- appwrite functions createDeployment \
- --functionId=6012cc93d5a7b \
- --activate=true \
- --entrypoint="index.js" \
- --code="."CMD
-
-
- appwrite functions createDeployment ^
- --functionId=6012cc93d5a7b ^
- --activate=true ^
- --entrypoint="index.js" ^
- --code="."PowerShell
-
-
- appwrite functions createDeployment `
- --functionId=6012cc93d5a7b `
- --activate=true `
- --entrypoint="index.js" `
- --code="."
-
-
-
-
-
-
-
- Name
- Description
-
-
- functionId
- The ID of the Function you created in the previous step. You can find your function ID on your function page in your project dashboard.
-
-
- entrypoint
- The file name of your custom code that is executed when the function is triggered.
-
-
-
-code
- Path to your function tarball. When used with the Appwrite CLI, simply pass the path to your code directory, and the CLI will automatically package your code.
- Manual Deployment
-
-.
-├── package.json
-└── index.js
-.tar.gz format with this tar command:
-
-
-Unix
-
-
- tar -czf code.tar.gz --exclude code.tar.gz .CMD
-
-
- tar -czf code.tar.gz --exclude code.tar.gz .PowerShell
-
-
- tar -czf code.tar.gz --exclude code.tar.gz .
-
-
-
-index.js. code.tar.gz.Builds
-buildId from the deployment.deploymentId.Build Times
- Execute
-
-
-
-
-Web
-
- import { Client, Functions } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1')
- .setProject('[PROJECT_ID]');
-
-const functions = new Functions(client);
-
-let promise = functions.createExecution('[FUNCTION_ID]');
-
-promise.then(function (response) {
- console.log(response); // Success
-}, function (error) {
- console.log(error); // Failure
-});Flutter
-
-
- import 'package:appwrite/appwrite.dart';
-
-void main() async {
- final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1')
- .setProject('[PROJECT_ID]');
-
- final functions = Functions(client);
-
- final execution = await functions.createExecution(
- functionId: '[FUNCTION_ID]'
- );
-}Android
-
-
- import io.appwrite.Client
-import io.appwrite.services.Functions
-
-suspend fun main() {
- val client = Client(applicationContext)
- .setEndpoint("https://cloud.appwrite.io/v1")
- .setProject("[PROJECT_ID]")
-
- val functions = Functions(client)
-
- val execution = functions.createExecution(
- functionId = "[FUNCTION_ID]"
- )
-}Apple
-
-
- import Appwrite
-
-func main() async throws {
- let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1")
- .setProject("[PROJECT_ID]")
-
- let functions = Functions(client)
-
- let execution = try await functions.createExecution(
- functionId: "[FUNCTION_ID]"
- )
-}GraphQL
-
-
- mutation {
- functionsCreateExecution(functionId: "[FUNCTION_ID]") {
- _id
- statusCode
- response
- stdout
- stderr
- duration
- }
-}Scheduled Execution
-
-
-
-
-
-
-
-
- Cron Expression
- Schedule
-
-
- */15 * * * *
- Every 15 minutes
-
-
- 0 * * * *
- Every Hour
-
-
- 0 0 * * *
- Every day at 00:00
-
-
-
-0 0 * * 1
- Every monday at 00:00
- Abuse and Limits
-
-appwrite.json for up to 900 seconds.Ignore Files
-
-node_modules or vendor should not be included in your tarball since these dependencies will be installed during your function's build process. Similarly, you should not include files containing secrets in your deployment. You can use the Appwite CLI's file ignoring feature to exclude specific files from a deployment.appwrite.json file to specify which files and folders should be ignored. This value must be an array of paths, as seen in the example below:
-{
- ...
- "functions": [
- {
- "$id": "6213b58cb21dda6c3263",
- "name": "My Awesome Function",
- "runtime": "node-17.0",
- "path": "My Awesome Function",
- "entrypoint": "src/index.js",
- "ignore": [ "node_modules", ".env" ]
- },
- ...
- ],
-}node_modules and the file .env..gitignore file into your function folder and Appwrite CLI will ignore files specified in there. Keep in mind that if present, the ignore configuration in appwrite.json will nullify your ignore file..gitignore file for your version control but don't want the Appwrite CLI to use it, you can specify the ignore key in appwrite.json to be an empty array.Supported Runtimes
-
-
-
-
-
-
-
-
-
- $runtime): ?>
-
- Name
- Image
- Architectures
-
-
-
-
-
- escape($key); ?>
- escape($runtime['image'] ?? ''); ?>
- escape(implode(' / ', $runtime['supports'] ?? [])); ?>
- node-16.0, php-8.0, python-3.9, ruby-3.0, and dart-2.17.Function Variables
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
- APPWRITE_FUNCTION_ID
-
- Your function's unique ID.
-
-
-
- APPWRITE_FUNCTION_NAME
-
- Your function's name.
-
-
-
- APPWRITE_FUNCTION_DEPLOYMENT
-
- Your function's code deployment unique ID.
-
-
-
- APPWRITE_FUNCTION_TRIGGER
-
- Either 'event' when triggered by one of the selected scopes, 'http' when triggered by an HTTP request or the Appwrite Console, or 'schedule' when triggered by the cron schedule.
-
-
-
- APPWRITE_FUNCTION_RUNTIME_NAME
-
- Your function runtime name. Can be any of Appwrite supported execution runtimes.
-
-
-
- APPWRITE_FUNCTION_RUNTIME_VERSION
-
- Your function runtime version.
-
-
-
- APPWRITE_FUNCTION_EVENT
-
- Your function event name. This value is available only when your function trigger is 'event.' This variable value can be any of Appwrite system events.
-
-
-
- APPWRITE_FUNCTION_EVENT_DATA
-
- Your function event payload. This value is available only when your function trigger is 'event'. This variable value contains a string in JSON format with your specific event data.
-
-
-
- APPWRITE_FUNCTION_DATA
-
- Your function's custom execution data. This variable's value contains a string in any format. If the custom data is in JSON FORMAT, it must be parsed inside the function code. Note that this variable can be set only when triggering a function using the SDK or HTTP API and the Appwrite Dashboard.
-
-
-
- APPWRITE_FUNCTION_PROJECT_ID
-
- Your function's project ID.
-
-
-
- APPWRITE_FUNCTION_USER_ID
-
- The userId of the user that triggered your function's execution. Executions triggered in the Appwrite console will be prepended with "admin-".
-
-
-
- APPWRITE_FUNCTION_JWT
-
- A JSON Web Token generated for the user that executes your function.
-
-
-
- APPWRITE_FUNCTION_EVENT_PAYLOAD
-
- Your function event payload. Deprecated in favor of APPWRITE_FUNCTION_EVENT_DATA in version 0.8.0.
-
-
-
- APPWRITE_FUNCTION_ENV_NAME
-
- Your function environment name. Can be any of Appwrite supported execution environments.
-
-
-
-
- APPWRITE_FUNCTION_ENV_VERSION
-
- Your function environment version.
- Using an Appwrite SDK in Your Function
- APPWRITE_FUNCTION_PROJECT_ID, but not the endpoint and API key. If you need to use a Server SDK, you will need to add function variables for your endpoint and API key in the Settings tab of your function.'https://localhost/v1'. Localhost inside the function's runtime container is not the same as localhost of your machine.Appwrite SDKs in Functions
-
-APPWRITE_FUNCTION_PROJECT_ID.Monitor & Debug
-
-Demos & Examples
-
-Getting Started
+Explore Features
+Templates
+Deploy
+Execute
+Syntax
+
+Appwrite supports many open-source runtimes. Find your prefered language and start writing your functions. +
++Learn more about using runtimes +
++Let's be honest, we spend more time debugging our code than writing our code. +So it's important to be able to log, debug, and test your Appwrite Functions in development and production. +
++Learn more about debugging functions +
\ No newline at end of file From 52bdc62f0470e2fdfdfce95f48d037c7f5ecbe2a Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge"- The quickest way to experience Appwrite functions is to [TODO: @matej What's a good example to show to give devs an idea of what Appwrite Functions workflow is like?] + Appwrite Functions unlock limitless possibilities, but it's simple to get started. You can deploy your first function and execute it in minutes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To fully harness the power of Appwrite Functions, explore the following features. @@ -35,6 +150,16 @@ $runtimes = $this->getParam('runtimes', []); Learn more about using function templates
++Writing Appwrite Functions should feel familiar to writing controllers in an HTTP server. +In your function, you'll receive a request object, add transformations and logic, then return a response. +Almost anything can be executed as code in an Appwrite Function. +
++Learn more about using function syntax +
+Appwrite Functions are designed to be maintainable and fit into a familiar development workflow. @@ -54,15 +179,6 @@ Explore using Appwrite Functions to execute a complex routine of logic, or execu Learn more about using executing functions
--Writing Appwrite Functions should feel familiar to writing controllers in an HTTP server. -In your function, you'll receive a request object, add transformations and logic, then return a response. -Almost anything can be executed as code in an Appwrite Function. -
-Learn more about using function syntax -
-Appwrite supports many open-source runtimes. Find your prefered language and start writing your functions. diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml index 7d9bb0b45..8b772de6c 100644 --- a/app/views/docs/index.phtml +++ b/app/views/docs/index.phtml @@ -96,9 +96,9 @@ $cols = [ Functions
From 6b2da17e590d92da5d8225df2dcd9643ef3154f1 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge"+ Appwrite Functions... do we need this page? +
+ diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml new file mode 100644 index 000000000..79d8fba2c --- /dev/null +++ b/app/views/docs/functions-deploy.phtml @@ -0,0 +1,37 @@ ++ Appwrite Functions are mini application in Appwrite with their own endpoint. + Each function can have many deployments, which can be thought of as versions of the mini-application. +
+ ++ Functions can be deployed in different ways to meet your unique development habbits. + You can automatically deploy Appwrite Functions from source control, build your own deployment pipelines using the Appwrite CLI, or upload code files manually. + Here's everything you need to know to deploy your first Appwrite Function. +
+ ++ The recommended way to manage your Appwrite Function deployments is to use a version control system, such as GitHub. + This offers simple versioning and collaboration that will easily fit into the rest of your development workflow. +
+ +[TODO: Describe how to create a GitHub deployment] + +Deployments will go through the following states throughout their life cycle.
+[TODO: @matej, describe the life cycle of a deployment (like being uploaded, built, etc)] + +[TODO: @matej What else?] \ No newline at end of file diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml new file mode 100644 index 000000000..4555356b5 --- /dev/null +++ b/app/views/docs/functions-develop.phtml @@ -0,0 +1,22 @@ ++ Appwrite Functions offer a familiar interface if you've developed REST endpoints. + Each function is handled following a request and response pattern. + Here's what you need to know to start writing your first Appwrite Function. +
+ ++ Appwrite Functions executions can be invoked in several ways. + Functions can be invoked through the Appwrite SDK and visting its preview link. Functions can also be triggered by events, webhooks, and scheduled executions. + Here are all the different ways to consume your new Appwrite Functions. +
+ ++ +
+ ++ Each Appwrite function also has its own preview link. + When requests are made to this link, whether through a browser or through an HTTP requests, + the request information like request headers and request body will be passed to the function. + This unlocks interesting ways to integrate other apps and backends to your Appwrite project. +
+ ++ +
+ ++ +
+ + ++ + +
\ No newline at end of file diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml new file mode 100644 index 000000000..5686a2d28 --- /dev/null +++ b/app/views/docs/functions-runtimes.phtml @@ -0,0 +1,5 @@ ++ Appwrite Functions supports ... + wait. wut we do with runtimes not yet on cloud??? +
+ diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml index b8b94d905..5ad3d8853 100644 --- a/app/views/docs/functions.phtml +++ b/app/views/docs/functions.phtml @@ -157,7 +157,7 @@ In your function, you'll receive a request object, add transformations and logic Almost anything can be executed as code in an Appwrite Function.-Learn more about using function syntax +Learn more about using function syntax
Learn more about debugging functions -
\ No newline at end of file + + ++ Appwrite Functions received major upgrades in Appwrite version 1.4. + If you still have functions from previous versions, [TODO: @matej what is the consequence what should they do?] +
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml index 8b772de6c..5f41f6647 100644 --- a/app/views/docs/index.phtml +++ b/app/views/docs/index.phtml @@ -96,7 +96,7 @@ $cols = [ Functions+ [TODO: Bradley try to fill this in with necessary information + limitations] +
\ No newline at end of file diff --git a/app/views/docs/migration-nhost.phtml b/app/views/docs/migration-nhost.phtml new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/docs/migration-supabase.phtml b/app/views/docs/migration-supabase.phtml new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/docs/migration.phtml b/app/views/docs/migration.phtml new file mode 100644 index 000000000..9757c6526 --- /dev/null +++ b/app/views/docs/migration.phtml @@ -0,0 +1,60 @@ ++ Moving your app from another platform to Appwrite? + You can move your app from Firebase, Supabase, NHost, and even other Appwrite projects to another Appwrite project using Migrations. + Migrations will automatically move accounts, database documents, and storage files from one source to another. +
+ ++ You can transfer from these sources to an Appwrite project. +
+ +| + | Source | ++ |
|---|---|---|
| + [IMAGE] + | ++ Firebase + | ++ + | +
| + [IMAGE] + | ++ Supabase + | ++ + | +
| + [IMAGE] + | ++ NHost + | ++ + | +
+ [TODO] @bradley help me out here. include performance, feature, all things annoying +
\ No newline at end of file From 6fbc33ae2c2b258ba35cd552a4a37bb18b9e28c6 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge"- Appwrite Functions... do we need this page? -
- diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml index 79d8fba2c..8f57badb0 100644 --- a/app/views/docs/functions-deploy.phtml +++ b/app/views/docs/functions-deploy.phtml @@ -9,20 +9,32 @@ Here's everything you need to know to deploy your first Appwrite Function. -- The recommended way to manage your Appwrite Function deployments is to use a version control system, such as GitHub. + The recommended way to manage your Appwrite Function deployments is to use Git. This offers simple versioning and collaboration that will easily fit into the rest of your development workflow.
[TODO: Describe how to create a GitHub deployment]Deployments will go through the following states throughout their life cycle.
-[TODO: @matej, describe the life cycle of a deployment (like being uploaded, built, etc)] +[TODO: @matej, describe the life cycle of a deployment (like being uploaded, built, build steps, etc.)] [TODO: @matej What else?] \ No newline at end of file diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml index 4555356b5..2997898fb 100644 --- a/app/views/docs/functions-develop.phtml +++ b/app/views/docs/functions-develop.phtml @@ -4,8 +4,7 @@ Here's what you need to know to start writing your first Appwrite Function. -Appwrite Functions executions can be invoked in several ways. - Functions can be invoked through the Appwrite SDK and visting its preview link. Functions can also be triggered by events, webhooks, and scheduled executions. + Functions can be invoked through the Appwrite SDK and visting its REST endpoint. Functions can also be triggered by events and scheduled executions. Here are all the different ways to consume your new Appwrite Functions.
-- -
- -- Each Appwrite function also has its own preview link. + Each Appwrite function has its own domain. (can be custom) When requests are made to this link, whether through a browser or through an HTTP requests, the request information like request headers and request body will be passed to the function. This unlocks interesting ways to integrate other apps and backends to your Appwrite project.
--
- +
-
\ No newline at end of file + + +[TODO: EXECUTION ARTIFACTS/LOGS/STUFF] + diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml index 5ad3d8853..86266c49a 100644 --- a/app/views/docs/functions.phtml +++ b/app/views/docs/functions.phtml @@ -24,9 +24,11 @@ $runtimes = $this->getParam('runtimes', []);
-
-
+ export default async ({ res }) => {
+ return res.json({
+ motto: 'Build Fast. Scale Big. All in One Place.'
+ });
+};
Writing Appwrite Functions should feel familiar to writing controllers in an HTTP server.
In your function, you'll receive a request object, add transformations and logic, then return a response.
From 3610aadf00ef588ead24a9a00ba24d1789146a20 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
If you prefer to learn through examples, explore the recipes section.
++ Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite console. + All input, output, and logging **must be** handled through the context object passed in. +
+ +You'll find these properties in the context object.
+| Property | +Description | +|
| context.req | +Contains request information like method, body, and headers. See full examples here. | +|
| context.res | +Contains methods to build a response and return information. See full examples here. | +|
| context.log | +Logs information to the Appwrite Console, end users will not be able to see these logs. See full examples here. | +|
| context.error | +Logs errors to the Appwrite Console, end users will not be able to see these errors. See full examples here. | ++ |
Some lamguages support unpacking. You'll see us use unpacking in examples, which has the following syntax.
+[TODO: Example below for relevant languages.] +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To protect user privacy, the request and response objects are not logged to the Appwrite Console by default.
+ This means, to see logs or debug function executions you need to use the context.log() and context.error() methods.
+ These logs are only visible to developers with access to the Appwrite Console.
+
+ If you need to pass constants or secrets to Appwrite Functions, you can use environment variables. +
+ +[TODO: ways to setup environment variables (link to deployment docs?)] + ++ You can access the environment variables through the systems library of each language. +
+ Appwrite Functions help you start small and scale big. + Now you've created your first Appwrite Function, it's time to learn the different ways to develop, deploy, and execute your Appwrite Functions. To fully harness the power of Appwrite Functions, explore the following features.
@@ -159,7 +161,7 @@ In your function, you'll receive a request object, add transformations and logic Almost anything can be executed as code in an Appwrite Function.-Learn more about using function syntax +Learn more about developing functions
-Learn more about using deploying functions +Learn more about using deploying functions
-Learn more about using executing functions +Learn more about using executing functions
+ If you pass data into an Appwrite function, it'll be found in the request object. + This includes all invokation methods, such as data from Appwrite SDKs, HTTP calls, Appwrite events, and browsers visiting the configured domain. + Explore the request object with the following function, which logs all request params to the Appwrite Console. +
+ +export default async ({ req, res, log }) => {
+ log(req.bodyString); // Raw request body, contains request data
+ log(req.body); // Body parsed on content-type, only supports JSON
+ log(req.headers); // Request headers
+ log(req.scheme); // Value of the x-forwarded-proto header, usually http or https
+ log(req.method); // Request method, such as GET, POST, PUT, DELETE, PATCH, etc.
+ log(req.url); // Full URL, for example: http://awesome.appwrite.io:8000/v1/hooks?limit=12&offset=50
+ log(req.host); // Hostname from the host header, such as awesome.appwrite.io
+ log(req.port); // Port from the host header, for example 8000
+ log(req.path); // Path part of URL, for example /v1/hooks
+ log(req.queryString); // Raw query params string. For example "limit=12&offset=50"
+ log(req.query); // Parsed query params. For example, req.query.limit
+
+ return res.send("All the request parameters are logged to the Appwrite Console.");
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object. + The response information will not be logged to the Appwrite Console. + There are several possible ways to send a response, explore them in the following Appwrite Function. +
+export default async ({ req, res, log }) => {
+ switch (req.body) {
+ case 'send':
+ return res.send(
+ "This is a text response",
+ 200,
+ {
+ "content-type": "application/text"
+ }
+ );
+ case 'json':
+ return res.json(
+ {
+ "type": "This is a JSON response"
+ },
+ 200,
+ {
+ "content-type": "application/json"
+ }
+ );
+ case 'redirect':
+ return res.json(
+ "https://appwrite.io",
+ 301,
+ {
+ "content-type": "application/json"
+ }
+ );
+ default:
+ return res.empty();
+ }
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/js.js b/app/views/js.js
new file mode 100644
index 000000000..e56b14ce6
--- /dev/null
+++ b/app/views/js.js
@@ -0,0 +1,32 @@
+export default async ({ req, res, log }) => {
+ switch (req.body) {
+ case 'send':
+ return res.send(
+ "This is a text response",
+ 200,
+ {
+ "content-type": "application/text"
+ }
+ );
+ case 'json':
+ return res.json(
+ {
+ "type": "This is a JSON response"
+ },
+ 200,
+ {
+ "content-type": "application/json"
+ }
+ );
+ case 'redirect':
+ return res.json(
+ "https://appwrite.io",
+ 301,
+ {
+ "content-type": "application/json"
+ }
+ );
+ default:
+ return res.empty();
+ }
+};
\ No newline at end of file
From 71439b8ee898d03eaf5e490ebd18cbee59031de3 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" context.log() and context.error() methods.
These logs are only visible to developers with access to the Appwrite Console.
Here's an example of using logs and errors.
+[TODO] +You can access these logs through the following steps.
+[TODO]If you need to pass constants or secrets to Appwrite Functions, you can use environment variables.
- [TODO: ways to setup environment variables (link to deployment docs?)]diff --git a/app/views/docs/functions-recipes.phtml b/app/views/docs/functions-recipes.phtml new file mode 100644 index 000000000..a8149e25f --- /dev/null +++ b/app/views/docs/functions-recipes.phtml @@ -0,0 +1,6 @@ +
+ Appwrite Functions is all about flexibility. + Behind the simple workflow hides some useful recipes that can help you accomplish your goals faster. + Take a look at the following. +
+[TODO: @matej] \ No newline at end of file From 16267be21e81e3f2104366c2c2ce765beebdb383 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge"
+ To deploy with the Appwrite CLI, your function's folder structure must be configured in a specific way.
+ The folder path is then added to a config file called appwrite.json that tells the CLI where each function is stored.
+ To ensure the folder structure is setup correctly and appwrite.json is configured correctly, use the appwrite init function method to create a shell function.
+
appwrite init function
+
+ Give your function a name and choose your runtime.
+ This will create a new starter function in the current directory and also add it to your appwrite.json file.
+
+ Edit the automatically generated code and add dependencies to the dependency files of your language or framework. + Then, deploy the function using the following command. +
-[tar --exclude code.tar.gz -czf code.tar.gz .] +appwrite deploy function
+Deployments will go through the following states throughout their life cycle.
-[TODO: @matej, describe the life cycle of a deployment (like being uploaded, built, build steps, etc.)] +If you prefer to learn through examples, explore the recipes section.
+ There is a clear flow for all Appwrite Functions, from beginning to end. + Here's everything that happens during a function execution. +
+ +context.res, when the user code throws an exception, or times out.Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite console. @@ -25,19 +39,19 @@
context.reqcontext.rescontext.logcontext.errorHere's an example of using logs and errors.
-[TODO] +export default async ({ res, log, error }) => {
+ log("This is a log, use for logging information to console");
+ error("This is an error, use for logging errors to console")
+
+ return res.send("Check the Appwrite Console to see logs and errors!");
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You can access these logs through the following steps.
[TODO]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + We have a dedicated page of recipes to implement common functionalities in Appwrite Functions, like parsing request path and params, or making requests to third party APIs. +
+ ++Explore examples and recipes +
+Libraries dependent on compiled binaries not available on the executors cannot be installed.
\ No newline at end of file diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml index 174d7d771..85476f0c0 100644 --- a/app/views/docs/functions-execute.phtml +++ b/app/views/docs/functions-execute.phtml @@ -12,27 +12,61 @@ This unlocks interesting ways to integrate other apps and backends to your Appwrite project. -DOMAIN IGNORE PERMISSIONS AOSDHFGAKSHDJG
- + TODO: Describe steps to navigate the UI
- -
+Appwrite supports scheduled function executions. You can schedule executions using cron expressions in the settings of your function. Cron supports recurring executions as frequently as every minute.
+ +Here are some cron expressions for common intervals.
+ +| Cron Expression | +Schedule | +
| */15 * * * * | +Every 15 minutes | +
| 0 * * * * | +Every Hour | +
| 0 0 * * * | +Every day at 00:00 | +
| 0 0 * * 1 | +Every monday at 00:00 | +
+ Appwrite Functions can be executed using Client or Server SDKs. + Client SDKs must be authenticated with an account that has been granted execution permissions on the function's settings page. + Server SDKs require an API key with the correct scopes. +
++ If your function with a generated or custom domain, permissions are disabled for this function. + Anyone visiting this domain will be able to execute the function. + If you need to enforce permissions for functions with a domain, use authentication methods like JWT. +
+Appwrite Functions supports ... wait. wut we do with runtimes not yet on cloud???
+Appwrite provides multiple code runtimes to execute your custom functions. Each runtime uses a Docker image tied to a specific language version to provide a safe, isolated playground to run your team's code.
+ +Below is a list of supported Cloud Functions runtimes. The Appwrite team continually adds support for new runtimes.
+ +| + | Name | +Image | +Architectures | +
|---|---|---|---|
| escape($key); ?> | +escape($runtime['image'] ?? ''); ?> | +escape(implode(' / ', $runtime['supports'] ?? [])); ?> | +
appwrite deploy function
-You can also upload your functions to be deployed using the Appwrite console. The example below shows a simple Node.JS function, but the same idea applies to any other language.
-[tar --exclude code.tar.gz -czf code.tar.gz .] \ No newline at end of file +.
+├── package.json
+└── index.js
+
+First, navigate inside the folder that contains your dependency file. Package your code files into the .tar.gz format with this tar command:
tar --exclude code.tar.gz -czf code.tar.gz .
+ tar --exclude code.tar.gz -czf code.tar.gz .
+ tar --exclude code.tar.gz -czf code.tar.gz .
+ Next, navigate to your Appwrite console and upload the function.
+ +index.js. code.tar.gz.
- Appwrite Functions supports ...
- wait. wut we do with runtimes not yet on cloud???
+ Appwrite Functions supports an extensive list of runtimes to meet your unique tech preferences.
+ Not all runtimes are available on Appwrite Cloud, check for the Cloud label in each listed runtime to know whichones are available.
- Functions can be deployed in different ways to meet your unique development habbits. + Functions can be created and deployed in different ways to meet your unique development habits. You can automatically deploy Appwrite Functions from source control, build your own deployment pipelines using the Appwrite CLI, or upload code files manually. Here's everything you need to know to deploy your first Appwrite Function.
@@ -15,27 +15,60 @@ This offers simple versioning and collaboration that will easily fit into the rest of your development workflow. -[TODO: Describe how to create a GitHub deployment] +Before deploying your function with Git, create a new function attached to your Git repo.
+
From 1092b844621658a60b45506e86b6af9a985e7040 Mon Sep 17 00:00:00 2001
From: Bradley Schofield
- [TODO: Bradley try to fill this in with necessary information + limitations]
+ - Appwrite will waive usage fees during the migration process, however Firebase may still charge you for usage on their platform.
+
+ - At the moment only top level document migrations are supported. Nested documents will not be transferred at this moment.
+
+ - Appwrite migrations only supports Firestore. Realtime Database is not supported at this time.
+
+ - OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
+
+ To begin migrating to Appwrite make sure to read the migration overview and
+ things to keep in mind sections above.
+
+ To begin you can either migrate while creating a new project or go into your project settings and click on the "Migrations" tab.
+
+ Next click on the "Create Migration" button and select "Firebase" as your source.
+
+ Things to keep in mind
Supported Resources
+
+
+
+
+
+
+
+
+
+ Users
+ Databases
+ Documents
+ Files
+ Functions
+
+
+
+Firebase
+ ✅
+ ✅
+ ✅
+ ✅
+
+ Migrating to Appwrite from Firebase
+Migrating to Appwrite Cloud
+ To simplify the migration process we have created an OAuth application that will allow you to sign in with Google and automatically
+ discover your Firebase projects then you can simply just select the project you want to migrate from.
+
+ Migrating to Appwrite Self-Hosted
+ If you are self-hosting Appwrite you will need to create a service account in your Firebase project and download the JSON file.
+
+ To create a service account navigate to your Firebase console then click on the gear icon and select "Project Settings".
+ Next click on the "Service Accounts" tab and click on the "Generate New Private Key" button to download the JSON file.
+
+
+
+ Once you have the JSON file downloaded you can click on "Manual Authentication" while going through the migration process and\
+ upload the JSON file.
- [TODO] @bradley help me out here. include performance, feature, all things annoying + - Migrations cannot transfer all data perfectly, so certain fields, such as $createdAt and $updatedAt, may not be transferred. More information can be found on the migration page for each source.
\ No newline at end of file From db2286b61f6200f67c82a8fde7559d930b9a4386 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Mon, 31 Jul 2023 16:34:00 +0100 Subject: [PATCH 026/183] feat: translate json response snippets --- app/views/docs/functions.phtml | 114 +++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 28 deletions(-) diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml index b3cadd9b7..f1727b4e9 100644 --- a/app/views/docs/functions.phtml +++ b/app/views/docs/functions.phtml @@ -25,9 +25,9 @@ $runtimes = $this->getParam('runtimes', []);export default async ({ res }) => {
- return res.json({
- motto: 'Build Fast. Scale Big. All in One Place.'
- });
+ return res.json({
+ motto: 'Build Fast. Scale Big. All in One Place.'
+ });
};
-
-
+ return function ($context) {
+ return $context->res->json([
+ 'motto' => 'Build Fast. Scale Big. All in One Place.'
+ ]);
+}
-
-
+ def main(context):
+ return context.res.json({
+ "motto": "Build Fast. Scale Big. All in One Place.",
+})
-
-
+ def main(context)
+ return context.res.json(
+ {
+ "motto": "Build Fast. Scale Big. All in One Place."
+ }
+ )
+end
-
-
+ export default ({ req, res, log, error }: any) => {
+ return res.json({
+ motto: "Build Fast. Scale Big. All in One Place."
+ });
+};
+ import 'dart:async';
-
+Future main(final context) async {
+ return context.res.json({
+ 'motto': 'Build Fast. Scale Big. All in One Place.',
+ });
+}
+ import Foundation
-
+ func main(context: RuntimeContext) async throws -> RuntimeOutput {
+ return try context.res.json([
+ "motto": "Build Fast. Scale Big. All in One Place."
+ ])
+}
-
-
+ namespace DotNetRuntime;
+public class Handler {
+ public async Task Main(RuntimeContext Context)
+ {
+ return Context.Res.Json(new Dictionary()
+ {
+ { "motto", "Build Fast. Scale Big. All in One Place." }
+ });
+ }
+}
+ package io.openruntimes.kotlin.src
-
+import io.openruntimes.kotlin.RuntimeContext
+import io.openruntimes.kotlin.RuntimeOutput
+
+class Main {
+ fun main(context: RuntimeContext): RuntimeOutput {
+ return context.res.json(mutableMapOf(
+ "motto" to "Build Fast. Scale Big. All in One Place.",
+ "learn" to "https://appwrite.io/docs",
+ "connect" to "https://appwrite.io/discord",
+ "getInspired" to "https://builtwith.appwrite.io"
+ ))
+ }
+}
+ package io.openruntimes.java.src;
+
+import io.openruntimes.java.RuntimeContext;
+import io.openruntimes.java.RuntimeOutput;
+import java.util.HashMap;
-
+public class Main {
+ public RuntimeOutput main(RuntimeContext context) throws Exception {
+ Map json = new HashMap<>();
+ json.put("motto", "Build Fast. Scale Big. All in One Place.");
+ return context.getRes().json(json);
+ }
+}
+ #include "../RuntimeResponse.h"
+#include "../RuntimeRequest.h"
+#include "../RuntimeOutput.h"
+#include "../RuntimeContext.h"
-
+namespace runtime {
+ class Handler {
+ public:
+ static RuntimeOutput main(RuntimeContext &context) {
+ Json::Value response;
+ response["motto"] = "Build Fast. Scale Big. All in One Place.";
+ return context.res.json(response);
+ }
+ };
+}
- - Appwrite will waive usage fees during the migration process, however Firebase may still charge you for usage on their platform. - - - At the moment only top level document migrations are supported. Nested documents will not be transferred at this moment. + Moving your project from Firebase to Appwrite? + Appwrite Migrations can help you streamline the process. + + Here's what you need to know to get started. +
- - Appwrite migrations only supports Firestore. Realtime Database is not supported at this time. +Some lamguages support unpacking. You'll see us use unpacking in examples, which has the following syntax.
-[TODO: Example below for relevant languages.] +[TODO: @luke for languages that have unpacking, let's add unpacking examples!]Here's an example of using logs and errors.
+[TODO: @luke Let's make sure we show an example for evert runtime with good string manip methods.]You can access these logs through the following steps.
-[TODO] +If you need to pass constants or secrets to Appwrite Functions, you can use environment variables. + Environmental variables can be global, or function specific. +
+ ++ Local variables will only be accessible in the function they belong to. + Local variables will override global variables when they have conflicting names. +
+.env file.+ Global variables are accessible to all Appwrite Functions. + Local variables will override global variables when they have conflicting names.
-[TODO: ways to setup environment variables (link to deployment docs?)] +.env file.You can access the environment variables through the systems library of each language.
+[TODO: @luke show how you access environment varibles for every language (sorry for the pain!)] +Explore examples and recipes -
- - -Libraries dependent on compiled binaries not available on the executors cannot be installed.
\ No newline at end of file + \ No newline at end of file diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml index 5f41f6647..44007ad43 100644 --- a/app/views/docs/index.phtml +++ b/app/views/docs/index.phtml @@ -100,7 +100,7 @@ $cols = [After deploying a function, you can find the status of the deployment and build logs in the Appwrite Console.
+Before you can deploy with the Appwrite CLI, make sure you've installed and initialized the CLI
+
To deploy with the Appwrite CLI, your function's folder structure must be configured in a specific way.
The folder path is then added to a config file called appwrite.json that tells the CLI where each function is stored.
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 44007ad43..d82d95a21 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -96,11 +96,11 @@ $cols = [
Functions
- TODO: Describe steps to navigate the UI + Changes in Appwrite emit events. + You can configure Functions to be executed in response to these events.
+
To simplify the migration process we have created an OAuth application that will allow you to sign in with Google and automatically
From d9c2d5d833ec38c0145fe7d48e791b212beeca08 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" The CLI also handles the creation and deployment of Appwrite Functions. You can initialize a new function using: The CLI also handles the creation and deployment of Appwrite Functions. Run this command in the folder holding your This command creates a new function My Awesome Function in your current Appwrite project and also creates a template function for you to get started. You can now deploy this function using: This command creates a new function My Awesome Function in your current Appwrite project and also creates a template function for you to get started. You can now deploy this function by running this command in the folder holding your The Appwrite CLI also helps you migrate your project's databases and collections from a development server to a production server. You can deploy all the databases and collections in your appwrite.json file using: The Appwrite CLI also helps you migrate your project's databases and collections from a development server to a production server. You can deploy all the databases and collections in your appwrite.json file by running this command in the folder holding your The Appwrite CLI can create teams to organize users. Teams can be used to grant access permissions to a group of users. Learn more about permissions. Deploy teams by running this command in the folder holding your The Appwrite CLI allows you to configure and deploy buckets across projects. All the bucket's settings are available through the appwrite.json file. Deploy storage buckets by running this command in the folder holding your Before you can deploy with the Appwrite CLI, make sure you've installed and initialized the CLI
- To deploy with the Appwrite CLI, your function's folder structure must be configured in a specific way.
- The folder path is then added to a config file called
+ Run the following command in the folder holding the
+ Want to leave the cloud and move your stuff to a Self Hosted instance? We're sorry to see you go, but we've got your back.
+ Migrations makes it easy as easy as a couple clicks to move all of your cloud data to a Self Hosted instance.
+
+ To begin migrating to Appwrite Self Hosted make sure to read the migration overview
+ and things to keep in mind sections above.
+
+ Navigate to your Appwrite Cloud and click on the Migrations tab.
+
+ From there you can click on the Export to Self Hosted button, you will then be asked to input the URL of your Self Hosted instance
+ aswell as an optional feedback question asking why Self Hosted is a better fit for you. Once done you can click on the Continue button and you will be
+ redirected to your Self Hosted instance to continue the migration process.
+
+ Once your at Self Hosted instance you will be prompted to select the organization aswell as the option to either create a new project
+ or select an existing project to migrate to.
+
+ After you have selected the project you want to migrate to you will be asked what data you want to migrate. You can select
+ to migrate users, databases, documents, files and functions. Once you have selected what data you want to migrate you can
+ click on the Start Migration button to begin the migration process.
+
+ Making the move to Appwrite Cloud? We've got your back.
+ Migrations makes it easy as easy as a couple clicks to move all of your self hosted data to Appwrite Cloud.
+
+ To begin migrating to Appwrite Self Hosted make sure to read the migration overview
+ and things to keep in mind sections above.
+
+ Navigate to your Self Hosted instance and click on the Migrations tab.
+
+ From there you can click on the Deploy to Cloud button, you will then be redirected to Appwrite Cloud.
+
+ Once your at Appwrite Cloud you will be prompted to select the organization aswell as the option to either create a new project
+ or select an existing project to migrate to.
+
+ After you have selected the project you want to migrate to you will be asked what data you want to migrate. You can select
+ to migrate users, databases, documents, files and functions. Once you have selected what data you want to migrate you can
+ click on the Start Migration button to begin the migration process.
+ Your Self Hosted instance will generate a API Key in the background to pass to Cloud. You can revoke this key after the migration process is complete.
- Want to leave the cloud and move your stuff to a Self Hosted instance? We're sorry to see you go, but we've got your back.
- Migrations makes it easy as easy as a couple clicks to move all of your cloud data to a Self Hosted instance.
-
- To begin migrating to Appwrite Self Hosted make sure to read the migration overview
- and things to keep in mind sections above.
-
- Navigate to your Appwrite Cloud and click on the Migrations tab.
-
- From there you can click on the Export to Self Hosted button, you will then be asked to input the URL of your Self Hosted instance
- aswell as an optional feedback question asking why Self Hosted is a better fit for you. Once done you can click on the Continue button and you will be
- redirected to your Self Hosted instance to continue the migration process.
-
- Once your at Self Hosted instance you will be prompted to select the organization aswell as the option to either create a new project
- or select an existing project to migrate to.
-
- After you have selected the project you want to migrate to you will be asked what data you want to migrate. You can select
- to migrate users, databases, documents, files and functions. Once you have selected what data you want to migrate you can
- click on the Start Migration button to begin the migration process.
-
+ Moving to a self-hosted instance? We've got you covered.
+ Migrations makes it easy as easy as a couple clicks to move all of your Appwrite Cloud project data to a self-hosted instance.
+
+ To begin migrating to Appwrite Self Hosted make sure to read the migration overview
+ and things to keep in mind sections above.
+
Moving to a self-hosted instance? We've got you covered.
- Migrations makes it easy as easy as a couple clicks to move all of your Appwrite Cloud project data to a self-hosted instance.
+ Migrations makes it as easy as a couple clicks to move all of your Appwrite Cloud project data to a self-hosted instance.
- To begin migrating to Appwrite Self Hosted make sure to read the migration overview
+ To begin migrating to Appwrite Self-hosted, make sure to read the migration overview
and things to keep in mind sections above.
Making the move to Appwrite Cloud? We've got your back.
- Migrations makes it easy as easy as a couple clicks to move all of your self hosted data to Appwrite Cloud.
+ Migrations makes it as easy as a couple clicks to move all of your self-hosted project data to a Cloud instance.
- To begin migrating to Appwrite Self Hosted make sure to read the migration overview
+ To begin migrating to self-hosted, make sure to read the migration overview
and things to keep in mind sections above.
- Navigate to your Self Hosted instance and click on the Migrations tab.
-
- From there you can click on the Deploy to Cloud button, you will then be redirected to Appwrite Cloud.
+ Your Self Hosted instance will generate a API Key in the background to pass to Cloud. You can revoke this key after the migration process is complete. Your Self-hosted instance will generate a API Key in the background to pass to Cloud. You can revoke this key after the migration process is complete.
- Appwrite Functions is all about flexibility.
- Behind the simple workflow hides some useful recipes that can help you accomplish your goals faster.
- Take a look at the following.
+ Appwrite Functions is all about flexibility.
+ Behind the simple workflow hides some useful recipes that can help you accomplish your goals faster.
+ Take a look at the following.
+ In this recipe, we'll build a simple function for currency conversion.
+ Create a new file, `index.js`. Add the following code to `index.js`. Create a new file, `index.php`. Add the following code to `index.php`. Create a new file, `index.py`. Add the following code to `index.py`. Create a new file, `index.dart`. Add the following code to `index.dart`. Create a new file, `index.rb`. Add the following code to `index.rb`. This code will return `1.13` when the function is called, because 1€ equals approximately 1.13$. Now, create a function in the Appwrite console, adding your Git repository as the remote source and using the path file you created as the entry point. Now, let's update the function to use the request payload. You can use a query string to pass data to your function. For example, `ghrfu9ewji.functions.appwrite.app?amount=5` will pass `5` as the `amount` parameter. Update `index.js` to use `req.query.amount` to access the `amount` parameter, and return the conversion result. Update `index.php` to use `$context->req->query['amount']` to access the `amount` parameter, and return the conversion result. Commit your changes and push them to your Git repository.
+ Execute the function and visit the URL (like `ghrfu9ewji.functions.appwrite.app?amount=5`) to see the response.
+
+ You should see the result of the conversion, like `5.65`.
+ Run the following bash command to create a `package.json` file. This file is used to manage your Node.js project's dependencies. Install the `undici` library. This library includes a `fetch` function that you can use to make HTTP requests. Finally, we need to add `npm install` to your function's build commands in the Appwrite console. Use `fetch` from `undici` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars. Deploy your changes After your function has updated, you can test it by visiting the URL and providing different amounts to convert in the query string. The conversion rate should now be more precise because we're using the current conversion rate. Let's add support multiple paths like `/eur` and `/inr`. Each path will convert from that currency to dollars.
+ After your function has updated, you can try out the new paths. For example, `ghrfu9ewji.functions.appwrite.app/eur?amount=5` should convert Euros to Dollars, while `ghrfu9ewji.functions.appwrite.app/inr?amount=100` should convert Indian Rupees to Dollars. Congratulations! You've built a powerful currency conversion function using Appwrite! Update `index.py` to use `context.req.query['amount']` to access the `amount` parameter, and return the conversion result. Update `index.dart` to use `context.req.query['amount']` to access the `amount` parameter, and return the conversion result. Update `index.rb` to use `context.req.query['amount']` to access the `amount` parameter, and return the conversion result. Commit your changes and push them to your Git repository. Finally, we need to add `npm install` to your function's build commands in the Appwrite console. Finally, add `npm install` to your function's build commands in the Appwrite console. You can use Composer to manage your PHP project's dependencies. Install it from getcomposer.org/download. Run the following bash command to create a `composer.json` file. This file is used to manage your PHP project's dependencies. Install the `guzzlehttp/guzzle` library. This library includes a `get` function that you can use to make HTTP requests. Finally, add `composer install` to your function's build commands in the Appwrite console. Run the following bash command to create a `requirements.txt` file. This file is used to manage your Python project's dependencies. Install the `requests` library. This library includes a `get` function that you can use to make HTTP requests. Finally, add `pip install -r requirements.txt` to your function's build commands in the Appwrite console.
+ Create a `pubspec.yaml` file with the following contents. This file is used to manage your Dart project's dependencies.
+
+ Install the `http` library. This library includes a `get` function that you can use to make HTTP requests.
+
+ Finally, add `pub get` to your function's build commands in the Appwrite console.
+
+ Create a `Gemfile` file with the following contents. This file is used to manage your Ruby project's dependencies.
+
+ Install the `httparty` library. This library includes a `get` function that you can use to make HTTP requests.
+
+ Finally, add `bundle install` to your function's build commands in the Appwrite console.
+
+ Use `get` from `requests` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars. Use `get` from `http` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars. Use `get` from `httparty` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars. Deploy your changes
+
+
+ After your function has updated, you can try out the new paths. For example, `ghrfu9ewji.functions.appwrite.app/eur?amount=5` should convert Euros to Dollars, while `ghrfu9ewji.functions.appwrite.app/inr?amount=100` should convert Indian Rupees to Dollars. Some lamguages support unpacking. You'll see us use unpacking in examples, which has the following syntax. Some languages support destructuring. You'll see us use destructing in examples, which has the following syntax.Deploying Appwrite Functions
-appwrite.json file.appwrite init function
@@ -36,7 +36,9 @@ The Apprite CLI allows you to create and deploy databases, collections, buckets,
✓ Successappwrite.json file.appwrite deploy function
@@ -47,7 +49,9 @@ The Apprite CLI allows you to create and deploy databases, collections, buckets,
Deploying Databases and Collections
-appwrite.json file.
@@ -57,15 +61,17 @@ The Apprite CLI allows you to create and deploy databases, collections, buckets,
appwrite deploy collectionappwrite.json file. appwrite deploy teamDeploying Storage Buckets
appwrite.json file. appwrite deploy bucketappwrite.json that tells the CLI where each function is stored.
- To ensure the folder structure is setup correctly and appwrite.json is configured correctly, use the appwrite init function method to create a shell function.
+ To deploy with the Appwrite CLI, your function must be added to appwrite.json that tells the CLI where each function is stored.
+ To ensure the folder structure is setup correctly and appwrite.json is configured correctly, use the appwrite init function method to create a shell function, then paste in your function code.
+appwrite.json file.
From b4fb7387e93fe53a59f37da3322eac3e5c03a60b Mon Sep 17 00:00:00 2001
From: Bradley Schofield appwrite init functionThings to keep in mind
+
+
+
+
+Migrating to Self Hosted from Cloud
+
+Things to keep in mind
+
+
+
+
+Migrating to Cloud from Self Hosted
+Keep in mind
+ Things to keep in mind
-
-
-
-
-Migrating to Self Hosted from Cloud
-
-Things to keep in mind
+
+
+
+
+Migrating to Self-hosted from Cloud
+
+Steps on Your Cloud Project
+
+
+
+Steps on Your Self-hosted Project
+
+
\ No newline at end of file
diff --git a/app/views/docs/local-to-cloud.phtml b/app/views/docs/migration-local-to-cloud.phtml
similarity index 100%
rename from app/views/docs/local-to-cloud.phtml
rename to app/views/docs/migration-local-to-cloud.phtml
From b84453104cbacea6743e38fee8e0068d328a645d Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge" Things to keep in mind
Migrating to Self-hosted from Cloud
Steps on Your Cloud Project
diff --git a/app/views/docs/migration-local-to-cloud.phtml b/app/views/docs/migration-local-to-cloud.phtml
index 3648b25ee..e30783d4b 100644
--- a/app/views/docs/migration-local-to-cloud.phtml
+++ b/app/views/docs/migration-local-to-cloud.phtml
@@ -1,34 +1,38 @@
Things to keep in mind
-Migrating to Cloud from Self Hosted
+Migrating to Self-hosted from Cloud
Steps on Your Self-hosted Project
- Once your at Appwrite Cloud you will be prompted to select the organization aswell as the option to either create a new project
- or select an existing project to migrate to.
+
+
- After you have selected the project you want to migrate to you will be asked what data you want to migrate. You can select
- to migrate users, databases, documents, files and functions. Once you have selected what data you want to migrate you can
- click on the Start Migration button to begin the migration process.
-
+Steps on Your Cloud Project
+
+
Keep in mind
- Section 1: My First Function
+Getting Started
-Creating the function
-
-
-
module.exports = async function ({ res }) {
- return res.end('1.13');
+
+
+
+Node.js
+
-export default async function ({ res }) {
+ return res.send('1.13');
};
-git init
-git add index.js
-git commit -m "Initial commit"
-Section 2: Let's Use Payload
-
-Updating the function
-
-
-
module.exports = async function ({ req, res }) {
+ PHP
+
+ <?php
+return function ($context) {
+ return $context->res->send('1.13');
+};Python
+
+ def main(context):
+ return context.res.send('1.13')Dart
+
+ import 'dart:async';
+
+Future<dynamic> main(final context) async {
+ return context.res.send('1.13');
+}Ruby
+
+ def main(context)
+ return context.res.send('1.13')
+endCurrency Conversion
+
+
+
Node.js
+
-export default async function ({ req, res }) {
const amountInEuros = Number(req.query.amount);
const amountInDollars = amountInEuros * 1.13;
- return res.end(amountInDollars.toString());
+ return res.send(amountInDollars.toString());
};Testing the function
-
-
-
-
-Section 3: Installing Dependencies
-
-Preparing for dependencies
+ PHP
+
+ <?php
+return function ($context) {
+ $amountInEuros = $context->req->query['amount'];
+ $amountInDollars = $amountInEuros * 1.13;
+ return $context->res->send($amountInDollars);
+};
-
+Updating the function
-
-
Testing the function
-const { fetch } = require('undici');
+Adding Dependencies
+
+
+
+
+Node.js
+
+ npm init -y
+ npm install undiciUsing Dependencies
+
+
+
Node.js
+
-import { fetch } from 'undici';
+
+export default async function ({ req, res }) {
const amountInEuros = Number(req.query.amount);
- const response = await fetch('https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/eur/usd.json');
+ const response = await fetch('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
const data = await response.json();
- const amountInDollars = amountInEuros * data.usd;
- return res.end(amountInDollars.toString());
+ const amountInDollars = amountInEuros * data.rates.USD;
+ return res.send(amountInDollars.toString());
};Testing the function
-
-
-
-
-Section 4: More Routes
-
-Updating the function
-
-
-
-
-Testing the function
-
-
-
+ Adding More Routes
+
+
+
+Node.js
+
+ import { fetch } from 'undici';
+
+export default async function ({ req, res }) {
+ if (req.path === '/eur') {
+ const amountInEuros = Number(req.query.amount);
+ const response = await fetch('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
+ const data = await response.json();
+ const amountInDollars = amountInEuros * data.rates.USD;
+ return res.send(amountInDollars.toString());
+ }
+
+ if (req.path === '/inr') {
+ const amountInRupees = Number(req.query.amount);
+ const response = await fetch('https://api.exchangerate.host/latest?base=INR&symbols=USD');
+ const data = await response.json();
+ const amountInDollars = amountInRupees * data.rates.USD;
+ return res.send(amountInDollars.toString());
+ }
+
+ return res.send('Invalid path');
+};Python
+
+ def main(context):
+ amountInEuros = context.req.query['amount']
+ amountInDollars = amountInEuros * 1.13
+ return context.res.send(amountInDollars)Dart
+
+ import 'dart:async';
+
+Future<dynamic> main(final context) async {
+ final amountInEuros = context.req.query['amount'];
+ final amountInDollars = amountInEuros * 1.13;
+ return context.res.send(amountInDollars);
+}Ruby
+
+ def main(context)
+ amountInEuros = context.req.query['amount']
+ amountInDollars = amountInEuros * 1.13
+ return context.res.send(amountInDollars)
+endnpm install undiciPHP
+
+ composer init -y
+ composer require guzzlehttp/guzzlePython
+
+ touch requirements.txt
+ echo "requests" >> requirements.txt
+pip -r requirements.txt
+ Dart
+
+
+ name: appwrite_function
+description: Appwrite Function
+version: 1.0.0
+environment:
+ sdk: '>=2.12.0 <3.0.0'
+
+ pub install http
+
+ Ruby
+
+
+ source 'https://rubygems.org'
+
+ echo "gem 'httparty'" >> Gemfile
+bundle installPHP
+
+ <?php
+
+require(__DIR__ . '/../vendor/autoload.php');
+
+use GuzzleHttp\Client;
+
+return function ($context) {
+ $amountInEuros = $context->getRequest()->getQuery('amount');
+ $client = new Client();
+ $response = $client->get('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
+ $data = json_decode($response->getBody(), true);
+ $amountInDollars = $amountInEuros * $data['rates']['USD'];
+ return $context->res->send(strval($amountInDollars));
+};Python
+
+ import requests
+
+def main(context):
+ amount_in_euros = float(context.req.query['amount'])
+ response = requests.get('https://api.exchangerate.host/latest?base=EUR&symbols=USD')
+ data = response.json()
+ amount_in_dollars = amount_in_euros * data['rates']['USD']
+ return context.res.send(str(amount_in_dollars))Dart
+
+ import 'dart:async';
+import 'package:http/http.dart' as http;
+
+Future<dynamic> main(final context) async {
+ final amountInEuros = double.parse(context.req.query['amount'])
+ final response = await http.get(Uri.parse('https://api.exchangerate.host/latest?base=EUR&symbols=USD'));
+ final data = json.decode(response.body);
+ final amountInDollars = amountInEuros * data['rates']['USD'];
+ return context.res.send(amountInDollars.toString());
+}Ruby
+
+ require 'httparty'
+
+def main(context)
+ amount_in_euros = context.req.query['amount'].to_f
+ response = HTTParty.get('https://api.exchangerate.host/latest?base=EUR&symbols=USD')
+ data = JSON.parse(response.body)
+ amount_in_dollars = amount_in_euros * data['rates']['USD']
+ return context.res.send(amount_in_dollars.to_s)
+endPython
+
+ import requests
+
+def main(context):
+ if context.req.path == '/eur':
+ amount_in_euros = float(context.req.query['amount'])
+ response = requests.get('https://api.exchangerate.host/latest?base=EUR&symbols=USD')
+ data = response.json()
+ amount_in_dollars = amount_in_euros * data['rates']['USD']
+ return context.res.send(str(amount_in_dollars))
+
+ if context.req.path == '/inr':
+ amount_in_rupees = float(context.req.query['amount'])
+ response = requests.get('https://api.exchangerate.host/latest?base=INR&symbols=USD')
+ data = response.json()
+ amount_in_dollars = amount_in_rupees * data['rates']['USD']
+ return context.res.send(str(amount_in_dollars))
+
+ return 'Invalid path'Dart
+
+ import 'dart:async';
+import 'package:http/http.dart' as http;
+
+Future<dynamic> main(final context) async {
+ if (context.req.path == '/eur') {
+ final amountInEuros = double.parse(context.req.query['amount'])
+ final response = await http.get(Uri.parse('https://api.exchangerate.host/latest?base=EUR&symbols=USD'));
+ final data = json.decode(response.body);
+ final amountInDollars = amountInEuros * data['rates']['USD'];
+ return context.res.send(amountInDollars.toString());
+ }
+
+ if (context.req.path == '/inr') {
+ final amountInRupees = double.parse(context.req.query['amount'])
+ final response = await http.get(Uri.parse('https://api.exchangerate.host/latest?base=INR&symbols=USD'));
+ final data = json.decode(response.body);
+ final amountInDollars = amountInRupees * data['rates']['USD'];
+ return context.res.send(amountInDollars.toString());
+ }
+
+ return 'Invalid path';
+}Ruby
+
+ require 'httparty'
+
+def main(context)
+ if context.request.path == '/eur'
+ amount_in_euros = context.request.query['amount'].to_f
+ response = HTTParty.get('https://api.exchangerate.host/latest?base=EUR&symbols=USD')
+ data = JSON.parse(response.body)
+ amount_in_dollars = amount_in_euros * data['rates']['USD']
+ return context.response.send(amount_in_dollars.to_s)
+ end
+
+ if context.request.path == '/inr'
+ amount_in_rupees = context.request.query['amount'].to_f
+ response = HTTParty.get('https://api.exchangerate.host/latest?base=INR&symbols=USD')
+ data = JSON.parse(response.body)
+ amount_in_dollars = amount_in_rupees * data['rates']['USD']
+ return context.response.send(amount_in_dollars.to_s)
+ end
+
+ return 'Invalid path'
+end
Node.js
-
-
- PHP
-
-
-
- Python
-
-
-
- Ruby
-
+
-
- export default async function ({ req, res, log, error }) {
+ log('This is a log!');
+ error('This is an error!');
+ return res.send(`This function was called with ${req.method} method!`)
+}Deno
-
-
- Dart
-
-
-
- Swift
-
-
-
- .NET
-
-
-
- Kotlin
-
-
-
- Java
-
-
-
- C++
-
+
-
- export default async function ({ req, res, log, error }: any) {
+ log('This is a log!');
+ error('This is an error!');
+ return res.send(`This function was called with ${req.method} method!`)
+}
export default async ({ req, res, log }) => {
- log(req.bodyString); // Raw request body, contains request data
+ log(req.bodyRaw); // Raw request body, contains request data
log(req.body); // Body parsed on content-type, only supports JSON
log(req.headers); // Request headers
log(req.scheme); // Value of the x-forwarded-proto header, usually http or https
@@ -538,7 +538,97 @@
You can access the environment variables through the systems library of each language.
-[TODO: @luke show how you access environment varibles for every language (sorry for the pain!)]
+
+ -
+
Node.js
+
+
+ process.env.MY_VAR
+
+
+
+ -
+
PHP
+
+
+ getenv('MY_VAR')
+
+
+
+ -
+
Python
+
+
+ os.environ['MY_VAR']
+
+
+
+ -
+
Ruby
+
+
+ ENV['MY_VAR']
+
+
+
+ -
+
Deno
+
+
+ Deno.env.get('MY_VAR')
+
+
+
+ -
+
Dart
+
+
+ Platform.environment['MY_VAR']
+
+
+
+ -
+
Swift
+
+
+ ProcessInfo.processInfo.environment["MY_VAR"]
+
+
+
+ -
+
.NET
+
+
+ Environment.GetEnvironmentVariable("MY_VAR")
+
+
+
+ -
+
Kotlin
+
+
+ System.getenv("MY_VAR")
+
+
+
+
+ -
+
Java
+
+
+ System.getenv("MY_VAR")
+
+
+
+ -
+
C++
+
+
+ std::getenv("MY_VAR")
+
+
+
+
Depencies
From df0754825a99e89179ba643178f9463ee1960f09 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Tue, 8 Aug 2023 15:10:29 +0100
Subject: [PATCH 042/183] feat: discussion
---
app/views/docs/functions-develop.phtml | 22 +++--
app/views/docs/functions-execute.phtml | 119 ++++++++++++++++++++++++-
app/views/docs/functions-recipes.phtml | 117 ++++++++++++------------
app/views/docs/functions.phtml | 4 +-
4 files changed, 195 insertions(+), 67 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 998b51f6a..0ff6a2dca 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -102,8 +102,8 @@
export default async ({ req, res, log }) => {
log(req.bodyRaw); // Raw request body, contains request data
- log(req.body); // Body parsed on content-type, only supports JSON
- log(req.headers); // Request headers
+ log(JSON.stringify(req.body)); // Body parsed on content-type, only supports JSON
+ log(JSON.stringify(req.headers)); // Request headers
log(req.scheme); // Value of the x-forwarded-proto header, usually http or https
log(req.method); // Request method, such as GET, POST, PUT, DELETE, PATCH, etc.
log(req.url); // Full URL, for example: http://awesome.appwrite.io:8000/v1/hooks?limit=12&offset=50
@@ -235,13 +235,13 @@
export default async ({ req, res, log }) => {
- switch (req.body) {
+ switch (req.query.type) {
case 'send':
return res.send(
"This is a text response",
200,
{
- "content-type": "application/text"
+ "content-type": "text/plain"
}
);
case 'json':
@@ -630,10 +630,22 @@
-Depencies
+Dependencies
[TODO: @luke is this different for every language? Idk what to put here, do we need to also @matej?]
+- The NodeJS runtime has npm installed.
+- The PHP runtime has composer installed.
+- The Python runtime has pip installed.
+- The Ruby runtime has bundler installed.
+- The Deno runtime has deno installed.
+- The Dart runtime has pub installed.
+- The Swift runtime has swift installed.
+- The .NET runtime has nuget installed.
+- The Kotlin runtime has gradle installed.
+- The Java runtime has gradle installed.
+
+
Using Appwrite in a Function
[TODO: @luke @matej 2 examples -> JWT and API keys]
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 387ca1dc3..d3080d5c1 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -16,9 +16,126 @@
SDK
[TODO: @luke @matej, two examples running the function sync and async form the SDK]
-
+ You can invoke your Appwrite Functions directly from the Appwrite SDKs.
+Learn more about using the Appwrite SDKs
+
+
+ -
+
Node.js
+
+
+
+
+
+
+
+ -
+
PHP
+
+
+
+
+
+
+
+
+ -
+
Python
+
+
+
+
+
+
+
+
+ -
+
Ruby
+
+
+
+
+
+
+
+
+ -
+
Deno
+
+
+
+
+
+
+
+
+ -
+
Dart
+
+
+
+
+
+
+
+
+ -
+
Swift
+
+
+
+
+
+
+
+
+ -
+
.NET
+
+
+
+
+
+
+
+
+ -
+
Kotlin
+
+
+
+
+
+
+
+
+
+ -
+
Java
+
+
+
+
+
+
+
+
+ -
+
C++
+
+
+
+
+
+
+
+
+
+
+
+
Events
Changes in Appwrite emit events.
diff --git a/app/views/docs/functions-recipes.phtml b/app/views/docs/functions-recipes.phtml
index b5cb305a7..d8896f77c 100644
--- a/app/views/docs/functions-recipes.phtml
+++ b/app/views/docs/functions-recipes.phtml
@@ -15,8 +15,8 @@
-
Node.js
- Create a new file, `index.js`.
- Add the following code to `index.js`.
+ Create a new file, index.js.
+ Add the following code to index.js.
export default async function ({ res }) {
return res.send('1.13');
@@ -27,12 +27,12 @@
-
PHP
- Create a new file, `index.php`.
- Add the following code to `index.php`.
+ Create a new file, index.php.
+ Add the following code to index.php.
<?php
return function ($context) {
- return $context->res->send('1.13');
+ return $context->res->send('1.13');
};
@@ -40,8 +40,8 @@ return function ($context) {
-
Python
- Create a new file, `index.py`.
- Add the following code to `index.py`.
+ Create a new file, index.py.
+ Add the following code to index.py.
def main(context):
return context.res.send('1.13')
@@ -51,12 +51,12 @@ return function ($context) {
-
Dart
- Create a new file, `index.dart`.
- Add the following code to `index.dart`.
+ Create a new file, index.dart.
+ Add the following code to index.dart.
import 'dart:async';
-Future<dynamic> main(final context) async {
+Future<dynamic> main(final context) async {
return context.res.send('1.13');
}
@@ -65,8 +65,8 @@ Future<dynamic> main(final context) async {
-
Ruby
- Create a new file, `index.rb`.
- Add the following code to `index.rb`.
+ Create a new file, index.rb.
+ Add the following code to index.rb.
def main(context)
return context.res.send('1.13')
@@ -76,20 +76,20 @@ end
-This code will return `1.13` when the function is called, because 1€ equals approximately 1.13$.
+This code will return 1.13 when the function is called, because 1€ equals approximately 1.13$.
Now, create a function in the Appwrite console, adding your Git repository as the remote source and using the path file you created as the entry point.
-- Finally, execute the function and visit the URL (like `ghrfu9ewji.functions.appwrite.app`) to see the response.
+- Finally, execute the function and visit the URL (like
ghrfu9ewji.functions.appwrite.app) to see the response.
Currency Conversion
Now, let's update the function to use the request payload.
-You can use a query string to pass data to your function. For example, `ghrfu9ewji.functions.appwrite.app?amount=5` will pass `5` as the `amount` parameter.
+You can use a query string to pass data to your function. For example, ghrfu9ewji.functions.appwrite.app?amount=5 will pass 5 as the amount parameter.
-
Node.js
- Update `index.js` to use `req.query.amount` to access the `amount` parameter, and return the conversion result.
+ Update index.js to use req.query.amount to access the amount parameter, and return the conversion result.
export default async function ({ req, res }) {
const amountInEuros = Number(req.query.amount);
@@ -102,13 +102,13 @@ end
-
PHP
- Update `index.php` to use `$context->req->query['amount']` to access the `amount` parameter, and return the conversion result.
+ Update index.php to use $context->req->query['amount'] to access the amount parameter, and return the conversion result.
<?php
return function ($context) {
- $amountInEuros = $context->req->query['amount'];
+ $amountInEuros = $context->req->query['amount'];
$amountInDollars = $amountInEuros * 1.13;
- return $context->res->send($amountInDollars);
+ return $context->res->send($amountInDollars);
};
@@ -116,7 +116,7 @@ return function ($context) {
-
Python
- Update `index.py` to use `context.req.query['amount']` to access the `amount` parameter, and return the conversion result.
+ Update index.py to use context.req.query['amount'] to access the amount parameter, and return the conversion result.
def main(context):
amountInEuros = context.req.query['amount']
@@ -128,11 +128,11 @@ return function ($context) {
-
Dart
- Update `index.dart` to use `context.req.query['amount']` to access the `amount` parameter, and return the conversion result.
+ Update index.dart to use context.req.query['amount'] to access the amount parameter, and return the conversion result.
import 'dart:async';
-Future<dynamic> main(final context) async {
+Future<dynamic> main(final context) async {
final amountInEuros = context.req.query['amount'];
final amountInDollars = amountInEuros * 1.13;
return context.res.send(amountInDollars);
@@ -143,7 +143,7 @@ Future<dynamic> main(final context) async {
-
Ruby
- Update `index.rb` to use `context.req.query['amount']` to access the `amount` parameter, and return the conversion result.
+ Update index.rb to use context.req.query['amount'] to access the amount parameter, and return the conversion result.
def main(context)
amountInEuros = context.req.query['amount']
@@ -161,10 +161,10 @@ end
Testing the function
- Execute the function and visit the URL (like `ghrfu9ewji.functions.appwrite.app?amount=5`) to see the response.
+ Execute the function and visit the URL (like ghrfu9ewji.functions.appwrite.app?amount=5) to see the response.
- You should see the result of the conversion, like `5.65`.
+ You should see the result of the conversion, like 5.65.
Adding Dependencies
@@ -173,45 +173,45 @@ end
-
Node.js
- Run the following bash command to create a `package.json` file. This file is used to manage your Node.js project's dependencies.
+ Run the following bash command to create a package.json file. This file is used to manage your Node.js project's dependencies.
npm init -y
- Install the `undici` library. This library includes a `fetch` function that you can use to make HTTP requests.
+ Install the undici library. This library includes a fetch function that you can use to make HTTP requests.
npm install undici
- Finally, add `npm install` to your function's build commands in the Appwrite console.
+ Finally, add npm install to your function's build commands in the Appwrite console.
-
PHP
You can use Composer to manage your PHP project's dependencies. Install it from getcomposer.org/download.
- Run the following bash command to create a `composer.json` file. This file is used to manage your PHP project's dependencies.
+ Run the following bash command to create a composer.json file. This file is used to manage your PHP project's dependencies.
composer init -y
- Install the `guzzlehttp/guzzle` library. This library includes a `get` function that you can use to make HTTP requests.
+ Install the guzzlehttp/guzzle library. This library includes a get function that you can use to make HTTP requests.
composer require guzzlehttp/guzzle
- Finally, add `composer install` to your function's build commands in the Appwrite console.
+ Finally, add composer install to your function's build commands in the Appwrite console.
-
Python
- Run the following bash command to create a `requirements.txt` file. This file is used to manage your Python project's dependencies.
+ Run the following bash command to create a requirements.txt file. This file is used to manage your Python project's dependencies.
touch requirements.txt
- Install the `requests` library. This library includes a `get` function that you can use to make HTTP requests.
+ Install the requests library. This library includes a get function that you can use to make HTTP requests.
- echo "requests" >> requirements.txt
+ echo "requests" >> requirements.txt
pip -r requirements.txt
- Finally, add `pip install -r requirements.txt` to your function's build commands in the Appwrite console.
+ Finally, add pip install -r requirements.txt to your function's build commands in the Appwrite console.
-
@@ -220,25 +220,25 @@ pip -r requirements.txt
- Create a `pubspec.yaml` file with the following contents. This file is used to manage your Dart project's dependencies.
+ Create a pubspec.yaml file with the following contents. This file is used to manage your Dart project's dependencies.
name: appwrite_function
description: Appwrite Function
version: 1.0.0
environment:
- sdk: '>=2.12.0 <3.0.0'
+ sdk: '>=2.12.0 <3.0.0'
- Install the `http` library. This library includes a `get` function that you can use to make HTTP requests.
+ Install the http library. This library includes a get function that you can use to make HTTP requests.
pub install http
- Finally, add `pub get` to your function's build commands in the Appwrite console.
+ Finally, add pub get to your function's build commands in the Appwrite console.
@@ -248,21 +248,21 @@ environment:
- Create a `Gemfile` file with the following contents. This file is used to manage your Ruby project's dependencies.
+ Create a Gemfile file with the following contents. This file is used to manage your Ruby project's dependencies.
source 'https://rubygems.org'
- Install the `httparty` library. This library includes a `get` function that you can use to make HTTP requests.
+ Install the httparty library. This library includes a get function that you can use to make HTTP requests.
- echo "gem 'httparty'" >> Gemfile
+ echo "gem 'httparty'" >> Gemfile
bundle install
- Finally, add `bundle install` to your function's build commands in the Appwrite console.
+ Finally, add bundle install to your function's build commands in the Appwrite console.
@@ -274,7 +274,7 @@ bundle install
-
Node.js
- Use `fetch` from `undici` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
+ Use fetch from undici to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
import { fetch } from 'undici';
@@ -300,12 +300,12 @@ require(__DIR__ . '/../vendor/autoload.php');
use GuzzleHttp\Client;
return function ($context) {
- $amountInEuros = $context->getRequest()->getQuery('amount');
+ $amountInEuros = $context->getRequest()->getQuery('amount');
$client = new Client();
- $response = $client->get('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
- $data = json_decode($response->getBody(), true);
+ $response = $client->get('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
+ $data = json_decode($response->getBody(), true);
$amountInDollars = $amountInEuros * $data['rates']['USD'];
- return $context->res->send(strval($amountInDollars));
+ return $context->res->send(strval($amountInDollars));
};
@@ -313,7 +313,7 @@ return function ($context) {
-
Python
- Use `get` from `requests` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
+ Use get from requests to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
import requests
@@ -329,12 +329,12 @@ def main(context):
-
Dart
- Use `get` from `http` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
+ Use get from http to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
import 'dart:async';
import 'package:http/http.dart' as http;
-Future<dynamic> main(final context) async {
+Future<dynamic> main(final context) async {
final amountInEuros = double.parse(context.req.query['amount'])
final response = await http.get(Uri.parse('https://api.exchangerate.host/latest?base=EUR&symbols=USD'));
final data = json.decode(response.body);
@@ -347,7 +347,7 @@ Future<dynamic> main(final context) async {
-
Ruby
- Use `get` from `httparty` to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
+ Use get from httparty to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
require 'httparty'
@@ -368,7 +368,7 @@ end
Adding More Routes
-Let's add support multiple paths like `/eur` and `/inr`. Each path will convert from that currency to dollars.
+Let's add support multiple paths like /eur and /inr. Each path will convert from that currency to dollars.
-
@@ -434,7 +434,7 @@ def main(context):
import 'dart:async';
import 'package:http/http.dart' as http;
-Future<dynamic> main(final context) async {
+Future<dynamic> main(final context) async {
if (context.req.path == '/eur') {
final amountInEuros = double.parse(context.req.query['amount'])
final response = await http.get(Uri.parse('https://api.exchangerate.host/latest?base=EUR&symbols=USD'));
@@ -488,24 +488,21 @@ end
-After your function has updated, you can try out the new paths. For example, `ghrfu9ewji.functions.appwrite.app/eur?amount=5` should convert Euros to Dollars, while `ghrfu9ewji.functions.appwrite.app/inr?amount=100` should convert Indian Rupees to Dollars.
+After your function has updated, you can try out the new paths. For example, ghrfu9ewji.functions.appwrite.app/eur?amount=5 should convert Euros to Dollars, while ghrfu9ewji.functions.appwrite.app/inr?amount=100 should convert Indian Rupees to Dollars.
Congratulations! You've built a powerful currency conversion function using Appwrite!
-[TODO: @luke -> translate code for other runtimes]
-
-[TODO: @matej @luke -> Example with JWT, show both client and server code]
+[TODO: @luke -> Example with JWT, show both client and server code]
+[TODO: @luke -> Example with API Key]
From c4e6f150924a9991886ebe03faf0c7689a1f9bf8 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 14 Aug 2023 18:07:32 +0000
Subject: [PATCH 064/183] Add tags for engineers to add examples
---
app/views/docs/authentication-anonymous.phtml | 8 ++++++-
.../docs/authentication-email-pass.phtml | 5 ++--
app/views/docs/authentication-magic.phtml | 2 +-
.../docs/authentication-management.phtml | 4 ++--
app/views/docs/authentication-oauth.phtml | 23 ++++++++++---------
app/views/docs/authentication-security.phtml | 3 ++-
app/views/docs/authentication-sms.phtml | 2 +-
app/views/docs/getting-started-for-web.phtml | 2 +-
8 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index 93d6dbc64..f0c9b236f 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -108,8 +108,14 @@ mutation {
-
Email and password
+
+ -
Phone
- Magic URL
+
+ -
+ Magic URL
+
+ -
OAuth2
\ No newline at end of file
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index c9cee86f7..8e8b5dd39 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -160,7 +160,7 @@ mutation {
In this example, the code below will be found in the page served at https://example.com/verify.
-[TODO: Who ever: examples to parse query params from page and complete verification]
+[TODO: @bradley examples to parse query params from page and complete verification]
Log In
@@ -457,4 +457,5 @@ let token = try await account.updateRecovery(
Security
-[TODO: Talk about the password security features]
\ No newline at end of file
+[TODO: @steven Talk about the password security features like password dictionary, passowrd history, and prevent personal information.]
+[Be brief, link to security page for details]
\ No newline at end of file
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index 1f89e0346..d863b7611 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -106,7 +106,7 @@ let user = try await account.createMagicURLSession(
After receiving your secret from an email, you can create a session.
-[TODO: Engineers, please update the examples below with how to get the secret from the magic URL]
+[TODO: @bradley, please update the examples below with how to get the secret from the magic URL]
-
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index 69db8cb05..8f636fcfc 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -4,9 +4,9 @@
Each user can also have their own preference object, which you can use to save preferences such as theme, language, and notification settings.
-[TODO @STEVEN: TEAMS examples]
+[TODO @steven: TEAMS docs]
-[TODO @STEVEN: Labels]
+[TODO @steven: Labels docs]
User Preferences
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 5fcbb32ee..18f8b69d1 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -14,11 +14,13 @@
Before using OAuth2 login, you need to enable and configure a OAuth2 login provider.
-[TODO]
-1. Navigate to your Appwrite project
-2. Navigate to **Auth** > **Settings**
-3. Find and open the OAuth provider
-4. In the **Zoom OAuth2 Settings** modal, use the toggle to enable the provider
+
+ - Navigate to your Appwrite project
+ - Navigate to Auth > Settings
+ - Find and open the OAuth provider.
+ - In the OAuth2 settings modal, use the toggle to enable the provider
+
+
Initialize OAuth2 Login
@@ -103,10 +105,9 @@ try await account.createOAuth2Session(provider: "amazon")
OAuth 2 Profile
-
+ [TODO: @steven fill the docs to access profile information]
-
Refresh Tokens
OAuth2 sessions expire to protect from security risks.
@@ -129,8 +130,8 @@ client
.setProject('[PROJECT_ID]') // Your Project ID
;
-// Go to Zoom OAuth login page
-account.createOAuth2Session('zoom', '[LINK_ON_SUCCESS]', '[LINK_ON_FAILURE]');
+// Go to Amazon OAuth login page
+account.createOAuth2Session('amazon', '[LINK_ON_SUCCESS]', '[LINK_ON_FAILURE]');
-
@@ -148,7 +149,7 @@ void main() async {
// OAuth Login, for simplest implementation you can leave both success and
// failure link empty so that Appwrite handles everything.
- await account.createOAuth2Session(provider: 'zoom');
+ await account.createOAuth2Session(provider: 'amazon');
}
@@ -165,7 +166,7 @@ val client = Client(context)
val account = Account(client)
-account.createOAuth2Session(provider = "zoom")
+account.createOAuth2Session(provider = "amazon")
-
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 28a1a475b..8e98a7b90 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -92,7 +92,8 @@
Password Dictionary
Password dictionary protects users from using bad passwords. It compares the user's password to the 10,000 most common passwords and throws an error if there's a match. Together with rate limits, password dictionary will significantly reduce the chance of a malicious actor from guessing user passwords.
-
Password dictionary can be enabled in the Auth service's Security tab on the Appwrite console.
Personal Information
+
+[TODO: @steven Talk about new personal information thing.]
\ No newline at end of file
diff --git a/app/views/docs/authentication-sms.phtml b/app/views/docs/authentication-sms.phtml
index b02f581b9..49c7c6483 100644
--- a/app/views/docs/authentication-sms.phtml
+++ b/app/views/docs/authentication-sms.phtml
@@ -16,7 +16,7 @@
A new account will be created for this phone number if it has never been used before.
-[TODO: to engineer: update these examples to show where the userID comes from (continuity from first request to next)]
+[TODO: @bradley update these examples to show where the userID comes from (continuity from first request to next)]
-
diff --git a/app/views/docs/getting-started-for-web.phtml b/app/views/docs/getting-started-for-web.phtml
index d7ec5bc2a..51d3428df 100644
--- a/app/views/docs/getting-started-for-web.phtml
+++ b/app/views/docs/getting-started-for-web.phtml
@@ -27,7 +27,7 @@ $demos = $platform['demos'] ?? [];
Web platforms allow wildcard hostnames through a * character. The wildcard character can be applied anywhere in a hostname, both *.example.com and prod.*.example.com are valid examples. Avoid using wildcards unless necessary to keep your Appwrite project secure.
-
+
Get Appwrite Web SDK
From a11daf828fcb4f7620489526072675c094ce1cfa Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 14 Aug 2023 19:57:00 +0000
Subject: [PATCH 065/183] Add information about environment variables that now
became headers
---
app/views/docs/functions-develop.phtml | 20 +++++++++++++++++++-
app/views/docs/functions.phtml | 3 +++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index fd43c4d4a..d32bdd973 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -26,7 +26,7 @@
The Context Object
Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite console.
- All input, output, and logging **must be** handled through the context object passed in.
+ All input, output, anddlogging **must be** handled through the context object passed in.
You'll find these properties in the context object.
@@ -940,6 +940,24 @@ namespace runtime {
Environmental variables can be global, or function specific.
+Default Environment Variables
+Appwrite Runtimes have some default environment variables. These are always accesible
+
+
+
+ Variable
+ Description
+
+
+
+
+
+
+
+
+
+
+
Local Environment Variables
Local variables will only be accessible in the function they belong to.
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 686e75906..93715532d 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -299,5 +299,8 @@ So it's important to be able to log, debug, and test your Appwrite Functions in
This prevents confusing errors when functions are terminated prematurely before a response is sent.
Learn about response.
+ -
+ Some variables about how a function was triggered are now found in the
context.req object as headers.
+
From d3645b2d4b22e565e9e8ac85974f8fa4af8a0784 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 14 Aug 2023 20:44:50 +0000
Subject: [PATCH 066/183] Move upgrade checklist to develop
---
app/views/docs/functions-develop.phtml | 49 +++++++++++++++++++++++++-
app/views/docs/functions.phtml | 49 +-------------------------
2 files changed, 49 insertions(+), 49 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index d32bdd973..42771b3ae 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -2069,4 +2069,51 @@ public class Main {
Explore examples and recipes
-
\ No newline at end of file
+
+
+Upgrade
+
+ Appwrite Functions received major updates in Appwrite version 1.4.
+ If you still have functions from previous versions, they will be read-only in Appwrite 1.4.
+ You will have to migrate your old functions to follow new runtime syntax.
+
+
+
+ Here's a checklist of things you need to know.
+
+
+
+ -
+ The parameter passed into functions has changed.
+
req and res has been replaced by context, which contains new logger methods.
+ Learn about context.
+
+ -
+ To improve privacy and logging reliability, we provide new
context.log() and context.error() functions.
+ You can no longer use native logging methods.
+ Learn about logging.
+
+ -
+ The old way of
req.variables has been deprecated.
+ You can now access variables passed into each function as environment variables.
+ Learn about environment variables.
+
+ -
+ The
req object has been updated to use terminology consistent with typical HTTP concepts.
+ You'll now find familiar concepts like headers, body, HTTP methods, and others.
+ Learn about request.
+
+ -
+ The response object has been updated.
+ You can now specify headers, as well as use new methods like return redirects or empty responses.
+ Learn about response.
+
+ -
+ Now, you must return a response such as
return context.res.send("").
+ This prevents confusing errors when functions are terminated prematurely before a response is sent.
+ Learn about response.
+
+ -
+ Some variables about how a function was triggered are now found in the
context.req object as headers.
+
+
\ No newline at end of file
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 93715532d..a014e4511 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -193,6 +193,7 @@ namespace runtime {
+[TODO: explore features should be like: Familiar HTTP concepts, many ways to execute, deploy from Git or xxx, built in templates, etc.]
Explore Features
@@ -256,51 +257,3 @@ So it's important to be able to log, debug, and test your Appwrite Functions in
Learn more about debugging functions
-
-Upgrade
-
- Appwrite Functions received major updates in Appwrite version 1.4.
- If you still have functions from previous versions, they will be read-only in Appwrite 1.4.
- You will have to migrate your old functions to follow new runtime syntax.
-
-
-
- Here's a checklist of things you need to know.
-
-
-
- -
- The parameter passed into functions has changed.
-
req and res has been replaced by context, which contains new logger methods.
- Learn about context.
-
- -
- To improve privacy and logging reliability, we provide new
context.log() and context.error() functions.
- You can no longer use native logging methods.
- Learn about logging.
-
- -
- The old way of
req.variables has been deprecated.
- You can now access variables passed into each function as environment variables.
- Learn about environment variables.
-
- -
- The
req object has been updated to use terminology consistent with typical HTTP concepts.
- You'll now find familiar concepts like headers, body, HTTP methods, and others.
- Learn about request.
-
- -
- The response object has been updated.
- You can now specify headers, as well as use new methods like return redirects or empty responses.
- Learn about response.
-
- -
- Now, you must return a response such as
return context.res.send("").
- This prevents confusing errors when functions are terminated prematurely before a response is sent.
- Learn about response.
-
- -
- Some variables about how a function was triggered are now found in the
context.req object as headers.
-
-
-
From 1ffc8e293eef1a4ac0cbd795f65c8bc8c3857bbc Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 14 Aug 2023 21:00:37 +0000
Subject: [PATCH 067/183] Add cloud/self-hosted tags as labels in runtimes
---
app/views/docs/functions-runtimes.phtml | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index 0a1e057e9..63d29e494 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -4,7 +4,12 @@ use Appwrite\Utopia\View;
$events = $this->getParam('events', []);
$runtimes = $this->getParam('runtimes', []);
-
+$runtimes['node-16.0']["cloud"] = true;
+$runtimes['node-18.0']["cloud"] = true;
+$runtimes['php-8.0']["cloud"] = true;
+$runtimes['ruby-3.0']["cloud"] = true;
+$runtimes['python-3.9']["cloud"] = true;
+$runtimes['dart-2.17']["cloud"] = true;
?>
@@ -26,6 +31,7 @@ $runtimes = $this->getParam('runtimes', []);
Name
Image
Architectures
+ Platforms
@@ -35,6 +41,12 @@ $runtimes = $this->getParam('runtimes', []);
escape($key); ?>
escape($runtime['image'] ?? ''); ?>
escape(implode(' / ', $runtime['supports'] ?? [])); ?>
+
+
+ Cloud
+
+ Self-hosted
+
From ca020879140790bfc666581366e531c570c01538 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 14 Aug 2023 23:21:35 +0000
Subject: [PATCH 068/183] Some minor improvements
---
app/views/docs/functions-deploy.phtml | 6 ++++-
app/views/docs/functions-execute.phtml | 32 ++++++++++++++++++-------
app/views/docs/functions-runtimes.phtml | 10 ++++----
3 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index c16a93e3d..0fac2e804 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -160,4 +160,8 @@
- Upload
code.tar.gz.
- Select Activate deployment after build to use your new function.
- Click Create to deploy your function.
-
\ No newline at end of file
+
+
+Domains
+
+[TODO: @matej steps to add a custom domain thanks]
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 88ca4327d..dbfb93d9c 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -4,11 +4,21 @@
Here are all the different ways to consume your new Appwrite Functions.
-Domain
+Domains
- Each Appwrite function has its own domain. You can find this in the Appwrite Console, under the Function overview.
- It looks something like this.https://64d4d22db370ae41a32e.functions.cloud.appwrite.io
- Alternatively you can add a custom domain to your Appwrite project, and use that instead.
+ Each Appwrite function has its own domain.
+ You can find this in the Appwrite Console, under the Function overview.
+
+
+
+ The generated domains will look like this.
+
+
+ https://64d4d22db370ae41a32e.functions.cloud.appwrite.io
+
+
+
+ Alternatively you can add a custom domain to your Appwrite project.
@@ -18,10 +28,12 @@
REST API
-curl -X POST [APPWRITE_FUNCTION_DOMAIN] \
--H "X-Custom-Header: 123" \
--H "Content-Type: application/json" \
--d '{"foo":"bar"}'
+
+ curl -X POST https://64d4d22db370ae41a32e.functions.cloud.appwrite.io \
+ -H "X-Custom-Header: 123" \
+ -H "Content-Type: application/json" \
+ -d '{"data":"this is json data"}'
+
SDK
@@ -455,6 +467,8 @@ public static void main(String[] args) throws Exception {
Permissions
+Permissions
+
Appwrite Functions can be executed using Client or Server SDKs.
Client SDKs must be authenticated with an account that has been granted execution permissions on the function's settings page.
@@ -466,7 +480,7 @@ public static void main(String[] args) throws Exception {
If you need to enforce permissions for functions with a domain, use authentication methods like JWT.
-Logs and results
+Logs and results
You can view the logs your function executions in the Appwrite Console.
Navigate to Functions and click on a function to view it's executions.
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index 63d29e494..cce760392 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -15,14 +15,12 @@ $runtimes['dart-2.17']["cloud"] = true;
Appwrite Functions supports an extensive list of runtimes to meet your unique tech preferences.
- Not all runtimes are available on Appwrite Cloud, check for the Cloud label in each listed runtime to know whichones are available.
+ Not all runtimes are available on Appwrite Cloud, check for the Cloud label in each listed runtime to know which ones are available.
Supported Runtimes
-Appwrite provides multiple code runtimes to execute your custom functions. Each runtime uses a Docker image tied to a specific language version to provide a safe, isolated playground to run your team's code.
-
-Below is a list of supported Cloud Functions runtimes. The Appwrite team continually adds support for new runtimes.
+Below is a list of supported Functions runtimes. The Appwrite team continually adds support for new runtimes.
@@ -52,4 +50,6 @@ $runtimes['dart-2.17']["cloud"] = true;
-[TODO: @matej Label which ones are cloud only, idk how to do cleanly]
+
+
- Learn more about permissions
+
\ No newline at end of file
From dbabc60a9d10d266804cb20e3796b96a791882cc Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 14 Aug 2023 23:24:35 +0000
Subject: [PATCH 069/183] Moved a p tag
---
app/views/docs/functions-execute.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index dbfb93d9c..54335a66b 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -21,13 +21,13 @@
Alternatively you can add a custom domain to your Appwrite project.
+REST API
When requests are made to this domain, whether through a browser or through an HTTP requests,
the request information like request headers and request body will be passed to the function.
This unlocks interesting ways to integrate other apps and backends to your Appwrite project.
-REST API
curl -X POST https://64d4d22db370ae41a32e.functions.cloud.appwrite.io \
-H "X-Custom-Header: 123" \
From 46ffc50db33703f4a9191e4ae226fca2a5aa27b5 Mon Sep 17 00:00:00 2001
From: Bradley Schofield
Date: Tue, 15 Aug 2023 10:23:07 +0100
Subject: [PATCH 070/183] Add NHost and Supabase Docs
---
app/views/docs/migration-nhost.phtml | 88 ++++++++++++++++++++++++
app/views/docs/migration-supabase.phtml | 91 +++++++++++++++++++++++++
2 files changed, 179 insertions(+)
diff --git a/app/views/docs/migration-nhost.phtml b/app/views/docs/migration-nhost.phtml
index e69de29bb..154555757 100644
--- a/app/views/docs/migration-nhost.phtml
+++ b/app/views/docs/migration-nhost.phtml
@@ -0,0 +1,88 @@
+
+ Moving your project from NHost to Appwrite?
+ Appwrite Migrations can help you streamline the process.
+
+ Here's what you need to know to get started.
+
+
+Things to keep in mind
+
+
+ - Appwrite will not charge usage during migrations, but NHost may still incur service charges.
+ - Appwrite's Database doesn't support all the features of the postgreSQL database so more advanced postgres centric things things like advanced indexes, postgres functions and scheduling will not be migrated.
+ - OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
+
+
+Supported resource types
+
+
+
+
+ Users
+ Databases
+ Documents
+ Files
+ Functions
+
+
+
+
+ NHost
+ ✅
+ ✅
+ ✅
+ ✅
+
+
+
+
+
+Migrating to Appwrite from NHost
+
+ To begin migrating to Appwrite make sure to read the migration overview
+ and things to keep in mind sections above.
+
+
+
+ -
+ Create a new project and click on the Migrations tab.
+
+ -
+ Click on the Create Migration button and select NHost as your source.
+
+ -
+ Enter the credentials following the instructions below and click Next.
+
+ -
+ Select the resources you want to migrate and finally click Start migration to begin the migration process.
+
+
+
+Migrating to Appwrite from NHost
+
+
+ -
+ Enter all the following credentials from your NHost project.
+
+ -
+ Region - The region your NHost project is hosted in. This can be found in your NHost project environment variables as NHOST_REGION.
+
+ -
+ Subdomain - The subdomain of your NHost project. This can be found in your NHost project environment variables as NHOST_SUBDOMAIN.
+
+ -
+ Database - The name of your NHost database. This can be found in your NHost project Database settings.
+
+ -
+ Username - The username of your NHost database. This can be found in your NHost project Database settings.
+
+ -
+ Password - The password of your NHost database. You set this when you created your NHost project, if you don't remember it you can reset it from your NHost project Database settings.
+
+ -
+ Admin Secret - The admin secret of your NHost project. This can be found in your NHost project environment variables as NHOST_ADMIN_SECRET. We use this to transfer your NHost Files to Appwrite.
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/docs/migration-supabase.phtml b/app/views/docs/migration-supabase.phtml
index e69de29bb..76f0188c6 100644
--- a/app/views/docs/migration-supabase.phtml
+++ b/app/views/docs/migration-supabase.phtml
@@ -0,0 +1,91 @@
+
+ Moving your project from Supabase to Appwrite?
+ Appwrite Migrations can help you streamline the process.
+
+ Here's what you need to know to get started.
+
+
+Things to keep in mind
+
+
+ - Appwrite will not charge usage during migrations, but Supabase may still incur service charges.
+ - Appwrite's Database doesn't support all the features of the postgreSQL database so more advanced postgres centric things things like advanced indexes, postgres functions and scheduling will not be migrated.
+ - OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
+
+
+Supported resource types
+
+
+
+
+ Users
+ Databases
+ Documents
+ Files
+ Functions
+
+
+
+
+ Supabase
+ ✅
+ ✅
+ ✅
+ ✅
+
+
+
+
+
+Migrating to Appwrite from Supabase
+
+ To begin migrating to Appwrite make sure to read the migration overview
+ and things to keep in mind sections above.
+
+
+
+ -
+ Create a new project and click on the Migrations tab.
+
+ -
+ Click on the Create Migration button and select Supabase as your source.
+
+ -
+ Enter the credentials following the instructions below and click Next.
+
+ -
+ Select the resources you want to migrate and finally click Start migration to begin the migration process.
+
+
+
+Migrating to Appwrite from Supabase
+
+
+ -
+ Enter all the following credentials from your Supabase project.
+
+ -
+ Region - The region your Supabase project is hosted in. This can be found in your Supabase project environment variables as Supabase_REGION.
+
+ -
+ Host - The host of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Host.
+
+ -
+ Port - The port of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Port. By default this is 5432.
+
+ -
+ Username - The username of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Username.
+
+ -
+ Password - The password of your Supabase Database, this was set when you created your Supabase project. If you forgot it you can reset it within your Database Settings
+
+ -
+ Endpoint - This is the endpoint of your Supabase instance under Project Settings -> API. This is used to migrate your files.
+
+ -
+ API Key - This is the key of your Supabase instance under Project Settings -> API. This is used to migrate your files. Make sure to use the hidden service_role key.
+
+
+
+
+
\ No newline at end of file
From 54097a42de357adf7e6ba1b668607241b1d043b1 Mon Sep 17 00:00:00 2001
From: "Luke B. Silver" <22452787+loks0n@users.noreply.github.com>
Date: Tue, 15 Aug 2023 13:20:29 +0100
Subject: [PATCH 071/183] fix: remove vscode settings
---
.vscode/settings.json | 9 ---------
1 file changed, 9 deletions(-)
delete mode 100644 .vscode/settings.json
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 8e639cda8..000000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "editor.formatOnSave": false,
- "[html][phtml]": {
- "editor.formatOnSave": false
- },
- "[php]": {
- "editor.formatOnSave": false
- }
-}
From 7d7c029dbfc9c1e32743271a70677aeaca73d050 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 14:34:23 +0000
Subject: [PATCH 072/183] update index to have all pages
---
app/views/docs/index.phtml | 14 +++++++++++++-
app/views/docs/migration.phtml | 3 ++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 11c8f4882..dac01f024 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -96,7 +96,19 @@ $cols = [
-
Migration
+
+ - Supabase
+
+
+ - NHost
+
+
+ - Cloud to Local
+
+
diff --git a/app/views/docs/migration.phtml b/app/views/docs/migration.phtml
index 542744618..336689026 100644
--- a/app/views/docs/migration.phtml
+++ b/app/views/docs/migration.phtml
@@ -56,5 +56,6 @@
Limitations
- - Migrations cannot transfer all data perfectly, so certain fields, such as $createdAt and $updatedAt, may not be transferred. More information can be found on the migration page for each source.
+ Migrations cannot transfer all data perfectly, so certain fields, such as $createdAt and $updatedAt, may not be transferred.
+ More information can be found on the migration page for each source.
\ No newline at end of file
From fc5ba4004d64e87dcd6f7abb9ac0593942890692 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 15:11:06 +0000
Subject: [PATCH 073/183] Fix ordered list tags and headings
---
app/views/docs/migration-nhost.phtml | 54 +++++++++++-----------
app/views/docs/migration-supabase.phtml | 61 ++++++++++++-------------
2 files changed, 56 insertions(+), 59 deletions(-)
diff --git a/app/views/docs/migration-nhost.phtml b/app/views/docs/migration-nhost.phtml
index 154555757..a556de4a0 100644
--- a/app/views/docs/migration-nhost.phtml
+++ b/app/views/docs/migration-nhost.phtml
@@ -58,31 +58,29 @@
-Migrating to Appwrite from NHost
-
-
- -
- Enter all the following credentials from your NHost project.
-
- -
- Region - The region your NHost project is hosted in. This can be found in your NHost project environment variables as NHOST_REGION.
-
- -
- Subdomain - The subdomain of your NHost project. This can be found in your NHost project environment variables as NHOST_SUBDOMAIN.
-
- -
- Database - The name of your NHost database. This can be found in your NHost project Database settings.
-
- -
- Username - The username of your NHost database. This can be found in your NHost project Database settings.
-
- -
- Password - The password of your NHost database. You set this when you created your NHost project, if you don't remember it you can reset it from your NHost project Database settings.
-
- -
- Admin Secret - The admin secret of your NHost project. This can be found in your NHost project environment variables as NHOST_ADMIN_SECRET. We use this to transfer your NHost Files to Appwrite.
-
-
-
-
-
\ No newline at end of file
+NHost Credentials
+
+ -
+ Enter all the following credentials from your NHost project.
+
+ -
+ Region - The region your NHost project is hosted in. This can be found in your NHost project environment variables as NHOST_REGION.
+
+ -
+ Subdomain - The subdomain of your NHost project. This can be found in your NHost project environment variables as NHOST_SUBDOMAIN.
+
+ -
+ Database - The name of your NHost database. This can be found in your NHost project Database settings.
+
+ -
+ Username - The username of your NHost database. This can be found in your NHost project Database settings.
+
+ -
+ Password - The password of your NHost database. You set this when you created your NHost project, if you don't remember it you can reset it from your NHost project Database settings.
+
+ -
+ Admin Secret - The admin secret of your NHost project. This can be found in your NHost project environment variables as NHOST_ADMIN_SECRET. We use this to transfer your NHost Files to Appwrite.
+
+
+
+
\ No newline at end of file
diff --git a/app/views/docs/migration-supabase.phtml b/app/views/docs/migration-supabase.phtml
index 76f0188c6..871ca85a9 100644
--- a/app/views/docs/migration-supabase.phtml
+++ b/app/views/docs/migration-supabase.phtml
@@ -58,34 +58,33 @@
-Migrating to Appwrite from Supabase
-
-
- -
- Enter all the following credentials from your Supabase project.
-
- -
- Region - The region your Supabase project is hosted in. This can be found in your Supabase project environment variables as Supabase_REGION.
-
- -
- Host - The host of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Host.
-
- -
- Port - The port of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Port. By default this is 5432.
-
- -
- Username - The username of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Username.
-
- -
- Password - The password of your Supabase Database, this was set when you created your Supabase project. If you forgot it you can reset it within your Database Settings
-
- -
- Endpoint - This is the endpoint of your Supabase instance under Project Settings -> API. This is used to migrate your files.
-
- -
- API Key - This is the key of your Supabase instance under Project Settings -> API. This is used to migrate your files. Make sure to use the hidden service_role key.
-
-
-
-
-
\ No newline at end of file
+Credentials
+
+
+ -
+ Enter all the following credentials from your Supabase project.
+
+ -
+ Region - The region your Supabase project is hosted in. This can be found in your Supabase project environment variables as Supabase_REGION.
+
+ -
+ Host - The host of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Host.
+
+ -
+ Port - The port of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Port. By default this is 5432.
+
+ -
+ Username - The username of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Username.
+
+ -
+ Password - The password of your Supabase Database, this was set when you created your Supabase project. If you forgot it you can reset it within your Database Settings
+
+ -
+ Endpoint - This is the endpoint of your Supabase instance under Project Settings -> API. This is used to migrate your files.
+
+ -
+ API Key - This is the key of your Supabase instance under Project Settings -> API. This is used to migrate your files. Make sure to use the hidden service_role key.
+
+
+
+
From 4b5185846b0041c4fe6aac6d745cafc8e408f290 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 16:03:00 +0000
Subject: [PATCH 074/183] Fix migrations index
---
app/views/docs/index.phtml | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index dac01f024..c4889dee5 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -97,19 +97,10 @@ $cols = [
Migration
- Firebase
-
-
- Supabase
-
-
- NHost
-
-
-
From 3b7d63e33e7a96f9a2aa37268836192af6030742 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 17:24:39 +0000
Subject: [PATCH 075/183] Fix language in migration guides for firebase,
supabase, and nhost
---
app/views/docs/index.phtml | 12 +--
app/views/docs/migration-supabase.phtml | 90 -------------------
....phtml => migrations-cloud-to-local.phtml} | 4 +-
...rebase.phtml => migrations-firebase.phtml} | 8 +-
....phtml => migrations-local-to-cloud.phtml} | 2 +-
...ion-nhost.phtml => migrations-nhost.phtml} | 48 +++++-----
app/views/docs/migrations-supabase.phtml | 88 ++++++++++++++++++
.../{migration.phtml => migrations.phtml} | 32 +++++--
8 files changed, 151 insertions(+), 133 deletions(-)
delete mode 100644 app/views/docs/migration-supabase.phtml
rename app/views/docs/{migration-cloud-to-local.phtml => migrations-cloud-to-local.phtml} (92%)
rename app/views/docs/{migration-firebase.phtml => migrations-firebase.phtml} (87%)
rename app/views/docs/{migration-local-to-cloud.phtml => migrations-local-to-cloud.phtml} (97%)
rename app/views/docs/{migration-nhost.phtml => migrations-nhost.phtml} (56%)
create mode 100644 app/views/docs/migrations-supabase.phtml
rename app/views/docs/{migration.phtml => migrations.phtml} (52%)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index c4889dee5..125f562c6 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -94,13 +94,13 @@ $cols = [
- Functions
-
- Migration
+ Migrations
- - Firebase
- - Supabase
- - NHost
- - Cloud to Local
- - Local to Cloud
+ - Firebase
+ - Supabase
+ - NHost
+ - Cloud to Local
+ - Local to Cloud
diff --git a/app/views/docs/migration-supabase.phtml b/app/views/docs/migration-supabase.phtml
deleted file mode 100644
index 871ca85a9..000000000
--- a/app/views/docs/migration-supabase.phtml
+++ /dev/null
@@ -1,90 +0,0 @@
-
- Moving your project from Supabase to Appwrite?
- Appwrite Migrations can help you streamline the process.
-
- Here's what you need to know to get started.
-
-
-Things to keep in mind
-
-
- - Appwrite will not charge usage during migrations, but Supabase may still incur service charges.
- - Appwrite's Database doesn't support all the features of the postgreSQL database so more advanced postgres centric things things like advanced indexes, postgres functions and scheduling will not be migrated.
- - OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
-
-
-Supported resource types
-
-
-
-
- Users
- Databases
- Documents
- Files
- Functions
-
-
-
-
- Supabase
- ✅
- ✅
- ✅
- ✅
-
-
-
-
-
-Migrating to Appwrite from Supabase
-
- To begin migrating to Appwrite make sure to read the migration overview
- and things to keep in mind sections above.
-
-
-
- -
- Create a new project and click on the Migrations tab.
-
- -
- Click on the Create Migration button and select Supabase as your source.
-
- -
- Enter the credentials following the instructions below and click Next.
-
- -
- Select the resources you want to migrate and finally click Start migration to begin the migration process.
-
-
-
-Credentials
-
-
- -
- Enter all the following credentials from your Supabase project.
-
- -
- Region - The region your Supabase project is hosted in. This can be found in your Supabase project environment variables as Supabase_REGION.
-
- -
- Host - The host of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Host.
-
- -
- Port - The port of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Port. By default this is 5432.
-
- -
- Username - The username of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Username.
-
- -
- Password - The password of your Supabase Database, this was set when you created your Supabase project. If you forgot it you can reset it within your Database Settings
-
- -
- Endpoint - This is the endpoint of your Supabase instance under Project Settings -> API. This is used to migrate your files.
-
- -
- API Key - This is the key of your Supabase instance under Project Settings -> API. This is used to migrate your files. Make sure to use the hidden service_role key.
-
-
-
-
diff --git a/app/views/docs/migration-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
similarity index 92%
rename from app/views/docs/migration-cloud-to-local.phtml
rename to app/views/docs/migrations-cloud-to-local.phtml
index 3f601a2ec..801d93c0e 100644
--- a/app/views/docs/migration-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -11,10 +11,10 @@
- Migrations are non-destructive. No data will be deleted or lost in the source project.
-Migrating to Self-hosted from Cloud
+Migrating to Self-hosted from Cloud
- To begin migrating to Appwrite Self-hosted, make sure to read the migration overview
+ To begin migrating to Appwrite Self-hosted, make sure to read the migrations overview
and things to keep in mind sections above.
diff --git a/app/views/docs/migration-firebase.phtml b/app/views/docs/migrations-firebase.phtml
similarity index 87%
rename from app/views/docs/migration-firebase.phtml
rename to app/views/docs/migrations-firebase.phtml
index 2d4951cc2..f8c236ea3 100644
--- a/app/views/docs/migration-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -8,10 +8,10 @@
Things to keep in mind
- - Appwrite will not charge usage during migrations, but Firebase may still incur service charges.
- - Appwrite migrations only supports Firestore as a database source. Realtime Database is currently not supported.
+ - Appwrite will not incur usage charges during migrations, but Firebase may still incur service charges.
+ - Appwrite Migrations only supports Firestore as a database source. Realtime Database is currently not supported.
- At the moment only top level document migration is supported. Nested documents will not be transferred automatically.
- - OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
+ - OAuth users will not be transferred. Users will need to re-authenticate with your OAuth provider after the migration is complete.
Supported resource types
@@ -40,7 +40,7 @@
Migrating to Appwrite from Firebase
- To begin migrating to Appwrite make sure to read the migration overview
+ To begin migrating to Appwrite make sure to read the migration overview
and things to keep in mind sections above.
diff --git a/app/views/docs/migration-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
similarity index 97%
rename from app/views/docs/migration-local-to-cloud.phtml
rename to app/views/docs/migrations-local-to-cloud.phtml
index e30783d4b..3e19aef74 100644
--- a/app/views/docs/migration-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -13,7 +13,7 @@
Migrating to Self-hosted from Cloud
- To begin migrating to self-hosted, make sure to read the migration overview
+ To begin migrating to self-hosted, make sure to read the migration overview
and things to keep in mind sections above.
diff --git a/app/views/docs/migration-nhost.phtml b/app/views/docs/migrations-nhost.phtml
similarity index 56%
rename from app/views/docs/migration-nhost.phtml
rename to app/views/docs/migrations-nhost.phtml
index a556de4a0..0d625eb67 100644
--- a/app/views/docs/migration-nhost.phtml
+++ b/app/views/docs/migrations-nhost.phtml
@@ -8,7 +8,7 @@
Things to keep in mind
- - Appwrite will not charge usage during migrations, but NHost may still incur service charges.
+ - Appwrite will not incur usage charges during migrations, but NHost may still incur service charges.
- Appwrite's Database doesn't support all the features of the postgreSQL database so more advanced postgres centric things things like advanced indexes, postgres functions and scheduling will not be migrated.
- OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
@@ -39,7 +39,7 @@
Migrating to Appwrite from NHost
- To begin migrating to Appwrite make sure to read the migration overview
+ To begin migrating to Appwrite make sure to read the migration overview
and things to keep in mind sections above.
@@ -59,28 +59,26 @@
NHost Credentials
+
+Enter all the following credentials from your NHost project.
+
- -
- Enter all the following credentials from your NHost project.
-
- -
- Region - The region your NHost project is hosted in. This can be found in your NHost project environment variables as NHOST_REGION.
-
- -
- Subdomain - The subdomain of your NHost project. This can be found in your NHost project environment variables as NHOST_SUBDOMAIN.
-
- -
- Database - The name of your NHost database. This can be found in your NHost project Database settings.
-
- -
- Username - The username of your NHost database. This can be found in your NHost project Database settings.
-
- -
- Password - The password of your NHost database. You set this when you created your NHost project, if you don't remember it you can reset it from your NHost project Database settings.
-
- -
- Admin Secret - The admin secret of your NHost project. This can be found in your NHost project environment variables as NHOST_ADMIN_SECRET. We use this to transfer your NHost Files to Appwrite.
-
-
-
+ -
+ Region - The region your NHost project is hosted in. This can be found in your NHost project environment variables as NHOST_REGION.
+
+ -
+ Subdomain - The subdomain of your NHost project. This can be found in your NHost project environment variables as NHOST_SUBDOMAIN.
+
+ -
+ Database - The name of your NHost database. This can be found in your NHost project Database settings.
+
+ -
+ Username - The username of your NHost database. This can be found in your NHost project Database settings.
+
+ -
+ Password - The password of your NHost database. You set this when you created your NHost project, if you don't remember it you can reset it from your NHost project Database settings.
+
+ -
+ Admin Secret - The admin secret of your NHost project. This can be found in your NHost project environment variables as NHOST_ADMIN_SECRET. We use this to transfer your NHost files to Appwrite.
+
\ No newline at end of file
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
new file mode 100644
index 000000000..58036bc5e
--- /dev/null
+++ b/app/views/docs/migrations-supabase.phtml
@@ -0,0 +1,88 @@
+
+ Moving your project from Supabase to Appwrite?
+ Appwrite Migrations can help you streamline the process.
+
+ Here's what you need to know to get started.
+
+
+Things to keep in mind
+
+
+ - Appwrite will not incur usage charges during migrations, but Supabase may still incur service charges.
+ - Appwrite's Databases services supports a different set of features as PostgreSQL. Some features like advanced indexes, Postgres functions and scheduling will not be migrated.
+ - OAuth users will not be transferred. Users will need to re-authenticate with your OAuth provider after the migration is complete.
+
+
+Supported resource types
+
+
+
+
+ Users
+ Databases
+ Documents
+ Files
+ Functions
+
+
+
+
+ Supabase
+ ✅
+ ✅
+ ✅
+ ✅
+
+
+
+
+
+Migrating to Appwrite from Supabase
+
+ To begin migrating to Appwrite make sure to read the migration overview
+ and things to keep in mind sections above.
+
+
+
+ -
+ Create a new project and click on the Migrations tab.
+
+ -
+ Click on the Create Migration button and select Supabase as your source.
+
+ -
+ Enter the credentials following the instructions below and click Next.
+
+ -
+ Select the resources you want to migrate and finally click Start migration to begin the migration process.
+
+
+
+Credentials
+
+Enter all the following credentials from your Supabase project.
+
+
+
+ -
+ Region - The region your Supabase project is hosted in. This can be found in your Supabase project environment variables as Supabase_REGION.
+
+ -
+ Host - The host of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Host.
+
+ -
+ Port - The port of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Port. By default this is 5432.
+
+ -
+ Username - The username of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Username.
+
+ -
+ Password - The password of your Supabase Database, this was set when you created your Supabase project. If you forgot your password, you can reset it within Database Settings.
+
+ -
+ Endpoint - This is the endpoint of your Supabase instance under Project Settings > API. This is used to migrate your files.
+
+ -
+ API Key - This is the key of your Supabase instance under Project Settings > API. This is used to migrate your files. Make sure to use the hidden service_role key.
+
+
diff --git a/app/views/docs/migration.phtml b/app/views/docs/migrations.phtml
similarity index 52%
rename from app/views/docs/migration.phtml
rename to app/views/docs/migrations.phtml
index 336689026..d15752efa 100644
--- a/app/views/docs/migration.phtml
+++ b/app/views/docs/migrations.phtml
@@ -1,6 +1,6 @@
- Moving your app from another platform to Appwrite?
- You can move your app from Firebase, Supabase, NHost, and even other Appwrite projects to another Appwrite project using Migrations.
+ Ready to migrate your project to Appwrite?
+ You can move your app from Firebase, Supabase, NHost, and even move between self-hosted and Cloud projects using Migrations.
Migrations will automatically move accounts, database documents, and storage files from one source to another.
@@ -26,7 +26,7 @@
Firebase
-
+
@@ -37,7 +37,7 @@
Supabase
-
+
@@ -48,7 +48,29 @@
NHost
-
+
+
+
+
+
+ [IMAGE]
+
+
+ Cloud to Self-host
+
+
+
+
+
+
+
+ [IMAGE]
+
+
+ Self-host to Cloud
+
+
+
From 1819b3288c0aff003288fe4d2800b3af035f3a5d Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 17:31:23 +0000
Subject: [PATCH 076/183] Fixed code tags in local to cloud page
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index 3e19aef74..5cfee4cb8 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -6,7 +6,7 @@
Things to keep in mind
- - Data transferred by migrations will reset `$createdAt` and `$updatedAt` timestamps to the date of the migration.
+ - Data transferred by migrations will reset
$createdAt and $updatedAt timestamps to the date of the migration.
- Your self-hosted Appwrite project must be accessible from the internet for the migration to work.
- Migrations are non-destructive. No data will be deleted or lost in the source project.
From 30bc686cae377cd6597f2cba8125e03bf9ae75ad Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 17:38:51 +0000
Subject: [PATCH 077/183] Fix titles in index
---
app/views/docs/index.phtml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 125f562c6..1d45bff57 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -99,8 +99,8 @@ $cols = [
- Firebase
- Supabase
- NHost
- - Cloud to Local
- - Local to Cloud
+ - Cloud to Self-hosted
+ - Self-hosted to Cloud
From 1b974feaec94c8022add7e7b7ca3b3b7fccc7fa5 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 17:42:20 +0000
Subject: [PATCH 078/183] Fix missing ul tag in index
---
app/views/docs/index.phtml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 1d45bff57..ecab000aa 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -101,6 +101,8 @@ $cols = [
- NHost
- Cloud to Self-hosted
- Self-hosted to Cloud
+ - Security
+
From b04e153eb7576ebb35aeb57b26d8e415c58067f3 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 15 Aug 2023 21:07:54 +0000
Subject: [PATCH 079/183] sell functions better in overview
---
app/views/docs/functions.phtml | 51 +++++++++++++---------------------
1 file changed, 20 insertions(+), 31 deletions(-)
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index a014e4511..971ac5fac 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -202,58 +202,47 @@ namespace runtime {
To fully harness the power of Appwrite Functions, explore the following features.
-Templates
+Familiar Concepts
- If you need to integrate Appwrite with a third-party API or add a function for common utilities,
- there might already be a function template made by the Appwrite community that fits your needs.
- Function templates are Appwrite Functions repositories that you can clone and add to your Appwrite instance.
+ Appwrite Functions follow common HTTP concepts you already know.
+ You can start building with minimal learning curve, without needing to learn niche concepts that don't apply elsewhere.
-
-Learn more about using function templates
-
-
-Develop
-
-Writing Appwrite Functions should feel familiar to writing controllers in an HTTP server.
-In your function, you'll receive a request object, add transformations and logic, then return a response.
-Almost anything can be executed as code in an Appwrite Function.
-
Learn more about developing functions
-Deploy
+Automated Deployment
- Appwrite Functions are designed to be maintainable and fit into a familiar development workflow.
- You can deploy them from a GitHub repository branch or using the Appwrite CLI.
+ Appwrite Functions can be deployed automatically from GitHub.
+ Integrate Appwrite Functions seemlessly into your existing development workflow, without needing annoying CI/CD configuration.
-Learn more about using deploying functions
+Learn more about deploying functions
-Execute
+Flexible Execution
-Appwrite Functions can be executed directly through a request to the API, or triggered by events, webhooks, or scheduled executions.
-This flexible execution models unlocks many potential usecases for Appwrite functions.
-Explore using Appwrite Functions to execute a complex routine of logic, or execute background tasks on a schedule.
+ Appwrite Functions can be executed through HTTP requests, async or synchronous SDK calls, webhooks, event or scheduled triggers, and even serve webpages to browsers.
+ Integrate Appwrite with infinite possibilities through a simple function.
-Learn more about using executing functions
+Learn more about executing functions
-Runtime
+All Your Favorite Runtimes
-Appwrite supports many open-source runtimes. Find your prefered language and start writing your functions.
+ Appwrite supports a growing list of 10+ runtimes.
+ Keep your codebase simple by writing functions in a language you already work with.
-Learn more about using runtimes
+Learn more about using function runtimes
-Debug
+Start with a Template
-Let's be honest, we spend more time debugging our code than writing our code.
-So it's important to be able to log, debug, and test your Appwrite Functions in development and production.
+ Appwrite Functions has many built in templates that help you jumpstart your creativity.
+ Add integrations by using templates out of the box, or clone the template to customize and fit your needs.
-Learn more about debugging functions
-
+Learn more about using function templates
+
\ No newline at end of file
From f088a1e8114b0562ef5cbea23d82a899bd0ddf5a Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 03:09:04 +0000
Subject: [PATCH 080/183] Add headers + env vars
---
app/views/docs/functions-develop.phtml | 109 ++++++++++++++++++++++++-
app/views/docs/functions.phtml | 1 -
2 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 42771b3ae..0fde8fa78 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -353,6 +353,67 @@ public class Main {
+Headers
+
+ Appwrite Functions will always receive a set of headers that provide meta data about the function execution.
+ These are provided along side any custom headers sent to the function.
+
+
+
+
+
+ Variable
+ Description
+
+
+
+
+ x-appwrite-trigger
+
+ Describes how the function execution was invoked.
+
+
+
+ x-appwrite-event
+
+ If the function execution was triggered by an event, describes the triggering event.
+
+
+
+ x-appwrite-user-id
+
+ If the function execution was invoked by an authenticated user, display the user ID.
+ This doesn't apply to Appwrite Console users or API keys.
+
+
+
+ x-appwrite-user-jwt
+
+ [TODO: @meldiron whats this]
+
+
+
+ x-appwrite-country-code
+
+ Displays the country code of the configured locale.
+
+
+
+ x-appwrite-continent-code
+
+ Displays the continent code of the configured locale.
+
+
+
+ x-appwrite-continent-eu
+
+ Describes if the configured local is within the EU.
+
+
+
+
+
+
Response
If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
@@ -941,7 +1002,19 @@ namespace runtime {
Default Environment Variables
-Appwrite Runtimes have some default environment variables. These are always accesible
+
+ Appwrite runtimes passes in some environment variables by default.
+ These are always accesible for every function at runtime.
+
+
+
+ Appwrite API keys
+
+ If your function is using an Appwrite SDK with an API key, this API key needs to be generated and passed in manually.
+ API keys are not passed by default for security reasons.
+
+
+
@@ -951,13 +1024,43 @@ namespace runtime {
-
+ APPWRITE_FUNCTION_ID
+
+ The ID of the running function.
+
+
+
+ APPWRITE_FUNCTION_NAME
+
+ The Name of the running function.
+
+
+
+ APPWRITE_FUNCTION_DEPLOYMENT
+
+ The deployment ID of the running function.
+
+
+
+ APPWRITE_FUNCTION_PROJECT_ID
+
+ The project ID of the running function.
+
+
+
+ APPWRITE_FUNCTION_RUNTIME_NAME
+
+ The runtime of the running function.
+
+
+
+ APPWRITE_FUNCTION_RUNTIME_VERSION
+ The runtime version of the running function.
-
Local Environment Variables
Local variables will only be accessible in the function they belong to.
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 971ac5fac..970befc03 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -193,7 +193,6 @@ namespace runtime {
-[TODO: explore features should be like: Familiar HTTP concepts, many ways to execute, deploy from Git or xxx, built in templates, etc.]
Explore Features
From ff3c2b495d35ca89fc2677c9af189421c50897f4 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 17:29:28 +0000
Subject: [PATCH 081/183] Fix web example format, add quickstart to auth
---
app/views/docs/authentication-anonymous.phtml | 8 +-
.../docs/authentication-email-pass.phtml | 36 +-----
app/views/docs/authentication-magic.phtml | 16 +--
.../docs/authentication-management.phtml | 16 +--
app/views/docs/authentication-server.phtml | 8 +-
app/views/docs/authentication-sms.phtml | 18 +--
app/views/docs/authentication.phtml | 105 +++++++++++++++++-
7 files changed, 118 insertions(+), 89 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index f0c9b236f..8c6f53929 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -26,13 +26,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createAnonymousSession();
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.createAnonymousSession();
-
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 8e8b5dd39..9ad52be88 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -22,17 +22,11 @@ const client = new Client()
const account = new Account(client);
-const promise = account.create(
+const user = await account.create(
ID.unique(),
'email@example.com',
'password'
-);
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+);
-
@@ -181,16 +175,10 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createEmailSession(
+const user = await account.createEmailSession(
'email@example.com',
'password'
-);
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+);
-
@@ -278,13 +266,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createPasswordRecovery('email@example.com', 'https://example.com');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.createPasswordRecovery('email@example.com', 'https://example.com');
-
@@ -371,13 +353,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
-
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index d863b7611..f06095ab5 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -23,13 +23,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createMagicURLSession('email@example.com', 'email@example.com');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.createMagicURLSession('email@example.com', 'email@example.com');
-
@@ -120,13 +114,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.updateMagicURLSession('email@example.com', '[SECRET]');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.updateMagicURLSession('email@example.com', '[SECRET]');
-
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index 8f636fcfc..f0c89799e 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -24,13 +24,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.updatePrefs({darkTheme: true, language: 'en'});
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.updatePrefs({darkTheme: true, language: 'en'});
-
@@ -123,13 +117,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.getPrefs();
-
-promise.then(function (prefs) {
- console.log(prefs);
-}, function (error) {
- console.log(error);
-});
+const user = await account.getPrefs();
-
diff --git a/app/views/docs/authentication-server.phtml b/app/views/docs/authentication-server.phtml
index 186b5eb5b..0313c8a11 100644
--- a/app/views/docs/authentication-server.phtml
+++ b/app/views/docs/authentication-server.phtml
@@ -30,13 +30,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createJWT();
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+const user = await account.createJWT();
-
diff --git a/app/views/docs/authentication-sms.phtml b/app/views/docs/authentication-sms.phtml
index 49c7c6483..2660ccc4f 100644
--- a/app/views/docs/authentication-sms.phtml
+++ b/app/views/docs/authentication-sms.phtml
@@ -30,17 +30,11 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createPhoneSession(
+const user = await account.createPhoneSession(
ID.unique(),
'+14255550123'
);
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
@@ -128,16 +122,10 @@ const client = new Client()
const account = new Account(client);
-const promise = account.updatePhoneSession(
+const user = await account.updatePhoneSession(
'[USER_ID]',
'[SECRET]'
-);
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
+);
-
diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml
index 7f8755d59..62fcdce3e 100644
--- a/app/views/docs/authentication.phtml
+++ b/app/views/docs/authentication.phtml
@@ -1,8 +1,109 @@
Appwrite Authentication delivers more than just user sign up and log in.
- Authentication makes it easy to build secure and robust authentication with support for many differnt authentication methods.
+ Authentication makes it easy to build secure and robust authentication with support for many different authentication methods.
+
+
+
You can manage user accounts with user preferences, user labeling, or organizing users into teams.
- Combined with a robust permissions system, Appwrite Authentication provides everything you need to authenticate and manager users.
+ Combined with a robust permissions system, Appwrite Authentication provides everything you need to authenticate and manage users.
+
+
+Getting Started
+
+ Adding Appwrite Authentication to your apps can be as easy as these lines of code.
+
+
+
+ -
+
Web
+
+ import { Client, Account, ID } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const user = await account.create(
+ ID.unique(),
+ 'email@example.com',
+ 'password'
+);
+
+
+ -
+
Flutter
+
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final user = await account.create(
+ userId: ID.unique(),
+ email: 'email@example.com',
+ password: 'password',
+);
+
+ -
+
Android
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+import io.appwrite.ID
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val user = account.create(
+ userId = ID.unique(),
+ email = "email@example.com",
+ password = "password"
+)
+
+
+ -
+
Apple
+
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+let account = Account(client)
+
+let user = try await account.create(
+ userId: ID.unique(),
+ email: "email@example.com",
+ password: "password"
+)
+
+
+ -
+
GraphQL
+
+
+mutation {
+ accountCreate(userId: "unique()", email: "email@example.com", password: "password") {
+ _id
+ email
+ name
+ }
+}
+
+
+
+
+
+ Use email and password authentication as a starting point and explore the many powerful features of Appwrite authentication.
Account vs Users API
From 21431cc4c3d045fa560f2a07e70d3e6b92e29a13 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 19:30:43 +0000
Subject: [PATCH 082/183] Fix auth index, add users api docs
---
.../docs/authentication-management.phtml | 21 ++++++++++++++++++-
app/views/docs/authentication.phtml | 6 ++++++
app/views/docs/index.phtml | 6 ++++++
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index f0c89799e..269233007 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -9,7 +9,7 @@
[TODO @steven: Labels docs]
-User Preferences
+User Preferences
You can store user preferences on a user's account using Appwrite's Update Preferences endpoint. You can store user preferences such as theme, notification settings, or preferred language so they can be synced across multiple devices.
Preferences are stored as a key-value JSON object. The maximum allowed prefs size is 64kB and throws an error if exceeded.
@@ -171,3 +171,22 @@ let prefs = try await account.getPrefs()
+
+Users API
+
+ The Users API is a dedicated API for managing users from an admin's perspective.
+ You'll notice that the Account API doesn't allow you to view or make changes to other users.
+ This is by design and for security reasons.
+
+
+
+ You can use the Users API with an API key authenticated Server SDK to manage users.
+ If you must expose parts of the Users API to normal users, we suggest doing so through an Appwrite Function.
+ Exposing API keys to users is dangerous and a security risk, by using an Appwrite Function, you can add your own validation to prevent malicious behavior.
+
+
+
+
+ Learn more about the Users API
+
+
\ No newline at end of file
diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml
index 62fcdce3e..c2691e24b 100644
--- a/app/views/docs/authentication.phtml
+++ b/app/views/docs/authentication.phtml
@@ -161,6 +161,12 @@ mutation {
+
+
+ Manage users
+
+
+
Server integrations
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 3554cba88..4643d1aca 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -88,6 +88,12 @@ $cols = [
-
Authentication
+ - Server Authentication
+ - Server Authentication
+ - Server Authentication
+ - Server Authentication
+ - Server Authentication
+ - Server Authentication
- Server Authentication
- Security
From 672a6df5bce31bcbba0040384f8103eb0bd0ecc0 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 19:34:06 +0000
Subject: [PATCH 083/183] Fix auth index display names
---
app/views/docs/index.phtml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 4643d1aca..48a97c0ff 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -88,13 +88,13 @@ $cols = [
-
Authentication
From 8050091707bd0cc36a250c1264e7f1164b29e23b Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 19:41:57 +0000
Subject: [PATCH 084/183] Maybe it should be user management vs just management
---
app/views/docs/index.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 48a97c0ff..e4f21b661 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -93,7 +93,7 @@ $cols = [
- Magic URL
- OAuth 2
- Anonymous
- - Management
+ - User Management
- Server Integrations
- Security
From e2f493ec3fde149be307a97249b10fd007a6af54 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 19:59:12 +0000
Subject: [PATCH 085/183] grammar check by GPT
---
app/views/docs/authentication-anonymous.phtml | 4 ++--
app/views/docs/authentication-email-pass.phtml | 2 +-
app/views/docs/authentication-management.phtml | 2 +-
app/views/docs/authentication-security.phtml | 6 +++---
app/views/docs/authentication-server.phtml | 4 ++--
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index 8c6f53929..9848c8097 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -92,7 +92,7 @@ mutation {
Anonymous users cannot sign back in.
If they close their browser, or go to another computer, they won't be able to log in again.
- Remeber to prompt the user to create an account to no lose their data.
+ Remeber to prompt the user to create an account to not lose their data.
@@ -104,7 +104,7 @@ mutation {
Email and password
-
- Phone
+ Phone (SMS)
-
Magic URL
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 9ad52be88..4cbb7d731 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -433,5 +433,5 @@ let token = try await account.updateRecovery(
Security
-[TODO: @steven Talk about the password security features like password dictionary, passowrd history, and prevent personal information.]
+[TODO: @steven Talk about the password security features like password dictionary, password history, and prevent personal information.]
[Be brief, link to security page for details]
\ No newline at end of file
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index 269233007..d140e01fd 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -1,5 +1,5 @@
- Appwrite has build in features to help manage user accounts.
+ Appwrite has built-in features to help manage user accounts.
Users can be organized into teams and be given labels, so they can be given different permissions and access different resources.
Each user can also have their own preference object, which you can use to save preferences such as theme, language, and notification settings.
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 8e98a7b90..153581615 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -10,7 +10,7 @@
Best Practice
- Only keep user sessions active as long as needed and only maintain one instance of the Client SDK in your app to avoid conflicting session data.
+ Only keep user sessions active as long as needed and maintain exactly one instance of the Client SDK in your app to avoid conflicting session data.
@@ -74,7 +74,7 @@
Session Limits
-In Appwrite versions 1.2 and above, you can limit the number of active sessions created per user to prevent the accumulation of unused but active sessions. New sessions created by the same user past the session limit deletes the oldest session.
+In Appwrite versions 1.2 and above, you can limit the number of active sessions created per user to prevent the accumulation of unused but active sessions. New sessions created by the same user past the session limit delete the oldest session.
You can change the session limit in the Security tab of the Auth Service in your Appwrite Console. The default session limit is 10 with a maximum configurable limit of 100.
@@ -85,7 +85,7 @@
Password History
-Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password everytime it's changed.
+Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password every time it's changed.
Password history can be enabled in the Auth service's Security tab on the Appwrite console. You can choose how many previous passwords to remember up to a maximum of 20 and block users from reusing them.
diff --git a/app/views/docs/authentication-server.phtml b/app/views/docs/authentication-server.phtml
index 0313c8a11..7e54f1d2e 100644
--- a/app/views/docs/authentication-server.phtml
+++ b/app/views/docs/authentication-server.phtml
@@ -12,7 +12,7 @@
When you build backend APIs to extend Appwrite's functionality, these APIs should still respect access permissions to keep user data secure. Appwrite's backend SDKs allows you to securely act on behalf of a user with the same permissions by using JWT authentication.
JWT Authentication
-JSON Web Tokens (JWTs) are a secure means to transfer information or claims between two parties. JWT act like temporary copies of the user's ID card that allow Appwrite's Server SDKs to access information oh behalf of a user.
+JSON Web Tokens (JWTs) are a secure means to transfer information or claims between two parties. JWTs act like temporary copies of the user's ID card that allow Appwrite's Server SDKs to access information on behalf of a user.
You need to create a session using the Client SDKs before generating a JWT. The JWT will be a stateless proof of claim for the identity of the authenticated user and expire after 15 minutes or when the session is deleted.
@@ -441,7 +441,7 @@ var documentList = await databases.ListDocuments(
-Only the birthday of Kevin is returned and documents where user-A has no permissions to access are not returned.
+Only Kevin's birthday is returned and documents where user-A has no permissions to access are not returned.
{
"total": 1,
From f1a41d254d810ea2cc192971377ed0b3edc86279 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 20:33:20 +0000
Subject: [PATCH 086/183] Add info about personal information in auth docs
---
app/views/docs/authentication-security.phtml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 153581615..99fd79a21 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -95,5 +95,8 @@
Password dictionary can be enabled in the Auth service's Security tab on the Appwrite console.
Personal Information
-
-[TODO: @steven Talk about new personal information thing.]
\ No newline at end of file
+
+ Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal information.
+ Personal information includes the user's name, email, and phone number.
+
+Disallowing personal information can be enabled in the Auth service's Security tab on the Appwrite console.
From 61be417bb523fd7babbac1042a766f531174173f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 20:34:35 +0000
Subject: [PATCH 087/183] Add more information about password security in
Appwrite
---
app/views/docs/authentication-email-pass.phtml | 12 ++++++++++--
app/views/docs/authentication-oauth.phtml | 2 +-
app/views/docs/authentication-security.phtml | 7 +++++--
app/views/docs/authentication.phtml | 4 ++--
4 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 4cbb7d731..119dd9fa0 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -433,5 +433,13 @@ let token = try await account.updateRecovery(
Security
-[TODO: @steven Talk about the password security features like password dictionary, password history, and prevent personal information.]
-[Be brief, link to security page for details]
\ No newline at end of file
+
+ Appwrite does more than use secure implementation of email and password authentication on the server-side to ensure security.
+ You can enable features like password dictionary, password history, and disallow personal information to encourage users to pick better passwords.
+ By enabling these features, you protect user data and teach better password choices, which helps make the internet a safer place.
+
+
\ No newline at end of file
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 18f8b69d1..35a6a9305 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -105,7 +105,7 @@ try await account.createOAuth2Session(provider: "amazon")
OAuth 2 Profile
- [TODO: @steven fill the docs to access profile information]
+ [TODO: @steven fill the docs to access oauth account profile information]
Refresh Tokens
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 99fd79a21..776c320d8 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -78,10 +78,13 @@
You can change the session limit in the Security tab of the Auth Service in your Appwrite Console. The default session limit is 10 with a maximum configurable limit of 100.
-Security
+Permissions
- Security is very important to protect users' data and privacy. Appwrite uses a permissions model coupled with user sessions to ensure users need correct permissions to access resources. With all Appwrite services, including databases and storage, access is granted at the collection, bucket, document, or file level. These permissions are enforced for client SDKs and server SDKs when using JWT, but are ignored when using a server SDK with an API key.
+ Security is very important to protect users' data and privacy.
+ Appwrite uses a permissions model coupled with user sessions to ensure users need correct permissions to access resources.
+ With all Appwrite services, including databases and storage, access is granted at the collection, bucket, document, or file level.
+ These permissions are enforced for client SDKs and server SDKs when using JWT, but are ignored when using a server SDK with an API key.
Password History
diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml
index c2691e24b..917c20852 100644
--- a/app/views/docs/authentication.phtml
+++ b/app/views/docs/authentication.phtml
@@ -162,7 +162,7 @@ mutation {
@@ -174,7 +174,7 @@ mutation {
From 2cd56dd807e90646a67e3c60989085f407b4faec Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 22:34:44 +0000
Subject: [PATCH 088/183] Improve overview page for functions and rename
recipes to examples
---
app/views/docs/functions-develop.phtml | 10 +-
...recipes.phtml => functions-examples.phtml} | 0
app/views/docs/functions.phtml | 229 ++----------------
app/views/docs/index.phtml | 2 +-
4 files changed, 27 insertions(+), 214 deletions(-)
rename app/views/docs/{functions-recipes.phtml => functions-examples.phtml} (100%)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 0fde8fa78..84a562cc7 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -6,7 +6,7 @@
Just want the code?
- If you prefer to learn through examples, explore the recipes section.
+ If you prefer to learn through examples, explore the examples page.
Function Flow
@@ -2165,14 +2165,6 @@ public class Main {
-Recipes
-
- We have a dedicated page of recipes to implement common functionalities in Appwrite Functions, like parsing request path and params, or making requests to third party APIs.
-
-
-
-Explore examples and recipes
-
Upgrade
diff --git a/app/views/docs/functions-recipes.phtml b/app/views/docs/functions-examples.phtml
similarity index 100%
rename from app/views/docs/functions-recipes.phtml
rename to app/views/docs/functions-examples.phtml
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 970befc03..39b8c8a27 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -2,246 +2,67 @@
use Appwrite\Utopia\View;
-$events = $this->getParam('events', []);
-$runtimes = $this->getParam('runtimes', []);
-
?>
- Appwrite Functions let you extend Appwrite by adding your own code and logic.
- You can think of them as code snippets that are triggered by server events, webhooks, scheduled executions, or user invokation.
+ Appwrite Functions unlock limitless potential for developers to extend Appwrite with code snippets.
+ Appwrite Functions are user defined functions that can start small and scale big, deploying automatically from source control.
+ These Functions can be triggered by HTTP requests, SDK methods, server events, webhooks, scheduled executions.
Each function will have their own URL, execute in their own isolated container, and have their own configurable environment variables and permissions.
- With these features, Appwrite Functions unlock limitless potential to expand Appwrite's capabilities with custom logic and integrations.
Getting Started
- Appwrite Functions unlock limitless possibilities, but it's simple to get started. You can deploy your first function and execute it in minutes.
+ Appwrite Functions let you build anything you can imagine, but this flexibility makes is difficult to know where to start.
+ Start exploring by cloning one of the quick start templates or using a template with pre-built integration to quickly implement features.
-
- -
-
Node.js
-
-
- export default async ({ res }) => {
- return res.json({
- motto: 'Build Fast. Scale Big. All in One Place.'
- });
-};
-
-
-
- -
-
PHP
-
-
- return function ($context) {
- return $context->res->json([
- 'motto' => 'Build Fast. Scale Big. All in One Place.'
- ]);
-}
-
-
-
- -
-
Python
-
-
- def main(context):
- return context.res.json({
- "motto": "Build Fast. Scale Big. All in One Place.",
-})
-
-
-
- -
-
Ruby
-
-
- def main(context)
- return context.res.json(
- {
- "motto": "Build Fast. Scale Big. All in One Place."
- }
- )
-end
-
-
-
- -
-
Deno
-
-
- export default ({ req, res, log, error }: any) => {
- return res.json({
- motto: "Build Fast. Scale Big. All in One Place."
- });
-};
-
-
-
- -
-
Dart
-
-
- import 'dart:async';
-
-Future main(final context) async {
- return context.res.json({
- 'motto': 'Build Fast. Scale Big. All in One Place.',
- });
-}
-
-
-
- -
-
Swift
-
-
- import Foundation
-
- func main(context: RuntimeContext) async throws -> RuntimeOutput {
- return try context.res.json([
- "motto": "Build Fast. Scale Big. All in One Place."
- ])
-}
-
-
-
- -
-
.NET
-
-
- namespace DotNetRuntime;
-public class Handler {
- public async Task Main(RuntimeContext Context)
- {
- return Context.Res.Json(new Dictionary()
- {
- { "motto", "Build Fast. Scale Big. All in One Place." }
- });
- }
-}
-
-
-
- -
-
Kotlin
-
-
- package io.openruntimes.kotlin.src
-
-import io.openruntimes.kotlin.RuntimeContext
-import io.openruntimes.kotlin.RuntimeOutput
-
-class Main {
- fun main(context: RuntimeContext): RuntimeOutput {
- return context.res.json(mutableMapOf(
- "motto" to "Build Fast. Scale Big. All in One Place.",
- "learn" to "https://appwrite.io/docs",
- "connect" to "https://appwrite.io/discord",
- "getInspired" to "https://builtwith.appwrite.io"
- ))
- }
-}
-
-
-
-
- -
-
Java
-
-
- package io.openruntimes.java.src;
-
-import io.openruntimes.java.RuntimeContext;
-import io.openruntimes.java.RuntimeOutput;
-import java.util.HashMap;
-
-public class Main {
- public RuntimeOutput main(RuntimeContext context) throws Exception {
- Map json = new HashMap<>();
- json.put("motto", "Build Fast. Scale Big. All in One Place.");
- return context.getRes().json(json);
- }
-}
-
-
-
- -
-
C++
-
-
- #include "../RuntimeResponse.h"
-#include "../RuntimeRequest.h"
-#include "../RuntimeOutput.h"
-#include "../RuntimeContext.h"
-
-namespace runtime {
- class Handler {
- public:
- static RuntimeOutput main(RuntimeContext &context) {
- Json::Value response;
- response["motto"] = "Build Fast. Scale Big. All in One Place.";
- return context.res.json(response);
- }
- };
-}
-
-
-
-
-
+setParam('srcLight', '/images-ee/docs/functions-starter-light.png')
+ ->setParam('srcDark', '/images-ee/docs/functions-starter-dark.png')
+ ->setParam('alt', 'Function settings page.')
+ ->setParam('description', 'Function settings page.')
+ ->render();
+?>
Explore Features
- Appwrite Functions help you start small and scale big.
- Now you've created your first Appwrite Function, it's time to learn the different ways to develop, deploy, and execute your Appwrite Functions.
- To fully harness the power of Appwrite Functions, explore the following features.
-
-
-Familiar Concepts
-
- Appwrite Functions follow common HTTP concepts you already know.
- You can start building with minimal learning curve, without needing to learn niche concepts that don't apply elsewhere.
+ Appwrite Functions use familiar HTTP concepts, so you can learn quickly and grain transferable skills.
-
Learn more about developing functions
-Automated Deployment
- Appwrite Functions can be deployed automatically from GitHub.
- Integrate Appwrite Functions seemlessly into your existing development workflow, without needing annoying CI/CD configuration.
+ Appwrite Functions can be deployed automatically from Git, through the Appwrite CLI, or be uploaded manually.
+ Develop and deploy with the workflow you're already comfortable with.
Learn more about deploying functions
-Flexible Execution
- Appwrite Functions can be executed through HTTP requests, async or synchronous SDK calls, webhooks, event or scheduled triggers, and even serve webpages to browsers.
- Integrate Appwrite with infinite possibilities through a simple function.
+ Appwrite Functions can be triggered by HTTP requests, SDK methods, server events, webhooks, scheduled executions.
+ Explore how Appwrite Functions can be invoked.
Learn more about executing functions
-All Your Favorite Runtimes
- Appwrite supports a growing list of 10+ runtimes.
- Keep your codebase simple by writing functions in a language you already work with.
+ Appwrite supports a growing list of 10+ runtimes.
+ Avoid adding additional complexity to your codebase by coding in languages you already use and love.
Learn more about using function runtimes
-Start with a Template
+
- Appwrite Functions has many built in templates that help you jumpstart your creativity.
- Add integrations by using templates out of the box, or clone the template to customize and fit your needs.
+ Like to learn from examples?
+ Here's a curated list of examples that showcase Appwrite Function's capabilies.
-Learn more about using function templates
+Learn more about using function examples
\ No newline at end of file
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index d82d95a21..f4cc3e7be 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -100,7 +100,7 @@ $cols = [
- Deploy
- Execute
- Runtimes
- - Recipes
+ - Examples
From e7b9b1cf6d48a301181da7e8e7257efff7336b48 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 17 Aug 2023 23:03:49 +0000
Subject: [PATCH 089/183] Fix style in index and add alt text to functions
---
app/views/docs/functions.phtml | 4 ++--
app/views/docs/index.phtml | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 39b8c8a27..0dc52264d 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -22,8 +22,8 @@ $image = new View(__DIR__.'/../general/image.phtml');
echo $image
->setParam('srcLight', '/images-ee/docs/functions-starter-light.png')
->setParam('srcDark', '/images-ee/docs/functions-starter-dark.png')
- ->setParam('alt', 'Function settings page.')
- ->setParam('description', 'Function settings page.')
+ ->setParam('alt', '"Create Function" page.')
+ ->setParam('description', '"Create Function" page.')
->render();
?>
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index f4cc3e7be..b1e885dbe 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -94,7 +94,6 @@ $cols = [
-
Functions
-
- Develop
- Deploy
From 12ebf382ac9054e78bb1f2214f08623f8a862f90 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 18 Aug 2023 13:40:40 +0000
Subject: [PATCH 090/183] Remove Health API temporarily from nav
---
app/views/docs/index.phtml | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 3554cba88..6d51b1dc3 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -68,7 +68,6 @@ $cols = [
- Functions
- Localization
- Avatars
- - Health
From e58af232b8febdaac87b57a52d864294149ba093 Mon Sep 17 00:00:00 2001
From: Bradley Schofield
Date: Fri, 18 Aug 2023 15:40:40 +0100
Subject: [PATCH 091/183] Improve Examples
---
.../docs/authentication-email-pass.phtml | 27 ++++++++++-
app/views/docs/authentication-magic.phtml | 8 ++--
app/views/docs/authentication-sms.phtml | 45 ++++++++++---------
3 files changed, 56 insertions(+), 24 deletions(-)
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 119dd9fa0..1f8b44012 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -154,7 +154,32 @@ mutation {
In this example, the code below will be found in the page served at https://example.com/verify.
-[TODO: @bradley examples to parse query params from page and complete verification]
+
+ -
+
Web
+
+ import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const urlParams = new URLSearchParams(window.location.search);
+const secret = urlParams.get('secret');
+const userId = urlParams.get('userId');
+
+const promise = account.updateVerification(userId, secret);
+
+promise.then(function (response) {
+ console.log(response);
+}, function (error) {
+ console.log(error);
+});
+
+
+
Log In
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index f06095ab5..29fc0fda9 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -100,8 +100,6 @@ let user = try await account.createMagicURLSession(
After receiving your secret from an email, you can create a session.
-[TODO: @bradley, please update the examples below with how to get the secret from the magic URL]
-
-
Web
@@ -114,7 +112,11 @@ const client = new Client()
const account = new Account(client);
-const user = await account.updateMagicURLSession('email@example.com', '[SECRET]');
+const urlParams = new URLSearchParams(window.location.search);
+const secret = urlParams.get('secret');
+const userId = urlParams.get('userId');
+
+const user = await account.updateMagicURLSession(userId, secret);
-
diff --git a/app/views/docs/authentication-sms.phtml b/app/views/docs/authentication-sms.phtml
index 2660ccc4f..54aea908e 100644
--- a/app/views/docs/authentication-sms.phtml
+++ b/app/views/docs/authentication-sms.phtml
@@ -16,8 +16,6 @@
A new account will be created for this phone number if it has never been used before.
-[TODO: @bradley update these examples to show where the userID comes from (continuity from first request to next)]
-
-
Web
@@ -30,12 +28,12 @@ const client = new Client()
const account = new Account(client);
-const user = await account.createPhoneSession(
+const sessionToken = await account.createPhoneSession(
ID.unique(),
'+14255550123'
);
-
+var userId = sessionToken.userId // Store this somewhere to use later when logging in
-
@@ -49,10 +47,12 @@ final client = Client()
final account = Account(client);
-final session = await account.createPhoneSession(
+final sessionToken = await account.createPhoneSession(
userId: ID.unique(),
phone: '+14255550123'
-);
+);
+
+final userId = sessionToken.userId // Store this somewhere to use later when logging in
-
Android
@@ -67,10 +67,12 @@ val client = Client()
val account = Account(client)
-val session = account.createPhoneSession(
+val sessionToken = account.createPhoneSession(
userId = ID.unique(),
phone = "+14255550123"
-)
+)
+
+val userId = sessionToken.userId // Store this somewhere to use later when logging in
-
Apple
@@ -83,10 +85,12 @@ let client = Client()
let account = Account(client)
-let session = try await account.createPhoneSession(
+let sessionToken = try await account.createPhoneSession(
userId: ID.unique(),
phone: "+14255550123"
-)
+)
+
+let userId = sessionToken.userId // Store this somewhere to use later when logging in
-
GraphQL
@@ -122,10 +126,11 @@ const client = new Client()
const account = new Account(client);
-const user = await account.updatePhoneSession(
- '[USER_ID]',
- '[SECRET]'
-);
+const session = await account.updatePhoneSession(
+ userId, // From when you called createPhoneSession
+ '[SECRET]' // The 6-digit code from the SMS message
+);
+
-
@@ -140,8 +145,8 @@ final client = Client()
final account = Account(client);
final session = await account.updatePhoneSession(
- userId: '[USER_ID]',
- secret: '[SECRET]'
+ userId: userId, // From when you called createPhoneSession
+ secret: '[SECRET]' // The 6-digit code from the SMS message
);
-
@@ -158,8 +163,8 @@ val client = Client()
val account = Account(client)
val session = account.updatePhoneSession(
- userId = "[USER_ID]",
- secret = "[SECRET]"
+ userId = userId, // From when you called createPhoneSession
+ secret = "[SECRET]" // The 6-digit code from the SMS message
)
-
@@ -174,8 +179,8 @@ let client = Client()
let account = Account(client)
let session = try await account.updatePhoneSession(
- userId: "[USER_ID]",
- secret: "[SECRET]"
+ userId: userId, // From when you called createPhoneSession
+ secret: "[SECRET]" // The 6-digit code from the SMS message
)
-
From 780b5e408ce5b03df62ed4a474583b286d91a104 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 18 Aug 2023 15:53:48 +0000
Subject: [PATCH 092/183] Talk about JWT and trigger headers
---
app/views/docs/functions-develop.phtml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 84a562cc7..c3174a8c1 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -370,7 +370,8 @@ public class Main {
x-appwrite-trigger
- Describes how the function execution was invoked.
+ Describes how the function execution was invoked.
+ Possible values are http, schedule or event.
@@ -389,7 +390,8 @@ public class Main {
x-appwrite-user-jwt
- [TODO: @meldiron whats this]
+ JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
+ Learn more about JWT tokens.
From 9921120e973274909378003eeb465be62088de6d Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 18 Aug 2023 16:44:03 +0000
Subject: [PATCH 093/183] user management docs
---
.../docs/authentication-management.phtml | 209 +++++++++++++++++-
1 file changed, 204 insertions(+), 5 deletions(-)
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index d140e01fd..83d284fc5 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -4,10 +4,6 @@
Each user can also have their own preference object, which you can use to save preferences such as theme, language, and notification settings.
-[TODO @steven: TEAMS docs]
-
-[TODO @steven: Labels docs]
-
User Preferences
You can store user preferences on a user's account using Appwrite's Update Preferences endpoint. You can store user preferences such as theme, notification settings, or preferred language so they can be synced across multiple devices.
@@ -189,4 +185,207 @@ let prefs = try await account.getPrefs()
Learn more about the Users API
-
\ No newline at end of file
+
+
+Labels
+
+ Labels are a good way to flag a user to grant them access to resources.
+ For example, a subscriber label can be added to a user once they've purchased a subscription.
+
+
+
+ -
+
Node.js
+
+ const sdk = require('node-appwrite');
+
+const client = new sdk.Client();
+
+const users = new sdk.Users(client);
+
+let res = await users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+
+
+ -
+
PHP
+
+
+ use Appwrite\Client;
+use Appwrite\Services\Users;
+use Appwrite\Role;
+
+$client = new Client();
+
+$client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+;
+
+$users = new Users($client);
+
+$result = $users->updateLabels(
+ '[USER_ID]',
+ [
+ Role.label('subscriber'),
+ ]
+);
+
+
+ -
+
Python
+
+ from appwrite.client import Client
+from appwrite.services.users import Users
+from appwrite.role import Role
+
+client = Client()
+
+(client
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('5df5acd0d48c2') # Your project ID
+ .set_key('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+)
+
+users = Users(client)
+
+result = users.update_labels('[USER_ID]', [ Role.label('subscriber') ])
+
+
+ -
+
Ruby
+
+ require 'Appwrite'
+
+include Appwrite
+
+client = Client.new
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('5df5acd0d48c2') # Your project ID
+ .set_key('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+
+users = Users.new(client)
+
+response = users.update_labels(user_id: '[USER_ID]', labels: [ Role.label('subscriber') ])
+
+puts response.inspect
+
+
+ -
+
Deno
+
+ import * as sdk from "https://deno.land/x/appwrite/mod.ts";
+
+// Init SDK
+let client = new sdk.Client();
+
+let users = new sdk.Users(client);
+
+client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+;
+
+
+let res = await users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+
+
+ -
+
Dart
+
+ import 'package:dart_appwrite/dart_appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Users users = Users(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+ ;
+
+ Future result = users.updateLabels(
+ userId: '[USER_ID]',
+ labels: [ Role.label('subscriber') ],
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+
+
+ -
+
Kotlin
+
+ import io.appwrite.Client
+import io.appwrite.services.Users
+import io.appwrite.Role
+
+suspend fun main() {
+ val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
+
+ val users = Users(client)
+ val response = users.updateLabels(
+ userId = "[USER_ID]",
+ labels = [ Role.label('subscriber') ]
+ )
+ val json = response.body?.string()
+}
+
+
+ -
+
Swift
+
+ import Appwrite
+
+func main() async throws {
+ let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
+ let users = Users(client)
+ let response = try await users.updateLabels(
+ userId: "[USER_ID]",
+ labels: [ Role.label('subscriber') ]
+ )
+
+ print(String(describing: response)
+}
+
+
+ -
+
.NET
+
+
+
+
+
+
+
+ This would correspond with the permissions Permissions.read(Role.label('subscriber')), Permissions.update(Role.label('subscriber')), Permissions.delete(Role.label('subscriber')), and Permissions.create(Role.label('subscriber')).
+
+
+
+
+
- Learn more about permissions
+
+
+Teams
+
+ Teams are a good way to allow users to share access to resources.
+
+
+
+ For example, in a todo app, a user can create a team for one of their todo lists and invite another user to the team to grant the other user access.
+ The invited user can accept the invitation to gain access.
+ If the user's ever removed from the team, they'll lose access again.
+
From 36a5b6b548062f44f24638d04fb269ff04017d06 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 18 Aug 2023 18:32:45 +0000
Subject: [PATCH 094/183] OAuth docs additions with steven's comments
---
app/views/docs/authentication-oauth.phtml | 120 +++++++++++++++++++++-
1 file changed, 119 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 35a6a9305..c75c2f9e8 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -105,7 +105,125 @@ try await account.createOAuth2Session(provider: "amazon")
OAuth 2 Profile
- [TODO: @steven fill the docs to access oauth account profile information]
+After authenticating a user through their OAuth2 provider, you can fetch their profile information such as their avatar image or name.
+To do this you can use the access token from the OAuth2 provider and make API calls to the provider.
+
+
+
+After creating an OAuth2 session, you can fetch the session to get information about the provider.
+
+
+
+-
+
Web
+
+ import { Client, Account } from "appwrite";
+
+const client = new Client();
+
+const account = new Account(client);
+
+const session = account.getSession('current');
+
+// Provider information
+console.log(session.provider);
+console.log(session.providerUid);
+console.log(session.provderAccessToken);
+
+
+ -
+
Flutter
+
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final session = await getSession(
+ sessionId : "[SESSION_ID]"
+);
+
+// Provider information
+print(session.provider);
+print(session.providerUid);
+print(session.provderAccessToken);
+
+ -
+
Android
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+val account = Account(client)
+
+val response = account.getSession(
+ sessionId = "[SESSION_ID]"
+)
+
+// Provider information
+print(session.provider);
+print(session.providerUid);
+print(session.provderAccessToken);
+
+ -
+
Apple
+
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+let account = Account(client)
+
+let session = try await account.getSession(
+ sessionId: "[SESSION_ID]"
+)
+
+// Provider information
+print(session.provider);
+print(session.providerUid);
+print(session.provderAccessToken);
+
+
+
+
+ An OAuth2 session will have the following attributes.
+
+
+
+
+
+ property
+ Description
+
+
+
+
+ provider
+ The OAuth2 Provider.
+
+
+ providerUid
+ User ID from the OAuth2 Provider.
+
+
+ provderAccessToken
+ Access token from the OAuth2 provider. Use this to make requests to the OAuth2 provider to fetch personal information.
+
+
+
+
+
+ You can use the provderAccessToken to make requests to your OAuth2 provider.
+ Refer to the docs for the OAuth2 provider you're using to learn about making API calls with the access token.
Refresh Tokens
From a5b28d62648897542700a4abcec362d854c9f17f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 18 Aug 2023 20:17:28 +0000
Subject: [PATCH 095/183] ChatGPT grammar check
---
app/views/docs/authentication-anonymous.phtml | 31 ++--
.../docs/authentication-email-pass.phtml | 4 +-
app/views/docs/authentication-magic.phtml | 20 ++-
.../docs/authentication-management.phtml | 12 +-
app/views/docs/authentication-oauth.phtml | 42 ++---
app/views/docs/authentication-server.phtml | 146 +++++++++---------
app/views/docs/authentication-sms.phtml | 6 +-
app/views/docs/authentication.phtml | 4 +-
8 files changed, 137 insertions(+), 128 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index 9848c8097..e9a73943a 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -5,7 +5,7 @@
- If a user later creates an account, their information will be inhereted by the newly created account.
+ If a user later creates an account, their information will be inherited by the newly created account.
Create Anonymous Session
@@ -92,24 +92,23 @@ mutation {
Anonymous users cannot sign back in.
If they close their browser, or go to another computer, they won't be able to log in again.
- Remeber to prompt the user to create an account to not lose their data.
+ Remember to prompt the user to create an account to not lose their data.
Create an account with any of these methods to transition from an anonymous session to a user account session.
-
- -
- Email and password
-
- -
- Phone (SMS)
-
- -
- Magic URL
-
- -
- OAuth2
-
-
\ No newline at end of file
+
+
+
+Phone (SMS)
+
+
+Magic URL
+
+
+OAuth2
+
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 1f8b44012..31a4b5580 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -363,7 +363,7 @@ let token = try await account.createRecovery(
-After receiving a email with the secret attached to the redirect link, submit a request to the Create Password Recovery (confirmation) endpoint to complete the recovery flow. The verification link sent to the user's email address is valid for 1 hour.
+After receiving an email with the secret attached to the redirect link, submit a request to the Create Password Recovery (confirmation) endpoint to complete the recovery flow. The verification link sent to the user's email address is valid for 1 hour.
@@ -459,7 +459,7 @@ let token = try await account.updateRecovery(
Security
- Appwrite does more than use secure implementation of email and password authentication on the server-side to ensure security.
+ Appwrite's security first mindset goes beyond a securely implementated of authentication API.
You can enable features like password dictionary, password history, and disallow personal information to encourage users to pick better passwords.
By enabling these features, you protect user data and teach better password choices, which helps make the internet a safer place.
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index 29fc0fda9..d5aeb16f4 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -1,14 +1,15 @@
Magic URL is a password-less way to authenticate users.
- When a user logs in, they will receive an email with a magic url that contains a secret used to log in the user.
+ When a user logs in, they will receive an email with a "magic" link that contains a secret used to log in the user.
+ The user can simply click the link to be logged in.
Send Email
Initialize the log in process with the Create Magic URL Session route.
- We recommend you use the user's email as their user ID instead of a random ID.
- This way, you will only need an email, and not an ID to log in the user.
+ If the email has never been used, a new user ID is generated, then the user will receive an email.
+ If the email is already attached to an account, the user ID is ignored and the user will receive a link in their email.
@@ -23,7 +24,10 @@ const client = new Client()
const account = new Account(client);
-const user = await account.createMagicURLSession('email@example.com', 'email@example.com');
+const user = await account.createMagicURLSession(
+ ID.unique(),
+ 'email@example.com'
+ );
-
@@ -33,12 +37,12 @@ const user = await account.createMagicURLSession('email@example.com', 'email@exa
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
final user = await account.createMagicURLSession(
- userId: 'email@example.com',
+ userId: ID.unique(),
email: 'email@example.com',
);
@@ -55,7 +59,7 @@ val client = Client(context)
val account = Account(client)
val user = account.createMagicURLSession(
- userId = 'email@example.com',
+ userId = ID.unique(),
email = "email@example.com"
)
@@ -71,7 +75,7 @@ let client = Client()
let account = Account(client)
let user = try await account.createMagicURLSession(
- userId: 'email@example.com',
+ userId: ID.unique(),
email: "email@example.com"
)
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index 83d284fc5..4e3514b27 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -6,8 +6,14 @@
User Preferences
-You can store user preferences on a user's account using Appwrite's Update Preferences endpoint. You can store user preferences such as theme, notification settings, or preferred language so they can be synced across multiple devices.
-Preferences are stored as a key-value JSON object. The maximum allowed prefs size is 64kB and throws an error if exceeded.
+
+ You can store user preferences on a user's account using Appwrite's Update Preferences endpoint.
+ You can store user preferences such as theme, notification settings, or preferred language so they can be synced across multiple devices.
+
+
+ Preferences are stored as a key-value JSON object.
+ The maximum allowed size for preferences is 64kB, and an error will be thrown if this limit is exceeded.
+
-
Web
@@ -376,7 +382,7 @@ func main() async throws {
-
- Learn more about permissions
+ Learn more about permissions
Teams
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index c75c2f9e8..dc99af316 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -6,26 +6,26 @@
When using OAuth to authenticate, the authentication request is initiated from the client application.
- The user is then redirected to an OAuth2 provider to complete the authentication step, and finally, the user is redirected back to the client application.
+ The user is then redirected to an OAuth 2 provider to complete the authentication step, and finally, the user is redirected back to the client application.
-Configure OAuth2 Login
+Configure OAuth 2 Login
- Before using OAuth2 login, you need to enable and configure a OAuth2 login provider.
+ Before using OAuth 2 login, you need to enable and configure an OAuth 2 login provider.
- Navigate to your Appwrite project
- Navigate to Auth > Settings
- Find and open the OAuth provider.
- - In the OAuth2 settings modal, use the toggle to enable the provider
+ - In the OAuth 2 settings modal, use the toggle to enable the provider
-Initialize OAuth2 Login
+Initialize OAuth 2 Login
- To initialize the OAuth2 login process, use the Create OAuth2 Session route.
+ To initialize the OAuth 2 login process, use the Create OAuth 2 Session route.
@@ -105,12 +105,12 @@ try await account.createOAuth2Session(provider: "amazon")
OAuth 2 Profile
-After authenticating a user through their OAuth2 provider, you can fetch their profile information such as their avatar image or name.
-To do this you can use the access token from the OAuth2 provider and make API calls to the provider.
+After authenticating a user through their OAuth 2 provider, you can fetch their profile information such as their avatar image or name.
+To do this you can use the access token from the OAuth 2 provider and make API calls to the provider.
-After creating an OAuth2 session, you can fetch the session to get information about the provider.
+After creating an OAuth 2 session, you can fetch the session to get information about the provider.
@@ -128,7 +128,7 @@ const session = account.getSession('current');
// Provider information
console.log(session.provider);
console.log(session.providerUid);
-console.log(session.provderAccessToken);
+console.log(session.providerAccessToken);
-
@@ -149,7 +149,7 @@ final session = await getSession(
// Provider information
print(session.provider);
print(session.providerUid);
-print(session.provderAccessToken);
+print(session.providerAccessToken);
-
Android
@@ -170,7 +170,7 @@ val response = account.getSession(
// Provider information
print(session.provider);
print(session.providerUid);
-print(session.provderAccessToken);
+print(session.providerAccessToken);
-
Apple
@@ -190,12 +190,12 @@ let session = try await account.getSession(
// Provider information
print(session.provider);
print(session.providerUid);
-print(session.provderAccessToken);
+print(session.providerAccessToken);
- An OAuth2 session will have the following attributes.
+ An OAuth 2 session will have the following attributes.
@@ -212,24 +212,24 @@ print(session.provderAccessToken);
providerUid
- User ID from the OAuth2 Provider.
+ User ID from the OAuth 2 Provider.
- provderAccessToken
- Access token from the OAuth2 provider. Use this to make requests to the OAuth2 provider to fetch personal information.
+ providerAccessToken
+ Access token from the OAuth 2 provider. Use this to make requests to the OAuth 2 provider to fetch personal information.
- You can use the provderAccessToken to make requests to your OAuth2 provider.
- Refer to the docs for the OAuth2 provider you're using to learn about making API calls with the access token.
+ You can use the providerAccessToken to make requests to your OAuth 2 provider.
+ Refer to the docs for the OAuth 2 provider you're using to learn about making API calls with the access token.
Refresh Tokens
- OAuth2 sessions expire to protect from security risks.
- This means, OAuth2 sessions should be refreshed to keep the user authenticated.
+ OAuth 2 sessions expire to protect from security risks.
+ OAuth 2 sessions should be periodically refreshed to keep the user authenticated.
You can do this by calling the Update OAuth Session endpoint when ever your user visits your app.
diff --git a/app/views/docs/authentication-server.phtml b/app/views/docs/authentication-server.phtml
index 7e54f1d2e..de1c90211 100644
--- a/app/views/docs/authentication-server.phtml
+++ b/app/views/docs/authentication-server.phtml
@@ -7,7 +7,7 @@
Proof of Identity
-Before making requests to your backend APIs, your client application needs to first create a session directly with Appwrite using the account service. This session will act like an ID card for the user and can be used to access resources in Appwrite. The client will only receive information accessible to the user based on the resources's permissions.
+Before making requests to your backend APIs, your client application needs to first create a session directly with Appwrite using the account service. This session will act like an ID card for the user and can be used to access resources in Appwrite. The client will only receive information accessible to the user based on the resources' permissions.
When you build backend APIs to extend Appwrite's functionality, these APIs should still respect access permissions to keep user data secure. Appwrite's backend SDKs allows you to securely act on behalf of a user with the same permissions by using JWT authentication.
@@ -26,7 +26,7 @@
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -40,7 +40,7 @@ const user = await account.createJWT();
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -56,7 +56,7 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -69,7 +69,7 @@ val jwt = account.createJWT()
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
@@ -99,8 +99,8 @@ const client = new Client();
client
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
-
@@ -113,8 +113,8 @@ $client = new Client();
$client
->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- ->setProject('[PROJECT_ID]') // Your project ID
- ->setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ ->setProject('[PROJECT_ID]') // Your project ID
+ ->setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
-
@@ -125,9 +125,9 @@ $client
client = Client()
(client
- .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('[PROJECT_ID]') # Your project ID
- .set_jwt('eyJJ9.eyJ...886ca') # Your secret JSON Web Token
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('[PROJECT_ID]') # Your project ID
+ .set_jwt('eyJJ9.eyJ...886ca') # Your secret JSON Web Token
)
@@ -141,9 +141,9 @@ include Appwrite
client = Client.new
client
- .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('[PROJECT_ID]') # Your project ID
- .set_jwt('eyJJ9.eyJ...886ca') # Your secret JSON Web Token
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('[PROJECT_ID]') # Your project ID
+ .set_jwt('eyJJ9.eyJ...886ca') # Your secret JSON Web Token
-
@@ -154,9 +154,9 @@ client
let client = new Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
-
@@ -167,9 +167,9 @@ client
final client = Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
-
@@ -180,9 +180,9 @@ client
val client = Client()
client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
-
@@ -193,9 +193,9 @@ client
let client = Client()
client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
-
@@ -206,9 +206,9 @@ client
var client = new Client();
client
- .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .SetProject("[PROJECT_ID]") // Your project ID
- .SetJWT("eyJJ9.eyJ...886ca"); // Your secret JSON Web Token
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .SetProject("[PROJECT_ID]") // Your project ID
+ .SetJWT("eyJJ9.eyJ...886ca"); // Your secret JSON Web Token
@@ -343,9 +343,9 @@ response = databases.list_documents(database_id: '642f358bf4084c662590', '642f35
let client = new Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
let databases = new sdk.Databases(client);
@@ -361,9 +361,9 @@ let promise = databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856a
final client = Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
Databases databases = Databases(client);
@@ -382,9 +382,9 @@ Future result = databases.listDocuments(
val client = Client()
client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
val databases = Databases(client)
@@ -403,9 +403,9 @@ val response = databases.listDocuments(
let client = Client()
client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
let databases = Databases(client)
@@ -426,9 +426,9 @@ using Appwrite.Models;
var client = new Client();
client
- .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .SetProject("[PROJECT_ID]") // Your project ID
- .SetJWT("eyJJ9.eyJ...886ca"); // Your secret JSON Web Token
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .SetProject("[PROJECT_ID]") // Your project ID
+ .SetJWT("eyJJ9.eyJ...886ca"); // Your secret JSON Web Token
var databases = new Databases(client);
@@ -461,7 +461,7 @@ var documentList = await databases.ListDocuments(
}
-If the same request is made where the Server SDK's client is authenticate with an API key instead of a JWT, the results returned will be different.
+If the same request is made where the Server SDK's client is authenticated with an API key instead of a JWT, the results returned will be different.
-
Node.js
@@ -471,9 +471,9 @@ var documentList = await databases.ListDocuments(
const client = new Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2')// Your secret API key
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
const databases = new sdk.Databases(client);
@@ -490,9 +490,9 @@ const birthday = await databases.listDocuments('642f358bf4084c662590', '642f3592
$client = new Client();
$client
- ->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- ->setProject('[PROJECT_ID]') // Your project ID
- ->setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+ ->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ ->setProject('[PROJECT_ID]') // Your project ID
+ ->setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
$databases = new Databases($client);
@@ -508,9 +508,9 @@ $result = $databases->listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1
client = Client()
(client
- .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('[PROJECT_ID]') # Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('[PROJECT_ID]') # Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
)
databases = Databases(client)
@@ -529,9 +529,9 @@ include Appwrite
client = Client
client.new
- .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('[PROJECT_ID]') # Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('[PROJECT_ID]') # Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
databases = Databases.new(client)
@@ -547,9 +547,9 @@ response = databases.list_documents(database_id: '642f358bf4084c662590', '642f35
let client = new Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
let databases = new sdk.Databases(client);
@@ -565,9 +565,9 @@ let promise = databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856a
final client = Client();
client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2')// Your secret API key
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
Databases databases = Databases(client);
@@ -586,9 +586,9 @@ Future result = databases.listDocuments(
val client = Client()
client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setKey("919c2d18fb5d4...a2ae413da83346ad2")// Your secret API key
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
val databases = Databases(client)
@@ -607,9 +607,9 @@ val response = databases.listDocuments(
let client = Client()
client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setKey("919c2d18fb5d4...a2ae413da83346ad2")// Your secret API key
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
let databases = Databases(client)
@@ -630,9 +630,9 @@ using Appwrite.Models;
var client = new Client();
client
- .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .SetProject("[PROJECT_ID]") // Your project ID
- .SetKey("919c2d18fb5d4...a2ae413da83346ad2"); // Your secret API key
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .SetProject("[PROJECT_ID]") // Your project ID
+ .SetKey("919c2d18fb5d4...a2ae413da83346ad2"); // Your secret API key
var databases = new Databases(client);
diff --git a/app/views/docs/authentication-sms.phtml b/app/views/docs/authentication-sms.phtml
index 54aea908e..8e03e7880 100644
--- a/app/views/docs/authentication-sms.phtml
+++ b/app/views/docs/authentication-sms.phtml
@@ -33,7 +33,7 @@ const sessionToken = await account.createPhoneSession(
'+14255550123'
);
-var userId = sessionToken.userId // Store this somewhere to use later when logging in
+var userId = sessionToken.userId; // Store this somewhere to use later when logging in
-
@@ -52,7 +52,7 @@ final sessionToken = await account.createPhoneSession(
phone: '+14255550123'
);
-final userId = sessionToken.userId // Store this somewhere to use later when logging in
+final userId = sessionToken.userId; // Store this somewhere to use later when logging in
-
Android
@@ -110,7 +110,7 @@ let userId = sessionToken.userId // Store this somewhere to use later when loggi
Log In
- After initiation, the returned user ID and secret are used to confirm the user.
+ After initiating the phone authentication process, the returned user ID and secret are used to confirm the user.
The secret will usually be a 6-digit number in the SMS message sent to the user.
diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml
index 917c20852..bade8dfc9 100644
--- a/app/views/docs/authentication.phtml
+++ b/app/views/docs/authentication.phtml
@@ -125,7 +125,7 @@ mutation {
Use the Users API when acting as an administrator in use cases like building admin consoles or server integrations.
The Users API uses API keys to authenticate, which means Appwrite only knows which API key is accessing data.
API keys don't respect permissions, which means they can access all data, and should never be shared with end users in client applications.
- The Users API also has batch operations, letting your query and manage users from an admin's perspective.
+ The Users API also has batch operations, letting you query and manage users from an admin's perspective.
Explore
@@ -177,4 +177,4 @@ mutation {
Security
-
+
\ No newline at end of file
From b2902ed45317760ea295233e8d4ea94a73294a8b Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 21 Aug 2023 20:19:15 +0000
Subject: [PATCH 096/183] Improve formatting and arrange items more logically
---
app/views/docs/functions-deploy.phtml | 4 +-
app/views/docs/functions-develop.phtml | 944 +++++++++++++++---------
app/views/docs/functions-execute.phtml | 21 +-
app/views/docs/functions-runtimes.phtml | 6 +-
4 files changed, 605 insertions(+), 370 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 0fac2e804..0244a4e5f 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -9,9 +9,9 @@
Here's everything you need to know to deploy your first Appwrite Function.
-Git
+VCS (Version Control System)
- The recommended way to manage your Appwrite Function deployments is to use Git.
+ The recommended way to manage your Appwrite Function deployments is to use a version control system, like Git.
This offers simple versioning and collaboration that will easily fit into the rest of your development workflow.
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index c3174a8c1..aa5cfc8b1 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -1,14 +1,8 @@
Appwrite Functions offer a familiar interface if you've developed REST endpoints.
Each function is handled following a request and response pattern.
- Here's what you need to know to start writing your first Appwrite Function.
-
- Just want the code?
- If you prefer to learn through examples, explore the examples page.
-
-
Function Flow
There is a clear flow for all Appwrite Functions, from beginning to end.
@@ -16,17 +10,443 @@
- - Invocation, where Appwrite receives a event to execute a Function. This event could be a request from an SDK, a request to the function's domain, a scheduled execution, or an execution triggered by an event within your Appwrite project.
- - After a function is invoked, Appwrite passes request information to your function's executor.
- - The executor runs the function code you deployed and waits for it to return.
- - Function terminates either when the user returns with a method from
res, when the user code throws an exception, or times out.
+ - The function is invoked.
+ - Appwrite passes in request information like headers and environment variables through the
context.req object.
+ - The runtime executes the code you defined, you can log through the
context.log or context.error methods.
+ - Function terminates when you return results using
context.res.
+You'll find all of these steps in a simple function like this.
+
+
+ -
+
Node.js
+
+ import { Client } from 'node-appwrite';
+
+// This is your Appwrite function
+// It's executed each time we get a request
+export default async ({ req, res, log, error }) => {
+ // Why not try the Appwrite SDK?
+ //
+ // const client = new Client()
+ // .setEndpoint('https://cloud.appwrite.io/v1')
+ // .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ // .setKey(process.env.APPWRITE_API_KEY);
+
+ // You can log messages to the console
+ log('Hello, Logs!');
+
+ // If something goes wrong, log an error
+ error('Hello, Errors!');
+
+ // The `req` object contains the request data
+ if (req.method === 'GET') {
+ // Send a response with the res object helpers
+ // `res.send()` dispatches a string back to the client
+ return res.send('Hello, World!');
+ }
+
+ // `res.json()` is a handy helper for sending JSON
+ return res.json({
+ motto: 'Build Fast. Scale Big. All in One Place.',
+ learn: 'https://appwrite.io/docs',
+ connect: 'https://appwrite.io/discord',
+ getInspired: 'https://builtwith.appwrite.io',
+ });
+};
+
+
+ -
+
PHP
+
+ require(__DIR__ . '/../vendor/autoload.php');
+
+use Appwrite\Client;
+use Appwrite\Exception;
+
+// This is your Appwrite function
+// It's executed each time we get a request
+return function ($context) {
+ // Why not try the Appwrite SDK?
+ //
+ // $client = new Client();
+ // $client
+ // ->setEndpoint('https://cloud.appwrite.io/v1')
+ // ->setProject(getenv('APPWRITE_FUNCTION_PROJECT_ID'))
+ // ->setKey(getenv('APPWRITE_API_KEY'));
+
+ // You can log messages to the console
+ $context->log('Hello, Logs!');
+
+ // If something goes wrong, log an error
+ $context->error('Hello, Errors!');
+
+ // The `req` object contains the request data
+ if ($context->req->method === 'GET') {
+ // Send a response with the res object helpers
+ // `res.send()` dispatches a string back to the client
+ return $context->res->send('Hello, World!');
+ }
+
+ // `res.json()` is a handy helper for sending JSON
+ return $context->res->json([
+ 'motto' => 'Build Fast. Scale Big. All in One Place.',
+ 'learn' => 'https://appwrite.io/docs',
+ 'connect' => 'https://appwrite.io/discord',
+ 'getInspired' => 'https://builtwith.appwrite.io',
+ ]);
+};
+
+
+ -
+
Python
+
+ from appwrite.client import Client
+import os
+
+
+# This is your Appwrite function
+# It's executed each time we get a request
+def main(context):
+ # Why not try the Appwrite SDK?
+ #
+ # client = (
+ # Client()
+ # .set_endpoint("https://cloud.appwrite.io/v1")
+ # .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ # .set_key(os.environ["APPWRITE_API_KEY"])
+ # )
+
+ # You can log messages to the console
+ context.log("Hello, Logs!")
+
+ # If something goes wrong, log an error
+ context.error("Hello, Errors!")
+
+ # The `ctx.req` object contains the request data
+ if context.req.method == "GET":
+ # Send a response with the res object helpers
+ # `ctx.res.send()` dispatches a string back to the client
+ return context.res.send("Hello, World!")
+
+ # `ctx.res.json()` is a handy helper for sending JSON
+ return context.res.json(
+ {
+ "motto": "Build Fast. Scale Big. All in One Place.",
+ "learn": "https://appwrite.io/docs",
+ "connect": "https://appwrite.io/discord",
+ "getInspired": "https://builtwith.appwrite.io",
+ }
+ )
+
+
+ -
+
Ruby
+
+ require "appwrite"
+
+# This is your Appwrite function
+# It's executed each time we get a request
+def main(context)
+ # Why not try the Appwrite SDK?
+ #
+ # client = Appwrite::Client.new
+ # client
+ # .set_endpoint('https://cloud.appwrite.io/v1')
+ # .set_project(ENV['APPWRITE_FUNCTION_PROJECT_ID'])
+ # .set_key(ENV['APPWRITE_API_KEY'])
+
+ # You can log messages to the console
+ context.log("Hello, Logs!")
+
+ # If something goes wrong, log an error
+ context.error("Hello, Errors!")
+
+ # The `ctx.req` object contains the request data
+ if (context.req.method == "GET")
+ # Send a response with the res object helpers
+ # `ctx.res.send()` dispatches a string back to the client
+ return context.res.send("Hello, World!")
+ end
+
+ # `ctx.res.json()` is a handy helper for sending JSON
+ return context.res.json(
+ {
+ "motto": "Build Fast. Scale Big. All in One Place.",
+ "learn": "https://appwrite.io/docs",
+ "connect": "https://appwrite.io/discord",
+ "getInspired": "https://builtwith.appwrite.io",
+ }
+ )
+end
+
+
+ -
+
Deno
+
+ import { Client } from "https://deno.land/x/appwrite@7.0.0/mod.ts";
+
+// This is your Appwrite function
+// It's executed each time we get a request
+export default ({ req, res, log, error }: any) => {
+ // Why not try the Appwrite SDK?
+ //
+ // const client = new Client()
+ // .setEndpoint('https://cloud.appwrite.io/v1')
+ // .setProject(Deno.env.get("APPWRITE_FUNCTION_PROJECT_ID"))
+ // .setKey(Deno.env.get("APPWRITE_API_KEY"));
+
+ // You can log messages to the console
+ log("Hello, Logs!");
+
+ // If something goes wrong, log an error
+ error("Hello, Errors!");
+
+ // The `req` object contains the request data
+ if (req.method === "GET") {
+ // Send a response with the res object helpers
+ // `res.send()` dispatches a string back to the client
+ return res.send("Hello, World!");
+ }
+
+ // `res.json()` is a handy helper for sending JSON
+ return res.json({
+ motto: "Build Fast. Scale Big. All in One Place.",
+ learn: "https://appwrite.io/docs",
+ connect: "https://appwrite.io/discord",
+ getInspired: "https://builtwith.appwrite.io",
+ });
+};
+
+
+ -
+
Dart
+
+ import 'dart:async';
+import 'package:dart_appwrite/dart_appwrite.dart';
+
+// This is your Appwrite function
+// It's executed each time we get a request
+Future main(final context) async {
+// Why not try the Appwrite SDK?
+ //
+ // final client = Client()
+ // .setEndpoint('https://cloud.appwrite.io/v1')
+ // .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ // .setKey(process.env.APPWRITE_API_KEY);
+
+ // You can log messages to the console
+ context.log('Hello, Logs!');
+
+ // If something goes wrong, log an error
+ context.error('Hello, Errors!');
+
+ // The `req` object contains the request data
+ if (context.req.method == 'GET') {
+ // Send a response with the res object helpers
+ // `res.send()` dispatches a string back to the client
+ return context.res.send('Hello, World!');
+ }
+
+ // `res.json()` is a handy helper for sending JSON
+ return context.res.json({
+ 'motto': 'Build Fast. Scale Big. All in One Place.',
+ 'learn': 'https://appwrite.io/docs',
+ 'connect': 'https://appwrite.io/discord',
+ 'getInspired': 'https://builtwith.appwrite.io',
+ });
+}
+
+
+ -
+
Swift
+
+ import Appwrite
+import AppwriteModels
+import Foundation
+
+// This is your Appwrite function
+// It's executed each time we get a request
+func main(context: RuntimeContext) async throws -> RuntimeOutput {
+ // Why not try the Appwrite SDK?
+ //
+ // let client = Client()
+ // .setEndpoint("https://cloud.appwrite.io/v1")
+ // .setProject(ProcessInfo.processInfo.environment["APPWRITE_FUNCTION_PROJECT_ID"])
+ // .setKey(ProcessInfo.processInfo.environment["APPWRITE_API_KEY"]);
+
+ // You can log messages to the console
+ context.log("Hello, Logs!")
+
+ // If something goes wrong, log an error
+ context.error("Hello, Errors!")
+
+ // The `context.req` object contains the request data
+ if context.req.method == "GET" {
+ // Send a response with the res object helpers
+ // `res.send()` dispatches a string back to the client
+ return try context.res.send("Hello, World!")
+ }
+
+ // `context.res.json()` is a handy helper for sending JSON
+ return try context.res.json([
+ "motto": "Build Fast. Scale Big. All in One Place.",
+ "learn": "https://appwrite.io/docs",
+ "connect": "https://appwrite.io/discord",
+ "getInspired": "https://builtwith.appwrite.io",
+ ])
+}
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
+
+using Appwrite;
+using Appwrite.Services;
+using Appwrite.Models;
+
+public class Handler {
+
+ // This is your Appwrite function
+ // It"s executed each time we get a request
+ public async Task Main(RuntimeContext Context)
+ {
+ // Why not try the Appwrite SDK?
+ //
+ // var client = new Client()
+ // .SetEndpoint("http://cloud.appwrite.io/v1")
+ // .SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
+ // .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"))
+
+ // You can log messages to the console
+ Context.Log("Hello, Logs!");
+
+ // If something goes wrong, log an error
+ Context.Error("Hello, Errors!");
+
+ // The `Context.Req` object contains the request data
+ if (Context.Req.Method == "GET") {
+ // Send a response with the res object helpers
+ // `Context.Res.Send()` dispatches a string back to the client
+ return Context.Res.Send("Hello, World!");
+ }
+
+ // `Context.Res.Json()` is a handy helper for sending JSON
+ return Context.Res.Json(new Dictionary()
+ {
+ { "motto", "Build Fast. Scale Big. All in One Place." },
+ { "learn", "https://appwrite.io/docs" },
+ { "connect", "https://appwrite.io/discord" },
+ { "getInspired", "https://builtwith.appwrite.io" },
+ });
+ }
+}
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
+
+import io.openruntimes.kotlin.RuntimeContext
+import io.openruntimes.kotlin.RuntimeOutput
+import io.appwrite.Client
+import java.util.HashMap
+
+class Main {
+ // This is your Appwrite function
+ // It's executed each time we get a request
+ fun main(context: RuntimeContext): RuntimeOutput {
+ // Why not try the Appwrite SDK?
+ // val client = Client().apply {
+ // setEndpoint("https://cloud.appwrite.io/v1")
+ // setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ // setKey(System.getenv("APPWRITE_API_KEY"))
+ // }
+
+ // You can log messages to the console
+ context.log("Hello, Logs!")
+
+ // If something goes wrong, log an error
+ context.error("Hello, Errors!")
+
+ // The `context.req` object contains the request data
+ if (context.req.method == "GET") {
+ // Send a response with the res object helpers
+ // `context.res.send()` dispatches a string back to the client
+ return context.res.send("Hello, World!")
+ }
+
+ // `context.res.json()` is a handy helper for sending JSON
+ return context.res.json(mutableMapOf(
+ "motto" to "Build Fast. Scale Big. All in One Place.",
+ "learn" to "https://appwrite.io/docs",
+ "connect" to "https://appwrite.io/discord",
+ "getInspired" to "https://builtwith.appwrite.io"
+ ))
+ }
+}
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
+
+import io.openruntimes.java.RuntimeContext;
+import io.openruntimes.java.RuntimeOutput;
+import java.util.HashMap;
+import io.appwrite.Client;
+
+public class Main {
+
+ // This is your Appwrite function
+ // It's executed each time we get a request
+ public RuntimeOutput main(RuntimeContext context) throws Exception {
+ // Why not try the Appwrite SDK?
+ //
+ // Client client = new Client();
+ // client
+ // .setEndpoint("https://cloud.appwrite.io/v1")
+ // .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ // .setKey(System.getenv("APPWRITE_API_KEY"));
+
+ // You can log messages to the console
+ context.log("Hello, Logs!");
+
+ // If something goes wrong, log an error
+ context.error("Hello, Errors!");
+
+ // The `context.getReq()` object contains the request data
+ if (context.getReq().getMethod().equals("GET")) {
+ // Send a response with the res object helpers
+ // `context.getRes().send()` dispatches a string back to the client
+ return context.getRes().send("Hello, World!");
+ }
+
+ Map json = new HashMap<>();
+ json.put("motto", "Build Fast. Scale Big. All in One Place.");
+ json.put("learn", "https://appwrite.io/docs");
+ json.put("connect", "https://appwrite.io/discord");
+ json.put("getInspired", "https://builtwith.appwrite.io");
+
+ // `context.getRes().json()` is a handy helper for sending JSON
+ return context.getRes().json(json);
+ }
+}
+
+
+
+
+If you prefer to learn through more examples like this, explore the examples page.
The Context Object
Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite console.
- All input, output, anddlogging **must be** handled through the context object passed in.
+ All input, output, anddlogging must be handled through the context object passed in.
You'll find these properties in the context object.
@@ -58,11 +478,11 @@
+Destructuring Assignment
Some languages, namely JavaScript, support destructuring. You'll see us use destructing in examples, which has the following syntax.
-
Node.js
-
export default async function ({ req, res, log, error }) {
log('This is a log!');
@@ -70,11 +490,9 @@
return res.send(`This function was called with ${req.method} method!`)
}
-
-
Deno
-
export default async function ({ req, res, log, error }: any) {
log('This is a log!');
@@ -82,7 +500,6 @@
return res.send(`This function was called with ${req.method} method!`)
}
-
@@ -96,7 +513,6 @@
-
Node.js
-
export default async ({ req, res, log }) => {
log(req.bodyRaw); // Raw request body, contains request data
@@ -114,11 +530,9 @@
return res.send("All the request parameters are logged to the Appwrite Console.");
};
-
-
PHP
-
<?php
return function ($context) {
@@ -137,11 +551,9 @@ return function ($context) {
return $context->res->send("All the request parameters are logged to the Appwrite Console.");
}
-
-
Python
-
import json
@@ -160,11 +572,9 @@ def main(context):
return context.res.send("All the request parameters are logged to the Appwrite Console.")
-
-
Ruby
-
require 'json'
@@ -184,11 +594,9 @@ def main(context)
return context.res.send("All the request parameters are logged to the Appwrite Console.")
end
-
-
Deno
-
export default async ({ req, res, log }: any) => {
log(req.bodyRaw); // Raw request body, contains request data
@@ -205,11 +613,9 @@ end
return res.send("All the request parameters are logged to the Appwrite Console.");
-
-
Dart
-
import 'dart:async';
import 'dart:convert';
@@ -230,11 +636,9 @@ Future<dynamic> main(final context) async {
return context.res.send("All the request parameters are logged to the Appwrite Console.");
}
-
-
Swift
-
import Foundation
import Foundation
@@ -255,11 +659,9 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return try context.res.send("All the request parameters are logged to the Appwrite Console.")
}
-
-
.NET
-
namespace DotNetRuntime;
@@ -284,11 +686,9 @@ public class Handler {
}
}
-
-
Kotlin
-
package io.openruntimes.kotlin.src
@@ -316,12 +716,9 @@ class Main {
}
}
-
-
-
Java
-
package io.openruntimes.java;
@@ -349,7 +746,6 @@ public class Main {
}
}
-
@@ -426,199 +822,115 @@ public class Main {
-
Node.js
-
export default async ({ req, res, log }) => {
switch (req.query.type) {
case 'text':
- return res.send(
- "This is a text response",
- 200
- );
+ return res.send("This is a text response", 200);
case 'json':
- return res.json(
- {
- "type": "This is a JSON response"
- },
- 200
- );
+ return res.json({"type": "This is a JSON response"}, 200);
case 'redirect':
- return res.redirect(
- "https://appwrite.io",
- 301
- );
+ return res.redirect("https://appwrite.io", 301);
case 'html':
return res.send(
- "<h1>This is an HTML response</h1>",
- 200,
- {
+ "<h1>This is an HTML response</h1>", 200, {
"content-type": "text/html"
- }
- );
+ });
default:
return res.empty();
}
}
-
-
PHP
-
<?php
return function ($context) {
switch ($context->req->query['type']) {
case 'text':
- return $context->res->send(
- "This is a text response",
- 200
- );
+ return $context->res->send("This is a text response", 200);
case 'json':
- return $context->res->json(
- [
- "type" => "This is a JSON response"
- ],
- 200
- );
+ return $context->res->json(["type" => "This is a JSON response"], 200);
case 'redirect':
- return $context->res->redirect(
- "https://appwrite.io",
- 301
- );
+ return $context->res->redirect("https://appwrite.io", 301);
case 'html':
- return $context->res->send(
- "<h1>This is an HTML response</h1>",
- 200,
- [
- "content-type" => "text/html"
- ]
- );
+ return $context->res->send("<h1>This is an HTML response</h1>", 200, [
+ "content-type" => "text/html"
+ ]);
default:
return $context->res->empty();
}
};
-
-
Python
-
def main(context):
switch context.req.query['type']:
case 'text':
- return context.res.send(
- "This is a text response",
- 200
- )
+ return context.res.send("This is a text response", 200)
case 'json':
- return context.res.json(
- {
- "type": "This is a JSON response"
- },
- 200
- )
+ return context.res.json({"type": "This is a JSON response"}, 200)
case 'redirect':
- return context.res.redirect(
- "https://appwrite.io",
- 301
- )
+ return context.res.redirect("https://appwrite.io", 301)
case 'html':
- return context.res.send(
- "<h1>This is an HTML response</h1>",
- 200,
- {
- "content-type": "text/html"
- }
- )
+ return context.res.send("<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ })
default:
return context.res.empty()
-
-
Ruby
-
def main(context)
case context.req.query['type']
when 'text'
- return context.res.send(
- "This is a text response",
- 200
- )
+ return context.res.send("This is a text response", 200)
when 'json'
- return context.res.json(
- {
- "type": "This is a JSON response"
- },
- 200
- )
+ return context.res.json({"type": "This is a JSON response"}, 200)
when 'redirect'
- return context.res.redirect(
- "https://appwrite.io",
- 301
- )
+ return context.res.redirect("https://appwrite.io", 301)
when 'html'
- return context.res.send(
- "<h1>This is an HTML response</h1>",
- 200,
- {
- "content-type": "text/html"
- }
- )
+ return context.res.send("<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ })
else
return context.res.empty()
end
end
-
-
Deno
-
export default async ({ req, res, log }) => {
switch (req.query.type) {
case 'text':
- return res.send(
- "This is a text response",
- 200
- );
+ return res.send("This is a text response", 200);
case 'json':
- return res.json(
- {
- "type": "This is a JSON response"
- },
- 200
- );
+ return res.json({type": "This is a JSON response"}, 200);
case 'redirect':
- return res.redirect(
- "https://appwrite.io",
- 301
- );
+ return res.redirect("https://appwrite.io", 301);
case 'html':
return res.send(
- "<h1>This is an HTML response</h1>",
- 200,
- {
+ "<h1>This is an HTML response</h1>", 200, {
"content-type": "text/html"
- }
- );
+ });
default:
return res.empty();
}
}
-
-
Dart
-
import 'dart:async';
@@ -629,9 +941,7 @@ Future<dynamic> main(final context) async {
.send('This is a text response', 200);
case 'json':
return context.res
- .json({
- 'type': 'This is a JSON response'
- });
+ .json({'type': 'This is a JSON response'});
case 'redirect':
return context.res
.redirect('https://appwrite.io', 301);
@@ -646,11 +956,9 @@ Future<dynamic> main(final context) async {
}
}
-
-
Swift
-
import Foundation
@@ -663,17 +971,17 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
case "redirect":
return try await context.redirect("https://appwrite.io", 301)
case "html":
- return try await context.send("<h1>This is an HTML response</h1>", 200, ["content-type": "text/html"])
+ return try await context.send("<h1>This is an HTML response</h1>", 200, [
+ "content-type": "text/html"
+ ])
default:
return try await context.empty()
}
}
-
-
.NET
-
namespace DotNetRuntime;
@@ -689,18 +997,18 @@ public class Handler {
case "redirect":
return await Context.Redirect("https://appwrite.io", 301);
case "html":
- return await Context.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() { { "content-type", "text/html" } });
+ return await Context.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
+ { "content-type", "text/html" }
+ });
default:
return await Context.Empty();
}
}
}
-
-
Kotlin
-
package io.openruntimes.kotlin.src
@@ -719,11 +1027,9 @@ class Main {
}
}
-
-
Java
-
package io.openruntimes.java.src;
@@ -751,11 +1057,9 @@ public class Main {
}
}
-
-
C++
-
#include "../RuntimeResponse.h"
#include "../RuntimeRequest.h"
@@ -787,7 +1091,6 @@ namespace runtime {
};
}
-
@@ -802,7 +1105,6 @@ namespace runtime {
-
Node.js
-
export default async ({ res, log, error }) => {
log("This is a log, use for logging information to console");
@@ -812,11 +1114,9 @@ namespace runtime {
return res.send("Check the Appwrite Console to see logs and errors!");
};
-
-
PHP
-
<?php
@@ -828,11 +1128,9 @@ return function ($context) {
return $context->send("Check the Appwrite Console to see logs and errors!");
};
-
-
Python
-
def main(context):
context.log("This is a log, use for logging information to console")
@@ -841,11 +1139,9 @@ return function ($context) {
return context.send("Check the Appwrite Console to see logs and errors!")
-
-
Ruby
-
def main(context)
context.log("This is a log, use for logging information to console")
@@ -855,11 +1151,9 @@ return function ($context) {
return context.send("Check the Appwrite Console to see logs and errors!")
end
-
-
Deno
-
export default async ({ res, log, error }: any) => {
log("This is a log, use for logging information to console");
@@ -869,11 +1163,9 @@ end
return res.send("Check the Appwrite Console to see logs and errors!");
};
-
-
Dart
-
import 'dart:async';
@@ -885,11 +1177,9 @@ Future<dynamic> main(final context) async {
return context.send("Check the Appwrite Console to see logs and errors!");
}
-
-
Swift
-
import Foundation
@@ -901,11 +1191,9 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return try context.send("Check the Appwrite Console to see logs and errors!")
}
-
-
.NET
-
namespace DotNetRuntime;
@@ -920,11 +1208,9 @@ public class Handler {
}
}
-
-
Kotlin
-
package io.openruntimes.kotlin.src
@@ -941,11 +1227,9 @@ class Main {
}
}
-
-
Java
-
package io.openruntimes.java.src;
@@ -962,11 +1246,9 @@ public class Main {
}
}
-
-
C++
-
#include "../RuntimeResponse.h"
#include "../RuntimeRequest.h"
@@ -986,7 +1268,6 @@ namespace runtime {
};
}
-
You can access these logs through the following steps.
@@ -1057,16 +1338,17 @@ namespace runtime {
APPWRITE_FUNCTION_RUNTIME_VERSION
+
The runtime version of the running function.
-
+
Local Environment Variables
- Local variables will only be accessible in the function they belong to.
- Local variables will override global variables when they have conflicting names.
+ Local environment variables will only be accessible in the function they belong to.
+ Local environment variables will override global environment variables when they have conflicting names.
- In Appwrite Console, navigate to Functions.
@@ -1075,10 +1357,10 @@ namespace runtime {
- Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
-Global Variables
+Global Environment Variables
- Global variables are accessible to all Appwrite Functions.
- Local variables will override global variables when they have conflicting names.
+ Global environment variables are accessible to all Appwrite Functions.
+ Local environment variables will override global environment variables when they have conflicting names.
- In Appwrite Console, navigate to your project's Settings page.
@@ -1093,7 +1375,6 @@ namespace runtime {
-
Node.js
-
process.env.MY_VAR
@@ -1101,7 +1382,6 @@ namespace runtime {
-
PHP
-
getenv('MY_VAR')
@@ -1109,75 +1389,57 @@ namespace runtime {
-
Python
-
os.environ['MY_VAR']
-
-
Ruby
-
ENV['MY_VAR']
-
-
Deno
-
Deno.env.get('MY_VAR')
-
-
Dart
-
Platform.environment['MY_VAR']
-
-
Swift
-
ProcessInfo.processInfo.environment["MY_VAR"]
-
-
.NET
-
Environment.GetEnvironmentVariable("MY_VAR")
-
-
Kotlin
-
System.getenv("MY_VAR")
-
-
Java
-
System.getenv("MY_VAR")
-
-
C++
-
std::getenv("MY_VAR")
-
@@ -1196,7 +1458,7 @@ namespace runtime {
Language
Package Manager
- Install Command
+ Commands
@@ -1262,13 +1524,15 @@ namespace runtime {
Authenticating with Appwrite is done via an API key or a JWT token. You can read more about authentication in the Server Authentication section of the docs.
-
-
-Using JWT
+Using with API Key
+
+ API keys have defined scopes when you create them.
+ They ignore permissions and operate without a sessions.
+ Use API keys if the function should act as an admin type role, instead of acting on behalf of a user.
+
-
Node.js
-
import { Client, Databases, ID } from 'node-appwrite';
@@ -1277,13 +1541,9 @@ export default async ({ req, res, log }) => {
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ .setKey(process.env.APPWRITE_API_KEY);
- if (req.headers['x-appwrite-jwt']) {
- client.setJWT(req.headers['x-appwrite-jwt'])
- } else {
- return res.send("Please sign in, JWT not found")
- }
-
const databases = new Databases(client);
try {
@@ -1295,11 +1555,9 @@ export default async ({ req, res, log }) => {
return res.send("Document created")
}
-
-
PHP
-
<?php
@@ -1315,12 +1573,8 @@ return function ($context) {
$client
->setEndpoint('https://cloud.appwrite.io/v1')
->setProject(getenv('APPWRITE_FUNCTION_PROJECT_ID'))
-
- if (isset($context->req->headers['x-appwrite-jwt'])) {
- $client->setJWT($context->req->headers['x-appwrite-jwt']);
- } else {
- return $context->res->send("Please sign in, JWT not found");
- }
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ ->setKey(getenv('APPWRITE_API_KEY'));
$databases = new Databases($client);
@@ -1333,11 +1587,9 @@ return function ($context) {
return $context->res->send("Document created");
};
-
-
Python
-
from appwrite.client import Client
from appwrite.services.databases import Databases
@@ -1345,19 +1597,15 @@ from appwrite.id import ID
import os
-
def main(context):
client = (
Client()
.set_endpoint("https://cloud.appwrite.io/v1")
.set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ # Pass in your API key as an environment variable. Never share API keys with users.
+ .set_key(os.environ["APPWRITE_API_KEY"])
)
- if "x-appwrite-jwt" in context.req.headers:
- client.set_jwt(context.req.headers["x-appwrite-jwt"])
- else:
- return context.res.send("Please sign in, JWT not found")
-
databases = Databases(client)
try:
@@ -1367,11 +1615,9 @@ def main(context):
return context.response.send("Document created")
-
-
Ruby
-
require "appwrite"
@@ -1380,12 +1626,8 @@ def main(context)
client
.set_endpoint('https://cloud.appwrite.io/v1')
.set_project(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
-
- if context.request.headers['x-appwrite-jwt']
- client.set_jwt(context.request.headers['x-appwrite-jwt'])
- else
- return context.response.send("Please sign in, JWT not found")
- end
+ # Pass in your API key as an environment variable. Never share API keys with users.
+ .set_key(req.variables['APPWRITE_API_KEY'])
databases = Appwrite::Databases.new(client)
@@ -1398,11 +1640,9 @@ def main(context)
return context.response.send("Document created")
end
-
-
Deno
-
import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
@@ -1411,12 +1651,8 @@ export default function ({req, res}: any){
client
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(Deno.env.get("APPWRITE_FUNCTION_PROJECT_ID") || "")
-
- if (req.headers["x-appwrite-jwt"]) {
- client.setJWT(req.headers["x-appwrite-jwt"]);
- } else {
- return res.send("Please sign in, JWT not found");
- }
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ .setKey(Deno.env.get("APPWRITE_API_KEY") || "");
const databases = new Databases(client);
@@ -1429,11 +1665,9 @@ export default function ({req, res}: any){
return res.send("Document created");
}
-
-
Dart
-
import 'dart:async';
import 'package:dart_appwrite/dart_appwrite.dart';
@@ -1443,12 +1677,8 @@ Future<dynamic> main(final context) async {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
-
- if (context.req.headers['x-appwrite-jwt'] != null) {
- client.setJWT(context.req.headers['x-appwrite-jwt']);
- } else {
- return context.res.send("Please sign in, JWT not found");
- }
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ .setKey(process.env.APPWRITE_API_KEY);
final databases = Databases(client);
@@ -1461,11 +1691,9 @@ Future<dynamic> main(final context) async {
return context.res.send("Document created");
}
-
-
Swift
-
import Appwrite
import AppwriteModels
@@ -1475,12 +1703,8 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(ProcessInfo.processInfo.environment["APPWRITE_FUNCTION_PROJECT_ID"])
-
- if let jwt = context.req.headers["x-appwrite-jwt"] {
- client.setJWT(jwt)
- } else {
- return context.res.send("Please sign in, JWT not found")
- }
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ .setKey(ProcessInfo.processInfo.environment["APPWRITE_API_KEY"]);
let databases = Databases(client: client)
@@ -1493,11 +1717,9 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return context.res.send("Document created")
}
-
-
.NET
-
namespace DotNetRuntime;
@@ -1512,30 +1734,24 @@ public class Handler {
var client = new Client()
.SetEndpoint("http://cloud.appwrite.io/v1")
.SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
-
- if (Context.Req.Headers.ContainsKey("x-appwrite-jwt")) {
- client.SetJWT(Context.Req.Headers["x-appwrite-jwt"]);
- } else {
- return Context.Res.Send("Please sign in, JWT not found");
- }
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"))
var databases = new Databases(client);
try {
await databases.CreateDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.Unique(), new Dictionary<string, object>());
} catch (Exception e) {
- return Context.Res.Send("We messed up, document not created");
+ return Context.Response.Send("We messed up, document not created");
}
- return Context.Res.Send("Document created");
+ return Context.Response.Send("Document created");
}
}
-
-
Kotlin
-
package io.openruntimes.kotlin.src
@@ -1551,12 +1767,8 @@ class Main {
val client = Client().apply {
setEndpoint("https://cloud.appwrite.io/v1")
setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- }
-
- if (context.req.headers["x-appwrite-jwt"] != null) {
- client.setJWT(context.req.headers["x-appwrite-jwt"])
- } else {
- return context.res.send("Please sign in, JWT not found")
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ setKey(System.getenv("APPWRITE_API_KEY"))
}
val databases = Databases(client)
@@ -1571,11 +1783,9 @@ class Main {
}
}
-
-
Java
-
package io.openruntimes.java.src;
@@ -1590,12 +1800,8 @@ public class Main {
client
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
-
- if (context.req.headers.containsKey("x-appwrite-jwt")) {
- client.setJWT(context.req.headers.get("x-appwrite-jwt"));
- } else {
- return context.res.send("Please sign in, JWT not found");
- }
+ // Pass in your API key as an environment variable. Never share API keys with users.
+ .setKey(System.getenv("APPWRITE_API_KEY"));
Databases databases = new Databases(client);
@@ -1610,15 +1816,24 @@ public class Main {
}
}
-
-Using with API Key
+
+Using JWT
+
+ JWTs allow you to act on behalf of an user in your Appwrite Function.
+ When using JWTs, you will be able to access and change only the resources with the same permissions as the user account that signed the JWT.
+ This preserves the permissions you configured on each resource.
+
+
+
+ If the Appwrite Function is invoked by an authenticated user, the x-appwrite-user-jwt header is automatically passed in.
+
+
-
Node.js
-
import { Client, Databases, ID } from 'node-appwrite';
@@ -1627,9 +1842,13 @@ export default async ({ req, res, log }) => {
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
- // Put your secret key in environment variables, so it doesn't leak
- .setKey(process.env.APPWRITE_API_KEY);
+ if (req.headers['x-appwrite-user-jwt']) {
+ client.setJWT(req.headers['x-appwrite-user-jwt'])
+ } else {
+ return res.send("Please sign in, JWT not found")
+ }
+
const databases = new Databases(client);
try {
@@ -1641,11 +1860,9 @@ export default async ({ req, res, log }) => {
return res.send("Document created")
}
-
-
PHP
-
<?php
@@ -1661,8 +1878,12 @@ return function ($context) {
$client
->setEndpoint('https://cloud.appwrite.io/v1')
->setProject(getenv('APPWRITE_FUNCTION_PROJECT_ID'))
- // Put your secret key in environment variables, so it doesn't leak
- ->setKey(getenv('APPWRITE_API_KEY'));
+
+ if (isset($context->req->headers['x-appwrite-user-jwt'])) {
+ $client->setJWT($context->req->headers['x-appwrite-user-jwt']);
+ } else {
+ return $context->res->send("Please sign in, JWT not found");
+ }
$databases = new Databases($client);
@@ -1675,11 +1896,9 @@ return function ($context) {
return $context->res->send("Document created");
};
-
-
Python
-
from appwrite.client import Client
from appwrite.services.databases import Databases
@@ -1693,10 +1912,13 @@ def main(context):
Client()
.set_endpoint("https://cloud.appwrite.io/v1")
.set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
- # Put your secret key in environment variables, so it doesn't leak
- .set_key(os.environ["APPWRITE_API_KEY"])
)
+ if "x-appwrite-user-jwt" in context.req.headers:
+ client.set_jwt(context.req.headers["x-appwrite-user-jwt"])
+ else:
+ return context.res.send("Please sign in, JWT not found")
+
databases = Databases(client)
try:
@@ -1706,11 +1928,9 @@ def main(context):
return context.response.send("Document created")
-
-
Ruby
-
require "appwrite"
@@ -1719,8 +1939,12 @@ def main(context)
client
.set_endpoint('https://cloud.appwrite.io/v1')
.set_project(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
- # Put your secret key in environment variables, so it doesn't leak
- .set_key(req.variables['APPWRITE_API_KEY'])
+
+ if context.request.headers['x-appwrite-user-jwt']
+ client.set_jwt(context.request.headers['x-appwrite-user-jwt'])
+ else
+ return context.response.send("Please sign in, JWT not found")
+ end
databases = Appwrite::Databases.new(client)
@@ -1733,11 +1957,9 @@ def main(context)
return context.response.send("Document created")
end
-
-
Deno
-
import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
@@ -1746,8 +1968,12 @@ export default function ({req, res}: any){
client
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(Deno.env.get("APPWRITE_FUNCTION_PROJECT_ID") || "")
- // Put your secret key in environment variables, so it doesn't leak
- .setKey(Deno.env.get("APPWRITE_API_KEY") || "");
+
+ if (req.headers["x-appwrite-user-jwt"]) {
+ client.setJWT(req.headers["x-appwrite-user-jwt"]);
+ } else {
+ return res.send("Please sign in, JWT not found");
+ }
const databases = new Databases(client);
@@ -1760,11 +1986,9 @@ export default function ({req, res}: any){
return res.send("Document created");
}
-
-
Dart
-
import 'dart:async';
import 'package:dart_appwrite/dart_appwrite.dart';
@@ -1774,8 +1998,12 @@ Future<dynamic> main(final context) async {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
- // Put your secret key in environment variables, so it doesn't leak
- .setKey(process.env.APPWRITE_API_KEY);
+
+ if (context.req.headers['x-appwrite-user-jwt'] != null) {
+ client.setJWT(context.req.headers['x-appwrite-user-jwt']);
+ } else {
+ return context.res.send("Please sign in, JWT not found");
+ }
final databases = Databases(client);
@@ -1788,11 +2016,9 @@ Future<dynamic> main(final context) async {
return context.res.send("Document created");
}
-
-
Swift
-
import Appwrite
import AppwriteModels
@@ -1802,8 +2028,12 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(ProcessInfo.processInfo.environment["APPWRITE_FUNCTION_PROJECT_ID"])
- // Put your secret key in environment variables, so it doesn't leak
- .setKey(ProcessInfo.processInfo.environment["APPWRITE_API_KEY"]);
+
+ if let jwt = context.req.headers["x-appwrite-user-jwt"] {
+ client.setJWT(jwt)
+ } else {
+ return context.res.send("Please sign in, JWT not found")
+ }
let databases = Databases(client: client)
@@ -1816,11 +2046,9 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return context.res.send("Document created")
}
-
-
.NET
-
namespace DotNetRuntime;
@@ -1835,26 +2063,28 @@ public class Handler {
var client = new Client()
.SetEndpoint("http://cloud.appwrite.io/v1")
.SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
- // Put your secret key in environment variables, so it doesn't leak
- .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"))
+
+ if (Context.Req.Headers.ContainsKey("x-appwrite-user-jwt")) {
+ client.SetJWT(Context.Req.Headers["x-appwrite-user-jwt"]);
+ } else {
+ return Context.Res.Send("Please sign in, JWT not found");
+ }
var databases = new Databases(client);
try {
await databases.CreateDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.Unique(), new Dictionary<string, object>());
} catch (Exception e) {
- return Context.Response.Send("We messed up, document not created");
+ return Context.Res.Send("We messed up, document not created");
}
- return Context.Response.Send("Document created");
+ return Context.Res.Send("Document created");
}
}
-
-
Kotlin
-
package io.openruntimes.kotlin.src
@@ -1870,8 +2100,12 @@ class Main {
val client = Client().apply {
setEndpoint("https://cloud.appwrite.io/v1")
setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- // Put your secret key in environment variables, so it doesn't leak
- setKey(System.getenv("APPWRITE_API_KEY"))
+ }
+
+ if (context.req.headers["x-appwrite-user-jwt"] != null) {
+ client.setJWT(context.req.headers["x-appwrite-user-jwt"])
+ } else {
+ return context.res.send("Please sign in, JWT not found")
}
val databases = Databases(client)
@@ -1886,11 +2120,9 @@ class Main {
}
}
-
-
Java
-
package io.openruntimes.java.src;
@@ -1905,8 +2137,12 @@ public class Main {
client
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- // Put your secret key in environment variables, so it doesn't leak
- .setKey(System.getenv("APPWRITE_API_KEY"));
+
+ if (context.req.headers.containsKey("x-appwrite-user-jwt")) {
+ client.setJWT(context.req.headers.get("x-appwrite-user-jwt"));
+ } else {
+ return context.res.send("Please sign in, JWT not found");
+ }
Databases databases = new Databases(client);
@@ -1921,15 +2157,19 @@ public class Main {
}
}
-
-Using Multiple Files
+
+Code Splitting
+
+ As your functions grow, you may find yourself needing to split your code into multiple files.
+ This helps you keep your codebase maintainable and easy to read.
+ Here's how you can accomplish code splitting.
+
-
Node.js
-
// src/utils.js
@@ -1947,11 +2187,9 @@ export defaut function ({res}) {
return res.send(add(1, 2));
}
-
-
PHP
-
// src/utils.php
@@ -1972,7 +2210,6 @@ return function ($context) {
-
Python
-
// src/utils.py
@@ -1988,11 +2225,9 @@ import utils
def main(context):
return context.res.send(utils.add(1, 2))
-
-
Ruby
-
# lib/utils.rb
@@ -2009,11 +2244,9 @@ def main(context)
return context.res.send(add(1, 2))
end
-
-
Deno
-
// src/utils.ts
@@ -2030,11 +2263,9 @@ export default function ({res}: {res: any}) {
return res.send(add(1, 2));
}
-
-
Dart
-
// lib/utils.dart
@@ -2050,11 +2281,9 @@ Future<dynamic> main(final context) async {
return context.res.send(add(1, 2));
}
-
-
Swift
-
// Sources/utils.swift
@@ -2072,11 +2301,9 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return context.res.send(add(1, 2))
}
-
-
.NET
-
// src/Utils.cs
@@ -2102,11 +2329,9 @@ public class Handler {
}
}
-
-
Kotlin
-
// src/Utils.kt
@@ -2133,11 +2358,9 @@ class Main {
}
}
-
-
Java
-
// src/Utils.java
@@ -2163,7 +2386,6 @@ public class Main {
}
}
-
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 54335a66b..4447b3e81 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -14,7 +14,7 @@
The generated domains will look like this.
- https://64d4d22db370ae41a32e.functions.cloud.appwrite.io
+ https://64d4d22db370ae41a32e.appwrite.global
@@ -29,7 +29,7 @@
- curl -X POST https://64d4d22db370ae41a32e.functions.cloud.appwrite.io \
+ curl -X POST https://64d4d22db370ae41a32e.appwrite.global \
-H "X-Custom-Header: 123" \
-H "Content-Type: application/json" \
-d '{"data":"this is json data"}'
@@ -41,7 +41,9 @@
You can invoke your Appwrite Functions directly from the Appwrite SDKs.
+
Learn more about using the Appwrite SDKs
+
Client SDKs
@@ -416,6 +418,21 @@ public static void main(String[] args) throws Exception {
+Console
+
+ Another easy way to test a function is directly in the Appwrite console.
+ You test a function by hitting the Execute now button and
+
+
+setParam('srcLight', '/images-ee/docs/functions-execute-light.png')
+ ->setParam('srcDark', '/images-ee/docs/functions-execute-dark.png')
+ ->setParam('alt', '"Create Function" page.')
+ ->setParam('description', '"Create Function" page.')
+ ->render();
+?>
Events
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index cce760392..96119f04d 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -48,8 +48,4 @@ $runtimes['dart-2.17']["cloud"] = true;
-
-
-
-
- Learn more about permissions
-
\ No newline at end of file
+
\ No newline at end of file
From 47dd97178925e79f9f2c2a6a37d589fa3f40cf84 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Mon, 21 Aug 2023 21:19:22 +0000
Subject: [PATCH 097/183] Where applicable, prefer promises because it's
copyable.
---
app/views/docs/authentication-anonymous.phtml | 8 +-
.../docs/authentication-email-pass.phtml | 215 ++++++++++++++++--
app/views/docs/authentication-magic.phtml | 12 +-
app/views/docs/authentication-oauth.phtml | 76 ++++---
app/views/docs/authentication.phtml | 2 +-
5 files changed, 254 insertions(+), 59 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index e9a73943a..4992ebe29 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -26,7 +26,13 @@ const client = new Client()
const account = new Account(client);
-const user = await account.createAnonymousSession();
+const promise = account.createAnonymousSession();
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 31a4b5580..d5f77c4ed 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -22,11 +22,13 @@ const client = new Client()
const account = new Account(client);
-const user = await account.create(
- ID.unique(),
- 'email@example.com',
- 'password'
-);
+const promise = account.create('[USER_ID]', 'email@example.com', '');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
@@ -120,30 +122,114 @@ mutation {
-
Web
-
+ import { Client, Account } from "appwrite";
+
+const client = new Client();
+
+const account = new Account(client);
+
+client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+;
+
+const promise = account.createVerification('https://example.com');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
Flutter
-
+ import 'package:appwrite/appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ ;
+ Future result = account.createVerification(
+ url: 'https://example.com',
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
-
Android
-
+ import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import io.appwrite.Client
+import io.appwrite.services.Account
+
+class MainActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ val client = Client(applicationContext)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+ val account = Account(client)
+
+ GlobalScope.launch {
+ val response = account.createVerification(
+ url = "https://example.com"
+ )
+ val json = response.body?.string()
+ }
+ }
+}
-
Apple
-
+ import Appwrite
+
+func main() async throws {
+ let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ let account = Account(client)
+ let token = try await account.createVerification(
+ url: "https://example.com"
+ )
+
+ print(String(describing: token)
+}
-
GraphQL
-
+ mutation {
+ accountCreateVerification(
+ url: "https://example.com"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
@@ -154,6 +240,10 @@ mutation {
In this example, the code below will be found in the page served at https://example.com/verify.
+
+ Since the secrets are passed in through url params, it will be easiest to perform this step in the browser.
+
+
-
Web
@@ -178,6 +268,84 @@ promise.then(function (response) {
console.log(error);
});
+
+ -
+
Flutter
+
+ import 'package:appwrite/appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ ;
+ Future result = account.updateVerification(
+ userId: '[USER_ID]',
+ secret: '[SECRET]',
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+
+ -
+
Android
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+val account = Account(client)
+
+val response = account.updateVerification(
+ userId = "[USER_ID]",
+ secret = "[SECRET]"
+)
+
+
+ -
+
Apple
+
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+let account = Account(client)
+
+let token = try await account.updateVerification(
+ userId: "[USER_ID]",
+ secret: "[SECRET]"
+)
+
+
+ -
+
GraphQL
+
+ mutation {
+ accountUpdateVerification(
+ userId: "[USER_ID]",
+ secret: "[SECRET]"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
+
@@ -200,10 +368,13 @@ const client = new Client()
const account = new Account(client);
-const user = await account.createEmailSession(
- 'email@example.com',
- 'password'
-);
+const promise = account.createEmailSession('email@example.com', 'password');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
@@ -289,9 +460,13 @@ const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]'); // Your project ID
-const account = new Account(client);
+const promise = account.createRecovery('email@example.com', 'https://example.com');
-const user = await account.createPasswordRecovery('email@example.com', 'https://example.com');
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
@@ -376,9 +551,13 @@ const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]'); // Your project ID
-const account = new Account(client);
+const promise = account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
-const user = await account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index d5aeb16f4..e50694877 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -24,10 +24,14 @@ const client = new Client()
const account = new Account(client);
-const user = await account.createMagicURLSession(
- ID.unique(),
- 'email@example.com'
- );
+
+const promise = account.createMagicURLSession('[USER_ID]', 'email@example.com');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index dc99af316..e136c6af7 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -123,7 +123,7 @@ const client = new Client();
const account = new Account(client);
-const session = account.getSession('current');
+const session = await account.getSession('current');
// Provider information
console.log(session.provider);
@@ -237,38 +237,38 @@ print(session.providerAccessToken);
-
Web
- import { Client, Account } from "appwrite";
-
-const client = new Client();
-
-const account = new Account(client);
-
-client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your Project ID
-;
+ const promise = account.updateSession('[SESSION_ID]');
-// Go to Amazon OAuth login page
-account.createOAuth2Session('amazon', '[LINK_ON_SUCCESS]', '[LINK_ON_FAILURE]');
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
Flutter
import 'package:appwrite/appwrite.dart';
-void main() async {
- final client = new Client();
- final account = new Account(client);
-
- client
- .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint
- .setProject('[PROJECT_ID]') // YOUR PROJECT ID
- ;
-
- // OAuth Login, for simplest implementation you can leave both success and
- // failure link empty so that Appwrite handles everything.
- await account.createOAuth2Session(provider: 'amazon');
-
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ ;
+ Future result = account.updateSession(
+ sessionId: '[SESSION_ID]',
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
}
@@ -280,23 +280,29 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your Project ID
+ .setProject("5df5acd0d48c2") // Your project ID
val account = Account(client)
-account.createOAuth2Session(provider = "amazon")
+val response = account.updateSession(
+ sessionId = "[SESSION_ID]"
+)
-
Apple
- func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
- guard let url = URLContexts.first?.url,
- url.absoluteString.contains("appwrite-callback") else {
- return
- }
- WebAuthComponent.handleIncomingCookie(from: url)
-}
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+let account = Account(client)
+
+let session = try await account.updateSession(
+ sessionId: "[SESSION_ID]"
+)
-
diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml
index bade8dfc9..05e44aa9c 100644
--- a/app/views/docs/authentication.phtml
+++ b/app/views/docs/authentication.phtml
@@ -145,7 +145,7 @@ mutation {
- Log in with magic URL
+ Log in with Magic URL
From fd8e391036e205072c17c7dce011b67eb5653815 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 22 Aug 2023 22:25:10 +0000
Subject: [PATCH 098/183] Don't use images and emojis for Appwrite migration
docs
---
app/views/docs/index.phtml | 1 -
app/views/docs/migrations-firebase.phtml | 10 +++++-----
app/views/docs/migrations-nhost.phtml | 10 +++++-----
app/views/docs/migrations-supabase.phtml | 10 +++++-----
app/views/docs/migrations.phtml | 16 ----------------
5 files changed, 15 insertions(+), 32 deletions(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index ecab000aa..ec9819fbf 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -101,7 +101,6 @@ $cols = [
- NHost
- Cloud to Self-hosted
- Self-hosted to Cloud
- - Security
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index f8c236ea3..0aacc6bc0 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -29,11 +29,11 @@
Firebase
- ✅
- ✅
- ✅
- ✅
-
+ supported
+ supported
+ supported
+ supported
+ not supported
diff --git a/app/views/docs/migrations-nhost.phtml b/app/views/docs/migrations-nhost.phtml
index 0d625eb67..e6c84a22b 100644
--- a/app/views/docs/migrations-nhost.phtml
+++ b/app/views/docs/migrations-nhost.phtml
@@ -28,11 +28,11 @@
NHost
- ✅
- ✅
- ✅
- ✅
-
+ supported
+ supported
+ supported
+ supported
+ not supported
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
index 58036bc5e..02b0bb132 100644
--- a/app/views/docs/migrations-supabase.phtml
+++ b/app/views/docs/migrations-supabase.phtml
@@ -28,11 +28,11 @@
Supabase
- ✅
- ✅
- ✅
- ✅
-
+ supported
+ supported
+ supported
+ supported
+ not supported
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index d15752efa..53dc3eae5 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -12,16 +12,12 @@
-
Source
-
- [IMAGE]
-
Firebase
@@ -30,9 +26,6 @@
-
- [IMAGE]
-
Supabase
@@ -41,9 +34,6 @@
-
- [IMAGE]
-
NHost
@@ -52,9 +42,6 @@
-
- [IMAGE]
-
Cloud to Self-host
@@ -63,9 +50,6 @@
-
- [IMAGE]
-
Self-host to Cloud
From e6f2aace423816b64e0f0bafa050a9dd82ef8f6f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 22 Aug 2023 22:49:21 +0000
Subject: [PATCH 099/183] Reformat support table to be in overview
---
app/views/docs/migrations-firebase.phtml | 24 ---------
app/views/docs/migrations-nhost.phtml | 24 ---------
app/views/docs/migrations-supabase.phtml | 24 ---------
app/views/docs/migrations.phtml | 65 +++++++++++++++---------
4 files changed, 42 insertions(+), 95 deletions(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index 0aacc6bc0..a8fdc3fed 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -14,30 +14,6 @@
- OAuth users will not be transferred. Users will need to re-authenticate with your OAuth provider after the migration is complete.
-Supported resource types
-
-
-
-
- Users
- Databases
- Documents
- Files
- Functions
-
-
-
-
- Firebase
- supported
- supported
- supported
- supported
- not supported
-
-
-
-
Migrating to Appwrite from Firebase
To begin migrating to Appwrite make sure to read the migration overview
diff --git a/app/views/docs/migrations-nhost.phtml b/app/views/docs/migrations-nhost.phtml
index e6c84a22b..ca9aed1d5 100644
--- a/app/views/docs/migrations-nhost.phtml
+++ b/app/views/docs/migrations-nhost.phtml
@@ -13,30 +13,6 @@
- OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
-Supported resource types
-
-
-
-
- Users
- Databases
- Documents
- Files
- Functions
-
-
-
-
- NHost
- supported
- supported
- supported
- supported
- not supported
-
-
-
-
Migrating to Appwrite from NHost
To begin migrating to Appwrite make sure to read the migration overview
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
index 02b0bb132..754445ad0 100644
--- a/app/views/docs/migrations-supabase.phtml
+++ b/app/views/docs/migrations-supabase.phtml
@@ -13,30 +13,6 @@
- OAuth users will not be transferred. Users will need to re-authenticate with your OAuth provider after the migration is complete.
-Supported resource types
-
-
-
-
- Users
- Databases
- Documents
- Files
- Functions
-
-
-
-
- Supabase
- supported
- supported
- supported
- supported
- not supported
-
-
-
-
Migrating to Appwrite from Supabase
To begin migrating to Appwrite make sure to read the migration overview
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index 53dc3eae5..a42226e95 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -1,5 +1,5 @@
- Ready to migrate your project to Appwrite?
+ If you're looking to migrate existing projects to Appwrite, Migrations can help you make the move more quickly.
You can move your app from Firebase, Supabase, NHost, and even move between self-hosted and Cloud projects using Migrations.
Migrations will automatically move accounts, database documents, and storage files from one source to another.
@@ -12,50 +12,64 @@
- Source
-
+ Source
+ Users
+ Databases
+ Documents
+ Files
+ Functions
- Firebase
-
-
-
+
+ supported
+ supported
+ partial
+ supported
+
- Supabase
-
-
-
+
+ supported
+ supported
+ partial
+ supported
+
- NHost
-
-
-
+
+ supported
+ supported
+ partial
+ supported
+
- Cloud to Self-host
-
-
-
+
+ supported
+ supported
+ supported
+ supported
+ supported
- Self-host to Cloud
-
-
-
+
+ supported
+ supported
+ supported
+ supported
+ supported
@@ -64,4 +78,9 @@
Migrations cannot transfer all data perfectly, so certain fields, such as $createdAt and $updatedAt, may not be transferred.
More information can be found on the migration page for each source.
+
+
+
+ Migrations help you jump start your move, but because each product is unique, complex databases and product unique features like functions need to be migrated manually.
+ We also recommend you carefully validate permissions and data integrity when moving between platforms.
\ No newline at end of file
From 7de3dd7d998566362a46afa9c1a8a81255ac48a6 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 22 Aug 2023 22:50:11 +0000
Subject: [PATCH 100/183] Instead of not support, call it manual
---
app/views/docs/migrations.phtml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index a42226e95..e5469750d 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -29,7 +29,7 @@
supported
partial
supported
-
+ manual
@@ -39,7 +39,7 @@
supported
partial
supported
-
+ manual
@@ -49,7 +49,7 @@
supported
partial
supported
-
+ manual
From 1d465e5fec72f39f457748d8e963f6d6d4134226 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 22 Aug 2023 22:54:02 +0000
Subject: [PATCH 101/183] Change partial to yellow
---
app/views/docs/migrations.phtml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index e5469750d..d51e3709f 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -27,7 +27,7 @@
supported
supported
- partial
+ partial
supported
manual
@@ -37,7 +37,7 @@
supported
supported
- partial
+ partial
supported
manual
@@ -47,7 +47,7 @@
supported
supported
- partial
+ partial
supported
manual
From 7d01bd477acbb8dfdca04fade1d8acb779af81cc Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 00:34:39 +0000
Subject: [PATCH 102/183] Personal Information -> Data
---
app/views/docs/authentication-email-pass.phtml | 2 +-
app/views/docs/authentication-oauth.phtml | 2 +-
app/views/docs/authentication-security.phtml | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index d5f77c4ed..8fde1db9a 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -639,7 +639,7 @@ let token = try await account.updateRecovery(
Security
Appwrite's security first mindset goes beyond a securely implementated of authentication API.
- You can enable features like password dictionary, password history, and disallow personal information to encourage users to pick better passwords.
+ You can enable features like password dictionary, password history, and disallow personal data in passwords to encourage users to pick better passwords.
By enabling these features, you protect user data and teach better password choices, which helps make the internet a safer place.
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index e136c6af7..2d87b8f7b 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -216,7 +216,7 @@ print(session.providerAccessToken);
providerAccessToken
- Access token from the OAuth 2 provider. Use this to make requests to the OAuth 2 provider to fetch personal information.
+ Access token from the OAuth 2 provider. Use this to make requests to the OAuth 2 provider to fetch personal data.
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 776c320d8..9bae92804 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -97,9 +97,9 @@
Password dictionary can be enabled in the Auth service's Security tab on the Appwrite console.
-Personal Information
+Personal Data
- Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal information.
- Personal information includes the user's name, email, and phone number.
+ Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal data.
+ Personal data includes the user's name, email, and phone number.
-Disallowing personal information can be enabled in the Auth service's Security tab on the Appwrite console.
+Disallowing personal data can be enabled in the Auth service's Security tab on the Appwrite console.
From cda41f592d8cfbc5b83243a93335cdefe536af61 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 00:52:59 +0000
Subject: [PATCH 103/183] address OAuth2 issues like redirect
---
app/views/docs/authentication-oauth.phtml | 58 ++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 2d87b8f7b..c1ab9671c 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -41,7 +41,7 @@ const client = new Client()
const account = new Account(client);
// Go to OAuth provider login page
-account.createOAuth2Session('amazon');
+account.createOAuth2Session('amazon', [LINK_ON_SUCCESS], [LINK_ON_FAILURE]);
-
@@ -61,6 +61,26 @@ await account.createOAuth2Session(provider: 'amazon');
-
Android
+ In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console.
+
+
+ escape('
+ ...
+
+ ...
+
+
+
+
+
+
+
+
+
+
+ '); ?>
+
+
import io.appwrite.Client
import io.appwrite.services.Account
@@ -77,6 +97,38 @@ account.createOAuth2Session(provider = "amazon")
-
Apple
+ In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your `Info.plist`
+
+
+ escape('CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLName
+ io.appwrite
+ CFBundleURLSchemes
+
+ appwrite-callback-[PROJECT_ID]
+
+
+
+');?>
+
+
+If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift file to ensure cookies work correctly.
+
+
+ escape('
+func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
+ guard let url = URLContexts.first?.url,
+ url.absoluteString.contains("appwrite-callback") else {
+ return
+ }
+ WebAuthComponent.handleIncomingCookie(from: url)
+}
+');?>
+
import Appwrite
@@ -103,6 +155,10 @@ try await account.createOAuth2Session(provider: "amazon")
Once complete, you'll be redirected to the redirect URL configured in your OAuth 2 provider.
+
+ You can optionally configure success or failure redirect links on web to handle success and failure scenarios.
+
+
OAuth 2 Profile
After authenticating a user through their OAuth 2 provider, you can fetch their profile information such as their avatar image or name.
From a4eac315c321292cceabb71a5a15a117e85b7fe7 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 00:57:40 +0000
Subject: [PATCH 104/183] improve getting started guide because we should
---
app/views/docs/authentication-oauth.phtml | 6 +++---
app/views/docs/getting-started-for-android.phtml | 2 +-
app/views/docs/getting-started-for-apple.phtml | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index c1ab9671c..0a3ec4854 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -61,7 +61,7 @@ await account.createOAuth2Session(provider: 'amazon');
-
Android
- In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console.
+ In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the <application> tag, along side the existing <activity> tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console.
escape('
@@ -97,7 +97,7 @@ account.createOAuth2Session(provider = "amazon")
-
Apple
- In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your `Info.plist`
+ In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your Info.plist.
escape('CFBundleURLTypes
@@ -116,7 +116,7 @@ account.createOAuth2Session(provider = "amazon")
');?>
-If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift file to ensure cookies work correctly.
+If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift file to ensure cookies work correctly.
escape('
diff --git a/app/views/docs/getting-started-for-android.phtml b/app/views/docs/getting-started-for-android.phtml
index 74d35cbf0..c410e4caa 100644
--- a/app/views/docs/getting-started-for-android.phtml
+++ b/app/views/docs/getting-started-for-android.phtml
@@ -40,7 +40,7 @@ $androidVersion = (isset($versions['android'])) ? $versions['android'] : '';
OAuth Callback
-In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console.
+In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the <application> tag, along side the existing <activity> tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console.
escape('
diff --git a/app/views/docs/getting-started-for-apple.phtml b/app/views/docs/getting-started-for-apple.phtml
index fc6ce3038..2e71911d9 100644
--- a/app/views/docs/getting-started-for-apple.phtml
+++ b/app/views/docs/getting-started-for-apple.phtml
@@ -64,7 +64,7 @@ $appleVersion = $versions['apple'] ?? '';
OAuth Callback
-In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your `Info.plist`
+In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your Info.plist.
escape('CFBundleURLTypes
@@ -83,7 +83,7 @@ $appleVersion = $versions['apple'] ?? '';
');?>
-If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift file to ensure cookies work correctly.
+If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift file to ensure cookies work correctly.
escape('
From e4e8b0ac2adb26053953c61ddb1f27da490b6483 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 14:43:27 +0000
Subject: [PATCH 105/183] fix view import
---
app/views/docs/functions-execute.phtml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 4447b3e81..e66d845da 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -1,3 +1,8 @@
+
Appwrite Functions executions can be invoked in several ways.
Functions can be invoked through the Appwrite SDK and visting its REST endpoint. Functions can also be triggered by events and scheduled executions.
From 75e79cbfcdbe59fcfe41dd08b97fb13bab03b8fe Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 15:26:17 +0000
Subject: [PATCH 106/183] fix view import + improve env var examples
---
app/views/docs/functions-develop.phtml | 148 ++++++++++++++++++++++---
1 file changed, 132 insertions(+), 16 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index aa5cfc8b1..89f5a3d2a 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -1372,73 +1372,191 @@ namespace runtime {
You can access the environment variables through the systems library of each language.
+
+
+
+ Variable
+ Description
+
+
+
+
+ x-appwrite-trigger
+
+ Describes how the function execution was invoked.
+ Possible values are http, schedule or event.
+
+
+
+ x-appwrite-event
+
+ If the function execution was triggered by an event, describes the triggering event.
+
+
+
+ x-appwrite-user-id
+
+ If the function execution was invoked by an authenticated user, display the user ID.
+ This doesn't apply to Appwrite Console users or API keys.
+
+
+
+ x-appwrite-user-jwt
+
+ JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
+ Learn more about JWT tokens.
+
+
+
+ x-appwrite-country-code
+
+ Displays the country code of the configured locale.
+
+
+
+ x-appwrite-continent-code
+
+ Displays the continent code of the configured locale.
+
+
+
+ x-appwrite-continent-eu
+
+ Describes if the configured local is within the EU.
+
+
+
+
+
+
+Response
+
+ If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
+ The response information will not be logged to the Appwrite Console.
+ There are several possible ways to send a response, explore them in the following Appwrite Function.
+
+
-
Node.js
- process.env.MY_VAR
-
+ export default async ({ req, res, log }) => {
+ return res.send(process.env.MY_VAR, 200);
+}
-
PHP
- getenv('MY_VAR')
-
+ <?php
+
+return function ($context) {
+ return $context->res->send(getenv('MY_VAR'), 200);
+};
-
Python
- os.environ['MY_VAR']
+ def main(context):
+ return context.res.send(os.environ['MY_VAR'], 200)
-
Ruby
- ENV['MY_VAR']
+ def main(context)
+ return context.res.send(ENV['MY_VAR'], 200)
+end
-
Deno
- Deno.env.get('MY_VAR')
+ export default async ({ req, res, log }) => {
+ return res.send(Deno.env.get('MY_VAR'), 200);
+}
-
Dart
- Platform.environment['MY_VAR']
+ import 'dart:async';
+
+Future<dynamic> main(final context) async {
+ return context.res.send(Platform.environment['MY_VAR'], 200);
+}
-
Swift
- ProcessInfo.processInfo.environment["MY_VAR"]
+ import Foundation
+
+func main(context: RuntimeContext) async throws -> RuntimeOutput {
+ return try await context.send(ProcessInfo.processInfo.environment["MY_VAR"], 200)
+}
-
.NET
- Environment.GetEnvironmentVariable("MY_VAR")
+ namespace DotNetRuntime;
+
+public class Handler {
+ public async Task<RuntimeOutput> Main(RuntimeContext Context)
+ {
+ return await Context.Send(Environment.GetEnvironmentVariable("MY_VAR"), 200);
+ }
+}
-
Kotlin
- System.getenv("MY_VAR")
+ package io.openruntimes.kotlin.src
+
+import io.openruntimes.kotlin.RuntimeContext
+import io.openruntimes.kotlin.RuntimeOutput
+
+class Main {
+ fun main(context: RuntimeContext): RuntimeOutput {
+ return context.send(System.getenv("MY_VAR"), 200)
+ }
+}
-
Java
- System.getenv("MY_VAR")
+ package io.openruntimes.java.src;
+
+import io.openruntimes.java.RuntimeContext;
+import io.openruntimes.java.RuntimeOutput;
+
+public class Main {
+ public RuntimeOutput main(RuntimeContext context) throws Exception {
+ return context.send(System.getenv("MY_VAR"), 200);
+ }
+}
-
C++
- std::getenv("MY_VAR")
+ #include "../RuntimeResponse.h"
+#include "../RuntimeRequest.h"
+#include "../RuntimeOutput.h"
+#include "../RuntimeContext.h"
+
+namespace runtime {
+ class Handler {
+ public:
+ static RuntimeOutput main(RuntimeContext &context) {
+
+ return context.send(std::getenv("MY_VAR"), 200);
+ };
+}
@@ -2206,7 +2324,6 @@ return function ($context) {
return $context->res->send(add(1, 2));
};
-
-
Python
@@ -2362,8 +2479,7 @@ class Main {
-
Java
-
-// src/Utils.java
+ // src/Utils.java
package io.openruntimes.java.src;
From 0f51947fb0562267bc42bb1655aefc56a23b3778 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 16:47:30 +0000
Subject: [PATCH 107/183] Add Domain name steps in deploy
---
app/views/docs/functions-deploy.phtml | 33 ++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 0244a4e5f..7be004807 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -164,4 +164,35 @@
Domains
-[TODO: @matej steps to add a custom domain thanks]
+
+ Each deployed function can have it's own domain.
+ By default, one is generated for each of your functions.
+ You can find the generated domain for your function like this.
+
+
+
+ - Navigate to the Appwrite Console's Functions page.
+ - Navigate to the Domains tab.
+ - In the table, you'll find a link formatted similar to
https://64d4d22db370ae41a32e.appwrite.global. This is your preview.
+
+
+
+ You can also add a custom domain, which allows you to build custom REST APIs using nothing but Appwrite Functions.
+ To do this, you need to first buy and register a domain.
+ After obtaining a domain, follow these steps to add the domain to Appwrite.
+
+
+
+ - Navigate to the Appwrite Console's Functions page.
+ - Navigate to the Domains tab.
+ - Click on Create domain.
+ - Input your domain in the Domain input field and click Next.
+ - Copy the CNAME record provided to you, and add it to your domain registar.
+ - Click Go to console and wait for the domain name to be verified and certificate to generate.
+
+
+
+ DNS records can take up to 48 hours to propagate after they're added.
+ Please retry verification over the next 48 hours.
+ If the domain verification still fails and you have confirmed DNS records are added correctly, please contact support.
+
\ No newline at end of file
From ab0cab25181919551aee5283618bda7a71ccc47c Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 18:04:13 +0000
Subject: [PATCH 108/183] Fix some wrong links
---
app/views/docs/functions.phtml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 0dc52264d..f45f4415b 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -48,7 +48,7 @@ $image = new View(__DIR__.'/../general/image.phtml');
Explore how Appwrite Functions can be invoked.
-Learn more about executing functions
+Learn more about executing functions
@@ -64,5 +64,5 @@ $image = new View(__DIR__.'/../general/image.phtml');
Here's a curated list of examples that showcase Appwrite Function's capabilies.
-Learn more about using function examples
+Learn more about using function examples
\ No newline at end of file
From 99c3600dba5c0a864c67f9f10d8327b9f0b29c12 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 19:19:20 +0000
Subject: [PATCH 109/183] Add locale examples
---
app/views/docs/email-and-sms-templates.phtml | 165 +++++++++++++++++--
1 file changed, 148 insertions(+), 17 deletions(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index 7511ce244..d0b0fc21d 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -91,7 +91,56 @@
Email Template Examples
-[TODO: @dlohani once we're ready, let's do examples for each type of template (maybe also what it would look like rendered)]
+Here's an example of using these variables in a template.
+
+ <!doctype html>
+<html>
+
+<head>
+ <style>
+ ... your style here
+ </style>
+</head>
+
+<body style="direction: ltr">
+
+<div style="max-width:650px; word-wrap: break-wrod; overflow-wrap: break-word;
+ word-break: break-all; margin:0 auto;">
+ <table style="margin-top: 32px">
+ <tr>
+ <td>
+ <h1>
+ {{subject}}
+ </h1>
+ </td>
+ </tr>
+ </table>
+
+ <table style="margin-top: 40px">
+ <tr>
+ <td>
+ <p>Hello </p>
+
+ <p>Follow this link to reset your {{project}} password.</p>
+
+ <a href="{{redirect}}" target="_blank">{{redirect}}</a>
+
+ <p><br />If you didn't ask to reset your password, you can ignore this message.</p>
+ <br />
+
+ <p>Thanks
+ <br />
+ {{project}} team
+ </p>
+ </td>
+ </tr>
+ </table>
+</div>
+
+</body>
+
+</html>
+
SMS Templates
You can customize the SMS emplates used for phone verification and login.
@@ -123,27 +172,109 @@
- {{project}}
- The project name.
-
-
- {{team}}
- Thee project team's name.
-
-
- {{user}}
- The name of the uer receiving the email.
-
-
- {{passcode}}
+ {{token}}
The secret code sent to users for phone verification or authentication.
SMS Template Examples
-[TODO: @dlohani once we're ready, let's do examples for each type of template (maybe also what it would look like rendered)]
+Here's an example of using these variables in a template.
+
+ Your account verification code is {{token}}
+
+
Localization
-You can configure localization by settling locale with client.setLocale in the SDKs or the X-Appwrite-Locale HTTP header.
-[TODO: @dlohani Maybe example of a template in two languages? (maybe also what it would look like rendered)]
+
+ Each template can have multiple supported locales, displayed in different format and language.
+ This can be configured under the Template language selector of each template.
+
+
+
+ You can send messages in different localizations by settling locale with client.setLocale() in the SDKs or the X-Appwrite-Locale HTTP header.
+
+
+For example, you can send a phone verification in French.
+
+ -
+
Web
+
+ import { Client, Account } from "appwrite";
+
+const client = new Client();
+
+const account = new Account(client);
+
+client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setLocale('fr') // Your locale
+;
+
+const promise = account.createPhoneVerification();
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+
+
+ -
+
Flutter
+
+ import 'package:appwrite/appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setLocale('fr') // Your locale
+ ;
+ Future result = account.createPhoneVerification();
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+
+
+ -
+
Android
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setLocale('fr') // Your locale
+
+val account = Account(client)
+
+val response = account.createPhoneVerification()
+
+
+ -
+
Apple
+
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setLocale('fr') // Your locale
+
+let account = Account(client)
+
+let token = try await account.createPhoneVerification()
+
+
+
\ No newline at end of file
From 82fe4846541d966b370d1234cfb931138d95684f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 19:28:06 +0000
Subject: [PATCH 110/183] chat GPT helps me spell!
---
app/views/docs/email-and-sms-templates.phtml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index d0b0fc21d..1d4ec7c15 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -27,7 +27,7 @@
- Update the email template fields and click **Update** to save your changes.
Email Templates
-You can customize the email emplates for account verification, magic-url authentication, password resets, and user invites.
+You can customize the email templates for account verification, magic-url authentication, password resets, and user invites.
Email Template Components
Each email templates has the following components that you can customize.
@@ -44,11 +44,11 @@
Sender email
- Readers will see this as the displayed email of the sender. This must be a valid email for the SMTP provider your configured.
+ Readers will see this as the displayed email of the sender. This must be a valid email for the SMTP provider you've configured.
Reply to
- Readers will reply to this email adress instead of the sender address. You can leave this field empty if unused.
+ Readers will reply to this email address instead of the sender address. You can leave this field empty if unused.
Subject
@@ -77,7 +77,7 @@
{{team}}
- Thee project team's name.
+ The project team's name.
{{user}}
@@ -104,7 +104,7 @@
<body style="direction: ltr">
-<div style="max-width:650px; word-wrap: break-wrod; overflow-wrap: break-word;
+<div style="max-width:650px; word-wrap: break-word; overflow-wrap: break-word;
word-break: break-all; margin:0 auto;">
<table style="margin-top: 32px">
<tr>
@@ -143,7 +143,7 @@
SMS Templates
-You can customize the SMS emplates used for phone verification and login.
+You can customize the SMS templates used for phone verification and login.
SMS Template Components
@@ -184,15 +184,15 @@
Your account verification code is {{token}}
+Localization
-Localization
Each template can have multiple supported locales, displayed in different format and language.
This can be configured under the Template language selector of each template.
- You can send messages in different localizations by settling locale with client.setLocale() in the SDKs or the X-Appwrite-Locale HTTP header.
+ You can send messages in different localizations by setting the locale with client.setLocale() in the SDKs or the X-Appwrite-Locale HTTP header.
For example, you can send a phone verification in French.
From 4d5419288713c0143bd60c529c7ab725dfe2975a Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Wed, 23 Aug 2023 20:54:10 +0000
Subject: [PATCH 111/183] deno cache command fixed
---
app/views/docs/functions-develop.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 89f5a3d2a..c251a31ae 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -1602,7 +1602,7 @@ namespace runtime {
Deno
deno
- deno cache
+ deno cache [ENTRYPOINT_FILE]
Dart
From 86d262a673eaef85043def166f989218639e7a19 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Wed, 23 Aug 2023 22:11:38 +0100
Subject: [PATCH 112/183] feat: better functions error handling
---
app/views/docs/functions-develop.phtml | 1810 ++++++++++++------------
1 file changed, 915 insertions(+), 895 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index c251a31ae..4817eb1aa 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -10,10 +10,10 @@
- - The function is invoked.
- - Appwrite passes in request information like headers and environment variables through the
context.req object.
- - The runtime executes the code you defined, you can log through the
context.log or context.error methods.
- - Function terminates when you return results using
context.res.
+ - The function is invoked.
+ - Appwrite passes in request information like headers and environment variables through the
context.req object.
+ - The runtime executes the code you defined, you can log through the
context.log or context.error methods.
+ - Function terminates when you return results using
context.res.
You'll find all of these steps in a simple function like this.
@@ -452,29 +452,29 @@ public class Main {
You'll find these properties in the context object.
-
- Property
- Description
-
+
+ Property
+ Description
+
-
- req
- Contains request information like method, body, and headers. See full examples here.
-
-
- res
- Contains methods to build a response and return information. See full examples here.
-
-
- log
- Logs information to the Appwrite Console, end users will not be able to see these logs. See full examples here.
-
-
- error
- Logs errors to the Appwrite Console, end users will not be able to see these errors. See full examples here.
-
-
+
+ req
+ Contains request information like method, body, and headers. See full examples here.
+
+
+ res
+ Contains methods to build a response and return information. See full examples here.
+
+
+ log
+ Logs information to the Appwrite Console, end users will not be able to see these logs. See full examples here.
+
+
+ error
+ Logs errors to the Appwrite Console, end users will not be able to see these errors. See full examples here.
+
+
@@ -505,7 +505,7 @@ public class Main {
Request
- If you pass data into an Appwrite function, it'll be found in the request object.
+ If you pass data into an Appwrite function, it'll be found in the request object.
This includes all invocation methods, such as data from Appwrite SDKs, HTTP calls, Appwrite events, and browsers visiting the configured domain.
Explore the request object with the following function, which logs all request params to the Appwrite Console.
@@ -750,80 +750,80 @@ public class Main {
Headers
-
- Appwrite Functions will always receive a set of headers that provide meta data about the function execution.
- These are provided along side any custom headers sent to the function.
-
-
-
-
-
- Variable
- Description
-
-
-
-
- x-appwrite-trigger
-
- Describes how the function execution was invoked.
- Possible values are http, schedule or event.
-
-
-
- x-appwrite-event
-
- If the function execution was triggered by an event, describes the triggering event.
-
-
-
- x-appwrite-user-id
-
- If the function execution was invoked by an authenticated user, display the user ID.
- This doesn't apply to Appwrite Console users or API keys.
-
-
-
- x-appwrite-user-jwt
-
- JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
- Learn more about JWT tokens.
-
-
-
- x-appwrite-country-code
-
- Displays the country code of the configured locale.
-
-
-
- x-appwrite-continent-code
-
- Displays the continent code of the configured locale.
-
-
-
- x-appwrite-continent-eu
-
- Describes if the configured local is within the EU.
-
-
-
-
-
-
-Response
-
- If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
- The response information will not be logged to the Appwrite Console.
- There are several possible ways to send a response, explore them in the following Appwrite Function.
-
-
-
- -
-
Node.js
-
- export default async ({ req, res, log }) => {
+
+ Appwrite Functions will always receive a set of headers that provide meta data about the function execution.
+ These are provided along side any custom headers sent to the function.
+
+
+
+
+
+ Variable
+ Description
+
+
+
+
+ x-appwrite-trigger
+
+ Describes how the function execution was invoked.
+ Possible values are http, schedule or event.
+
+
+
+ x-appwrite-event
+
+ If the function execution was triggered by an event, describes the triggering event.
+
+
+
+ x-appwrite-user-id
+
+ If the function execution was invoked by an authenticated user, display the user ID.
+ This doesn't apply to Appwrite Console users or API keys.
+
+
+
+ x-appwrite-user-jwt
+
+ JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
+ Learn more about JWT tokens.
+
+
+
+ x-appwrite-country-code
+
+ Displays the country code of the configured locale.
+
+
+
+ x-appwrite-continent-code
+
+ Displays the continent code of the configured locale.
+
+
+
+ x-appwrite-continent-eu
+
+ Describes if the configured local is within the EU.
+
+
+
+
+
+
+ Response
+
+ If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
+ The response information will not be logged to the Appwrite Console.
+ There are several possible ways to send a response, explore them in the following Appwrite Function.
+
+
+
+ -
+
Node.js
+
+ export default async ({ req, res, log }) => {
switch (req.query.type) {
case 'text':
@@ -841,12 +841,12 @@ public class Main {
return res.empty();
}
}
-
-
- -
-
PHP
-
- <?php
+
+
+ -
+
PHP
+
+ <?php
return function ($context) {
switch ($context->req->query['type']) {
@@ -864,12 +864,12 @@ return function ($context) {
return $context->res->empty();
}
};
-
-
- -
-
Python
-
- def main(context):
+
+
+ -
+
Python
+
+ def main(context):
switch context.req.query['type']:
case 'text':
return context.res.send("This is a text response", 200)
@@ -883,12 +883,12 @@ return function ($context) {
})
default:
return context.res.empty()
-
-
- -
-
Ruby
-
- def main(context)
+
+
+ -
+
Ruby
+
+ def main(context)
case context.req.query['type']
when 'text'
return context.res.send("This is a text response", 200)
@@ -904,12 +904,12 @@ return function ($context) {
return context.res.empty()
end
end
-
-
- -
-
Deno
-
- export default async ({ req, res, log }) => {
+
+
+ -
+
Deno
+
+ export default async ({ req, res, log }) => {
switch (req.query.type) {
case 'text':
@@ -927,12 +927,12 @@ end
return res.empty();
}
}
-
-
- -
-
Dart
-
- import 'dart:async';
+
+
+ -
+
Dart
+
+ import 'dart:async';
Future<dynamic> main(final context) async {
switch (context.req.query['type']) {
@@ -955,12 +955,12 @@ Future<dynamic> main(final context) async {
.empty();
}
}
-
-
- -
-
Swift
-
- import Foundation
+
+
+ -
+
Swift
+
+ import Foundation
func main(context: RuntimeContext) async throws -> RuntimeOutput {
switch context.req.query["type"] {
@@ -978,12 +978,12 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return try await context.empty()
}
}
-
-
- -
-
.NET
-
- namespace DotNetRuntime;
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
public class Handler {
public async Task<RuntimeOutput> Main(RuntimeContext Context)
@@ -1005,12 +1005,12 @@ public class Handler {
}
}
}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
import io.openruntimes.kotlin.RuntimeContext
import io.openruntimes.kotlin.RuntimeOutput
@@ -1026,12 +1026,12 @@ class Main {
}
}
}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
import io.openruntimes.java.RuntimeContext;
import io.openruntimes.java.RuntimeOutput;
@@ -1056,12 +1056,12 @@ public class Main {
}
}
}
-
-
- -
-
C++
-
- #include "../RuntimeResponse.h"
+
+
+ -
+
C++
+
+ #include "../RuntimeResponse.h"
#include "../RuntimeRequest.h"
#include "../RuntimeOutput.h"
#include "../RuntimeContext.h"
@@ -1090,35 +1090,35 @@ namespace runtime {
}
};
}
-
-
-
-
-Logging
-
- To protect user privacy, the request and response objects are not logged to the Appwrite Console by default.
- This means, to see logs or debug function executions you need to use the log() and error() methods.
- These logs are only visible to developers with access to the Appwrite Console.
-
-
-Here's an example of using logs and errors.
-
- -
-
Node.js
-
- export default async ({ res, log, error }) => {
+
+
+
+
+ Logging
+
+ To protect user privacy, the request and response objects are not logged to the Appwrite Console by default.
+ This means, to see logs or debug function executions you need to use the log() and error() methods.
+ These logs are only visible to developers with access to the Appwrite Console.
+
+
+ Here's an example of using logs and errors.
+
+ -
+
Node.js
+
+ export default async ({ res, log, error }) => {
log("This is a log, use for logging information to console");
log(`This function was called with ${context.req.method} method`);
error("This is an error, use for logging errors to console");
return res.send("Check the Appwrite Console to see logs and errors!");
};
-
-
- -
-
PHP
-
- <?php
+
+
+ -
+
PHP
+
+ <?php
return function ($context) {
$context->log("This is a log, use for logging information to console");
@@ -1127,47 +1127,47 @@ return function ($context) {
return $context->send("Check the Appwrite Console to see logs and errors!");
};
-
-
- -
-
Python
-
- def main(context):
+
+
+ -
+
Python
+
+ def main(context):
context.log("This is a log, use for logging information to console")
context.log(f"This function was called with {context.req.method} method")
context.error("This is an error, use for logging errors to console")
return context.send("Check the Appwrite Console to see logs and errors!")
-
-
- -
-
Ruby
-
- def main(context)
+
+
+ -
+
Ruby
+
+ def main(context)
context.log("This is a log, use for logging information to console")
context.log("This function was called with #{context.req.method} method")
context.error("This is an error, use for logging errors to console")
return context.send("Check the Appwrite Console to see logs and errors!")
end
-
-
- -
-
Deno
-
- export default async ({ res, log, error }: any) => {
+
+
+ -
+
Deno
+
+ export default async ({ res, log, error }: any) => {
log("This is a log, use for logging information to console");
log(`This function was called with ${context.req.method} method`);
error("This is an error, use for logging errors to console");
return res.send("Check the Appwrite Console to see logs and errors!");
};
-
-
- -
-
Dart
-
- import 'dart:async';
+
+
+ -
+
Dart
+
+ import 'dart:async';
Future<dynamic> main(final context) async {
context.log("This is a log, use for logging information to console");
@@ -1176,12 +1176,12 @@ Future<dynamic> main(final context) async {
return context.send("Check the Appwrite Console to see logs and errors!");
}
-
-
- -
-
Swift
-
- import Foundation
+
+
+ -
+
Swift
+
+ import Foundation
func main(context: RuntimeContext) async throws -> RuntimeOutput {
context.log("This is a log, use for logging information to console")
@@ -1190,12 +1190,12 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
return try context.send("Check the Appwrite Console to see logs and errors!")
}
-
-
- -
-
.NET
-
- namespace DotNetRuntime;
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
public class Handler {
public async Task<RuntimeOutput> Main(RuntimeContext Context)
@@ -1207,12 +1207,12 @@ public class Handler {
return await Context.Send("Check the Appwrite Console to see logs and errors!");
}
}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
import io.openruntimes.kotlin.RuntimeContext
import io.openruntimes.kotlin.RuntimeOutput
@@ -1226,12 +1226,12 @@ class Main {
return context.send("Check the Appwrite Console to see logs and errors!")
}
}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
import io.openruntimes.java.RuntimeContext;
import io.openruntimes.java.RuntimeOutput;
@@ -1245,12 +1245,12 @@ public class Main {
return context.send("Check the Appwrite Console to see logs and errors!");
}
}
-
-
- -
-
C++
-
- #include "../RuntimeResponse.h"
+
+
+ -
+
C++
+
+ #include "../RuntimeResponse.h"
#include "../RuntimeRequest.h"
#include "../RuntimeOutput.h"
#include "../RuntimeContext.h"
@@ -1267,394 +1267,394 @@ namespace runtime {
}
};
}
-
-
-
-You can access these logs through the following steps.
-
- - In Appwrite Console, navigate to Functions.
- - Click to open a function you wish to inspect.
- - Under the Executions tab, click on an execution.
- - In the Response section, you'll be able to view logs under the Logs and Errors tabs.
-
+
+
+
+ You can access these logs through the following steps.
+
+ - In Appwrite Console, navigate to Functions.
+ - Click to open a function you wish to inspect.
+ - Under the Executions tab, click on an execution.
+ - In the Response section, you'll be able to view logs under the Logs and Errors tabs.
+
+
+ Accessing Environment Variables
+
+ If you need to pass constants or secrets to Appwrite Functions, you can use environment variables.
+ Environmental variables can be global, or function specific.
+
+
+ Default Environment Variables
+
+ Appwrite runtimes passes in some environment variables by default.
+ These are always accesible for every function at runtime.
+
+
+
+ Appwrite API keys
+
+ If your function is using an Appwrite SDK with an API key, this API key needs to be generated and passed in manually.
+ API keys are not passed by default for security reasons.
+
+
+
+
+
+
+ Variable
+ Description
+
+
+
+
+ APPWRITE_FUNCTION_ID
+
+ The ID of the running function.
+
+
+
+ APPWRITE_FUNCTION_NAME
+
+ The Name of the running function.
+
+
+
+ APPWRITE_FUNCTION_DEPLOYMENT
+
+ The deployment ID of the running function.
+
+
+
+ APPWRITE_FUNCTION_PROJECT_ID
+
+ The project ID of the running function.
+
+
+
+ APPWRITE_FUNCTION_RUNTIME_NAME
+
+ The runtime of the running function.
+
+
+
+ APPWRITE_FUNCTION_RUNTIME_VERSION
+
+ The runtime version of the running function.
+
+
+
+
+
+ Local Environment Variables
+
+ Local environment variables will only be accessible in the function they belong to.
+ Local environment variables will override global environment variables when they have conflicting names.
+
+
+ - In Appwrite Console, navigate to Functions.
+ - Click to open a function you wish to add variables to.
+ - Under the Settings tab, navigate to Environment variables.
+ - Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
+
+
+ Global Environment Variables
+
+ Global environment variables are accessible to all Appwrite Functions.
+ Local environment variables will override global environment variables when they have conflicting names.
+
+
+ - In Appwrite Console, navigate to your project's Settings page.
+ - Navigate to Global variables section.
+ - Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
+
+
+
+ You can access the environment variables through the systems library of each language.
+
+
+
+
+
+ Variable
+ Description
+
+
+
+
+ x-appwrite-trigger
+
+ Describes how the function execution was invoked.
+ Possible values are http, schedule or event.
+
+
+
+ x-appwrite-event
+
+ If the function execution was triggered by an event, describes the triggering event.
+
+
+
+ x-appwrite-user-id
+
+ If the function execution was invoked by an authenticated user, display the user ID.
+ This doesn't apply to Appwrite Console users or API keys.
+
+
+
+ x-appwrite-user-jwt
+
+ JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
+ Learn more about JWT tokens.
+
+
+
+ x-appwrite-country-code
+
+ Displays the country code of the configured locale.
+
+
+
+ x-appwrite-continent-code
+
+ Displays the continent code of the configured locale.
+
+
+
+ x-appwrite-continent-eu
+
+ Describes if the configured local is within the EU.
+
+
+
+
+
+
+ Response
+
+ If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
+ The response information will not be logged to the Appwrite Console.
+ There are several possible ways to send a response, explore them in the following Appwrite Function.
+
+
+
+ -
+
Node.js
+
+ export default async ({ req, res, log }) => {
+ return res.send(process.env.MY_VAR, 200);
+}
+
+
+ -
+
PHP
+
+ <?php
-Accessing Environment Variables
-
- If you need to pass constants or secrets to Appwrite Functions, you can use environment variables.
- Environmental variables can be global, or function specific.
-
+return function ($context) {
+ return $context->res->send(getenv('MY_VAR'), 200);
+};
+
+
+ -
+
Python
+
+ def main(context):
+ return context.res.send(os.environ['MY_VAR'], 200)
+
+
+ -
+
Ruby
+
+ def main(context)
+ return context.res.send(ENV['MY_VAR'], 200)
+end
+
+
+ -
+
Deno
+
+ export default async ({ req, res, log }) => {
+ return res.send(Deno.env.get('MY_VAR'), 200);
+}
+
+
+ -
+
Dart
+
+ import 'dart:async';
-Default Environment Variables
-
- Appwrite runtimes passes in some environment variables by default.
- These are always accesible for every function at runtime.
-
+Future<dynamic> main(final context) async {
+ return context.res.send(Platform.environment['MY_VAR'], 200);
+}
+
+
+ -
+
Swift
+
+ import Foundation
-
- Appwrite API keys
-
- If your function is using an Appwrite SDK with an API key, this API key needs to be generated and passed in manually.
- API keys are not passed by default for security reasons.
-
-
+func main(context: RuntimeContext) async throws -> RuntimeOutput {
+ return try await context.send(ProcessInfo.processInfo.environment["MY_VAR"], 200)
+}
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
-
-
-
- Variable
- Description
-
-
-
-
- APPWRITE_FUNCTION_ID
-
- The ID of the running function.
-
-
-
- APPWRITE_FUNCTION_NAME
-
- The Name of the running function.
-
-
-
- APPWRITE_FUNCTION_DEPLOYMENT
-
- The deployment ID of the running function.
-
-
+public class Handler {
+ public async Task<RuntimeOutput> Main(RuntimeContext Context)
+ {
+ return await Context.Send(Environment.GetEnvironmentVariable("MY_VAR"), 200);
+ }
+}
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
+
+import io.openruntimes.kotlin.RuntimeContext
+import io.openruntimes.kotlin.RuntimeOutput
+
+class Main {
+ fun main(context: RuntimeContext): RuntimeOutput {
+ return context.send(System.getenv("MY_VAR"), 200)
+ }
+}
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
+
+import io.openruntimes.java.RuntimeContext;
+import io.openruntimes.java.RuntimeOutput;
+
+public class Main {
+ public RuntimeOutput main(RuntimeContext context) throws Exception {
+ return context.send(System.getenv("MY_VAR"), 200);
+ }
+}
+
+
+ -
+
C++
+
+ #include "../RuntimeResponse.h"
+#include "../RuntimeRequest.h"
+#include "../RuntimeOutput.h"
+#include "../RuntimeContext.h"
+
+namespace runtime {
+ class Handler {
+ public:
+ static RuntimeOutput main(RuntimeContext &context) {
+
+ return context.send(std::getenv("MY_VAR"), 200);
+ };
+}
+
+
+
+
+ Dependencies
+
+
+ Your function's dependencies should be managed by the package manager of each language. By default, we include the following package managers in each runtime:
+
+
+
+ To install your dependencies before your function is built, you should add the relevant install command to the top your functions Build Commands script.
+
+
+
+
+
+ Language
+ Package Manager
+ Commands
+
+
- APPWRITE_FUNCTION_PROJECT_ID
-
- The project ID of the running function.
-
+ Node.js
+ npm
+ npm install
- APPWRITE_FUNCTION_RUNTIME_NAME
-
- The runtime of the running function.
-
+ PHP
+ Composer
+ composer install
- APPWRITE_FUNCTION_RUNTIME_VERSION
-
- The runtime version of the running function.
-
+ Python
+ pip
+ pip install -r requirements.txt
-
-
-
-Local Environment Variables
-
- Local environment variables will only be accessible in the function they belong to.
- Local environment variables will override global environment variables when they have conflicting names.
-
-
- - In Appwrite Console, navigate to Functions.
- - Click to open a function you wish to add variables to.
- - Under the Settings tab, navigate to Environment variables.
- - Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
-
-
-Global Environment Variables
-
- Global environment variables are accessible to all Appwrite Functions.
- Local environment variables will override global environment variables when they have conflicting names.
-
-
- - In Appwrite Console, navigate to your project's Settings page.
- - Navigate to Global variables section.
- - Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
-
-
-
- You can access the environment variables through the systems library of each language.
-
-
-
-
- Variable
- Description
+ Ruby
+ Bundler
+ bundle install
-
-
- x-appwrite-trigger
-
- Describes how the function execution was invoked.
- Possible values are http, schedule or event.
-
+ Deno
+ deno
+ deno cache [ENTRYPOINT_FILE]
- x-appwrite-event
-
- If the function execution was triggered by an event, describes the triggering event.
-
+ Dart
+ pub
+ pub get
- x-appwrite-user-id
-
- If the function execution was invoked by an authenticated user, display the user ID.
- This doesn't apply to Appwrite Console users or API keys.
-
+ Swift
+ Swift Package Manager
+ N/A
- x-appwrite-user-jwt
-
- JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
- Learn more about JWT tokens.
-
+ .NET
+ NuGet
+ N/A
- x-appwrite-country-code
-
- Displays the country code of the configured locale.
-
+ Kotlin
+ Gradle
+ N/A
- x-appwrite-continent-code
-
- Displays the continent code of the configured locale.
-
+ Java
+ Gradle
+ N/A
- x-appwrite-continent-eu
-
- Describes if the configured local is within the EU.
-
+ C++
+ None
+ N/A
-
-
+
+ Using Appwrite in a Function
-Response
-
- If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
- The response information will not be logged to the Appwrite Console.
- There are several possible ways to send a response, explore them in the following Appwrite Function.
-
-
-
- -
-
Node.js
-
- export default async ({ req, res, log }) => {
- return res.send(process.env.MY_VAR, 200);
-}
-
-
- -
-
PHP
-
- <?php
-
-return function ($context) {
- return $context->res->send(getenv('MY_VAR'), 200);
-};
-
-
- -
-
Python
-
- def main(context):
- return context.res.send(os.environ['MY_VAR'], 200)
-
-
- -
-
Ruby
-
- def main(context)
- return context.res.send(ENV['MY_VAR'], 200)
-end
-
-
- -
-
Deno
-
- export default async ({ req, res, log }) => {
- return res.send(Deno.env.get('MY_VAR'), 200);
-}
-
-
- -
-
Dart
-
- import 'dart:async';
+ Appwrite can be used in your functions by adding the relevant SDK to your function's dependencies
+ Authenticating with Appwrite is done via an API key or a JWT token. You can read more about authentication in the Server Authentication section of the docs.
-Future<dynamic> main(final context) async {
- return context.res.send(Platform.environment['MY_VAR'], 200);
-}
-
-
- -
-
Swift
-
- import Foundation
-
-func main(context: RuntimeContext) async throws -> RuntimeOutput {
- return try await context.send(ProcessInfo.processInfo.environment["MY_VAR"], 200)
-}
-
-
- -
-
.NET
-
- namespace DotNetRuntime;
-
-public class Handler {
- public async Task<RuntimeOutput> Main(RuntimeContext Context)
- {
- return await Context.Send(Environment.GetEnvironmentVariable("MY_VAR"), 200);
- }
-}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
-
-import io.openruntimes.kotlin.RuntimeContext
-import io.openruntimes.kotlin.RuntimeOutput
-class Main {
- fun main(context: RuntimeContext): RuntimeOutput {
- return context.send(System.getenv("MY_VAR"), 200)
- }
-}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
+ Using with API Key
+
+ API keys have defined scopes when you create them.
+ They ignore permissions and operate without a sessions.
+ Use API keys if the function should act as an admin type role, instead of acting on behalf of a user.
+
+
+ -
+
Node.js
+
+ import { Client, Databases, ID } from 'node-appwrite';
-import io.openruntimes.java.RuntimeContext;
-import io.openruntimes.java.RuntimeOutput;
-
-public class Main {
- public RuntimeOutput main(RuntimeContext context) throws Exception {
- return context.send(System.getenv("MY_VAR"), 200);
- }
-}
-
-
- -
-
C++
-
- #include "../RuntimeResponse.h"
-#include "../RuntimeRequest.h"
-#include "../RuntimeOutput.h"
-#include "../RuntimeContext.h"
-
-namespace runtime {
- class Handler {
- public:
- static RuntimeOutput main(RuntimeContext &context) {
-
- return context.send(std::getenv("MY_VAR"), 200);
- };
-}
-
-
-
-
-Dependencies
-
-
- Your function's dependencies should be managed by the package manager of each language. By default, we include the following package managers in each runtime:
-
-
-
- To install your dependencies before your function is built, you should add the relevant install command to the top your functions Build Commands script.
-
-
-
-
-
- Language
- Package Manager
- Commands
-
-
-
- Node.js
- npm
- npm install
-
-
- PHP
- Composer
- composer install
-
-
- Python
- pip
- pip install -r requirements.txt
-
-
- Ruby
- Bundler
- bundle install
-
-
- Deno
- deno
- deno cache [ENTRYPOINT_FILE]
-
-
- Dart
- pub
- pub get
-
-
- Swift
- Swift Package Manager
- N/A
-
-
- .NET
- NuGet
- N/A
-
-
- Kotlin
- Gradle
- N/A
-
-
- Java
- Gradle
- N/A
-
-
- C++
- None
- N/A
-
-
-
-Using Appwrite in a Function
-
-Appwrite can be used in your functions by adding the relevant SDK to your function's dependencies
-Authenticating with Appwrite is done via an API key or a JWT token. You can read more about authentication in the Server Authentication section of the docs.
-
-
-Using with API Key
-
- API keys have defined scopes when you create them.
- They ignore permissions and operate without a sessions.
- Use API keys if the function should act as an admin type role, instead of acting on behalf of a user.
-
-
- -
-
Node.js
-
- import { Client, Databases, ID } from 'node-appwrite';
-
-export default async ({ req, res, log }) => {
+export default async ({ req, res, log, error }) => {
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
@@ -1667,17 +1667,18 @@ export default async ({ req, res, log }) => {
try {
databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
} catch (e) {
- return res.send("We messed up, document not created")
+ error("Failed to create document: " + e.message)
+ return res.send("Failed to create document")
}
return res.send("Document created")
}
-
-
- -
-
PHP
-
- <?php
+
+
+ -
+
PHP
+
+ <?php
require(__DIR__ . '/../vendor/autoload.php');
@@ -1699,17 +1700,18 @@ return function ($context) {
try {
$databases->createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID::unique(), []);
} catch (Exception $e) {
- return $context->res->send("We messed up, document not created");
+ $context->error("Failed to create document: " . $e->getMessage());
+ return $context->res->send("Failed to create document");
}
return $context->res->send("Document created");
};
-
-
- -
-
Python
-
- from appwrite.client import Client
+
+
+ -
+
Python
+
+ from appwrite.client import Client
from appwrite.services.databases import Databases
from appwrite.id import ID
@@ -1729,15 +1731,16 @@ def main(context):
try:
databases.create_document("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {})
except Exception as e:
- return context.response.send("We messed up, document not created")
+ context.error("Failed to create document: " + e.message)
+ return context.response.send("Failed to create document")
return context.response.send("Document created")
-
-
- -
-
Ruby
-
- require "appwrite"
+
+
+ -
+
Ruby
+
+ require "appwrite"
def main(context)
client = Appwrite::Client.new
@@ -1752,19 +1755,20 @@ def main(context)
begin
databases.create_document('[DATABASE_ID]', '[COLLECTION_ID]', Appwrite::ID.unique(), {})
rescue Appwrite::Exception => e
- return context.response.send("We messed up, document not created")
+ context.error("Failed to create document: " + e.message)
+ return context.response.send("Failed to create document")
end
return context.response.send("Document created")
end
-
-
- -
-
Deno
-
- import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
+
+
+ -
+
Deno
+
+ import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
-export default function ({req, res}: any){
+export default function ({req, res, error}: any){
const client = new Client();
client
.setEndpoint("https://cloud.appwrite.io/v1")
@@ -1777,17 +1781,18 @@ export default function ({req, res}: any){
try {
databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {});
} catch (e) {
- return res.send("We messed up, document not created");
+ error("Failed to create document: " + e.message);
+ return res.send("Failed to create document");
}
return res.send("Document created");
-}
-
-
- -
-
Dart
-
- import 'dart:async';
+}
+
+
+ -
+
Dart
+
+ import 'dart:async';
import 'package:dart_appwrite/dart_appwrite.dart';
@@ -1803,17 +1808,18 @@ Future<dynamic> main(final context) async {
try {
await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {});
} catch (e) {
- return context.res.send("We messed up, document not created");
+ context.error("Failed to create document: " + e.message);
+ return context.res.send("Failed to create document");
}
return context.res.send("Document created");
}
-
-
- -
-
Swift
-
- import Appwrite
+
+
+ -
+
Swift
+
+ import Appwrite
import AppwriteModels
import Foundation
@@ -1829,17 +1835,18 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
do {
try await databases.createDocument(databaseId: "[DATABASE_ID]", collectionId: "[COLLECTION_ID]", data: [:])
} catch {
- return context.res.send("We messed up, document not created")
+ context.error("Failed to create document: \(error.localizedDescription)")
+ return try await context.res.send("Failed to create document")
}
return context.res.send("Document created")
}
-
-
- -
-
.NET
-
- namespace DotNetRuntime;
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
using Appwrite;
using Appwrite.Services;
@@ -1860,18 +1867,19 @@ public class Handler {
try {
await databases.CreateDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.Unique(), new Dictionary<string, object>());
} catch (Exception e) {
- return Context.Response.Send("We messed up, document not created");
+ Context.Error("Failed to create document: " + e.Message);
+ return Context.Response.Send("Failed to create document");
}
return Context.Response.Send("Document created");
}
}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
import io.openruntimes.kotlin.RuntimeContext
import io.openruntimes.kotlin.RuntimeOutput
@@ -1894,18 +1902,19 @@ class Main {
try {
databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), HashMap())
} catch (e: Exception) {
- return context.res.send("We messed up, document not created")
+ context.error("Failed to create document: " + e.message)
+ return context.res.send("Failed to create document")
}
return context.res.send("Document created")
}
}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
import io.openruntimes.java.RuntimeContext;
import io.openruntimes.java.RuntimeOutput;
@@ -1926,34 +1935,35 @@ public class Main {
try {
databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), new HashMap<>());
} catch (Exception e) {
- return context.res.send("We messed up, document not created");
+ context.error("Failed to create document: " + e.getMessage());
+ return context.res.send("Failed to create document");
}
return context.res.send("Document created");
}
}
-
-
-
+
+
+
-Using JWT
-
- JWTs allow you to act on behalf of an user in your Appwrite Function.
- When using JWTs, you will be able to access and change only the resources with the same permissions as the user account that signed the JWT.
- This preserves the permissions you configured on each resource.
-
+ Using JWT
+
+ JWTs allow you to act on behalf of an user in your Appwrite Function.
+ When using JWTs, you will be able to access and change only the resources with the same permissions as the user account that signed the JWT.
+ This preserves the permissions you configured on each resource.
+
-
- If the Appwrite Function is invoked by an authenticated user, the x-appwrite-user-jwt header is automatically passed in.
-
+
+ If the Appwrite Function is invoked by an authenticated user, the x-appwrite-user-jwt header is automatically passed in.
+
-
- -
-
Node.js
-
- import { Client, Databases, ID } from 'node-appwrite';
+
+ -
+
Node.js
+
+ import { Client, Databases, ID } from 'node-appwrite';
export default async ({ req, res, log }) => {
@@ -1972,17 +1982,18 @@ export default async ({ req, res, log }) => {
try {
databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
} catch (e) {
- return res.send("We messed up, document not created")
+ log("Failed to create document: " + e.message)
+ return res.send("Failed to create document")
}
return res.send("Document created")
}
-
-
- -
-
PHP
-
- <?php
+
+
+ -
+
PHP
+
+ <?php
require(__DIR__ . '/../vendor/autoload.php');
@@ -2008,17 +2019,18 @@ return function ($context) {
try {
$databases->createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID::unique(), []);
} catch (Exception $e) {
- return $context->res->send("We messed up, document not created");
+ $context->error("Failed to create document: " . $e->getMessage());
+ return $context->res->send("Failed to create document");
}
return $context->res->send("Document created");
};
-
-
- -
-
Python
-
- from appwrite.client import Client
+
+
+ -
+
Python
+
+ from appwrite.client import Client
from appwrite.services.databases import Databases
from appwrite.id import ID
@@ -2042,15 +2054,16 @@ def main(context):
try:
databases.create_document("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {})
except Exception as e:
- return context.response.send("We messed up, document not created")
+ context.error("Failed to create document: " + e.message)
+ return context.response.send("Failed to create document")
return context.response.send("Document created")
-
-
- -
-
Ruby
-
- require "appwrite"
+
+
+ -
+
Ruby
+
+ require "appwrite"
def main(context)
client = Appwrite::Client.new
@@ -2069,19 +2082,20 @@ def main(context)
begin
databases.create_document('[DATABASE_ID]', '[COLLECTION_ID]', Appwrite::ID.unique(), {})
rescue Appwrite::Exception => e
- return context.response.send("We messed up, document not created")
+ context.error("Failed to create document: " + e.message)
+ return context.response.send("Failed to create document")
end
return context.response.send("Document created")
end
-
-
- -
-
Deno
-
- import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
+
+
+ -
+
Deno
+
+ import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
-export default function ({req, res}: any){
+export default function ({req, res, error}: any){
const client = new Client();
client
.setEndpoint("https://cloud.appwrite.io/v1")
@@ -2098,17 +2112,18 @@ export default function ({req, res}: any){
try {
databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {});
} catch (e) {
- return res.send("We messed up, document not created");
+ error("Failed to create document: " + e.message)
+ return res.send("Failed to create document");
}
return res.send("Document created");
-}
-
-
- -
-
Dart
-
- import 'dart:async';
+}
+
+
+ -
+
Dart
+
+ import 'dart:async';
import 'package:dart_appwrite/dart_appwrite.dart';
@@ -2128,17 +2143,18 @@ Future<dynamic> main(final context) async {
try {
await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {});
} catch (e) {
- return context.res.send("We messed up, document not created");
+ context.error("Failed to create document: " + e.message);
+ return context.res.send("Failed to create document");
}
return context.res.send("Document created");
}
-
-
- -
-
Swift
-
- import Appwrite
+
+
+ -
+
Swift
+
+ import Appwrite
import AppwriteModels
import Foundation
@@ -2158,17 +2174,18 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
do {
try await databases.createDocument(databaseId: "[DATABASE_ID]", collectionId: "[COLLECTION_ID]", data: [:])
} catch {
- return context.res.send("We messed up, document not created")
+ context.error("Failed to create document: \(error.localizedDescription)")
+ return context.res.send("Failed to create document")
}
return context.res.send("Document created")
}
-
-
- -
-
.NET
-
- namespace DotNetRuntime;
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
using Appwrite;
using Appwrite.Services;
@@ -2193,18 +2210,19 @@ public class Handler {
try {
await databases.CreateDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.Unique(), new Dictionary<string, object>());
} catch (Exception e) {
- return Context.Res.Send("We messed up, document not created");
+ Context.Error("Failed to create document: " + e.Message);
+ return Context.Res.Send("Failed to create document");
}
return Context.Res.Send("Document created");
}
}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
import io.openruntimes.kotlin.RuntimeContext
import io.openruntimes.kotlin.RuntimeOutput
@@ -2231,18 +2249,19 @@ class Main {
try {
databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), HashMap())
} catch (e: Exception) {
- return context.res.send("We messed up, document not created")
+ context.error("Failed to create document: " + e.message)
+ return context.res.send("Failed to create document")
}
return context.res.send("Document created")
}
}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
import io.openruntimes.java.RuntimeContext;
import io.openruntimes.java.RuntimeOutput;
@@ -2267,162 +2286,163 @@ public class Main {
try {
databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), new HashMap<>());
} catch (Exception e) {
- return context.res.send("We messed up, document not created");
+ context.error("Failed to create document: " + e.getMessage());
+ return context.res.send("Failed to create document");
}
return context.res.send("Document created");
}
}
-
-
-
-
-
-Code Splitting
-
- As your functions grow, you may find yourself needing to split your code into multiple files.
- This helps you keep your codebase maintainable and easy to read.
- Here's how you can accomplish code splitting.
-
-
- -
-
Node.js
-
- // src/utils.js
+
+
+
+
+
+ Code Splitting
+
+ As your functions grow, you may find yourself needing to split your code into multiple files.
+ This helps you keep your codebase maintainable and easy to read.
+ Here's how you can accomplish code splitting.
+
+
+ -
+
Node.js
+
+ // src/utils.js
export function add(a, b) {
return a + b;
}
-
-
- // src/main.js
+
+
+ // src/main.js
import { add } from './utils.js';
export defaut function ({res}) {
return res.send(add(1, 2));
}
-
-
- -
-
PHP
-
- // src/utils.php
+
+
+ -
+
PHP
+
+ // src/utils.php
function add($a, $b) {
return $a + $b;
}
-
-
- // src/main.php
+
+
+ // src/main.php
include 'utils.php';
return function ($context) {
return $context->res->send(add(1, 2));
};
-
-
- -
-
Python
-
- // src/utils.py
+
+
+ -
+
Python
+
+ // src/utils.py
def add(a, b):
return a + b;
-
-
- // src/main.py
+
+
+ // src/main.py
import utils
def main(context):
return context.res.send(utils.add(1, 2))
-
-
- -
-
Ruby
-
- # lib/utils.rb
+
+
+ -
+
Ruby
+
+ # lib/utils.rb
def add(a, b)
return a + b
end
-
-
- # lib/main.rb
+
+
+ # lib/main.rb
require_relative 'utils'
def main(context)
return context.res.send(add(1, 2))
end
-
-
- -
-
Deno
-
- // src/utils.ts
+
+
+ -
+
Deno
+
+ // src/utils.ts
export function add(a: number, b: number): number {
return a + b;
-}
-
-
- // src/main.ts
+}
+
+
+ // src/main.ts
import { add } from './utils.ts';
export default function ({res}: {res: any}) {
return res.send(add(1, 2));
}
-
-
- -
-
Dart
-
- // lib/utils.dart
+
+
+ -
+
Dart
+
+ // lib/utils.dart
int add(int a, int b) {
return a + b;
}
-
-
- // lib/main.dart
+
+
+ // lib/main.dart
import 'dart:async';
Future<dynamic> main(final context) async {
return context.res.send(add(1, 2));
}
-
-
- -
-
Swift
-
- // Sources/utils.swift
+
+
+ -
+
Swift
+
+ // Sources/utils.swift
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
-
-
- // Sources/index.swift
+
+
+ // Sources/index.swift
import Foundation
func main(context: RuntimeContext) async throws -> RuntimeOutput {
return context.res.send(add(1, 2))
}
-
-
- -
-
.NET
-
- // src/Utils.cs
+
+
+ -
+
.NET
+
+ // src/Utils.cs
namespace DotNetRuntime
@@ -2433,9 +2453,9 @@ public static class Utils
return a + b;
}
}
-
-
- // src/Index.cs
+
+
+ // src/Index.cs
namespace DotNetRuntime
@@ -2445,12 +2465,12 @@ public class Handler {
return Context.Res.Send(Utils.Add(1, 2));
}
}
-
-
- -
-
Kotlin
-
- // src/Utils.kt
+
+
+ -
+
Kotlin
+
+ // src/Utils.kt
package io.openruntimes.kotlin.src
@@ -2459,9 +2479,9 @@ class Utils {
return a + b
}
}
-
-
- // src/Main.kt
+
+
+ // src/Main.kt
package io.openruntimes.kotlin.src
@@ -2474,12 +2494,12 @@ class Main {
return context.res.send(Utils.add(1, 2))
}
}
-
-
- -
-
Java
-
- // src/Utils.java
+
+
+ -
+
Java
+
+ // src/Utils.java
package io.openruntimes.java.src;
@@ -2488,9 +2508,9 @@ class Utils {
return a + b;
}
}
-
-
- package io.openruntimes.java.src;
+
+
+ package io.openruntimes.java.src;
import io.openruntimes.java.RuntimeContext;
import io.openruntimes.java.RuntimeOutput;
@@ -2501,54 +2521,54 @@ public class Main {
return context.res.send(Utils.add(1, 2));
}
}
-
-
-
-
-
-Upgrade
-
- Appwrite Functions received major updates in Appwrite version 1.4.
- If you still have functions from previous versions, they will be read-only in Appwrite 1.4.
- You will have to migrate your old functions to follow new runtime syntax.
-
-
-
- Here's a checklist of things you need to know.
-
-
-
- -
- The parameter passed into functions has changed.
-
req and res has been replaced by context, which contains new logger methods.
- Learn about context.
-
- -
- To improve privacy and logging reliability, we provide new
context.log() and context.error() functions.
- You can no longer use native logging methods.
- Learn about logging.
-
- -
- The old way of
req.variables has been deprecated.
- You can now access variables passed into each function as environment variables.
- Learn about environment variables.
-
- -
- The
req object has been updated to use terminology consistent with typical HTTP concepts.
- You'll now find familiar concepts like headers, body, HTTP methods, and others.
- Learn about request.
-
- -
- The response object has been updated.
- You can now specify headers, as well as use new methods like return redirects or empty responses.
- Learn about response.
-
- -
- Now, you must return a response such as
return context.res.send("").
- This prevents confusing errors when functions are terminated prematurely before a response is sent.
- Learn about response.
-
- -
- Some variables about how a function was triggered are now found in the
context.req object as headers.
-
-
\ No newline at end of file
+
+
+
+
+
+ Upgrade
+
+ Appwrite Functions received major updates in Appwrite version 1.4.
+ If you still have functions from previous versions, they will be read-only in Appwrite 1.4.
+ You will have to migrate your old functions to follow new runtime syntax.
+
+
+
+ Here's a checklist of things you need to know.
+
+
+
+ -
+ The parameter passed into functions has changed.
+
req and res has been replaced by context, which contains new logger methods.
+ Learn about context.
+
+ -
+ To improve privacy and logging reliability, we provide new
context.log() and context.error() functions.
+ You can no longer use native logging methods.
+ Learn about logging.
+
+ -
+ The old way of
req.variables has been deprecated.
+ You can now access variables passed into each function as environment variables.
+ Learn about environment variables.
+
+ -
+ The
req object has been updated to use terminology consistent with typical HTTP concepts.
+ You'll now find familiar concepts like headers, body, HTTP methods, and others.
+ Learn about request.
+
+ -
+ The response object has been updated.
+ You can now specify headers, as well as use new methods like return redirects or empty responses.
+ Learn about response.
+
+ -
+ Now, you must return a response such as
return context.res.send("").
+ This prevents confusing errors when functions are terminated prematurely before a response is sent.
+ Learn about response.
+
+ -
+ Some variables about how a function was triggered are now found in the
context.req object as headers.
+
+
\ No newline at end of file
From 4548a4d2a0e1c7132e6aa408e9e893dace0f97c4 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Wed, 23 Aug 2023 22:13:31 +0100
Subject: [PATCH 113/183] fix: await document create
---
app/views/docs/functions-develop.phtml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 4817eb1aa..aaab1175b 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -1665,7 +1665,7 @@ export default async ({ req, res, log, error }) => {
const databases = new Databases(client);
try {
- databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
+ await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
} catch (e) {
error("Failed to create document: " + e.message)
return res.send("Failed to create document")
@@ -1980,7 +1980,7 @@ export default async ({ req, res, log }) => {
const databases = new Databases(client);
try {
- databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
+ await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
} catch (e) {
log("Failed to create document: " + e.message)
return res.send("Failed to create document")
From 2b868da2bf7e49cce4583c5082ec8f1287fb9fb7 Mon Sep 17 00:00:00 2001
From: Bradley Schofield
Date: Thu, 24 Aug 2023 11:01:08 +0100
Subject: [PATCH 114/183] Add alot more details around service account key
creation
---
app/views/docs/migrations-firebase.phtml | 158 +++++++++++++++++++----
1 file changed, 130 insertions(+), 28 deletions(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index f8c236ea3..67cbd68e9 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -1,7 +1,7 @@
Moving your project from Firebase to Appwrite?
Appwrite Migrations can help you streamline the process.
-
+
Here's what you need to know to get started.
@@ -16,34 +16,34 @@
Supported resource types
-
-
-
- Users
- Databases
- Documents
- Files
- Functions
-
-
-
-
- Firebase
- ✅
- ✅
- ✅
- ✅
-
-
-
+
+
+
+ Users
+ Databases
+ Documents
+ Files
+ Functions
+
+
+
+
+ Firebase
+ ✅
+ ✅
+ ✅
+ ✅
+
+
+
Migrating to Appwrite from Firebase
- To begin migrating to Appwrite make sure to read the migration overview
+ To begin migrating to Appwrite make sure to read the migration overview
and things to keep in mind sections above.
-
+
-
Create a new project and click on the Migrations tab.
@@ -52,7 +52,7 @@
Click on the Create Migration button and select Firebase as your source.
-
- Depending on where your Appwrite project is hosted, you'll need to use different methods to authorize with Firebase.
+ Depending on where your Appwrite project is hosted, you'll need to use different methods to authorize with Firebase.
See the Cloud and Self-hosting sections for details.
-
@@ -79,12 +79,114 @@
Click the gear icon to access your Project Settings.
-
- Click Service Accounts, then Generate New Private Key. Don't share this key with anyone!
+ Click on Service Accounts, then click on the Manage service account permissions link redirecting you to the Google Cloud Console.
-
- Once you've downloaded your private key, head back to Appwrite and click Manual Authentication.
+ Click on Create Service Account, give it any name, id and description you want, then click Continue.
-
- Upload the JSON private key and follow the wizard.
+ Next you'll be prompted to grant the service account roles, grant the following roles:
-
+
+
+
+ Role
+ Reason
+
+
+
+
+ Firebase Viewer
+ Read access to your entire Firebase project including Database and Storage
+
+
+ Identity Toolkit Viewer
+ Read access to your users including their hash config
+
+
+
+ - If you prefer to create a custom role, you can use the following permissions:
+
+
+
+ Permission
+ Reason
+
+
+
+
+ datastore.databases.get
+ Read access to your Firestore database
+
+
+ datastore.databases.list
+ Read access to your Firestore database
+
+
+ datastore.entities.get
+ Read access to your Firestore database's documents
+
+
+ datastore.entities.list
+ Read access to your Firestore database's documents
+
+
+ datastore.indexes.get
+ Read access to your Firestore database's indexes
+
+
+ datastore.indexes.list
+ Read access to your Firestore database's indexes
+
+
+ firebaseauth.configs.get
+ Read access to your Firebase project's authentication configs
+
+
+ firebaseauth.configs.getHashConfig
+ Read access to your Firebase project's authentication configs including hash salt
+
+
+ firebaseauth.configs.getSecret
+ Read access to your Firebase project's authentication configs including secret
+
+
+ firebaseauth.users.get
+ Read access to your Firebase project's users
+
+
+ identitytoolkit.tenants.get
+ Read access to your Firebase project's users
+
+
+ identitytoolkit.tenants.list
+ Read access to your Firebase project's users
+
+
+ storage.buckets.get
+ Read access to your Firebase project's storage buckets
+
+
+ storage.buckets.list
+ Read access to your Firebase project's storage buckets
+
+
+ storage.objects.get
+ Read access to your Firebase project's storage objects
+
+
+ storage.objects.list
+ Read access to your Firebase project's storage objects
+
+
+
+ -
+ Click Done to create the service account. After that you'll be redirected back to the service accounts page. Select the service account you just created and click Keys.
+
+ -
+ Click Add Key and select Create new key. Select JSON as the key type and click Create. This will download a JSON file to your computer.
+
+ -
+ Upload the JSON file to Appwrite and follow the migration wizard.
+
+
\ No newline at end of file
From f7fe08ed2e4eb7f0edeb74dea6aeea063d475166 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 11:51:36 -0400
Subject: [PATCH 115/183] Update app/views/docs/migrations-firebase.phtml
---
app/views/docs/migrations-firebase.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index 893659197..cf575693e 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -58,7 +58,7 @@
Click on Service Accounts, then click on the Manage service account permissions link redirecting you to the Google Cloud Console.
-
- Click on Create Service Account, give it any name, id and description you want, then click Continue.
+ Click on Create Service Account, give it a name, id and description you want, then click Continue.
-
Next you'll be prompted to grant the service account roles, grant the following roles:
From 255224e3bfaaa36b219f548955bc0ea72030222f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 11:51:41 -0400
Subject: [PATCH 116/183] Update app/views/docs/migrations-firebase.phtml
---
app/views/docs/migrations-firebase.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index cf575693e..c7a40ab3a 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -61,7 +61,7 @@
Click on Create Service Account, give it a name, id and description you want, then click Continue.
-
- Next you'll be prompted to grant the service account roles, grant the following roles:
+ Next you'll be prompted to grant the service account roles. You need to grant the following roles.
From d33d2230e3c66c3b98428cdd81db0b73304363c2 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 11:51:46 -0400
Subject: [PATCH 117/183] Update app/views/docs/migrations-firebase.phtml
---
app/views/docs/migrations-firebase.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index c7a40ab3a..e131a7826 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -73,7 +73,7 @@
Firebase Viewer
- Read access to your entire Firebase project including Database and Storage
+ Read access to your entire Firebase project including Database and Storage.
Identity Toolkit Viewer
From 6f67e62e39902e51efc8924839c801f8ca77e287 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 11:51:51 -0400
Subject: [PATCH 118/183] Update app/views/docs/migrations-firebase.phtml
---
app/views/docs/migrations-firebase.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index e131a7826..cb27cd23b 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -77,7 +77,7 @@
Identity Toolkit Viewer
- Read access to your users including their hash config
+ Read access to your users including their hash config.
From 124826a67e84e87a08917c78a3ddfeeb78bdfe29 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 16:08:08 +0000
Subject: [PATCH 119/183] fix some style and grammar
---
.../docs/migrations-cloud-to-local.phtml | 2 +-
app/views/docs/migrations-firebase.phtml | 47 ++++++++++---------
.../docs/migrations-local-to-cloud.phtml | 2 +-
3 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index 801d93c0e..743efb54b 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -1,5 +1,5 @@
- Moving to a self-hosted instance? We've got you covered.
+ If you're moving your projects from Appwrite Cloud to self-hosted, we've got you covered.
Migrations makes it as easy as a couple clicks to move all of your Appwrite Cloud project data to a self-hosted instance.
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index cb27cd23b..c5d234175 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -36,13 +36,15 @@
-Appwrite Cloud
+Migrate to Cloud
To simplify the migration process we have created an OAuth application that will allow you to sign in with Google and automatically
discover your Firebase projects. Simply select the source project and follow the migration wizard.
-Migrating to Appwrite Self-Hosted
+After completing the migration wizard, migration will begin. Return to step 4 of the migration steps.
+
+Migrating to Self-Hosted
If you are self-hosting Appwrite you will need to create a service account in your Firebase project and download the JSON file.
@@ -63,7 +65,7 @@
-
Next you'll be prompted to grant the service account roles. You need to grant the following roles.
-
+
Role
@@ -81,8 +83,8 @@
- - If you prefer to create a custom role, you can use the following permissions:
-
+ - If you prefer to create a custom role, you can use the following permissions.
+
Permission
@@ -92,67 +94,67 @@
datastore.databases.get
- Read access to your Firestore database
+ Read access to your Firestore database.
datastore.databases.list
- Read access to your Firestore database
+ Read access to your Firestore database.
datastore.entities.get
- Read access to your Firestore database's documents
+ Read access to your Firestore database's documents.
datastore.entities.list
- Read access to your Firestore database's documents
+ Read access to your Firestore database's documents.
datastore.indexes.get
- Read access to your Firestore database's indexes
+ Read access to your Firestore database's indexes.
datastore.indexes.list
- Read access to your Firestore database's indexes
+ Read access to your Firestore database's indexes.
firebaseauth.configs.get
- Read access to your Firebase project's authentication configs
+ Read access to your Firebase project's authentication configs.
firebaseauth.configs.getHashConfig
- Read access to your Firebase project's authentication configs including hash salt
+ Read access to your Firebase project's authentication configs including hash salt.
firebaseauth.configs.getSecret
- Read access to your Firebase project's authentication configs including secret
+ Read access to your Firebase project's authentication configs including secret.
firebaseauth.users.get
- Read access to your Firebase project's users
+ Read access to your Firebase project's users.
identitytoolkit.tenants.get
- Read access to your Firebase project's users
+ Read access to your Firebase project's users.
identitytoolkit.tenants.list
- Read access to your Firebase project's users
+ Read access to your Firebase project's users.
storage.buckets.get
- Read access to your Firebase project's storage buckets
+ Read access to your Firebase project's storage buckets.
storage.buckets.list
- Read access to your Firebase project's storage buckets
+ Read access to your Firebase project's storage buckets.
storage.objects.get
- Read access to your Firebase project's storage objects
+ Read access to your Firebase project's storage objects.
storage.objects.list
- Read access to your Firebase project's storage objects
+ Read access to your Firebase project's storage objects.
@@ -165,4 +167,7 @@
-
Upload the JSON file to Appwrite and follow the migration wizard.
+ -
+ After completing the migration wizard, migration will begin. Return to step 4 of the migration steps.
+
\ No newline at end of file
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index 5cfee4cb8..96cd51ec3 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -1,5 +1,5 @@
- Making the move to Appwrite Cloud? We've got your back.
+ If you're moving your self-hosted projects to Appwrite Cloud, we've got your back.
Migrations makes it as easy as a couple clicks to move all of your self-hosted project data to a Cloud instance.
From 3f57c8df1b8be4cbaf9634334f12cf040d28b1db Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 12:12:00 -0400
Subject: [PATCH 120/183] Update app/views/docs/functions-deploy.phtml
Co-authored-by: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com>
---
app/views/docs/functions-deploy.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 7be004807..5d8eed8fb 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -53,7 +53,7 @@
Deploy
-
- Checkout your prodction branch in Git.
+ Checkout your production branch in Git.
-
Create a new commit.
From eaa9683820bde906933c40c4500dcb77f15ffd8f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 12:12:27 -0400
Subject: [PATCH 121/183] Update app/views/docs/migrations-supabase.phtml
Co-authored-by: Bradley Schofield
---
app/views/docs/migrations-supabase.phtml | 3 ---
1 file changed, 3 deletions(-)
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
index 754445ad0..e5b789ebd 100644
--- a/app/views/docs/migrations-supabase.phtml
+++ b/app/views/docs/migrations-supabase.phtml
@@ -40,9 +40,6 @@
- -
- Region - The region your Supabase project is hosted in. This can be found in your Supabase project environment variables as Supabase_REGION.
-
-
Host - The host of your Supabase Database, this can be found in your Supabase project settings under Database Settings and Host.
From c0e4011fc3be15bbcfc529f9ec56015cbc86da3b Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 16:19:17 +0000
Subject: [PATCH 122/183] Add entry file and html tags got deno
---
app/views/docs/functions-develop.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index c251a31ae..3febbd757 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -1602,7 +1602,7 @@ namespace runtime {
Deno
deno
- deno cache [ENTRYPOINT_FILE]
+ deno cache <ENTRYPOINT_FILE>
Dart
From c6e548cf6a61b4b2a8932a4792bd6f5f105f8222 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 19:56:05 +0000
Subject: [PATCH 123/183] add debug and redeploy
---
app/views/docs/functions-deploy.phtml | 40 +++++++++++++++++++--------
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 5d8eed8fb..0405d7445 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -16,7 +16,7 @@
Create Funcion
-Before deploying your function with Git, create a new function attached to your Git repo.
+Before deploying your function with VCS, create a new function attached to your VCS repo.
-
Navigate to Functions from the side bar of the Appwrite Console.
@@ -43,7 +43,8 @@
Name your function, select a runtime that matches your function, and enter an entry point path, relative to the root directory from the previous step.
-
- If you have build steps, like installing dependencies, input the commands into the Build settings heading's Command field.
+ If you have build steps, like installing dependencies, input the commands into the Build settings heading's Command field.
+ You can combine multiple commands using
&&, such as npm install && npm build.
-
Finally, configure the execute permissions of the function. For security, only provide execute permissions to the necessary roles.
@@ -65,14 +66,6 @@
A new deployment will be automatically created. Deployments will be automatically activated when new commits are added to the production branch.
-Debugging Builds
-After deploying a function, you can find the status of the deployment and build logs in the Appwrite Console.
-
- - In Appwrite Console, navigate to Functions.
- - Click to open a function you wish to inspect.
- - Under the Deployments tab, you'll find the status of the current active deployment and previous inactive deployments.
- - You can access build logs for the active deployment by clicking the Build logs button. You can click on an inactive function's three dots button to find their build logs.
-
CLI
@@ -163,7 +156,6 @@
Domains
-
Each deployed function can have it's own domain.
By default, one is generated for each of your functions.
@@ -195,4 +187,30 @@
DNS records can take up to 48 hours to propagate after they're added.
Please retry verification over the next 48 hours.
If the domain verification still fails and you have confirmed DNS records are added correctly, please contact support.
+
+
+Debugging Build
+After deploying a function, you can find the status of the deployment and build logs in the Appwrite Console.
+
+ - In Appwrite Console, navigate to Functions.
+ - Click to open a function you wish to inspect.
+ - Under the Deployments tab, you'll find the status of the current active deployment and previous inactive deployments.
+ - You can access build logs for the active deployment by clicking the Build logs button. You can click on an inactive function's three dots button to find their build logs.
+
+
+Redeploy Builds
+
+ After updateing the configuration of your Appwrite Function, you need to redeploy your function for the changes to take effect.
+ You can also redeploy builds to retry failed builds.
+
+
+ - In Appwrite Console, navigate to Functions.
+ - Click to open a function you wish to inspect.
+ - Under the Deployments tab, you'll find the status of the current active deployment.
+ - You can redeploy by clicking the Redeploy button.
+
+
+ The redeployment behavior varies depending on how the initial deployment is created.
+ For VCS deployments, redeploy uses the same commit hash but updated function settings.
+ For manual and CLI deployments, redeploy uses previously updated code but updated function settings.
\ No newline at end of file
From 8337b4ecd8183cba949ffd43436ef837d4225258 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Thu, 24 Aug 2023 20:04:27 +0000
Subject: [PATCH 124/183] Fix modal text
---
app/views/docs/functions-execute.phtml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index e66d845da..685756b8f 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -434,8 +434,8 @@ $image = new View(__DIR__.'/../general/image.phtml');
echo $image
->setParam('srcLight', '/images-ee/docs/functions-execute-light.png')
->setParam('srcDark', '/images-ee/docs/functions-execute-dark.png')
- ->setParam('alt', '"Create Function" page.')
- ->setParam('description', '"Create Function" page.')
+ ->setParam('alt', '"Execute Function" modal.')
+ ->setParam('description', '"Execute Function" modal.')
->render();
?>
From 28cd6fe65bfcea30e128c7170d01d4d073c2a465 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Thu, 24 Aug 2023 21:50:58 +0100
Subject: [PATCH 125/183] feat: simplify function examples
---
app/views/docs/functions-examples.phtml | 413 +++++-------------------
1 file changed, 83 insertions(+), 330 deletions(-)
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index e125d902e..d7971d657 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -1,176 +1,16 @@
Appwrite Functions is all about flexibility.
- Behind the simple workflow hides some useful recipes that can help you accomplish your goals faster.
+ Behind the simple workflow hides some useful examples that can help you accomplish your goals faster.
Take a look at the following.
-[TODO: @matej @luke -> Let's have some simple recipes here for common actions]
Currency Conversion API
-Getting Started
-
-
- In this recipe, we'll build a simple function for currency conversion.
- Let's start with a static converstion rate. We'll show you how to integrate an API later in this example.
-
-
-
- -
-
Node.js
-
- Create a new file, index.js.
- Add the following code to index.js.
-
- export default async function ({ res }) {
- return res.send('1.13');
-};
-
-
-
- -
-
PHP
-
- Create a new file, index.php.
- Add the following code to index.php.
-
- <?php
-return function ($context) {
- return $context->res->send('1.13');
-};
-
-
-
- -
-
Python
-
- Create a new file, index.py.
- Add the following code to index.py.
-
- def main(context):
- return context.res.send('1.13')
-
-
-
- -
-
Dart
-
- Create a new file, index.dart.
- Add the following code to index.dart.
-
- import 'dart:async';
-
-Future<dynamic> main(final context) async {
- return context.res.send('1.13');
-}
-
-
-
- -
-
Ruby
-
- Create a new file, index.rb.
- Add the following code to index.rb.
-
- def main(context)
- return context.res.send('1.13')
-end
-
-
-
-
-
-This code will return 1.13 when the function is called, because 1€ equals approximately 1.13$.
-Now, create a function in the Appwrite console, adding your Git repository as the remote source and using the path file you created as the entry point.
-Finally, execute the function and visit the URL (like ghrfu9ewji.functions.appwrite.app) to see the response.
-
-Adding the Business Logic
-
-Now, let's update the function to use the request payload.
-You can use a query string to pass data to your function. For example, ghrfu9ewji.functions.appwrite.app?amount=5 will pass 5 as the amount parameter.
-
-
- -
-
Node.js
-
- Update index.js to use req.query.amount to access the amount parameter, and return the conversion result.
-
- export default async function ({ req, res }) {
- const amountInEuros = Number(req.query.amount);
- const amountInDollars = amountInEuros * 1.13;
- return res.send(amountInDollars.toString());
-};
-
-
-
- -
-
PHP
-
- Update index.php to use $context->req->query['amount'] to access the amount parameter, and return the conversion result.
-
- <?php
-return function ($context) {
- $amountInEuros = $context->req->query['amount'];
- $amountInDollars = $amountInEuros * 1.13;
- return $context->res->send($amountInDollars);
-};
-
-
-
- -
-
Python
-
- Update index.py to use context.req.query['amount'] to access the amount parameter, and return the conversion result.
-
- def main(context):
- amountInEuros = context.req.query['amount']
- amountInDollars = amountInEuros * 1.13
- return context.res.send(amountInDollars)
-
-
-
- -
-
Dart
-
- Update index.dart to use context.req.query['amount'] to access the amount parameter, and return the conversion result.
-
- import 'dart:async';
-
-Future<dynamic> main(final context) async {
- final amountInEuros = context.req.query['amount'];
- final amountInDollars = amountInEuros * 1.13;
- return context.res.send(amountInDollars);
-}
-
-
-
- -
-
Ruby
-
- Update index.rb to use context.req.query['amount'] to access the amount parameter, and return the conversion result.
-
- def main(context)
- amountInEuros = context.req.query['amount']
- amountInDollars = amountInEuros * 1.13
- return context.res.send(amountInDollars)
-end
-
-
-
-
-
-Commit your changes and push them to your Git repository.
-
-
-Testing our Function
-
-
- Execute the function and visit the URL (like ghrfu9ewji.functions.appwrite.app?amount=5) to see the response.
-
- You should see the result of the conversion, like 5.65.
+ Here's a currency conversion API that converts from Euros and Indian Rupees to US Dollars. We'll use an external API to get the latest exchange rates, and query it using an dependency specific to each runtime.
-Adding Dependencies
+Prerequisites
-
@@ -190,7 +30,6 @@ end
-
PHP
- You can use Composer to manage your PHP project's dependencies. Install it from getcomposer.org/download.
Run the following bash command to create a composer.json file. This file is used to manage your PHP project's dependencies.
composer init -y
@@ -236,9 +75,7 @@ environment:
Install the http library. This library includes a get function that you can use to make HTTP requests.
-
- pub install http
-
+ pub install http
Finally, add pub get to your function's build commands in the Appwrite console.
@@ -254,8 +91,7 @@ environment:
Create a Gemfile file with the following contents. This file is used to manage your Ruby project's dependencies.
- source 'https://rubygems.org'
-
+ source 'https://rubygems.org'
Install the httparty library. This library includes a get function that you can use to make HTTP requests.
@@ -271,106 +107,7 @@ bundle install
-
Using Dependencies
-
-
- -
-
Node.js
-
- Use fetch from undici to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
-
- import { fetch } from 'undici';
-
-export default async function ({ req, res }) {
- const amountInEuros = Number(req.query.amount);
- const response = await fetch('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
- const data = await response.json();
- const amountInDollars = amountInEuros * data.rates.USD;
- return res.send(amountInDollars.toString());
-};
-
-
-
- -
-
PHP
-
-
-
- <?php
-
-require(__DIR__ . '/../vendor/autoload.php');
-
-use GuzzleHttp\Client;
-
-return function ($context) {
- $amountInEuros = $context->getRequest()->getQuery('amount');
- $client = new Client();
- $response = $client->get('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
- $data = json_decode($response->getBody(), true);
- $amountInDollars = $amountInEuros * $data['rates']['USD'];
- return $context->res->send(strval($amountInDollars));
-};
-
-
-
- -
-
Python
-
- Use get from requests to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
-
- import requests
-
-def main(context):
- amount_in_euros = float(context.req.query['amount'])
- response = requests.get('https://api.exchangerate.host/latest?base=EUR&symbols=USD')
- data = response.json()
- amount_in_dollars = amount_in_euros * data['rates']['USD']
- return context.res.send(str(amount_in_dollars))
-
-
-
- -
-
Dart
-
- Use get from http to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
-
- import 'dart:async';
-import 'package:http/http.dart' as http;
-
-Future<dynamic> main(final context) async {
- final amountInEuros = double.parse(context.req.query['amount'])
- final response = await http.get(Uri.parse('https://api.exchangerate.host/latest?base=EUR&symbols=USD'));
- final data = json.decode(response.body);
- final amountInDollars = amountInEuros * data['rates']['USD'];
- return context.res.send(amountInDollars.toString());
-}
-
-
-
- -
-
Ruby
-
- Use get from httparty to get the current conversion rate. This API call will return the current conversion rate between Euros and Dollars.
-
- require 'httparty'
-
-def main(context)
- amount_in_euros = context.req.query['amount'].to_f
- response = HTTParty.get('https://api.exchangerate.host/latest?base=EUR&symbols=USD')
- data = JSON.parse(response.body)
- amount_in_dollars = amount_in_euros * data['rates']['USD']
- return context.res.send(amount_in_dollars.to_s)
-end
-
-
-
-
-
-After your function has updated, you can test it by visiting the URL and providing different amounts to convert in the query string. The conversion rate should now be more precise because we're using the current conversion rate.
-
-Adding Multiple Routes
-
-Let's add support multiple paths like /eur and /inr. Each path will convert from that currency to dollars.
+Code
-
@@ -490,44 +227,78 @@ end
-After your function has updated, you can try out the new paths. For example, ghrfu9ewji.functions.appwrite.app/eur?amount=5 should convert Euros to Dollars, while ghrfu9ewji.functions.appwrite.app/inr?amount=100 should convert Indian Rupees to Dollars.
-Congratulations! You've built a currency conversion API using Appwrite functions!
-
-Voting System Using Appwrite
-
-Getting Started
-
- In this recipe, you will build a simple voting system that allows users to vote on various topics. Appwrite functions and the server SDK will be used to enforce voting rules and prevent multiple votes from the same user for a single topic.
+ Use the function by navigating to function URL in the browser. The path should contain the currency and amount parameter.
+ For example, [YOUR_FUNCTION_URL]/eur?amount=5 should convert Euros to Dollars.
-Setting Up
-
- -
-
Appwrite Project
-
- 1. Create a new Appwrite project.
- 2. Add your development domain to your Appwrite project's trusted domains.
-
-
- -
-
Create Collections
-
- Create two collections named "topics" and "votes."
- For "topics" collection, have fields: title and description.
- For "votes" collection, have fields: topicId, userId, and vote.
-
-
-
+Voting System Using Appwrite
+
+ Here's a simple voting system that allows users to vote on various topics. Appwrite Functions and the server SDK are used to enforce voting rules and prevent multiple votes from the same user for a single topic.
+
-Building the Voting Function
+Prerequisites
+
+Create a Topics collection with the following attributes:
+
+
+
+
+ Name
+ Type
+ Description
+
+
+
+
+ title
+ string
+ The name of the topic
+
+
+ description
+ string
+ Long form description of the topic
+
+
+
+
+Create a Votes collection with the following attributes:
+
+
+
+
+ Name
+ Type
+ Description
+
+
+
+
+ userId
+ string
+ The ID of the user who cast the vote
+
+
+ topicId
+ string
+ The ID of the topic that was voted on
+
+
+ vote
+ string
+ The vote cast by the user. Must be either "yes" or "no"
+
+
+
+
+Code
-
Node.js
- Create a new located at functions/vote/src/main.js.
import { Client, Databases, Query } from 'node-appwrite';
@@ -539,7 +310,7 @@ export default async function ({ req, res }) {
};
if (vote.vote !== 'yes' && vote.vote !== 'no') {
- return res.json({ ok: false, message: 'You must vote yes or no.' });
+ return res.json({ ok: false, message: 'You must vote yes or no.' }, 400);
}
const client = new Client();
@@ -556,7 +327,7 @@ export default async function ({ req, res }) {
]);
if (existingVotes.total > 0) {
- return res.json({ message: 'You have already voted on this topic.' });
+ return res.json({ ok: false, message: 'You have already voted on this topic.' }, 400);
}
const voteDocument = await database.createDocument('[VOTES_COLLECTION_ID]', {
@@ -567,7 +338,7 @@ export default async function ({ req, res }) {
return res.json({ ok: true, message: 'Vote cast.', vote: voteDocument });
}
-
+
-
@@ -588,7 +359,7 @@ def main(context):
}
if vote['vote'] != 'yes' and vote['vote'] != 'no':
- return context.res.json({'ok': False, 'message': 'You must vote yes or no.'})
+ return context.res.json({'ok': False, 'message': 'You must vote yes or no.'}, 400)
client = Client()
client.set_endpoint('https://cloud.appwrite.io/v1')
@@ -606,7 +377,7 @@ def main(context):
return context.res.json({
'ok': False,
'message': 'You have already voted on this topic.'
- })
+ }, 400)
vote_document = database.create_document('[VOTES_COLLECTION_ID]', {
'userId': vote['userId'],
@@ -640,7 +411,7 @@ return function ($context) {
];
if ($vote['vote'] !== 'yes' && $vote['vote'] !== 'no') {
- return $context->res->json(['ok' => false, 'message' => 'You must vote yes or no.']);
+ return $context->res->json(['ok' => false, 'message' => 'You must vote yes or no.'], 400);
}
$client = new Client();
@@ -660,7 +431,7 @@ return function ($context) {
return $context->res->json([
'ok' => false,
'message' => 'You have already voted on this topic.'
- ]);
+ ], 400);
}
$voteDocument = $database->createDocument('[VOTES_COLLECTION_ID]', [
@@ -686,7 +457,6 @@ return function ($context) {
require "appwrite"
def main(context)
-
vote = {
'userId' => context.req.query['userId'],
'topicId' => context.req.query['topicId'],
@@ -694,7 +464,7 @@ def main(context)
}
if vote['vote'] != 'yes' and vote['vote'] != 'no'
- return context.res.json({'ok': false, 'message': 'You must vote yes or no.'})
+ return context.res.json({'ok': false, 'message': 'You must vote yes or no.'}, 400)
end
client = Appwrite::Client.new()
@@ -714,7 +484,7 @@ def main(context)
return context.res.json({
'ok': false,
'message': 'You have already voted on this topic.'
- })
+ }, 400)
end
vote_document = database.create_document('[VOTES_COLLECTION_ID]', {
@@ -748,7 +518,7 @@ Future main(final context) async {
};
if (vote['vote'] != 'yes' && vote['vote'] != 'no') {
- return context.res.json({'ok': false, 'message': 'You must vote yes or no.'});
+ return context.res.json({'ok': false, 'message': 'You must vote yes or no.'}, 400);
}
final client = Client()
@@ -767,7 +537,7 @@ Future main(final context) async {
return context.res.json({
'ok': false,
'message': 'You have already voted on this topic.'
- });
+ }, 400);
}
final voteDocument = await database.createDocument('[VOTES_COLLECTION_ID]', {
@@ -804,7 +574,7 @@ def main(context):
}
if vote['vote'] != 'yes' and vote['vote'] != 'no':
- return context.res.json({'ok': False, 'message': 'You must vote yes or no.'})
+ return context.res.json({'ok': False, 'message': 'You must vote yes or no.'}, 400)
client = Client()
client.set_endpoint('https://cloud.appwrite.io/v1')
@@ -822,7 +592,7 @@ def main(context):
return context.res.json({
'ok': False,
'message': 'You have already voted on this topic.'
- })
+ }, 400)
vote_document = database.create_document('[VOTES_COLLECTION_ID]', vote)
@@ -836,28 +606,11 @@ def main(context):
-In the Appwrite console, create a function and use the file you created as the entry point.
-
-Testing the Function
-
- Execute the function and visit the URL, passing the required parameters [YOUR_FUNCTION_URL]?userId=[USER_ID]&topicId=[TOPIC_ID];&vote=yes to cast a vote. You should see a response confirming the vote. Trying to vote again with the same user ID and topic ID should result in a message indicating that the user has already voted on this topic.
+ Use the function by navigating to the function URL in the browser. The URL should contain the required parameters.
+ For example, [YOUR_FUNCTION_URL]?userId=[USER_ID]&topicId=[TOPIC_ID];&vote=yes to cast a vote.
-Conclusion
-
-
- To further improve this function, try adding the following checks:
-
- - Check that the user ID and topic ID exist.
- - Replace the user ID query parameter with the
x-appwrite-user-id header, so votes may only be cast by logged in users.
- - Convert the function to POST requests with a JSON body to cast votes, so that the vote data is not visible in the URL.
-
-
-
-
- Congratulations! You've built a voting system that leverages Appwrite functions and the Appwrite server SDK to enforce business logic and ensure that users can only vote once per topic.
-
[TODO: @luke -> Example with JWT, show both client and server code]
From 9673f0446197b9c0e9c9b5e4d9b175a0af11c880 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Thu, 24 Aug 2023 22:37:31 +0100
Subject: [PATCH 126/183] feat: html form function example
---
app/views/docs/functions-examples.phtml | 331 +++++++++++++++++++++++-
1 file changed, 328 insertions(+), 3 deletions(-)
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index d7971d657..a8dd01968 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -611,6 +611,334 @@ def main(context):
For example, [YOUR_FUNCTION_URL]?userId=[USER_ID]&topicId=[TOPIC_ID];&vote=yes to cast a vote.
+HTML Contact Form
+
+
+ Here's a simple form page that can be used to store a user's message in a collection.
+ The form is submitted to the function using the POST method and the form data is sent as a URL-encoded string in the request body.
+
+
+Prerequisites
+
+Create a Messages collection with the following attributes:
+
+
+
+
+ Name
+ Type
+ Description
+
+
+
+
+ name
+ string
+ The name of the message author
+
+ email
+ string
+ The email of the message author
+
+
+ content
+ string
+ The content of the message
+
+
+
+
+Code
+
+
+ -
+
Node.js
+
+
+ import { Client, Databases, Query, ID } from 'node-appwrite';
+import querystring from 'node:querystring';
+
+const html = `<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Contact Form</title>
+ </head>
+ <body>
+ <form action="/" method="POST">
+ <input type="text" id="name" name="name" placeholder="Name" required>
+ <input type="email" id="email" name="email" placeholder="Email" required>
+ <textarea id="content" name="content" placeholder="Message" required></textarea>
+ <button type="submit">Submit</button>
+ </form>
+ </body>
+</html>`
+
+export default async function ({ req, res }) {
+ if (req.method === 'GET') {
+ return res.send(html, 200, {'content-type': 'text/html'});
+ }
+
+ if (req.method === 'POST' && req.headers['content-type'] === 'application/x-www-form-urlencoded') {
+ const formData = querystring.parse(req.body);
+
+ const message = {
+ name: formData.name,
+ email: formData.email,
+ content: formData.content
+ };
+
+ const client = new Client();
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1')
+ .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ .setKey(process.env.APPWRITE_API_KEY);
+
+ const databases = new Databases(client);
+ const document = await databases.createDocument('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message);
+
+ return res.send("Message sent", 200);
+ }
+
+ return res.send('Not found', 404);
+}
+
+
+
+ -
+
Python
+
+
+
+ from appwrite.client import Client
+from appwrite.services.databases import Databases
+from appwrite.query import Query
+from urllib.parse import parse_qs
+import os
+
+html = '''<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Contact Form</title>
+ </head>
+ <body>
+ <form action="/" method="POST">
+ <input type="text" id="name" name="name" placeholder="Name" required>
+ <input type="email" id="email" name="email" placeholder="Email" required>
+ <textarea id="content" name="content" placeholder="Message" required></textarea>
+ <button type="submit">Submit</button>
+ </form>
+ </body>
+</html>
+'''
+
+def main(context):
+ if context.req.method == 'GET':
+ return context.res.send(html, 200, {'content-type': 'text/html'})
+
+ if context.req.method == 'POST' and context.req.headers['content-type'] == 'application/x-www-form-urlencoded':
+ formData = parse_qs(context.req.body)
+
+ message = {
+ 'name': formData['name'][0],
+ 'email': formData['email'][0],
+ 'content': formData['content'][0]
+ }
+
+ client = (
+ Client()
+ .set_endpoint('https://cloud.appwrite.io/v1')
+ .set_project(os.environ['APPWRITE_FUNCTION_PROJECT_ID'])
+ .set_key(os.environ['APPWRITE_API_KEY'])
+ )
+
+ databases = Databases(client)
+ document = databases.create_document('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message)
+
+ return context.res.send("Message sent", 200)
+
+ return context.res.send('Not found', 404)
+
+
+
+ -
+
PHP
+
+
+
+ <?php
+
+require(__DIR__ . '/../vendor/autoload.php');
+
+use Appwrite\Client;
+use Appwrite\Exception;
+use Appwrite\Services\Databases;
+
+$html = '<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Contact Form</title>
+ </head>
+ <body>
+ <form action="/" method="POST">
+ <input type="text" id="name" name="name" placeholder="Name" required>
+ <input type="email" id="email" name="email" placeholder="Email" required>
+ <textarea id="content" name="content" placeholder="Message" required></textarea>
+ <button type="submit">Submit</button>
+ </form>
+ </body>
+</html>';
+
+return function ($context) {
+ global $html;
+
+ if ($context->req->method === 'GET') {
+ return $context->res->send($html, 200, ['content-type' => 'text/html']);
+ }
+
+ if ($context->req->method === 'POST' && $context->req->headers['content-type'] === 'application/x-www-form-urlencoded') {
+ \parse_str($context->req->body, $formData);
+
+ $message = [
+ 'name' => $formData['name'],
+ 'email' => $formData['email'],
+ 'content' => $formData['content']
+ ];
+
+ $client = new Client();
+ $client
+ ->setEndpoint('https://cloud.appwrite.io/v1')
+ ->setProject(getenv('APPWRITE_FUNCTION_PROJECT_ID'))
+ ->setKey(getenv('APPWRITE_API_KEY'));
+
+ $databases = new Databases($client);
+ $document = $databases->createDocument('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID::unique(), $message);
+
+ return $context->res->send("Message sent", 200);
+ }
+
+ return $context->res->send('Not found', 404);
+};
+
+
+
+ -
+
Ruby
+
+
+
+ require "appwrite"
+
+html = '''<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Contact Form</title>
+ </head>
+ <body>
+ <form action="/" method="POST">
+ <input type="text" id="name" name="name" placeholder="Name" required>
+ <input type="email" id="email" name="email" placeholder="Email" required>
+ <textarea id="content" name="content" placeholder="Message" required></textarea>
+ <button type="submit">Submit</button>
+ </form>
+ </body>
+</html>
+'''
+
+def main(context)
+ if context.req.method == 'GET'
+ return context.res.send(html, 200, {'content-type': 'text/html'})
+ end
+
+ if context.req.method == 'POST' and context.req.headers['content-type'] == 'application/x-www-form-urlencoded'
+ formData = URI.decode_www_form(context.req.body).to_h
+
+ message = {
+ 'name' => formData['name'],
+ 'email' => formData['email'],
+ 'content' => formData['content']
+ }
+
+ client = Appwrite::Client.new()
+ client
+ .set_endpoint('https://cloud.appwrite.io/v1')
+ .set_project(ENV['APPWRITE_FUNCTION_PROJECT_ID'])
+ .set_key(ENV['APPWRITE_API_KEY'])
+
+ databases = Appwrite::Database.new(client)
+ document = databases.create_document('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message)
+
+ return context.res.send("Message sent", 200)
+ end
+
+ return context.res.send('Not found', 404)
+end
+
+
+
+ -
+
Dart
+
+
+
+ import 'dart:async';
+import 'package:dart_appwrite/dart_appwrite.dart';
+
+Future main(final context) async {
+ final html = '''<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Contact Form</title>
+ </head>
+ <body>
+ <form action="/" method="POST">
+ <input type="text" id="name" name="name" placeholder="Name" required>
+ <input type="email" id="email" name="email" placeholder="Email" required>
+ <textarea id="content" name="content" placeholder="Message" required></textarea>
+ <button type="submit">Submit</button>
+ </form>
+ </body>
+</html>
+''';
+
+ if (context.req.method == 'GET') {
+ return context.res.send(html, 200, {'content-type': 'text/html'});
+ }
+
+ if (context.req.method == 'POST' && context.req.headers['content-type'] == 'application/x-www-form-urlencoded') {
+ final formData = Uri.splitQueryString(context.req.body);
+
+ final message = {
+ 'name': formData['name'],
+ 'email': formData['email'],
+ 'content': formData['content']
+ };
+
+ final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1')
+ .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ .setKey(process.env.APPWRITE_API_KEY);
+
+ final databases = Database(client);
+ final document = await databases.createDocument('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message);
+
+ return context.res.send("Message sent", 200);
+ }
+
+ return context.res.send('Not found', 404);
+}
+
+
+
+
+
+
+ Use the function by navigating to the function URL in the browser. Submit the form to store the message in the collection.
+
[TODO: @luke -> Example with JWT, show both client and server code]
@@ -618,15 +946,12 @@ def main(context):
\ No newline at end of file
From f6dff91336e60e90ef216ab7d343fbd66e9f2a5f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:30:55 -0400
Subject: [PATCH 127/183] Update app/views/docs/migrations-cloud-to-local.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-cloud-to-local.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index 743efb54b..8fb11b0cb 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -20,7 +20,7 @@
Steps on Your Cloud Project
- - Navigate to your Appwrite Cloud Console and click on the Migrations tab.
+ - Navigate to your Appwrite Cloud Console and click on the Migrations tab in Project Settings.
- Click Export to Self-hosted, you will be prompted to input the URL of your self-hosted Appwrite project.
- Optionally, tell us about why you're moving to self-hosted.
- After clicking Continue, you'll be directed back to your self-hosted project to complete the process.
From 54300083b3e7b8fb12cf4b7a5870ca985dab3640 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:31:04 -0400
Subject: [PATCH 128/183] Update app/views/docs/migrations-cloud-to-local.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-cloud-to-local.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index 8fb11b0cb..184e43bd1 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -23,7 +23,7 @@
- Navigate to your Appwrite Cloud Console and click on the Migrations tab in Project Settings.
- Click Export to Self-hosted, you will be prompted to input the URL of your self-hosted Appwrite project.
- Optionally, tell us about why you're moving to self-hosted.
- - After clicking Continue, you'll be directed back to your self-hosted project to complete the process.
+ - After clicking Continue, you'll be redirected to your self-hosted project to complete the process.
Steps on Your Self-hosted Project
From 635ee8dbeadc61da5cf37b9802b5bbe406988757 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:31:19 -0400
Subject: [PATCH 129/183] Update app/views/docs/migrations-cloud-to-local.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-cloud-to-local.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index 184e43bd1..c66644803 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -18,7 +18,7 @@
and things to keep in mind sections above.
-Steps on Your Cloud Project
+Steps in Cloud Console
- Navigate to your Appwrite Cloud Console and click on the Migrations tab in Project Settings.
- Click Export to Self-hosted, you will be prompted to input the URL of your self-hosted Appwrite project.
From 47dd217e4365b9b6ce5a3046054cb7c89a81b24a Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:31:32 -0400
Subject: [PATCH 130/183] Update app/views/docs/migrations-cloud-to-local.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-cloud-to-local.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index c66644803..abfb8e673 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -26,7 +26,7 @@
- After clicking Continue, you'll be redirected to your self-hosted project to complete the process.
-Steps on Your Self-hosted Project
+Steps in Self-hosted Console
- Once redirected to your self-hosted project, you'll be prompted to select an organization and a project. You can migrate to an existing project or create a new one.
- Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
From 3cdd52d888b82dcb4bbb8b4ae6c1e4fbe73ba454 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:31:58 -0400
Subject: [PATCH 131/183] Update app/views/docs/migrations-cloud-to-local.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-cloud-to-local.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index abfb8e673..c242905ad 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -28,7 +28,7 @@
Steps in Self-hosted Console
- - Once redirected to your self-hosted project, you'll be prompted to select an organization and a project. You can migrate to an existing project or create a new one.
+ - Once redirected to your self-hosted server, you'll be prompted to select a project. If you have multiple organizations, you will also be asked to pick one. You can migrate to an existing project or create a new one.
- Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
- Click Start migration to start the migration process. You do not need to keep the Appwrite Console open through the process.
\ No newline at end of file
From 98f2b36efd36f33d2fabdecfdb7435efd6165707 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:32:13 -0400
Subject: [PATCH 132/183] Update app/views/docs/migrations-cloud-to-local.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-cloud-to-local.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-cloud-to-local.phtml b/app/views/docs/migrations-cloud-to-local.phtml
index c242905ad..6c012e1ef 100644
--- a/app/views/docs/migrations-cloud-to-local.phtml
+++ b/app/views/docs/migrations-cloud-to-local.phtml
@@ -30,5 +30,5 @@
- Once redirected to your self-hosted server, you'll be prompted to select a project. If you have multiple organizations, you will also be asked to pick one. You can migrate to an existing project or create a new one.
- Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
- - Click Start migration to start the migration process. You do not need to keep the Appwrite Console open through the process.
+ - Click Start migration to begin the migration process. You do not need to keep the Appwrite Console open through the process.
\ No newline at end of file
From 09607691e7824b53393e776569ed81fed8c73624 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:32:48 -0400
Subject: [PATCH 133/183] Update app/views/docs/migrations-local-to-cloud.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index 96cd51ec3..e69a47ff0 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -11,7 +11,7 @@
- Migrations are non-destructive. No data will be deleted or lost in the source project.
-Migrating to Self-hosted from Cloud
+Migrating to Cloud from Self-hosted
To begin migrating to self-hosted, make sure to read the migration overview
and things to keep in mind sections above.
From b8d7cafd11c538ab25b7e4977dbb8c81317cd9cf Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:33:03 -0400
Subject: [PATCH 134/183] Update app/views/docs/migrations-local-to-cloud.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index e69a47ff0..3b51000a9 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -17,7 +17,7 @@
and things to keep in mind sections above.
-Steps on Your Self-hosted Project
+Steps in Self-hosted Console
- Navigate to your self-hosted project's console and click on the Migrations tab.
From d21952e2340b8a78596ab3b4764143ad28cb60ab Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:33:12 -0400
Subject: [PATCH 135/183] Update app/views/docs/migrations-local-to-cloud.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index 3b51000a9..4f6e8ac78 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -25,7 +25,7 @@
- You will complete the migration on Appwrite Cloud.
-Steps on Your Cloud Project
+Steps in Cloud Console
- Once redirected to Appwrite Cloud, you'll be prompted to select an organization and a project. You can migrate to an existing project or create a new one.
- Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
From d18687646ba34a710c55ec7d7fa4daa361d31e34 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:33:19 -0400
Subject: [PATCH 136/183] Update app/views/docs/migrations-local-to-cloud.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index 4f6e8ac78..f1db09fb4 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -20,7 +20,7 @@
Steps in Self-hosted Console
- - Navigate to your self-hosted project's console and click on the Migrations tab.
+ - Navigate to your self-hosted project's console and click on the Migrations tab in Project Settings.
- Click Deploy to cloud, you will be redirected to Appwrite Cloud.
- You will complete the migration on Appwrite Cloud.
From 3b6ca9aee33137e745fa35d70688ff68b2f8beb8 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:33:41 -0400
Subject: [PATCH 137/183] Update app/views/docs/migrations-local-to-cloud.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index f1db09fb4..bf2efd78c 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -21,7 +21,7 @@
- Navigate to your self-hosted project's console and click on the Migrations tab in Project Settings.
- - Click Deploy to cloud, you will be redirected to Appwrite Cloud.
+ - Click Deploy to cloud, and you will be redirected to Appwrite Cloud.
- You will complete the migration on Appwrite Cloud.
From 70d285eb1b328420a869c22eeb39e51663bd5962 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:34:53 -0400
Subject: [PATCH 138/183] Update app/views/docs/migrations-local-to-cloud.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-local-to-cloud.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-local-to-cloud.phtml b/app/views/docs/migrations-local-to-cloud.phtml
index bf2efd78c..9040dafa1 100644
--- a/app/views/docs/migrations-local-to-cloud.phtml
+++ b/app/views/docs/migrations-local-to-cloud.phtml
@@ -27,7 +27,7 @@
Steps in Cloud Console
- - Once redirected to Appwrite Cloud, you'll be prompted to select an organization and a project. You can migrate to an existing project or create a new one.
+ - Once redirected to Appwrite Cloud, you'll be prompted to select a project. If you have multiple organizations, you will also be asked to pick one. You can migrate to an existing project or create a new one.
- Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
- Click Start migration to start the migration process. You do not need to keep the Appwrite Console open through the process.
From 70518866774a5be3262c8faa455d433b5ff80233 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:36:04 -0400
Subject: [PATCH 139/183] Update app/views/docs/migrations.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations.phtml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index d51e3709f..8f1b98d8e 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -1,6 +1,7 @@
If you're looking to migrate existing projects to Appwrite, Migrations can help you make the move more quickly.
You can move your app from Firebase, Supabase, NHost, and even move between self-hosted and Cloud projects using Migrations.
+ You can also use Migrations to move between two self-hosted instances or even to duplicate project on the same instance.
Migrations will automatically move accounts, database documents, and storage files from one source to another.
From 645eb610e20c31003a5e4739d70c5bdb37e49e2a Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:36:14 -0400
Subject: [PATCH 140/183] Update app/views/docs/migrations.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index 8f1b98d8e..6e3e09661 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -82,6 +82,6 @@
- Migrations help you jump start your move, but because each product is unique, complex databases and product unique features like functions need to be migrated manually.
+ Migrations help you jump start your move, but because each product is unique, complex databases and product unique features like functions might need to be migrated manually.
We also recommend you carefully validate permissions and data integrity when moving between platforms.
\ No newline at end of file
From 6ddde09aaa2b391f2d2aa7b253ac3cef0dc10332 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:36:40 -0400
Subject: [PATCH 141/183] Update app/views/docs/migrations-nhost.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-nhost.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-nhost.phtml b/app/views/docs/migrations-nhost.phtml
index ca9aed1d5..0c48071da 100644
--- a/app/views/docs/migrations-nhost.phtml
+++ b/app/views/docs/migrations-nhost.phtml
@@ -21,7 +21,7 @@
-
- Create a new project and click on the Migrations tab.
+ Create a new project and click on the Migrations tab in Project Settings.
-
Click on the Create Migration button and select NHost as your source.
From 7e06a3068ca577f62e7c4748544214a8a88d5050 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:36:49 -0400
Subject: [PATCH 142/183] Update app/views/docs/migrations-supabase.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-supabase.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
index e5b789ebd..09ecd1fd3 100644
--- a/app/views/docs/migrations-supabase.phtml
+++ b/app/views/docs/migrations-supabase.phtml
@@ -21,7 +21,7 @@
-
- Create a new project and click on the Migrations tab.
+ Create a new project and click on the Migrations tab in Project Settings.
-
Click on the Create Migration button and select Supabase as your source.
From bf58e0f0ced58b2ca6ae12d3ecdca9176d83e152 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 10:37:02 -0400
Subject: [PATCH 143/183] Update app/views/docs/migrations-firebase.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/migrations-firebase.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index c5d234175..999147a8d 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -22,7 +22,7 @@
-
- Create a new project and click on the Migrations tab.
+ Create a new project and click on the Migrations tab in Project Settings.
-
Click on the Create Migration button and select Firebase as your source.
From 2e5216e28024ff25e85af015ba1a6a25d7966724 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 16:37:03 +0000
Subject: [PATCH 144/183] Resolve conflicts with upstream
---
app/views/docs/index.phtml | 4 +-
.../migrations-cloud-to-self-hosted.phtml | 34 +++++++++++++++++
app/views/docs/migrations-firebase.phtml | 5 ++-
app/views/docs/migrations-nhost.phtml | 3 +-
.../migrations-self-hosted-to-cloud.phtml | 38 +++++++++++++++++++
app/views/docs/migrations-supabase.phtml | 3 +-
app/views/docs/migrations.phtml | 9 +++--
7 files changed, 87 insertions(+), 9 deletions(-)
create mode 100644 app/views/docs/migrations-cloud-to-self-hosted.phtml
create mode 100644 app/views/docs/migrations-self-hosted-to-cloud.phtml
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index ec9819fbf..b57eb9a43 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -99,8 +99,8 @@ $cols = [
- Firebase
- Supabase
- NHost
- - Cloud to Self-hosted
- - Self-hosted to Cloud
+ - Cloud to Self-hosted
+ - Self-hosted to Cloud
diff --git a/app/views/docs/migrations-cloud-to-self-hosted.phtml b/app/views/docs/migrations-cloud-to-self-hosted.phtml
new file mode 100644
index 000000000..801d93c0e
--- /dev/null
+++ b/app/views/docs/migrations-cloud-to-self-hosted.phtml
@@ -0,0 +1,34 @@
+
+ Moving to a self-hosted instance? We've got you covered.
+ Migrations makes it as easy as a couple clicks to move all of your Appwrite Cloud project data to a self-hosted instance.
+
+
+Things to keep in mind
+
+
+ - Data transferred by migrations will reset `$createdAt` and `$updatedAt` timestamps to the date of the migration.
+ - Your self-hosted Appwrite project must be accessible from the internet for the migration to work.
+ - Migrations are non-destructive. No data will be deleted or lost in the source project.
+
+
+Migrating to Self-hosted from Cloud
+
+
+ To begin migrating to Appwrite Self-hosted, make sure to read the migrations overview
+ and things to keep in mind sections above.
+
+
+Steps on Your Cloud Project
+
+ - Navigate to your Appwrite Cloud Console and click on the Migrations tab.
+ - Click Export to Self-hosted, you will be prompted to input the URL of your self-hosted Appwrite project.
+ - Optionally, tell us about why you're moving to self-hosted.
+ - After clicking Continue, you'll be directed back to your self-hosted project to complete the process.
+
+
+Steps on Your Self-hosted Project
+
+ - Once redirected to your self-hosted project, you'll be prompted to select an organization and a project. You can migrate to an existing project or create a new one.
+ - Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
+ - Click Start migration to start the migration process. You do not need to keep the Appwrite Console open through the process.
+
\ No newline at end of file
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index 999147a8d..f16efc879 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -10,8 +10,9 @@
- Appwrite will not incur usage charges during migrations, but Firebase may still incur service charges.
- Appwrite Migrations only supports Firestore as a database source. Realtime Database is currently not supported.
- - At the moment only top level document migration is supported. Nested documents will not be transferred automatically.
- - OAuth users will not be transferred. Users will need to re-authenticate with your OAuth provider after the migration is complete.
+ - At the moment only top level document migration is supported. Nested documents will not be migrated automatically.
+ - OAuth users will not be migrated because the sessions are managed by the third-party OAuth provider. Users will need to re-authenticate with your OAuth provider after the migration is complete.
+ - Functions are not automatically migrated because of syntax and runtime differences.
Migrating to Appwrite from Firebase
diff --git a/app/views/docs/migrations-nhost.phtml b/app/views/docs/migrations-nhost.phtml
index 0c48071da..20a8edef2 100644
--- a/app/views/docs/migrations-nhost.phtml
+++ b/app/views/docs/migrations-nhost.phtml
@@ -10,7 +10,8 @@
- Appwrite will not incur usage charges during migrations, but NHost may still incur service charges.
- Appwrite's Database doesn't support all the features of the postgreSQL database so more advanced postgres centric things things like advanced indexes, postgres functions and scheduling will not be migrated.
- - OAuth users will not be transferred. You will need to re-authenticate with your OAuth provider after the migration is complete.
+ - OAuth users will not be migrated because the sessions are managed by the third-party OAuth provider. Users will need to re-authenticate with your OAuth provider after the migration is complete.
+ - Functions are not automatically migrated because of syntax and runtime differences.
Migrating to Appwrite from NHost
diff --git a/app/views/docs/migrations-self-hosted-to-cloud.phtml b/app/views/docs/migrations-self-hosted-to-cloud.phtml
new file mode 100644
index 000000000..5cfee4cb8
--- /dev/null
+++ b/app/views/docs/migrations-self-hosted-to-cloud.phtml
@@ -0,0 +1,38 @@
+
+ Making the move to Appwrite Cloud? We've got your back.
+ Migrations makes it as easy as a couple clicks to move all of your self-hosted project data to a Cloud instance.
+
+
+Things to keep in mind
+
+
+ - Data transferred by migrations will reset
$createdAt and $updatedAt timestamps to the date of the migration.
+ - Your self-hosted Appwrite project must be accessible from the internet for the migration to work.
+ - Migrations are non-destructive. No data will be deleted or lost in the source project.
+
+
+Migrating to Self-hosted from Cloud
+
+ To begin migrating to self-hosted, make sure to read the migration overview
+ and things to keep in mind sections above.
+
+
+Steps on Your Self-hosted Project
+
+
+ - Navigate to your self-hosted project's console and click on the Migrations tab.
+ - Click Deploy to cloud, you will be redirected to Appwrite Cloud.
+ - You will complete the migration on Appwrite Cloud.
+
+
+Steps on Your Cloud Project
+
+ - Once redirected to Appwrite Cloud, you'll be prompted to select an organization and a project. You can migrate to an existing project or create a new one.
+ - Select the data you wish to migrate. You can choose among accounts, databases, documents, files, and functions.
+ - Click Start migration to start the migration process. You do not need to keep the Appwrite Console open through the process.
+
+
+
+ Keep in mind
+ Your Self-hosted instance will generate a API Key in the background to pass to Cloud. You can revoke this key after the migration process is complete.
+
\ No newline at end of file
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
index 09ecd1fd3..dedbcbcb7 100644
--- a/app/views/docs/migrations-supabase.phtml
+++ b/app/views/docs/migrations-supabase.phtml
@@ -10,7 +10,8 @@
- Appwrite will not incur usage charges during migrations, but Supabase may still incur service charges.
- Appwrite's Databases services supports a different set of features as PostgreSQL. Some features like advanced indexes, Postgres functions and scheduling will not be migrated.
- - OAuth users will not be transferred. Users will need to re-authenticate with your OAuth provider after the migration is complete.
+ - OAuth users will not be migrated because the sessions are managed by the third-party OAuth provider. Users will need to re-authenticate with your OAuth provider after the migration is complete.
+ - Functions are not automatically migrated because of syntax and runtime differences.
Migrating to Appwrite from Supabase
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index 6e3e09661..e130ae472 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -7,7 +7,10 @@
Supported sources
- You can transfer from these sources to an Appwrite project.
+ You can transfer from these sources to an Appwrite project.
+ Resources marked supported are migrated automatically.
+ Resources marked partial can be migrated, but with limitations or caveats, check the guide for each source to learn more.
+ Resources marked manual require manual migration.
@@ -54,7 +57,7 @@
-
+
supported
supported
@@ -64,7 +67,7 @@
-
+
supported
supported
From eb9d20aa77914b85e99288bcc4888a30110e9a06 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 16:51:04 +0000
Subject: [PATCH 145/183] Address matej's comments
---
app/views/docs/migrations-firebase.phtml | 26 +++---------------------
app/views/docs/migrations-nhost.phtml | 3 +++
app/views/docs/migrations-supabase.phtml | 3 +++
3 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/app/views/docs/migrations-firebase.phtml b/app/views/docs/migrations-firebase.phtml
index f16efc879..2c351d599 100644
--- a/app/views/docs/migrations-firebase.phtml
+++ b/app/views/docs/migrations-firebase.phtml
@@ -28,29 +28,6 @@
-
Click on the Create Migration button and select Firebase as your source.
- -
- Depending on where your Appwrite project is hosted, you'll need to use different methods to authorize with Firebase.
- See the Cloud and Self-hosting sections for details.
-
- -
- Finally, add the platforms for your Web, Flutter, Android, and iOS apps.
-
-
-
-Migrate to Cloud
-
- To simplify the migration process we have created an OAuth application that will allow you to sign in with Google and automatically
- discover your Firebase projects. Simply select the source project and follow the migration wizard.
-
-
-After completing the migration wizard, migration will begin. Return to step 4 of the migration steps.
-
-Migrating to Self-Hosted
-
- If you are self-hosting Appwrite you will need to create a service account in your Firebase project and download the JSON file.
-
-
-
-
Navigate to your Firebase console.
@@ -171,4 +148,7 @@
-
After completing the migration wizard, migration will begin. Return to step 4 of the migration steps.
+ -
+ Finally, add the platforms for your Web, Flutter, Android, and iOS apps.
+
\ No newline at end of file
diff --git a/app/views/docs/migrations-nhost.phtml b/app/views/docs/migrations-nhost.phtml
index 20a8edef2..7558fe9b5 100644
--- a/app/views/docs/migrations-nhost.phtml
+++ b/app/views/docs/migrations-nhost.phtml
@@ -33,6 +33,9 @@
-
Select the resources you want to migrate and finally click Start migration to begin the migration process.
+ -
+ Finally, add the platforms for your Web, Flutter, Android, and iOS apps.
+
NHost Credentials
diff --git a/app/views/docs/migrations-supabase.phtml b/app/views/docs/migrations-supabase.phtml
index dedbcbcb7..8ff4a7bca 100644
--- a/app/views/docs/migrations-supabase.phtml
+++ b/app/views/docs/migrations-supabase.phtml
@@ -33,6 +33,9 @@
-
Select the resources you want to migrate and finally click Start migration to begin the migration process.
+ -
+ Finally, add the platforms for your Web, Flutter, Android, and iOS apps.
+
Credentials
From b5dd0689288869e94b36dd1afd00be3af8fb21f9 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 14:08:56 -0400
Subject: [PATCH 146/183] Update app/views/docs/email-and-sms-templates.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/email-and-sms-templates.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index 1d4ec7c15..63730e086 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -2,7 +2,7 @@
Each Appwrite project can have its own set of unique templates.
- Templates also support localization, every template can be written in multiple languages and served
+ Templates also support localization, so every template can be written in multiple languages and served
depending on the configured locale.
From e6b6fee0da3a75ab50a768b456761a821940e870 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 14:09:06 -0400
Subject: [PATCH 147/183] Update app/views/docs/email-and-sms-templates.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/email-and-sms-templates.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index 63730e086..bb6b6b4d6 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -1,4 +1,4 @@
-Appwrite uses email and SMS messages to communicate with users to perform authentication actions. Emails and SMS messages can be customized to fit your app's design and voice.
+Appwrite uses email and SMS messages to communicate with users to perform authentication and verification actions. Emails and SMS messages can be customized to fit your app's design and voice.
Each Appwrite project can have its own set of unique templates.
From 9249017aa0c8d6eafe3dbb8c24b8606eda8adee4 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 14:11:47 -0400
Subject: [PATCH 148/183] Apply suggestions from code review
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/email-and-sms-templates.phtml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index bb6b6b4d6..c7a723c36 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -17,7 +17,7 @@
You can customize email templates for each of your projects in the Appwrite console.
Custom SMTP Server Required
- The built-in email service does not support custom email templates. Configure a custom SMTP server to enable custom email templates.
+ The built-in email service does not support custom email templates to prevent malicious templates. Configure a custom SMTP server to enable custom email templates.
- In your project, navigate to the Auth service.
@@ -40,15 +40,15 @@
Sender name
- Readers will see this as display name of the sender.
+ Readers will see this as a display name of the sender.
Sender email
- Readers will see this as the displayed email of the sender. This must be a valid email for the SMTP provider you've configured.
+ Readers will see this as a display email of the sender. This email must be authenticated on the SMTP provider you've configured, otherwise it will be delivered to the spam folder. This usually means the email must end with the same domain as your SMTP username.
Reply to
- Readers will reply to this email address instead of the sender address. You can leave this field empty if unused.
+ Readers will reply to this email address instead of the sender address. You can leave this field empty, and the sender email will be used automatically.
Subject
@@ -56,12 +56,12 @@
Message
- The body of the email. You can find the variables available in the Email Template Syntax section.
+ The body of the email in HTML format. You can find the variables available in the Email Template Syntax section.
Email Template Syntax
-Variables can be used in email templates to dynamically format unique emails for each reader. These variables can only be accessed in the Message field of the email template.
+Variables can be used in email templates to dynamically construct unique emails for each reader. These variables can only be used in the Message field of the email template.
@@ -81,7 +81,7 @@
{{user}}
- The name of the user receiving the email.
+ The name of the user receiving the email. This variable is not available in the Magic URL template, as there might not be a user yet.
{{redirect}}
@@ -192,7 +192,7 @@
- You can send messages in different localizations by setting the locale with client.setLocale() in the SDKs or the X-Appwrite-Locale HTTP header.
+ You can send messages in different languages by setting the locale with client.setLocale() in the SDKs or the X-Appwrite-Locale HTTP header. View here the list of available locales
For example, you can send a phone verification in French.
From 5353edfb0505d9e2f8f913f1207e55a2bf84e18d Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 18:39:31 +0000
Subject: [PATCH 149/183] Console capitalized
---
app/views/docs/email-and-sms-templates.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index c7a723c36..aed0abe2d 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -14,7 +14,7 @@
Customize Templates
-You can customize email templates for each of your projects in the Appwrite console.
+You can customize email templates for each of your projects in the Appwrite Console.
Custom SMTP Server Required
The built-in email service does not support custom email templates to prevent malicious templates. Configure a custom SMTP server to enable custom email templates.
From 7844c58d5f6382dc29eb97f608404fbc32bb3f2b Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 18:47:07 +0000
Subject: [PATCH 150/183] remove reference of phone/sms template
---
app/views/docs/email-and-sms-templates.phtml | 61 ++------------------
1 file changed, 6 insertions(+), 55 deletions(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index aed0abe2d..f1327335d 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -1,4 +1,4 @@
-Appwrite uses email and SMS messages to communicate with users to perform authentication and verification actions. Emails and SMS messages can be customized to fit your app's design and voice.
+Appwrite uses emails to communicate with users to perform authentication and verification actions. Emails can be customized to fit your app's design and voice.
Each Appwrite project can have its own set of unique templates.
@@ -6,13 +6,6 @@
depending on the configured locale.
-
-
-
Customize Templates
You can customize email templates for each of your projects in the Appwrite Console.
@@ -142,48 +135,6 @@
</html>
-SMS Templates
-You can customize the SMS templates used for phone verification and login.
-SMS Template Components
-
-
-
- Component
- Description
-
-
-
-
- Message
- The body of the SMS message. You can find the variables available in the SMS Template Syntax section.
-
-
-
-
-SMS Template Syntax
-Variables can be used in SMS templates to dynamically format unique messages for each reader.
-
-
-
-
- Variable
- Description
-
-
-
-
- {{token}}
- The secret code sent to users for phone verification or authentication.
-
-
-
-
-SMS Template Examples
-Here's an example of using these variables in a template.
-
- Your account verification code is {{token}}
-
-
Localization
@@ -195,7 +146,7 @@
You can send messages in different languages by setting the locale with client.setLocale() in the SDKs or the X-Appwrite-Locale HTTP header. View here the list of available locales
-For example, you can send a phone verification in French.
+For example, you can send an email verification in French.
-
Web
@@ -212,7 +163,7 @@ client
.setLocale('fr') // Your locale
;
-const promise = account.createPhoneVerification();
+const promise = account.createVerification('https://example.com');
promise.then(function (response) {
console.log(response); // Success
@@ -235,7 +186,7 @@ void main() { // Init SDK
.setProject('5df5acd0d48c2') // Your project ID
.setLocale('fr') // Your locale
;
- Future result = account.createPhoneVerification();
+ Future result = account.createVerification('https://example.com');
result
.then((response) {
@@ -259,7 +210,7 @@ val client = Client(context)
val account = Account(client)
-val response = account.createPhoneVerification()
+val response = account.createVerification('https://example.com')
-
@@ -274,7 +225,7 @@ let client = Client()
let account = Account(client)
-let token = try await account.createPhoneVerification()
+let token = try await account.createVerification('https://example.com')
\ No newline at end of file
From 24ebe2fd296bf26bf5b1130127a4b2aa1926a687 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Fri, 25 Aug 2023 19:03:44 +0000
Subject: [PATCH 151/183] Fix index
---
app/views/docs/index.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 5db26d3dc..8f0bd9a08 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -107,7 +107,7 @@ $cols = [
- Pagination
- Webhooks
- Custom Domains
- - Email and SMS Templates
+ - Email Templates
- Response Codes
- Rate Limits
-
From 8872899bf9a2c9b672d99039cbdd633ac4161644 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sat, 26 Aug 2023 20:37:18 +0000
Subject: [PATCH 152/183] Runtimes merged on one line
---
app/views/docs/functions-runtimes.phtml | 56 +++++++++++++++++--------
1 file changed, 39 insertions(+), 17 deletions(-)
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index 96119f04d..928071a3f 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -4,12 +4,26 @@ use Appwrite\Utopia\View;
$events = $this->getParam('events', []);
$runtimes = $this->getParam('runtimes', []);
-$runtimes['node-16.0']["cloud"] = true;
-$runtimes['node-18.0']["cloud"] = true;
-$runtimes['php-8.0']["cloud"] = true;
-$runtimes['ruby-3.0']["cloud"] = true;
-$runtimes['python-3.9']["cloud"] = true;
-$runtimes['dart-2.17']["cloud"] = true;
+
+$sorted_runtimes = [];
+
+foreach ($runtimes as $key => $item) {
+ $name = $item['name'];
+
+ if (!isset($sorted_runtimes[$name])) {
+ $sorted_runtimes[$name] = [];
+ }
+
+ $item['version'] = $key;
+
+ $sorted_runtimes[$name]['versions'][] = $item;
+}
+
+$sorted_runtimes['Node.js']["cloud"] = true;
+$sorted_runtimes['PHP']["cloud"] = true;
+$sorted_runtimes['Ruby']["cloud"] = true;
+$sorted_runtimes['Python']["cloud"] = true;
+$sorted_runtimes['Dart']["cloud"] = true;
?>
@@ -26,24 +40,32 @@ $runtimes['dart-2.17']["cloud"] = true;
- Name
+ Name
Image
- Architectures
- Platforms
+ Architectures
+ Platforms
- $runtime): ?>
+ $runtime): ?>
- ![Function Env.]()
- escape($key); ?>
- escape($runtime['image'] ?? ''); ?>
- escape(implode(' / ', $runtime['supports'] ?? [])); ?>
-
+
+
+
+ escape($key); ?>
+
+
+ $version): ?>
+ escape($version['image'] ?? ''); ?>
+
+
+ escape(implode(' / ', $runtime['versions'][0]['supports'] ?? [])); ?>
+
+ Self-hosted
+
Cloud
-
- Self-hosted
+
From 77337c1edf209eb235fe60155e818c3d447bdff1 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sat, 26 Aug 2023 20:50:20 +0000
Subject: [PATCH 153/183] Fix response code examples
---
app/views/docs/functions-develop.phtml | 338 ++++++++++++++++++++-----
1 file changed, 279 insertions(+), 59 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index a780b61e7..8f5c4cd8a 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -1301,7 +1301,7 @@ namespace runtime {
- Variable
+ Variable
Description
@@ -1372,64 +1372,7 @@ namespace runtime {
You can access the environment variables through the systems library of each language.
-
-
-
- Variable
- Description
-
-
-
-
- x-appwrite-trigger
-
- Describes how the function execution was invoked.
- Possible values are http, schedule or event.
-
-
-
- x-appwrite-event
-
- If the function execution was triggered by an event, describes the triggering event.
-
-
-
- x-appwrite-user-id
-
- If the function execution was invoked by an authenticated user, display the user ID.
- This doesn't apply to Appwrite Console users or API keys.
-
-
-
- x-appwrite-user-jwt
-
- JWT token generated from the invoking user's session. Used to authenticate Server SDKs to respect access permissions.
- Learn more about JWT tokens.
-
-
-
- x-appwrite-country-code
-
- Displays the country code of the configured locale.
-
-
-
- x-appwrite-continent-code
-
- Displays the continent code of the configured locale.
-
-
-
- x-appwrite-continent-eu
-
- Describes if the configured local is within the EU.
-
-
-
-
-
-
- Response
+
If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
The response information will not be logged to the Appwrite Console.
@@ -1561,6 +1504,283 @@ namespace runtime {
+
Response
+
+
+ -
+
Node.js
+
+ export default async ({ req, res, log }) => {
+
+ switch (req.query.type) {
+ case 'text':
+ return res.send("This is a text response", 200);
+ case 'json':
+ return res.json({"type": "This is a JSON response"}, 200);
+ case 'redirect':
+ return res.redirect("https://appwrite.io", 301);
+ case 'html':
+ return res.send(
+ "<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ });
+ default:
+ return res.empty();
+ }
+}
+
+
+ -
+
PHP
+
+ <?php
+
+return function ($context) {
+ switch ($context->req->query['type']) {
+ case 'text':
+ return $context->res->send("This is a text response", 200);
+ case 'json':
+ return $context->res->json(["type" => "This is a JSON response"], 200);
+ case 'redirect':
+ return $context->res->redirect("https://appwrite.io", 301);
+ case 'html':
+ return $context->res->send("<h1>This is an HTML response</h1>", 200, [
+ "content-type" => "text/html"
+ ]);
+ default:
+ return $context->res->empty();
+ }
+};
+
+
+ -
+
Python
+
+ def main(context):
+ switch context.req.query['type']:
+ case 'text':
+ return context.res.send("This is a text response", 200)
+ case 'json':
+ return context.res.json({"type": "This is a JSON response"}, 200)
+ case 'redirect':
+ return context.res.redirect("https://appwrite.io", 301)
+ case 'html':
+ return context.res.send("<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ })
+ default:
+ return context.res.empty()
+
+
+ -
+
Ruby
+
+ def main(context)
+ case context.req.query['type']
+ when 'text'
+ return context.res.send("This is a text response", 200)
+ when 'json'
+ return context.res.json({"type": "This is a JSON response"}, 200)
+ when 'redirect'
+ return context.res.redirect("https://appwrite.io", 301)
+ when 'html'
+ return context.res.send("<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ })
+ else
+ return context.res.empty()
+ end
+end
+
+
+ -
+
Deno
+
+ export default async ({ req, res, log }) => {
+
+ switch (req.query.type) {
+ case 'text':
+ return res.send("This is a text response", 200);
+ case 'json':
+ return res.json({type": "This is a JSON response"}, 200);
+ case 'redirect':
+ return res.redirect("https://appwrite.io", 301);
+ case 'html':
+ return res.send(
+ "<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ });
+ default:
+ return res.empty();
+ }
+}
+
+
+ -
+
Dart
+
+ import 'dart:async';
+
+Future<dynamic> main(final context) async {
+ switch (context.req.query['type']) {
+ case 'text':
+ return context.res
+ .send('This is a text response', 200);
+ case 'json':
+ return context.res
+ .json({'type': 'This is a JSON response'});
+ case 'redirect':
+ return context.res
+ .redirect('https://appwrite.io', 301);
+ case 'html':
+ return context.res
+ .send('<h1>This is an HTML response</h1>', 200, {
+ 'content-type': 'text/html'
+ });
+ default:
+ return context.res
+ .empty();
+ }
+}
+
+
+ -
+
Swift
+
+ import Foundation
+
+func main(context: RuntimeContext) async throws -> RuntimeOutput {
+ switch context.req.query["type"] {
+ case "text":
+ return try await context.send("This is a text response", 200)
+ case "json":
+ return try await context.send(["type": "This is a JSON response"], 200)
+ case "redirect":
+ return try await context.redirect("https://appwrite.io", 301)
+ case "html":
+ return try await context.send("<h1>This is an HTML response</h1>", 200, [
+ "content-type": "text/html"
+ ])
+ default:
+ return try await context.empty()
+ }
+}
+
+
+ -
+
.NET
+
+ namespace DotNetRuntime;
+
+public class Handler {
+ public async Task<RuntimeOutput> Main(RuntimeContext Context)
+ {
+ switch (Context.Request.Query["type"])
+ {
+ case "text":
+ return await Context.Send("This is a text response", 200);
+ case "json":
+ return await Context.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } }, 200);
+ case "redirect":
+ return await Context.Redirect("https://appwrite.io", 301);
+ case "html":
+ return await Context.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
+ { "content-type", "text/html" }
+ });
+ default:
+ return await Context.Empty();
+ }
+ }
+}
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
+
+import io.openruntimes.kotlin.RuntimeContext
+import io.openruntimes.kotlin.RuntimeOutput
+
+class Main {
+ fun main(context: RuntimeContext): RuntimeOutput {
+ when (context.req.query["type"]) {
+ "text" -> return context.send("This is a text response", 200)
+ "json" -> return context.send(mapOf("type" to "This is a JSON response"), 200)
+ "redirect" -> return context.redirect("https://appwrite.io", 301)
+ "html" -> return context.send("<h1>This is an HTML response</h1>", 200, mapOf("content-type" to "text/html"))
+ else -> return context.empty()
+ }
+ }
+}
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
+
+import io.openruntimes.java.RuntimeContext;
+import io.openruntimes.java.RuntimeOutput;
+import java.util.Map;
+import java.util.HashMap;
+
+public class Main {
+ public RuntimeOutput main(RuntimeContext context) throws Exception {
+ switch (context.getReq().getQuery()["type"]) {
+ case "text":
+ return context.send("This is a text response", 200);
+ case "json":
+ HashMap<String, Object> data = new HashMap<>();
+ data.put("type", "This is a JSON response");
+ return context.send(data, 200);
+ case "redirect":
+ return context.redirect("https://appwrite.io", 301);
+ case "html":
+ return context.send("<h1>This is an HTML response</h1>", 200, Map.of("content-type", "text/html"));
+ default:
+ return context.empty();
+ }
+ }
+}
+
+
+ -
+
C++
+
+ #include "../RuntimeResponse.h"
+#include "../RuntimeRequest.h"
+#include "../RuntimeOutput.h"
+#include "../RuntimeContext.h"
+
+namespace runtime {
+ class Handler {
+ public:
+ static RuntimeOutput main(RuntimeContext &context) {
+ std::string type = context.req.query["type"];
+
+ if (type == "text") {
+ return context.send("This is a text response", 200);
+ } else if (type == "json") {
+ Json::Value data;
+ data["type"] = "This is a JSON response";
+ return context.send(data, 200);
+ } else if (type == "redirect") {
+ return context.redirect("https://appwrite.io", 301);
+ } else if (type == "html") {
+ Json::Value headers;
+ headers["content-type"] = "text/html";
+ return context.send("<h1>This is an HTML response</h1>", 200, headers);
+ } else {
+ return context.empty();
+ }
+ }
+ };
+}
+
+
+
+
Dependencies
From 7228e69949d250284603ecd10341e36a2ae0700f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sat, 26 Aug 2023 21:16:52 +0000
Subject: [PATCH 154/183] Add link to Destructuring Assignment
---
app/views/docs/functions-develop.phtml | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 8f5c4cd8a..ae7ea3d84 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -3,7 +3,7 @@
Each function is handled following a request and response pattern.
-Function Flow
+Function Flow
There is a clear flow for all Appwrite Functions, from beginning to end.
Here's everything that happens during a function execution.
@@ -478,8 +478,11 @@ public class Main {
-Destructuring Assignment
-Some languages, namely JavaScript, support destructuring. You'll see us use destructing in examples, which has the following syntax.
+Destructuring Assignment
+
+ Some languages, namely JavaScript, support destructuring. You'll see us use destructing in examples, which has the following syntax.
+ Learn more about destructuring assignment.
+
-
Node.js
From 7a24d8eb3e2e6d113f651b8b05f63ae113b007b9 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sat, 26 Aug 2023 22:02:27 +0000
Subject: [PATCH 155/183] ChatGPT reviewed grammar and spelling:
---
app/views/docs/functions-deploy.phtml | 10 +++++-----
app/views/docs/functions-develop.phtml | 8 ++++----
app/views/docs/functions-execute.phtml | 26 +++++++++++++-------------
app/views/docs/functions.phtml | 14 +++++++-------
4 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 0405d7445..9071a415f 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -1,5 +1,5 @@
- Appwrite Functions are mini application in Appwrite with their own endpoint.
+ Appwrite Functions are mini-applications in Appwrite with their own endpoints.
Each function can have many deployments, which can be thought of as versions of the mini-application.
@@ -15,7 +15,7 @@
This offers simple versioning and collaboration that will easily fit into the rest of your development workflow.
-Create Funcion
+Create Function
Before deploying your function with VCS, create a new function attached to your VCS repo.
-
@@ -157,7 +157,7 @@
Domains
- Each deployed function can have it's own domain.
+ Each deployed function can have its own domain.
By default, one is generated for each of your functions.
You can find the generated domain for your function like this.
@@ -179,7 +179,7 @@
- Navigate to the Domains tab.
- Click on Create domain.
- Input your domain in the Domain input field and click Next.
- - Copy the CNAME record provided to you, and add it to your domain registar.
+ - Copy the CNAME record provided to you, and add it to your domain registrar.
- Click Go to console and wait for the domain name to be verified and certificate to generate.
@@ -200,7 +200,7 @@
Redeploy Builds
- After updateing the configuration of your Appwrite Function, you need to redeploy your function for the changes to take effect.
+ After updating the configuration of your Appwrite Function, you need to redeploy your function for the changes to take effect.
You can also redeploy builds to retry failed builds.
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index ae7ea3d84..f3afdaee5 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -446,7 +446,7 @@ public class Main {
The Context Object
Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite console.
- All input, output, anddlogging must be handled through the context object passed in.
+ All input, output, and logging must be handled through the context object passed in.
You'll find these properties in the context object.
@@ -1284,13 +1284,13 @@ namespace runtime {
Accessing Environment Variables
If you need to pass constants or secrets to Appwrite Functions, you can use environment variables.
- Environmental variables can be global, or function specific.
+ Environmental variables can be global, or function-specific.
Default Environment Variables
Appwrite runtimes passes in some environment variables by default.
- These are always accesible for every function at runtime.
+ These are always accessible for every function at runtime.
@@ -2544,7 +2544,7 @@ export function add(a, b) {
import { add } from './utils.js';
-export defaut function ({res}) {
+export default function ({res}) {
return res.send(add(1, 2));
}
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 685756b8f..4fc4dc929 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -4,8 +4,8 @@ use Appwrite\Utopia\View;
?>
- Appwrite Functions executions can be invoked in several ways.
- Functions can be invoked through the Appwrite SDK and visting its REST endpoint. Functions can also be triggered by events and scheduled executions.
+ Appwrite Functions can be executed in several ways.
+ Executions can be invoked through the Appwrite SDK and visiting its REST endpoint. Functions can also be triggered by events and scheduled executions.
Here are all the different ways to consume your new Appwrite Functions.
@@ -73,7 +73,7 @@ try {
})
console.log(data)
} catch (err) {
- console.err(err.message)
+ console.error(err.message)
}
@@ -175,7 +175,7 @@ try {
})
console.log(data)
} catch (err) {
- console.err(err.message)
+ console.error(err.message)
}
@@ -274,7 +274,7 @@ try {
})
console.log(data)
} catch (err) {
- console.err(err.message)
+ console.error(err.message)
}
@@ -425,8 +425,9 @@ public static void main(String[] args) throws Exception {
Console
- Another easy way to test a function is directly in the Appwrite console.
- You test a function by hitting the Execute now button and
+ Another easy way to test a function is directly in the Appwrite Console.
+ You test a function by hitting the Execute now button, which will display with modal below.
+ You'll be able to mock executions by configuring the path, method, headers, and body.
- In Appwrite Console, navigate to Functions.
- - Click to open a function you wish to add variables to.
+ - Click to open a function you wish to configure.
- Under the Settings tab, navigate to Events.
- Add one or multiple events as triggers for the function.
-
Be careful to avoid selecting events that can be caused by the function itself.
- This can cause the function to trigger it's own execution, resulting in infinite recursions.
+ This can cause the function to trigger its own execution, resulting in infinite recursions.
@@ -488,7 +489,6 @@ $image = new View(__DIR__.'/../general/image.phtml');
-Permissions
Permissions
@@ -497,15 +497,15 @@ $image = new View(__DIR__.'/../general/image.phtml');
Server SDKs require an API key with the correct scopes.
- If your function with a generated or custom domain, permissions are disabled for this function.
- Anyone visiting this domain will be able to execute the function.
+ If your function has a generated or custom domain, execute permissions are ignored for this function.
+ Anyone visiting the configured domains will be able to execute the function.
If you need to enforce permissions for functions with a domain, use authentication methods like JWT.
Logs and results
You can view the logs your function executions in the Appwrite Console.
- Navigate to Functions and click on a function to view it's executions.
+ Navigate to Functions and click on a function to view its executions.
For security reasons, Appwrite does not store the response of function executions.
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index f45f4415b..9fb059feb 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -6,14 +6,14 @@ use Appwrite\Utopia\View;
Appwrite Functions unlock limitless potential for developers to extend Appwrite with code snippets.
- Appwrite Functions are user defined functions that can start small and scale big, deploying automatically from source control.
- These Functions can be triggered by HTTP requests, SDK methods, server events, webhooks, scheduled executions.
- Each function will have their own URL, execute in their own isolated container, and have their own configurable environment variables and permissions.
+ Appwrite Functions are user-defined functions that can start small and scale big, deploying automatically from source control.
+ These Functions can be triggered by HTTP requests, SDK methods, server events, webhooks, and scheduled executions.
+ Each function will have its own URL, execute in its own isolated container, and have its own configurable environment variables and permissions.
Getting Started
- Appwrite Functions let you build anything you can imagine, but this flexibility makes is difficult to know where to start.
+ Appwrite Functions let you build anything you can imagine, but this flexibility makes it difficult to know where to start.
Start exploring by cloning one of the quick start templates or using a template with pre-built integration to quickly implement features.
@@ -29,7 +29,7 @@ $image = new View(__DIR__.'/../general/image.phtml');
Explore Features
- Appwrite Functions use familiar HTTP concepts, so you can learn quickly and grain transferable skills.
+ Appwrite Functions use familiar HTTP concepts, so you can learn quickly and gain transferable skills.
Learn more about developing functions
@@ -44,7 +44,7 @@ $image = new View(__DIR__.'/../general/image.phtml');
- Appwrite Functions can be triggered by HTTP requests, SDK methods, server events, webhooks, scheduled executions.
+ Appwrite Functions can be triggered by HTTP requests, SDK methods, server events, webhooks, and scheduled executions.
Explore how Appwrite Functions can be invoked.
@@ -61,7 +61,7 @@ $image = new View(__DIR__.'/../general/image.phtml');
Like to learn from examples?
- Here's a curated list of examples that showcase Appwrite Function's capabilies.
+ Here's a curated list of examples that showcase Appwrite Functions' capabilities.
Learn more about using function examples
From e3683ed4a1bdd1ff3497af9b1afc79794868777c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Sun, 27 Aug 2023 13:37:11 +0000
Subject: [PATCH 156/183] PR review changes
---
app/views/docs/functions-develop.phtml | 316 ++----------------------
app/views/docs/functions-examples.phtml | 28 +--
2 files changed, 22 insertions(+), 322 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index f3afdaee5..369b8148d 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -11,9 +11,9 @@
- The function is invoked.
- - Appwrite passes in request information like headers and environment variables through the
context.req object.
- - The runtime executes the code you defined, you can log through the
context.log or context.error methods.
- - Function terminates when you return results using
context.res.
+ - Appwrite passes in request information like headers, body or path through the
context.req object.
+ - The runtime executes the code you defined, you can log through the
context.log() or context.error() methods.
+ - Function terminates when you return results using
return context.res.send(), return context.res.json() or similar.
You'll find all of these steps in a simple function like this.
@@ -445,7 +445,7 @@ public class Main {
The Context Object
- Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite console.
+ Context is an object passed into every function to handle communication to both the end users, and logging to the Appwrite Console.
All input, output, and logging must be handled through the context object passed in.
@@ -467,12 +467,12 @@ public class Main {
Contains methods to build a response and return information. See full examples here.
- log
- Logs information to the Appwrite Console, end users will not be able to see these logs. See full examples here.
+ log()
+ Method to log information to the Appwrite Console, end users will not be able to see these logs. See full examples here.
- error
- Logs errors to the Appwrite Console, end users will not be able to see these errors. See full examples here.
+ error()
+ Methoc to log errors to the Appwrite Console, end users will not be able to see these errors. See full examples here.
@@ -508,8 +508,8 @@ public class Main {
Request
- If you pass data into an Appwrite function, it'll be found in the request object.
- This includes all invocation methods, such as data from Appwrite SDKs, HTTP calls, Appwrite events, and browsers visiting the configured domain.
+ If you pass data into an Appwrite Function, it'll be found in the request object.
+ This includes all invocation inputs from Appwrite SDKs, HTTP calls, Appwrite events, or browsers visiting the configured domain.
Explore the request object with the following function, which logs all request params to the Appwrite Console.
@@ -528,7 +528,7 @@ public class Main {
log(req.port); // Port from the host header, for example 8000
log(req.path); // Path part of URL, for example /v1/hooks
log(req.queryString); // Raw query params string. For example "limit=12&offset=50"
- log(req.query); // Parsed query params. For example, req.query.limit
+ log(JSON.stringify(req.query)); // Parsed query params. For example, req.query.limit
return res.send("All the request parameters are logged to the Appwrite Console.");
};
@@ -612,7 +612,7 @@ end
log(req.port); // Port from the host header, for example 8000
log(req.path); // Path part of URL, for example /v1/hooks
log(req.queryString); // Raw query params string. For example "limit=12&offset=50"
- log(req.query); // Parsed query params. For example, req.query.limit
+ log(JSON.stringify(req.query)); // Parsed query params. For example, req.query.limit
return res.send("All the request parameters are logged to the Appwrite Console.");
@@ -1348,10 +1348,10 @@ namespace runtime {
- Local Environment Variables
+ Function Environment Variables
- Local environment variables will only be accessible in the function they belong to.
- Local environment variables will override global environment variables when they have conflicting names.
+ Function environment variables will only be accessible in the function they belong to.
+ Function environment variables will override global environment variables when they have conflicting names.
- In Appwrite Console, navigate to Functions.
@@ -1362,7 +1362,7 @@ namespace runtime {
Global Environment Variables
- Global environment variables are accessible to all Appwrite Functions.
+ Global environment variables are accessible to all Appwrite Functions in your project.
Local environment variables will override global environment variables when they have conflicting names.
@@ -1375,13 +1375,6 @@ namespace runtime {
You can access the environment variables through the systems library of each language.
-
-
- If you need to send a response to the invoker of the function, such as a user, client app, or an integration, use the response object.
- The response information will not be logged to the Appwrite Console.
- There are several possible ways to send a response, explore them in the following Appwrite Function.
-
-
-
Node.js
@@ -1507,283 +1500,6 @@ namespace runtime {
- Response
-
-
- -
-
Node.js
-
- export default async ({ req, res, log }) => {
-
- switch (req.query.type) {
- case 'text':
- return res.send("This is a text response", 200);
- case 'json':
- return res.json({"type": "This is a JSON response"}, 200);
- case 'redirect':
- return res.redirect("https://appwrite.io", 301);
- case 'html':
- return res.send(
- "<h1>This is an HTML response</h1>", 200, {
- "content-type": "text/html"
- });
- default:
- return res.empty();
- }
-}
-
-
- -
-
PHP
-
- <?php
-
-return function ($context) {
- switch ($context->req->query['type']) {
- case 'text':
- return $context->res->send("This is a text response", 200);
- case 'json':
- return $context->res->json(["type" => "This is a JSON response"], 200);
- case 'redirect':
- return $context->res->redirect("https://appwrite.io", 301);
- case 'html':
- return $context->res->send("<h1>This is an HTML response</h1>", 200, [
- "content-type" => "text/html"
- ]);
- default:
- return $context->res->empty();
- }
-};
-
-
- -
-
Python
-
- def main(context):
- switch context.req.query['type']:
- case 'text':
- return context.res.send("This is a text response", 200)
- case 'json':
- return context.res.json({"type": "This is a JSON response"}, 200)
- case 'redirect':
- return context.res.redirect("https://appwrite.io", 301)
- case 'html':
- return context.res.send("<h1>This is an HTML response</h1>", 200, {
- "content-type": "text/html"
- })
- default:
- return context.res.empty()
-
-
- -
-
Ruby
-
- def main(context)
- case context.req.query['type']
- when 'text'
- return context.res.send("This is a text response", 200)
- when 'json'
- return context.res.json({"type": "This is a JSON response"}, 200)
- when 'redirect'
- return context.res.redirect("https://appwrite.io", 301)
- when 'html'
- return context.res.send("<h1>This is an HTML response</h1>", 200, {
- "content-type": "text/html"
- })
- else
- return context.res.empty()
- end
-end
-
-
- -
-
Deno
-
- export default async ({ req, res, log }) => {
-
- switch (req.query.type) {
- case 'text':
- return res.send("This is a text response", 200);
- case 'json':
- return res.json({type": "This is a JSON response"}, 200);
- case 'redirect':
- return res.redirect("https://appwrite.io", 301);
- case 'html':
- return res.send(
- "<h1>This is an HTML response</h1>", 200, {
- "content-type": "text/html"
- });
- default:
- return res.empty();
- }
-}
-
-
- -
-
Dart
-
- import 'dart:async';
-
-Future<dynamic> main(final context) async {
- switch (context.req.query['type']) {
- case 'text':
- return context.res
- .send('This is a text response', 200);
- case 'json':
- return context.res
- .json({'type': 'This is a JSON response'});
- case 'redirect':
- return context.res
- .redirect('https://appwrite.io', 301);
- case 'html':
- return context.res
- .send('<h1>This is an HTML response</h1>', 200, {
- 'content-type': 'text/html'
- });
- default:
- return context.res
- .empty();
- }
-}
-
-
- -
-
Swift
-
- import Foundation
-
-func main(context: RuntimeContext) async throws -> RuntimeOutput {
- switch context.req.query["type"] {
- case "text":
- return try await context.send("This is a text response", 200)
- case "json":
- return try await context.send(["type": "This is a JSON response"], 200)
- case "redirect":
- return try await context.redirect("https://appwrite.io", 301)
- case "html":
- return try await context.send("<h1>This is an HTML response</h1>", 200, [
- "content-type": "text/html"
- ])
- default:
- return try await context.empty()
- }
-}
-
-
- -
-
.NET
-
- namespace DotNetRuntime;
-
-public class Handler {
- public async Task<RuntimeOutput> Main(RuntimeContext Context)
- {
- switch (Context.Request.Query["type"])
- {
- case "text":
- return await Context.Send("This is a text response", 200);
- case "json":
- return await Context.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } }, 200);
- case "redirect":
- return await Context.Redirect("https://appwrite.io", 301);
- case "html":
- return await Context.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
- { "content-type", "text/html" }
- });
- default:
- return await Context.Empty();
- }
- }
-}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
-
-import io.openruntimes.kotlin.RuntimeContext
-import io.openruntimes.kotlin.RuntimeOutput
-
-class Main {
- fun main(context: RuntimeContext): RuntimeOutput {
- when (context.req.query["type"]) {
- "text" -> return context.send("This is a text response", 200)
- "json" -> return context.send(mapOf("type" to "This is a JSON response"), 200)
- "redirect" -> return context.redirect("https://appwrite.io", 301)
- "html" -> return context.send("<h1>This is an HTML response</h1>", 200, mapOf("content-type" to "text/html"))
- else -> return context.empty()
- }
- }
-}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
-
-import io.openruntimes.java.RuntimeContext;
-import io.openruntimes.java.RuntimeOutput;
-import java.util.Map;
-import java.util.HashMap;
-
-public class Main {
- public RuntimeOutput main(RuntimeContext context) throws Exception {
- switch (context.getReq().getQuery()["type"]) {
- case "text":
- return context.send("This is a text response", 200);
- case "json":
- HashMap<String, Object> data = new HashMap<>();
- data.put("type", "This is a JSON response");
- return context.send(data, 200);
- case "redirect":
- return context.redirect("https://appwrite.io", 301);
- case "html":
- return context.send("<h1>This is an HTML response</h1>", 200, Map.of("content-type", "text/html"));
- default:
- return context.empty();
- }
- }
-}
-
-
- -
-
C++
-
- #include "../RuntimeResponse.h"
-#include "../RuntimeRequest.h"
-#include "../RuntimeOutput.h"
-#include "../RuntimeContext.h"
-
-namespace runtime {
- class Handler {
- public:
- static RuntimeOutput main(RuntimeContext &context) {
- std::string type = context.req.query["type"];
-
- if (type == "text") {
- return context.send("This is a text response", 200);
- } else if (type == "json") {
- Json::Value data;
- data["type"] = "This is a JSON response";
- return context.send(data, 200);
- } else if (type == "redirect") {
- return context.redirect("https://appwrite.io", 301);
- } else if (type == "html") {
- Json::Value headers;
- headers["content-type"] = "text/html";
- return context.send("<h1>This is an HTML response</h1>", 200, headers);
- } else {
- return context.empty();
- }
- }
- };
-}
-
-
-
-
Dependencies
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index a8dd01968..d30c0b827 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -24,7 +24,7 @@
npm install undici
- Finally, add npm install to your function's build commands in the Appwrite console.
+ Finally, add npm install to your function's build commands in the Appwrite Console.
-
@@ -38,7 +38,7 @@
composer require guzzlehttp/guzzle
- Finally, add composer install to your function's build commands in the Appwrite console.
+ Finally, add composer install to your function's build commands in the Appwrite Console.
-
@@ -53,7 +53,7 @@
echo "requests" >> requirements.txt
pip install -r requirements.txt
- Finally, add pip install -r requirements.txt to your function's build commands in the Appwrite console.
+ Finally, add pip install -r requirements.txt to your function's build commands in the Appwrite Console.
-
@@ -78,7 +78,7 @@ environment:
pub install http
- Finally, add pub get to your function's build commands in the Appwrite console.
+ Finally, add pub get to your function's build commands in the Appwrite Console.
@@ -101,7 +101,7 @@ environment:
bundle install
- Finally, add bundle install to your function's build commands in the Appwrite console.
+ Finally, add bundle install to your function's build commands in the Appwrite Console.
@@ -608,7 +608,7 @@ def main(context):
Use the function by navigating to the function URL in the browser. The URL should contain the required parameters.
- For example, [YOUR_FUNCTION_URL]?userId=[USER_ID]&topicId=[TOPIC_ID];&vote=yes to cast a vote.
+ For example, [YOUR_FUNCTION_URL]/?userId=[USER_ID]&topicId=[TOPIC_ID]&vote=yes to cast a vote.
HTML Contact Form
@@ -939,19 +939,3 @@ Future main(final context) async {
Use the function by navigating to the function URL in the browser. Submit the form to store the message in the collection.
-
-
-[TODO: @luke -> Example with JWT, show both client and server code]
-
-
-
-
\ No newline at end of file
From 67f2c434162c53a2530230f4c777865611f6f635 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Sun, 27 Aug 2023 13:37:31 +0000
Subject: [PATCH 157/183] Fix console name spelling
---
app/views/docs/authentication-security.phtml | 4 ++--
app/views/docs/authentication.phtml | 4 ++--
app/views/docs/custom-domains.phtml | 2 +-
app/views/docs/email-delivery.phtml | 2 +-
app/views/docs/functions-deploy.phtml | 6 +++---
app/views/docs/getting-started-for-android.phtml | 4 ++--
app/views/docs/getting-started-for-apple.phtml | 2 +-
app/views/docs/getting-started-for-flutter.phtml | 4 ++--
app/views/docs/getting-started-for-server.phtml | 2 +-
app/views/docs/getting-started-for-web.phtml | 2 +-
app/views/docs/keys.phtml | 2 +-
app/views/docs/permissions-old.phtml | 2 +-
app/views/docs/permissions.phtml | 2 +-
app/views/docs/production.phtml | 2 +-
app/views/docs/self-hosting.phtml | 2 +-
15 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 241e6893e..fe26070e9 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -87,10 +87,10 @@
Password History
Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password everytime it's changed.
-Password history can be enabled in the Auth service's Security tab on the Appwrite console. You can choose how many previous passwords to remember up to a maximum of 20 and block users from reusing them.
+Password history can be enabled in the Auth service's Security tab on the Appwrite Console. You can choose how many previous passwords to remember up to a maximum of 20 and block users from reusing them.
Password Dictionary
Password dictionary protects users from using bad passwords. It compares the user's password to the 10,000 most common passwords and throws an error if there's a match. Together with rate limits, password dictionary will significantly reduce the chance of a malicious actor from guessing user passwords.
-Password dictionary can be enabled in the Auth service's Security tab on the Appwrite console.
\ No newline at end of file
+Password dictionary can be enabled in the Auth service's Security tab on the Appwrite Console.
\ No newline at end of file
diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml
index 9910bc286..065b96683 100644
--- a/app/views/docs/authentication.phtml
+++ b/app/views/docs/authentication.phtml
@@ -513,7 +513,7 @@ mutation {
- Only redirect URLs to domains added as a platform on your Appwrite console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks.
+ Only redirect URLs to domains added as a platform on your Appwrite Console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks.
@@ -898,7 +898,7 @@ let session = try await account.get()
- Only redirect URLs to domains added as a platform on your Appwrite console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks.
+ Only redirect URLs to domains added as a platform on your Appwrite Console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks.
diff --git a/app/views/docs/custom-domains.phtml b/app/views/docs/custom-domains.phtml
index 74c087140..5c178c322 100644
--- a/app/views/docs/custom-domains.phtml
+++ b/app/views/docs/custom-domains.phtml
@@ -356,7 +356,7 @@ $dns = [
Confirm and Verify Your Domain
-Once you added your new CNAME record to your DNS settings, you will need to verify your new domain name from your Appwrite console. Enter your custom domains tab from your project settings, click the DNS Settings link and click on the 'Confirm and Verify" button. If everything went well, Appwrite will approve your domain and generate a new SSL certificate for it in the background.
+Once you added your new CNAME record to your DNS settings, you will need to verify your new domain name from your Appwrite Console. Enter your custom domains tab from your project settings, click the DNS Settings link and click on the 'Confirm and Verify" button. If everything went well, Appwrite will approve your domain and generate a new SSL certificate for it in the background.
Enjoy your Free SSL Certificate
diff --git a/app/views/docs/email-delivery.phtml b/app/views/docs/email-delivery.phtml
index ad8000572..1ad88c091 100644
--- a/app/views/docs/email-delivery.phtml
+++ b/app/views/docs/email-delivery.phtml
@@ -66,4 +66,4 @@ The next possible source of error is the configuration in your .env file. Make s
docker compose up -d --build --force-recreate
-Now you can head over to your Appwrite console, logout from your account and try to recover your password or send invites to other team members from your Appwrite console using your newly configured SMTP provider.
+Now you can head over to your Appwrite Console, logout from your account and try to recover your password or send invites to other team members from your Appwrite Console using your newly configured SMTP provider.
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 9071a415f..100d4e95a 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -101,14 +101,14 @@
Overwrite Warning
- If you made changes in the Appwrite console that is different from your appwrite.json,
+ If you made changes in the Appwrite Console that is different from your appwrite.json,
using the CLI deploy command will overwrite your console changes, such as execution schedule or permissions.
Update your appwrite.json manually before deploying to avoid overwriting changes.
Manual Deployment
-You can also upload your functions to be deployed using the Appwrite console. The example below shows a simple Node.JS function, but the same idea applies to any other language.
+You can also upload your functions to be deployed using the Appwrite Console. The example below shows a simple Node.JS function, but the same idea applies to any other language.
.
@@ -143,7 +143,7 @@
-Next, navigate to your Appwrite console and upload the function.
+Next, navigate to your Appwrite Console and upload the function.
- Navigate to the function you want to deploy.
diff --git a/app/views/docs/getting-started-for-android.phtml b/app/views/docs/getting-started-for-android.phtml
index 74d35cbf0..207aed6af 100644
--- a/app/views/docs/getting-started-for-android.phtml
+++ b/app/views/docs/getting-started-for-android.phtml
@@ -19,7 +19,7 @@ $androidVersion = (isset($versions['android'])) ? $versions['android'] : '';
Add your Android Platform
-To init your SDK and start interacting with Appwrite services, you need to add a new Android platform to your project. To add a new platform, go to your Appwrite console, choose the project you created in the step before, and click the 'Add Platform' button. Only API requests initiated from platforms added to your Appwrite project will be accepted. This prevents unauthorized apps from accessing your Appwrite project.
+To init your SDK and start interacting with Appwrite services, you need to add a new Android platform to your project. To add a new platform, go to your Appwrite Console, choose the project you created in the step before, and click the 'Add Platform' button. Only API requests initiated from platforms added to your Appwrite project will be accepted. This prevents unauthorized apps from accessing your Appwrite project.
From the options, choose to add a new Android platform and add add your app name and package name, your package name is generally the applicationId in your app-level build.gradle file. By registering your new app platform, you are allowing your app to communicate with the Appwrite API.
@@ -40,7 +40,7 @@ $androidVersion = (isset($versions['android'])) ? $versions['android'] : '';
OAuth Callback
-In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console.
+In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite Console.
escape('
diff --git a/app/views/docs/getting-started-for-apple.phtml b/app/views/docs/getting-started-for-apple.phtml
index fc6ce3038..fd431809c 100644
--- a/app/views/docs/getting-started-for-apple.phtml
+++ b/app/views/docs/getting-started-for-apple.phtml
@@ -19,7 +19,7 @@ $appleVersion = $versions['apple'] ?? '';
Add your Apple Platform
-To init your SDK and start interacting with Appwrite services, you need to add a new Apple platform to your project. To add a new platform, go to your Appwrite console, choose the project you created in the step before, and click the 'Add Platform' button. Only API requests initiated from platforms added to your Appwrite project will be accepted. This prevents unauthorized apps from accessing your Appwrite project.
+To init your SDK and start interacting with Appwrite services, you need to add a new Apple platform to your project. To add a new platform, go to your Appwrite Console, choose the project you created in the step before, and click the 'Add Platform' button. Only API requests initiated from platforms added to your Appwrite project will be accepted. This prevents unauthorized apps from accessing your Appwrite project.
From the options, choose to add a new Apple platform, select the iOS, macOS, watchOS or tvOS tab and add your app name and bundle identifier, Your bundle identifier can be found at the top of the General tab in your project settings, or in your Info.plist file. By registering your new app platform, you are allowing your app to communicate with the Appwrite API.
diff --git a/app/views/docs/getting-started-for-flutter.phtml b/app/views/docs/getting-started-for-flutter.phtml
index 6bd614873..47355fa81 100644
--- a/app/views/docs/getting-started-for-flutter.phtml
+++ b/app/views/docs/getting-started-for-flutter.phtml
@@ -19,7 +19,7 @@ $version = (isset($versions['flutter'])) ? $versions['flutter'] : '';
Add your Flutter Platform
-To init your SDK and start interacting with Appwrite services, you need to add a new Flutter platform to your project. To add a new platform, go to your Appwrite console, choose the project you created in the step before, and click the 'Add Platform' button. Only API requests initiated from platforms added to your Appwrite project will be accepted. This prevents unauthorized apps from accessing your Appwrite project.
+To init your SDK and start interacting with Appwrite services, you need to add a new Flutter platform to your project. To add a new platform, go to your Appwrite Console, choose the project you created in the step before, and click the 'Add Platform' button. Only API requests initiated from platforms added to your Appwrite project will be accepted. This prevents unauthorized apps from accessing your Appwrite project.
From the options, choose to add a new Flutter platform and add your app credentials. Appwrite Flutter SDK currently supports building apps for Android, iOS, Linux, Mac OS, Web and Windows.
@@ -29,7 +29,7 @@ $version = (isset($versions['flutter'])) ? $versions['flutter'] : '';
For Android first add your app name and package name, Your package name is generally the applicationId in your app-level build.gradle file. By registering your new app platform, you are allowing your app to communicate with the Appwrite API.
-In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in you project settings screen in your Appwrite console.
+In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in you project settings screen in your Appwrite Console.
escape('
diff --git a/app/views/docs/getting-started-for-server.phtml b/app/views/docs/getting-started-for-server.phtml
index e5ede12fe..b05dd86e3 100644
--- a/app/views/docs/getting-started-for-server.phtml
+++ b/app/views/docs/getting-started-for-server.phtml
@@ -109,7 +109,7 @@ $swiftVersion = $versions['swift'] ?? '';
Create Your First Appwrite Project
-Go to your new Appwrite console and click the icon in the top navigation header or on the 'Create Project' button on your console homepage. Choose a name for your project and click create to get started.
+Go to your new Appwrite Console and click the icon in the top navigation header or on the 'Create Project' button on your console homepage. Choose a name for your project and click create to get started.
Authentication
diff --git a/app/views/docs/getting-started-for-web.phtml b/app/views/docs/getting-started-for-web.phtml
index d7ec5bc2a..979053852 100644
--- a/app/views/docs/getting-started-for-web.phtml
+++ b/app/views/docs/getting-started-for-web.phtml
@@ -21,7 +21,7 @@ $demos = $platform['demos'] ?? [];
Add Your Web Platform
-To init your SDK and interact with Appwrite services, you need to add a web platform to your project. To add a new platform, go to your Appwrite console, choose the project you created in the step before and click the 'Add Platform' button.
+To init your SDK and interact with Appwrite services, you need to add a web platform to your project. To add a new platform, go to your Appwrite Console, choose the project you created in the step before and click the 'Add Platform' button.
From the options, choose to add a web platform and add your client app hostname. By adding your hostname to your project platform, you are allowing cross-domain communication between your project and the Appwrite API. Only web apps hosted on domains specified in a web platform will be able to make requests to your Appwrite instance, preventing unwanted access from malicious actors.
diff --git a/app/views/docs/keys.phtml b/app/views/docs/keys.phtml
index cfff198a4..a63fff508 100644
--- a/app/views/docs/keys.phtml
+++ b/app/views/docs/keys.phtml
@@ -2,7 +2,7 @@
$scopes = $this->getParam('scopes', );
?>
-Using your API Keys, you can access Appwrite services using the SDK of your choice. To create a new API key, go to your API keys tab in your project setting using your Appwrite console and click the 'Add API Key' button.
+Using your API Keys, you can access Appwrite services using the SDK of your choice. To create a new API key, go to your API keys tab in your project setting using your Appwrite Console and click the 'Add API Key' button.
When adding a new API Key, you can choose which scope to grant your application. If you need to replace your API Key, create a new key, update your app credentials and, once ready, delete your old key.
diff --git a/app/views/docs/permissions-old.phtml b/app/views/docs/permissions-old.phtml
index ac8cb8ecb..a1d7ff4c5 100644
--- a/app/views/docs/permissions-old.phtml
+++ b/app/views/docs/permissions-old.phtml
@@ -10,7 +10,7 @@
For example, only users with a guest role can access authentication endpoints while access to member users is denied.
-You can change your project members' roles from your project settings in the Appwrite console.
+You can change your project members' roles from your project settings in the Appwrite Console.
diff --git a/app/views/docs/permissions.phtml b/app/views/docs/permissions.phtml
index adb1bbd3d..1c10fc523 100644
--- a/app/views/docs/permissions.phtml
+++ b/app/views/docs/permissions.phtml
@@ -18,7 +18,7 @@
Default Values
-If you create a resource using a Server SDK or the Appwrite console without explicit permissions, no one can access it by default because the permissions will be empty. If you create a resource using a Client SDK without explicit permissions, the creator will be granted read, update, and delete permissions on that resource by default.
+If you create a resource using a Server SDK or the Appwrite Console without explicit permissions, no one can access it by default because the permissions will be empty. If you create a resource using a Client SDK without explicit permissions, the creator will be granted read, update, and delete permissions on that resource by default.
Server Integration
diff --git a/app/views/docs/production.phtml b/app/views/docs/production.phtml
index 3133817d1..460e73f91 100644
--- a/app/views/docs/production.phtml
+++ b/app/views/docs/production.phtml
@@ -15,7 +15,7 @@
Limit Console Access
-Appwrite provides three different methods to limit access to your Appwrite console.
+Appwrite provides three different methods to limit access to your Appwrite Console.
- Whitelist a group of developers by IP using the
_APP_CONSOLE_WHITELIST_IPS environment variable.
diff --git a/app/views/docs/self-hosting.phtml b/app/views/docs/self-hosting.phtml
index 2aafd2f6f..2f6c39fd9 100644
--- a/app/views/docs/self-hosting.phtml
+++ b/app/views/docs/self-hosting.phtml
@@ -136,7 +136,7 @@
docker compose up -d --remove-orphans
-Once the Docker installation completes, go to your machine's hostname or IP address on your browser to access the Appwrite console. Please note that on hosts that are not Linux-native, the server might take a few minutes to start after installation completes.
+Once the Docker installation completes, go to your machine's hostname or IP address on your browser to access the Appwrite Console. Please note that on hosts that are not Linux-native, the server might take a few minutes to start after installation completes.
Stop
From 870726e6a2011b60b90ab45d88228b1698c200e5 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 09:50:26 -0400
Subject: [PATCH 158/183] Update app/views/docs/functions.phtml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/functions.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions.phtml b/app/views/docs/functions.phtml
index 9fb059feb..0d1f9e026 100644
--- a/app/views/docs/functions.phtml
+++ b/app/views/docs/functions.phtml
@@ -56,7 +56,7 @@ $image = new View(__DIR__.'/../general/image.phtml');
Avoid adding additional complexity to your codebase by coding in languages you already use and love.
-Learn more about using function runtimes
+Learn more about using function runtimes
From a84c5650b4becdd3b5043c1cf67ed4e7e75ce3ef Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 09:53:37 -0400
Subject: [PATCH 159/183] Apply suggestions from code review
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/functions-deploy.phtml | 19 ++++++++++---------
app/views/docs/functions-execute.phtml | 16 +++++++++-------
app/views/docs/functions-runtimes.phtml | 2 +-
3 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 100d4e95a..0a6c2b8e0 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -31,20 +31,21 @@
Search for the Git repository that hold your function and click connect.
-
- Select a production branch. New commits made to the production branch will be automatically deployed and activated.
+ Select a production branch. New commits pushed to the production branch will be automatically activated. Commits to any other branch will still be deployed, but not be activated.
-
- Input the root directory of the function inside the repository.
+ Input the root directory of the function inside the repository. If you have only one function in your repository, you can leave this empty. If you have multiple, root directory should point to the folder of your function. This should be the directory in which your custom build commands can run successfully. It also improves efficiency because only what's necessary is cloned.
-
- If you don't want deploy comments to be made on your PRs, select Silent mode.
+ If you don't want deploy comments to be made on your pull requests or commits, select Silent mode.
-
- Name your function, select a runtime that matches your function, and enter an entry point path, relative to the root directory from the previous step.
+ Name your function, select a runtime that matches your function, and enter entrypoint, relative to the root directory from the previous step. Entrypoint is path to the main file of your function, which exports the function to be run on every execution.
-
If you have build steps, like installing dependencies, input the commands into the Build settings heading's Command field.
You can combine multiple commands using
&&, such as npm install && npm build.
+ For compiled languages you don't need to worry about installing dependencies, as that's done automatically during compilation step.
-
Finally, configure the execute permissions of the function. For security, only provide execute permissions to the necessary roles.
@@ -54,7 +55,7 @@
Deploy
-
- Checkout your production branch in Git.
+ Using Git, checkout the branch you configured as production branch when creating the Appwrite Function.
-
Create a new commit.
@@ -63,18 +64,18 @@
Push your new commit.
-
- A new deployment will be automatically created. Deployments will be automatically activated when new commits are added to the production branch.
+ A new deployment will be automatically created, built and activated.
CLI
CLI Setup
- Before you can deploy with the Appwrite CLI, make sure you've installed and initialized the CLI
+ Before you can deploy with the Appwrite CLI, make sure you've installed and initialized the CLI.
To deploy with the Appwrite CLI, your function must be added to appwrite.json that tells the CLI where each function is stored.
- To ensure the folder structure is setup correctly and appwrite.json is configured correctly, use the appwrite init function method to create a shell function, then paste in your function code.
+ To ensure the folder structure is setup correctly and appwrite.json is configured correctly, use the appwrite init function method to create a starter function, then paste in your function code.
@@ -151,7 +152,7 @@
- Select the Manual tab.
- Input the entry point of your function under Entrypoint. For the example above, it would be
index.js.
- Upload
code.tar.gz.
- - Select Activate deployment after build to use your new function.
+ - Select Activate deployment after build to use your new deployment.
- Click Create to deploy your function.
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 4fc4dc929..c017e601b 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -6,7 +6,7 @@ use Appwrite\Utopia\View;
Appwrite Functions can be executed in several ways.
Executions can be invoked through the Appwrite SDK and visiting its REST endpoint. Functions can also be triggered by events and scheduled executions.
- Here are all the different ways to consume your new Appwrite Functions.
+ Here are all the different ways to consume your Appwrite Functions.
Domains
@@ -23,14 +23,14 @@ use Appwrite\Utopia\View;
- Alternatively you can add a custom domain to your Appwrite project.
+ Alternatively you can add a custom domain to your Appwrite Function.
REST API
When requests are made to this domain, whether through a browser or through an HTTP requests,
- the request information like request headers and request body will be passed to the function.
- This unlocks interesting ways to integrate other apps and backends to your Appwrite project.
+ the request information like request URL, request headers, and request body will be passed to the function.
+ This unlocks ability for Appwrite Function to become a full-blown API server on its own. It also allows accepting incoming webhooks for handling online payments, hosting social platform bots, and much more.
@@ -68,8 +68,10 @@ client
const functions = new Functions(client)
try {
- const data = await functions.createExecution('[FUNCTION_ID]', {
+ const data = await functions.createExecution('[FUNCTION_ID]', JSON.stringify({
'foo': 'bar'
+ }), '/', 'GET', {
+ 'X-Custom-Header': '123'
})
console.log(data)
} catch (err) {
@@ -497,8 +499,8 @@ $image = new View(__DIR__.'/../general/image.phtml');
Server SDKs require an API key with the correct scopes.
- If your function has a generated or custom domain, execute permissions are ignored for this function.
- Anyone visiting the configured domains will be able to execute the function.
+ If your function has a generated or custom domain, executions are not authenticated.
+ Anyone visiting the configured domains will be considered a guest, so make sure to give `Any` execute permission in order for domain executions to work.
If you need to enforce permissions for functions with a domain, use authentication methods like JWT.
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index 928071a3f..e1fe3be9c 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -29,7 +29,7 @@ $sorted_runtimes['Dart']["cloud"] = true;
Appwrite Functions supports an extensive list of runtimes to meet your unique tech preferences.
- Not all runtimes are available on Appwrite Cloud, check for the Cloud label in each listed runtime to know which ones are available.
+ Not all runtimes are available on Appwrite Cloud yet. Check for the Cloud label in each listed runtime to know which ones are available.
Supported Runtimes
From f70b7671ebe7f25c1ef58427f75785ad93e58de9 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 14:22:32 +0000
Subject: [PATCH 160/183] Address matej's review comments
---
app/views/docs/functions-deploy.phtml | 13 +++++------
app/views/docs/functions-execute.phtml | 2 +-
app/views/docs/functions-runtimes.phtml | 30 +++++++++++++------------
3 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 0a6c2b8e0..62ee5219f 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -9,14 +9,14 @@
Here's everything you need to know to deploy your first Appwrite Function.
-VCS (Version Control System)
+Git
The recommended way to manage your Appwrite Function deployments is to use a version control system, like Git.
This offers simple versioning and collaboration that will easily fit into the rest of your development workflow.
Create Function
-Before deploying your function with VCS, create a new function attached to your VCS repo.
+Before deploying your function with Git, create a new function attached to your Git repo.
-
Navigate to Functions from the side bar of the Appwrite Console.
@@ -109,8 +109,7 @@
Manual Deployment
-You can also upload your functions to be deployed using the Appwrite Console. The example below shows a simple Node.JS function, but the same idea applies to any other language.
-
+You can upload your functions to be deployed using the Appwrite Console. The example below shows a simple Node.js function, but the same idea applies to any other language.
.
├── package.json
@@ -166,7 +165,7 @@
- Navigate to the Appwrite Console's Functions page.
- Navigate to the Domains tab.
- - In the table, you'll find a link formatted similar to
https://64d4d22db370ae41a32e.appwrite.global. This is your preview.
+ - In the table, you'll find a link formatted similar to
https://64d4d22db370ae41a32e.appwrite.global. This is your generated domain.
@@ -208,10 +207,10 @@
- In Appwrite Console, navigate to Functions.
- Click to open a function you wish to inspect.
- Under the Deployments tab, you'll find the status of the current active deployment.
- - You can redeploy by clicking the Redeploy button.
+ - You can redeploy by clicking the triple-dots beside an execution, and hitting the Redeploy button.
The redeployment behavior varies depending on how the initial deployment is created.
- For VCS deployments, redeploy uses the same commit hash but updated function settings.
+ For Git deployments, redeploy uses the same commit hash but updated function settings.
For manual and CLI deployments, redeploy uses previously updated code but updated function settings.
\ No newline at end of file
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index c017e601b..2df0337d3 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -47,7 +47,7 @@ use Appwrite\Utopia\View;
-Learn more about using the Appwrite SDKs
+Learn more about using the Appwrite SDKs
Client SDKs
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index e1fe3be9c..69a946b74 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -4,6 +4,12 @@ use Appwrite\Utopia\View;
$events = $this->getParam('events', []);
$runtimes = $this->getParam('runtimes', []);
+$runtimes['node-16.0']["cloud"] = true;
+$runtimes['node-18.0']["cloud"] = true;
+$runtimes['php-8.0']["cloud"] = true;
+$runtimes['ruby-3.0']["cloud"] = true;
+$runtimes['python-3.9']["cloud"] = true;
+$runtimes['dart-2.17']["cloud"] = true;
$sorted_runtimes = [];
@@ -18,12 +24,6 @@ foreach ($runtimes as $key => $item) {
$sorted_runtimes[$name]['versions'][] = $item;
}
-
-$sorted_runtimes['Node.js']["cloud"] = true;
-$sorted_runtimes['PHP']["cloud"] = true;
-$sorted_runtimes['Ruby']["cloud"] = true;
-$sorted_runtimes['Python']["cloud"] = true;
-$sorted_runtimes['Dart']["cloud"] = true;
?>
@@ -41,9 +41,9 @@ $sorted_runtimes['Dart']["cloud"] = true;
Name
+ version
Image
Architectures
- Platforms
@@ -53,7 +53,15 @@ $sorted_runtimes['Dart']["cloud"] = true;
- escape($key); ?>
+ escape($key); ?>
+
+
+
+ Self-hosted
+
+ Cloud
+
+
$version): ?>
@@ -61,12 +69,6 @@ $sorted_runtimes['Dart']["cloud"] = true;
escape(implode(' / ', $runtime['versions'][0]['supports'] ?? [])); ?>
-
- Self-hosted
-
- Cloud
-
-
From 7a307fb3a95fc98737d3cbab536226ea21c67660 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 14:23:35 +0000
Subject: [PATCH 161/183] Fix runtimes by showing only cloud tags beside
relevant items + return the copy button
---
app/views/docs/functions-runtimes.phtml | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/app/views/docs/functions-runtimes.phtml b/app/views/docs/functions-runtimes.phtml
index 69a946b74..663d4eaf0 100644
--- a/app/views/docs/functions-runtimes.phtml
+++ b/app/views/docs/functions-runtimes.phtml
@@ -40,10 +40,11 @@ foreach ($runtimes as $key => $item) {
- Name
- version
+ Name
+ Version
+
Image
- Architectures
+ Architectures
@@ -53,17 +54,21 @@ foreach ($runtimes as $key => $item) {
- escape($key); ?>
+ escape($key); ?>
-
- Self-hosted
-
- Cloud
-
-
+ $version): ?>
+ escape($version['version']); ?>
+
+ $version): ?>
+
+ Cloud
+
+
+
+
$version): ?>
escape($version['image'] ?? ''); ?>
From e9fb6375ccdebba92a5ba0295107ea2467e5993d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Sun, 27 Aug 2023 14:44:47 +0000
Subject: [PATCH 162/183] Improve SDK function execute code examples
---
app/views/docs/functions-execute.phtml | 99 ++++++++++++++++++++------
1 file changed, 77 insertions(+), 22 deletions(-)
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 2df0337d3..a6e52cfcb 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -85,6 +85,7 @@ try {
import 'package:appwrite/appwrite.dart';
+import 'dart:convert';
final client = Client();
client
@@ -94,8 +95,10 @@ client
final functions = Functions(client);
try {
- final response = await functions.createExecution('[FUNCTION_ID]', {
+ final response = await functions.createExecution('[FUNCTION_ID]', json.encode({
'foo': 'bar'
+ }), '/', 'GET', {
+ 'X-Custom-Header': '123'
});
print(response.data);
} catch (e) {
@@ -110,6 +113,7 @@ try {
import io.appwrite.Client;
import io.appwrite.services.Functions;
+import com.google.gson.Gson;
val client = new Client();
client
@@ -119,8 +123,10 @@ client
val functions = new Functions(client);
try {
- val response = await functions.createExecution('[FUNCTION_ID]', {
+ val response = await functions.createExecution('[FUNCTION_ID]', gson.toString({
'foo': 'bar'
+ }), '/', 'GET', {
+ 'X-Custom-Header': '123'
});
print(response.data);
} catch (e) {
@@ -134,6 +140,7 @@ try {
import Appwrite
+import Foundation
let client = Client()
client
@@ -143,7 +150,15 @@ client
let functions = Functions(client: client)
do {
- let response = try functions.createExecution(functionId: "[FUNCTION_ID]", data: ["foo": "bar"])
+ let response = try functions.createExecution(
+ functionId: "[FUNCTION_ID]",
+ data: NSJSONSerialization.jsonObject(with: ["foo": "bar"], options: [])!,
+ xpath: "/",
+ method: "GET",
+ headers: [
+ "X-Custom-Header": "123"
+ ]
+ )
print(response)
} catch let error {
print(error)
@@ -172,8 +187,10 @@ client
const functions = new Functions(client)
try {
- const data = await functions.createExecution('[FUNCTION_ID]', {
+ const data = await functions.createExecution('[FUNCTION_ID]', JSON.stringify({
'foo': 'bar'
+ }), '/', 'GET', {
+ 'X-Custom-Header': '123'
})
console.log(data)
} catch (err) {
@@ -203,7 +220,11 @@ $client
$functions = new Functions($client);
-$result = $functions->createExecution('[FUNCTION_ID]');
+$result = $functions->createExecution('[FUNCTION_ID]', json_encode([
+ 'foo' => 'bar'
+], '/', 'GET', [
+ 'X-Custom-Header': '123'
+]);
@@ -213,6 +234,7 @@ $result = $functions->createExecution('[FUNCTION_ID]');
from appwrite.client import Client
from appwrite.services.functions import Functions
+import json
client = Client()
@@ -224,11 +246,11 @@ client = Client()
functions = Functions(client)
-result = functions.create_execution('[FUNCTION_ID]',
- {
- 'foo': 'bar'
- }
-)
+result = functions.create_execution('[FUNCTION_ID]', json.dumps({
+ 'foo': 'bar'
+}, '/', 'GET', {
+ 'X-Custom-Header': '123'
+})
@@ -237,6 +259,7 @@ result = functions.create_execution('[FUNCTION_ID]',
require 'Appwrite'
+require 'json'
include Appwrite
@@ -247,8 +270,10 @@ client = Client.new
functions = Functions.new(client)
-response = functions.create_execution(function_id: '[FUNCTION_ID]', data: {
+response = functions.create_execution(function_id: '[FUNCTION_ID]', data: JSON.generate({
'foo': 'bar'
+}), '/', 'GET', {
+ 'X-Custom-Header': '123'
})
puts response.inspect
@@ -271,8 +296,10 @@ client
const functions = new Functions(client)
try {
- const data = await functions.createExecution('[FUNCTION_ID]', {
+ const data = await functions.createExecution('[FUNCTION_ID]', JSON.stringify({
'foo': 'bar'
+ }), '/', 'GET', {
+ 'X-Custom-Header': '123'
})
console.log(data)
} catch (err) {
@@ -286,6 +313,7 @@ try {
import 'package:dart_appwrite/dart_appwrite.dart';
+import 'dart:convert';
void main() {
Client client = Client();
@@ -299,8 +327,13 @@ void main() {
Future result = functions.createExecution(
functionId: '[FUNCTION_ID]',
- data: {
+ data: json.encode({
'foo': 'bar'
+ }),
+ xpath: '/',
+ method: 'GET',
+ headers: {
+ 'X-Custom-Header': '123'
}
);
@@ -319,6 +352,7 @@ void main() {
import Appwrite
+import Foundation
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1")
@@ -329,10 +363,14 @@ let functions = Functions(client)
let execution = try await functions.createExecution(
functionId: "[FUNCTION_ID]",
- data: [
+ data: NSJSONSerialization.jsonObject(with: [
"foo": "bar"
- ]
-)
+ ], options: [])!),
+ xpath: '/',
+ method: 'GET',
+ headers: [
+ "X-Custom-Header": "123"
+])
@@ -343,6 +381,7 @@ let execution = try await functions.createExecution(
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
+using System.Text.Json;
var client = new Client()
.SetEndPoint("https://cloud.appwrite.io/v1")
@@ -353,10 +392,14 @@ var functions = new Functions(client);
Execution result = await functions.CreateExecution(
functionId: "[FUNCTION_ID]",
- data: new Dictionary<string, object> {
+ data: JsonSerializer.Serialize<object>(new Dictionary<string, object> {
{ "foo", "bar" }
- }
-);
+ }),
+ xpath: "/",
+ method: "GET",
+ headers: new Dictionary<string, object> {
+ { "X-Custom-Header", "123" }
+});
@@ -366,6 +409,7 @@ Execution result = await functions.CreateExecution(
import io.appwrite.Client
import io.appwrite.services.Functions
+import com.google.gson.Gson
fun main(args: Array<String>) {
val client = Client(context)
@@ -377,8 +421,13 @@ fun main(args: Array<String>) {
val response = functions.createExecution(
functionId = "[FUNCTION_ID]",
- data = mapOf(
+ data = gson.toString(mapOf(
"foo" to "bar"
+ )),
+ xpath = "/",
+ method = "GET",
+ headers = mapOf(
+ "X-Custom-Header" to "123"
)
)
}
@@ -395,6 +444,7 @@ fun main(args: Array<String>) {
import io.appwrite.Client;
import io.appwrite.services.Functions;
import java.util.HashMap;
+import com.google.gson.Gson;
public static void main(String[] args) throws Exception {
Client client = new Client()
@@ -414,9 +464,14 @@ public static void main(String[] args) throws Exception {
System.out.println(result);
}),
- new HashMap() {{
+ gson.toString(new HashMap() {{
put("foo", "bar");
- }}
+ }}),
+ "/",
+ "GET",
+ new HashMap() {{
+ put("X-Custom-Header", "123");
+ }},
);
}
From e22eee160e3d5a9559f23ffebe0c20bc81ff50c3 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 15:10:46 +0000
Subject: [PATCH 163/183] Address Eldad's comments
---
app/views/docs/functions-deploy.phtml | 2 +-
app/views/docs/functions-develop.phtml | 153 +++++++++++++++++++-----
app/views/docs/functions-examples.phtml | 9 +-
3 files changed, 128 insertions(+), 36 deletions(-)
diff --git a/app/views/docs/functions-deploy.phtml b/app/views/docs/functions-deploy.phtml
index 62ee5219f..934166ed4 100644
--- a/app/views/docs/functions-deploy.phtml
+++ b/app/views/docs/functions-deploy.phtml
@@ -69,7 +69,7 @@
CLI
-
+
CLI Setup
Before you can deploy with the Appwrite CLI, make sure you've installed and initialized the CLI.
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 369b8148d..b2b7bad38 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -3,9 +3,9 @@
Each function is handled following a request and response pattern.
-Function Flow
+Lifecycle
- There is a clear flow for all Appwrite Functions, from beginning to end.
+ There is a clear lifecycle for all Appwrite Functions, from beginning to end.
Here's everything that happens during a function execution.
@@ -460,19 +460,19 @@ public class Main {
req
- Contains request information like method, body, and headers. See full examples here.
+ Contains request information like method, body, and headers. See full examples here.
res
- Contains methods to build a response and return information. See full examples here.
+ Contains methods to build a response and return information. See full examples here.
log()
- Method to log information to the Appwrite Console, end users will not be able to see these logs. See full examples here.
+ Method to log information to the Appwrite Console, end users will not be able to see these logs. See full examples here.
error()
- Methoc to log errors to the Appwrite Console, end users will not be able to see these errors. See full examples here.
+ Methoc to log errors to the Appwrite Console, end users will not be able to see these errors. See full examples here.
@@ -487,20 +487,32 @@ public class Main {
-
Node.js
- export default async function ({ req, res, log, error }) {
- log('This is a log!');
- error('This is an error!');
- return res.send(`This function was called with ${req.method} method!`)
+ // before destructuring
+export default async function (context) {
+ context.log("This is a log!");
+ // ... more code
+}
+
+// after destructuring
+export default async function ({ req, res, log, error }) {
+ log("This is a log!");
+ // ... more code
}
-
Deno
- export default async function ({ req, res, log, error }: any) {
- log('This is a log!');
- error('This is an error!');
- return res.send(`This function was called with ${req.method} method!`)
+ // before destructuring
+export default async function (context: any) {
+ context.log("This is a log!");
+ // ... more code
+}
+
+// after destructuring
+export default async function ({ req, res, log, error }: any) {
+ context.log("This is a log!");
+ // ... more code
}
@@ -829,7 +841,7 @@ public class Main {
export default async ({ req, res, log }) => {
switch (req.query.type) {
- case 'text':
+ case 'text':
return res.send("This is a text response", 200);
case 'json':
return res.json({"type": "This is a JSON response"}, 200);
@@ -1097,6 +1109,47 @@ namespace runtime {
+
+ To get the different response types, set one of the following query parameters in the generated domain of your function.
+
+
+
+
+
+ Type
+ Query Param
+ Example
+
+
+
+
+ text
+ /?type=text
+ https://64d4d22db370ae41a32e.appwrite.global/?type=text
+
+
+ json
+ /?type=json
+ https://64d4d22db370ae41a32e.appwrite.global/?type=json
+
+
+ redirect
+ /?type=redirect
+ https://64d4d22db370ae41a32e.appwrite.global/?type=redirect
+
+
+ html
+ /?type=html
+ https://64d4d22db370ae41a32e.appwrite.global/?type=html
+
+
+ empty
+ /
+ https://64d4d22db370ae41a32e.appwrite.global/
+
+
+
+
Logging
To protect user privacy, the request and response objects are not logged to the Appwrite Console by default.
@@ -1348,10 +1401,10 @@ namespace runtime {
- Function Environment Variables
+ Function-level Environment Variables
- Function environment variables will only be accessible in the function they belong to.
- Function environment variables will override global environment variables when they have conflicting names.
+ Function-level environment variables will only be accessible in the function they belong to.
+ Function-level environment variables will override project-level variables when they have conflicting names.
- In Appwrite Console, navigate to Functions.
@@ -1360,13 +1413,13 @@ namespace runtime {
- Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
- Global Environment Variables
+ Project-level Variables
- Global environment variables are accessible to all Appwrite Functions in your project.
- Local environment variables will override global environment variables when they have conflicting names.
+ Project-level variables are accessible to all Appwrite Functions in your project.
+ Function-level environment variables will override project-level variables when they have conflicting names.
- - In Appwrite Console, navigate to your project's Settings page.
+ - In the Appwrite Console, navigate to your project's Settings page.
- Navigate to Global variables section.
- Create an environment variable by clicking Create variable, using the Editor, or import new variables through a
.env file.
@@ -1506,79 +1559,119 @@ namespace runtime {
Your function's dependencies should be managed by the package manager of each language. By default, we include the following package managers in each runtime:
-
- To install your dependencies before your function is built, you should add the relevant install command to the top your functions Build Commands script.
-
-
- Language
- Package Manager
+
+ Language
+ Package Manager
Commands
+
+
+
Node.js
npm
npm install
+
+
+
PHP
Composer
composer install
+
+
+
Python
pip
pip install -r requirements.txt
+
+
+
Ruby
Bundler
bundle install
+
+
+
Deno
deno
deno cache <ENTRYPOINT_FILE>
+
+
+
Dart
pub
pub get
+
+
+
Swift
Swift Package Manager
N/A
+
+
+
.NET
NuGet
N/A
+
+
+
Kotlin
Gradle
N/A
+
+
+
Java
Gradle
N/A
+
+
+
C++
None
N/A
+
+ To install your dependencies before your function is built, you should add the relevant install command to the top your function's Build setting > Commands.
+
+
Using Appwrite in a Function
- Appwrite can be used in your functions by adding the relevant SDK to your function's dependencies
- Authenticating with Appwrite is done via an API key or a JWT token. You can read more about authentication in the Server Authentication section of the docs.
+
+ Appwrite can be used in your functions by adding the relevant SDK to your function's dependencies.
+ Authenticating with Appwrite is done via an API key or a JWT token.
+ API keys must be generated and exported as an environment variable.
+
+
+ You can read more about authentication in the Server Authentication section of the docs.
+
Using with API Key
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index d30c0b827..485c4fe3b 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -4,7 +4,7 @@
Take a look at the following.
-Currency Conversion API
+Currency Conversion API
Here's a currency conversion API that converts from Euros and Indian Rupees to US Dollars. We'll use an external API to get the latest exchange rates, and query it using an dependency specific to each runtime.
@@ -233,7 +233,7 @@ end
-Voting System Using Appwrite
+Voting System Using Appwrite
Here's a simple voting system that allows users to vote on various topics. Appwrite Functions and the server SDK are used to enforce voting rules and prevent multiple votes from the same user for a single topic.
@@ -611,10 +611,9 @@ def main(context):
For example, [YOUR_FUNCTION_URL]/?userId=[USER_ID]&topicId=[TOPIC_ID]&vote=yes to cast a vote.
-HTML Contact Form
-
+HTML Contact Form
- Here's a simple form page that can be used to store a user's message in a collection.
+ Here's a simple form page that handles form submissions, and can be used to store a user's message in a collection.
The form is submitted to the function using the POST method and the form data is sent as a URL-encoded string in the request body.
From 8d9be11cf97dcd2b79720d06c8083ac98bd802ac Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 15:12:05 +0000
Subject: [PATCH 164/183] use enabled instead of supported in migrations
---
app/views/docs/migrations.phtml | 40 ++++++++++++++++-----------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/app/views/docs/migrations.phtml b/app/views/docs/migrations.phtml
index e130ae472..7d4308bac 100644
--- a/app/views/docs/migrations.phtml
+++ b/app/views/docs/migrations.phtml
@@ -8,7 +8,7 @@
Supported sources
You can transfer from these sources to an Appwrite project.
- Resources marked supported are migrated automatically.
+ Resources marked enabled are migrated automatically.
Resources marked partial can be migrated, but with limitations or caveats, check the guide for each source to learn more.
Resources marked manual require manual migration.
@@ -29,51 +29,51 @@
- supported
- supported
+ enabled
+ enabled
partial
- supported
+ enabled
manual
- supported
- supported
+ enabled
+ enabled
partial
- supported
+ enabled
manual
- supported
- supported
+ enabled
+ enabled
partial
- supported
+ enabled
manual
- supported
- supported
- supported
- supported
- supported
+ enabled
+ enabled
+ enabled
+ enabled
+ enabled
- supported
- supported
- supported
- supported
- supported
+ enabled
+ enabled
+ enabled
+ enabled
+ enabled
From 3eaa24612b83692fb221185647b42c596a9e83e9 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 11:17:01 -0400
Subject: [PATCH 165/183] Apply suggestions from code review
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Matej Bačo
---
app/views/docs/authentication-magic.phtml | 2 +-
app/views/docs/authentication-oauth.phtml | 2 +-
app/views/docs/authentication-security.phtml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index e50694877..7ef26927f 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -1,6 +1,6 @@
Magic URL is a password-less way to authenticate users.
- When a user logs in, they will receive an email with a "magic" link that contains a secret used to log in the user.
+ When a user logs in by providing their email, they will receive an email with a "magic" link that contains a secret used to log in the user.
The user can simply click the link to be logged in.
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 0a3ec4854..e8dee928b 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -284,7 +284,7 @@ print(session.providerAccessToken);
Refresh Tokens
- OAuth 2 sessions expire to protect from security risks.
+ OAuth 2 access tokens expire to protect from security risks.
OAuth 2 sessions should be periodically refreshed to keep the user authenticated.
You can do this by calling the Update OAuth Session endpoint when ever your user visits your app.
diff --git a/app/views/docs/authentication-security.phtml b/app/views/docs/authentication-security.phtml
index 9bae92804..ed68f5229 100644
--- a/app/views/docs/authentication-security.phtml
+++ b/app/views/docs/authentication-security.phtml
@@ -102,4 +102,4 @@
Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal data.
Personal data includes the user's name, email, and phone number.
-Disallowing personal data can be enabled in the Auth service's Security tab on the Appwrite console.
+Disallowing personal data can be enabled in the Auth service's Security tab on the Appwrite Console.
From 56213ec352b30326859e6bdbd2cdf7aa4f8cd85f Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Sun, 27 Aug 2023 19:29:31 +0000
Subject: [PATCH 166/183] Fix code example errors and other items pointed out
during review
---
app/views/docs/authentication-anonymous.phtml | 2 +-
app/views/docs/authentication-magic.phtml | 106 +-----------------
.../docs/authentication-management.phtml | 48 +++++---
app/views/docs/authentication-oauth.phtml | 15 ++-
4 files changed, 50 insertions(+), 121 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index 4992ebe29..a64394aca 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -97,7 +97,7 @@ mutation {
Attaching an Account
Anonymous users cannot sign back in.
- If they close their browser, or go to another computer, they won't be able to log in again.
+ If the session expires, they move to another computer, or they clear their browser data, they won't be able to log in again.
Remember to prompt the user to create an account to not lose their data.
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index e50694877..2e3ea2262 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -8,7 +8,7 @@
Initialize the log in process with the Create Magic URL Session route.
- If the email has never been used, a new user ID is generated, then the user will receive an email.
+ If the email has never been used, a new account is generated, then the user will receive an email.
If the email is already attached to an account, the user ID is ignored and the user will receive a link in their email.
@@ -25,7 +25,7 @@ const client = new Client()
const account = new Account(client);
-const promise = account.createMagicURLSession('[USER_ID]', 'email@example.com');
+const promise = account.createMagicURLSession(ID.unique(), 'email@example.com');
promise.then(function (response) {
console.log(response); // Success
@@ -34,61 +34,12 @@ promise.then(function (response) {
});
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.createMagicURLSession(
- userId: ID.unique(),
- email: 'email@example.com',
-);
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client(context)
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val user = account.createMagicURLSession(
- userId = ID.unique(),
- email = "email@example.com"
-)
-
- -
-
Apple
-
- import Appwrite
-
-let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-let account = Account(client)
-
-let user = try await account.createMagicURLSession(
- userId: ID.unique(),
- email: "email@example.com"
-)
-
-
GraphQL
mutation {
accountCreateMagicURLSession(
- userId: "email@example.com",
+ userId: "ID.unique()",
email: "email@example.com"
) {
_id
@@ -127,61 +78,12 @@ const userId = urlParams.get('userId');
const user = await account.updateMagicURLSession(userId, secret);
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.updateMagicURLSession(
- userId: 'email@example.com',
- secret: '[SECRET]',
-);
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client(context)
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val user = account.updateMagicURLSession(
- userId = 'email@example.com',
- secret = '[SECRET]'
-)
-
- -
-
Apple
-
- import Appwrite
-
-let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-let account = Account(client)
-
-let user = try await account.updateMagicURLSession(
- userId: 'email@example.com',
- secret: "[SECRET]"
-)
-
-
GraphQL
mutation {
accountUpdateMagicURLSession(
- userId: "email@example.com",
+ userId: "[USER_ID]",
secret: "[SECRET]"
) {
_id
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index 4e3514b27..d0b15fb2a 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -26,7 +26,13 @@ const client = new Client()
const account = new Account(client);
-const user = await account.updatePrefs({darkTheme: true, language: 'en'});
+const promise = account.updatePrefs({darkTheme: true, language: 'en'});
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
@@ -86,16 +92,7 @@ let user = try await account.updatePrefs(
prefs: "{\"darkTheme\": true, \"language\": \"en\"}"
) {
_id
- _createdAt
- _updatedAt
name
- registration
- status
- passwordUpdate
- email
- phone
- emailVerification
- phoneVerification
prefs {
data
}
@@ -119,7 +116,13 @@ const client = new Client()
const account = new Account(client);
-const user = await account.getPrefs();
+const promise = account.getPrefs();
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
@@ -205,11 +208,24 @@ let prefs = try await account.getPrefs()
const sdk = require('node-appwrite');
+// Init SDK
const client = new sdk.Client();
const users = new sdk.Users(client);
-let res = await users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+;
+
+const promise = users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
@@ -294,7 +310,13 @@ client
;
-let res = await users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+const promise = users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
-
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 0a3ec4854..00fa1c211 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -15,10 +15,13 @@
- - Navigate to your Appwrite project
- - Navigate to Auth > Settings
+ - Navigate to your Appwrite project.
+ - Navigate to Auth > Settings.
- Find and open the OAuth provider.
- - In the OAuth 2 settings modal, use the toggle to enable the provider
+ - In the OAuth 2 settings modal, use the toggle to enable the provider.
+ - Create and OAuth 2 app on the provider's developer platform.
+ - Copy information from your OAuth2 provider's developer platform to fill the OAuth2 Settings modal in the Appwrite Console.
+ - Configure redirect URL in your OAuth 2 provider's developer platform. Set it to URL provided to you by OAuth2 Settings modal in Appwrite Console.
@@ -152,7 +155,7 @@ try await account.createOAuth2Session(provider: "amazon")
You'll be redirected to the OAuth 2 provider's login page to log in.
- Once complete, you'll be redirected to the redirect URL configured in your OAuth 2 provider.
+ Once complete, your user will be redirected back to your app.
@@ -285,7 +288,9 @@ print(session.providerAccessToken);
Refresh Tokens
OAuth 2 sessions expire to protect from security risks.
- OAuth 2 sessions should be periodically refreshed to keep the user authenticated.
+ OAuth 2 sessions should be refreshed periodically, so access tokens don't expire.
+ Check value of providerAccessTokenExpiry to know if the token is expired or is about to expire.
+ Refreshing before every request might cause rate limit problems.
You can do this by calling the Update OAuth Session endpoint when ever your user visits your app.
From 36bda50ba9dc89de1211103c327e8fe71fc7bbde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Tue, 29 Aug 2023 13:25:38 +0000
Subject: [PATCH 167/183] Improve destructuring snippets
---
app/views/docs/functions-develop.phtml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index b2b7bad38..a8a01e4ba 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -490,13 +490,13 @@ public class Main {
// before destructuring
export default async function (context) {
context.log("This is a log!");
- // ... more code
+ return context.res.send("This is a response!");
}
// after destructuring
export default async function ({ req, res, log, error }) {
log("This is a log!");
- // ... more code
+ return res.send("This is a response!");
}
@@ -506,13 +506,13 @@ export default async function ({ req, res, log, error }) {
// before destructuring
export default async function (context: any) {
context.log("This is a log!");
- // ... more code
+ return context.res.send("This is a response!");
}
// after destructuring
export default async function ({ req, res, log, error }: any) {
context.log("This is a log!");
- // ... more code
+ return res.send("This is a response!");
}
From 6e68633af77f648c860eb7a3701730715e80f386 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Tue, 29 Aug 2023 13:26:26 +0000
Subject: [PATCH 168/183] Fix deno destructing
---
app/views/docs/functions-develop.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index a8a01e4ba..4f5adbb6e 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -511,7 +511,7 @@ export default async function (context: any) {
// after destructuring
export default async function ({ req, res, log, error }: any) {
- context.log("This is a log!");
+ log("This is a log!");
return res.send("This is a response!");
}
From 034de4ad39903e4a761011ed9a58ce04830e67da Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 29 Aug 2023 13:49:28 +0000
Subject: [PATCH 169/183] Add SMTP steps
---
app/views/docs/email-and-sms-templates.phtml | 22 +++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/app/views/docs/email-and-sms-templates.phtml b/app/views/docs/email-and-sms-templates.phtml
index f1327335d..e685405f0 100644
--- a/app/views/docs/email-and-sms-templates.phtml
+++ b/app/views/docs/email-and-sms-templates.phtml
@@ -6,6 +6,26 @@
depending on the configured locale.
+Custom SMTP server
+
+ Appwrite Cloud has a default SMTP server to get you started.
+ This SMTP server sends generic emails and doesn't allow customizing SMTP templates.
+ To use custom SMTP templates, you will need to configure your own SMTP server.
+
+
+
+ There are many third-party SMTP providers like SendGrid and Mailgun.
+ Before proceeding, pick an SMTP provider, create an account, and obtain Sender name, Sender email, Server host, Server port, Username, and Password.
+
+
+
+ - Navigate to your project's Settings.
+ - Navigate to the SMTP tab.
+ - Under SMTP server, toggle Custom SMTP server.
+ - Input Sender name, Sender email, Server host, Server port, Username, and Password from your provider.
+ - Click Update.
+
+
Customize Templates
You can customize email templates for each of your projects in the Appwrite Console.
@@ -17,7 +37,7 @@
- Under the Auth service, navigate to the Templates tab.
- Expand the email template you want to edit.
- Select the Template language. You can have a different template for each language your app supports.
- - Update the email template fields and click **Update** to save your changes.
+ - Update the email template fields and click Update to save your changes.
Email Templates
You can customize the email templates for account verification, magic-url authentication, password resets, and user invites.
From 4deefa26750f9512db482ee0795910dea897c9a5 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Tue, 29 Aug 2023 14:58:48 +0100
Subject: [PATCH 170/183] fix: response helper examples
---
app/views/docs/functions-develop.phtml | 339 ++++++++++++-------------
1 file changed, 167 insertions(+), 172 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 4f5adbb6e..dc1929220 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -841,8 +841,8 @@ public class Main {
export default async ({ req, res, log }) => {
switch (req.query.type) {
- case 'text':
- return res.send("This is a text response", 200);
+ case 'empty':
+ return res.empty();
case 'json':
return res.json({"type": "This is a JSON response"}, 200);
case 'redirect':
@@ -853,7 +853,7 @@ public class Main {
"content-type": "text/html"
});
default:
- return res.empty();
+ return res.send("This is a text response", 200);
}
}
@@ -865,8 +865,8 @@ public class Main {
return function ($context) {
switch ($context->req->query['type']) {
- case 'text':
- return $context->res->send("This is a text response", 200);
+ case 'empty':
+ return $context->res->empty();
case 'json':
return $context->res->json(["type" => "This is a JSON response"], 200);
case 'redirect':
@@ -876,7 +876,7 @@ return function ($context) {
"content-type" => "text/html"
]);
default:
- return $context->res->empty();
+ return $context->res->send("This is a text response", 200);
}
};
@@ -886,8 +886,8 @@ return function ($context) {
def main(context):
switch context.req.query['type']:
- case 'text':
- return context.res.send("This is a text response", 200)
+ case 'empty':
+ return context.res.empty()
case 'json':
return context.res.json({"type": "This is a JSON response"}, 200)
case 'redirect':
@@ -897,7 +897,7 @@ return function ($context) {
"content-type": "text/html"
})
default:
- return context.res.empty()
+ return context.res.send("This is a text response", 200)
-
@@ -905,8 +905,8 @@ return function ($context) {
def main(context)
case context.req.query['type']
- when 'text'
- return context.res.send("This is a text response", 200)
+ when 'empty'
+ return context.res.empty()
when 'json'
return context.res.json({"type": "This is a JSON response"}, 200)
when 'redirect'
@@ -916,7 +916,8 @@ return function ($context) {
"content-type": "text/html"
})
else
- return context.res.empty()
+ return context.res.send("This is a text response", 200)
+
end
end
@@ -927,8 +928,8 @@ end
export default async ({ req, res, log }) => {
switch (req.query.type) {
- case 'text':
- return res.send("This is a text response", 200);
+ case 'empty':
+ return res.empty();
case 'json':
return res.json({type": "This is a JSON response"}, 200);
case 'redirect':
@@ -939,7 +940,7 @@ end
"content-type": "text/html"
});
default:
- return res.empty();
+ return res.send("This is a text response", 200);
}
}
@@ -951,24 +952,18 @@ end
Future<dynamic> main(final context) async {
switch (context.req.query['type']) {
- case 'text':
- return context.res
- .send('This is a text response', 200);
+ case 'empty':
+ return context.res.empty();
case 'json':
- return context.res
- .json({'type': 'This is a JSON response'});
+ return context.res.json({'type': 'This is a JSON response'});
case 'redirect':
- return context.res
- .redirect('https://appwrite.io', 301);
+ return context.res.redirect('https://appwrite.io', 301);
case 'html':
- return context.res
- .send('<h1>This is an HTML response</h1>', 200, {
- 'content-type': 'text/html'
- });
+ return context.res.send('<h1>This is an HTML response</h1>',
+ 200, {'content-type': 'text/html'});
default:
- return context.res
- .empty();
- }
+ return context.res.send('This is a text response', 200);
+ }
}
@@ -979,18 +974,18 @@ Future<dynamic> main(final context) async {
func main(context: RuntimeContext) async throws -> RuntimeOutput {
switch context.req.query["type"] {
- case "text":
- return try await context.send("This is a text response", 200)
+ case "empty":
+ return try await context.res.empty()
case "json":
- return try await context.send(["type": "This is a JSON response"], 200)
+ return try await context.res.send(["type": "This is a JSON response"], 200)
case "redirect":
- return try await context.redirect("https://appwrite.io", 301)
+ return try await context.res.redirect("https://appwrite.io", 301)
case "html":
- return try await context.send("<h1>This is an HTML response</h1>", 200, [
+ return try await context.res.send("<h1>This is an HTML response</h1>", 200, [
"content-type": "text/html"
])
default:
- return try await context.empty()
+ return try await context.res.send("This is a text response", 200)
}
}
@@ -1005,18 +1000,18 @@ public class Handler {
{
switch (Context.Request.Query["type"])
{
- case "text":
- return await Context.Send("This is a text response", 200);
+ case "empty":
+ return await Context.Res.Empty();
case "json":
- return await Context.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } }, 200);
+ return await Context.Res.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } }, 200);
case "redirect":
- return await Context.Redirect("https://appwrite.io", 301);
+ return await Context.Res.Redirect("https://appwrite.io", 301);
case "html":
- return await Context.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
+ return await Context.Res.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
{ "content-type", "text/html" }
});
- default:
- return await Context.Empty();
+ default:
+ return await Context.Res.Send("This is a text response", 200);
}
}
}
@@ -1033,11 +1028,11 @@ import io.openruntimes.kotlin.RuntimeOutput
class Main {
fun main(context: RuntimeContext): RuntimeOutput {
when (context.req.query["type"]) {
- "text" -> return context.send("This is a text response", 200)
- "json" -> return context.send(mapOf("type" to "This is a JSON response"), 200)
- "redirect" -> return context.redirect("https://appwrite.io", 301)
- "html" -> return context.send("<h1>This is an HTML response</h1>", 200, mapOf("content-type" to "text/html"))
- else -> return context.empty()
+ "empty" -> return context.res.empty()
+ "json" -> return context.res.send(mapOf("type" to "This is a JSON response"), 200)
+ "redirect" -> return context.res.redirect("https://appwrite.io", 301)
+ "html" -> return context.res.send("<h1>This is an HTML response</h1>", 200, mapOf("content-type" to "text/html"))
+ else -> return context.res.send("This is a text response", 200)
}
}
}
@@ -1057,17 +1052,17 @@ public class Main {
public RuntimeOutput main(RuntimeContext context) throws Exception {
switch (context.getReq().getQuery()["type"]) {
case "text":
- return context.send("This is a text response", 200);
+ return context.getRes().empty();
case "json":
HashMap<String, Object> data = new HashMap<>();
data.put("type", "This is a JSON response");
- return context.send(data, 200);
+ return context.getRes().send(data, 200);
case "redirect":
- return context.redirect("https://appwrite.io", 301);
+ return context.getRes().redirect("https://appwrite.io", 301);
case "html":
- return context.send("<h1>This is an HTML response</h1>", 200, Map.of("content-type", "text/html"));
+ return context.getRes().send("<h1>This is an HTML response</h1>", 200, Map.of("content-type", "text/html"));
default:
- return context.empty();
+ return context.getRes().send("This is a text response", 200);
}
}
}
@@ -1087,20 +1082,20 @@ namespace runtime {
static RuntimeOutput main(RuntimeContext &context) {
std::string type = context.req.query["type"];
- if (type == "text") {
- return context.send("This is a text response", 200);
+ if (type == "empty") {
+ return context.res.empty();
} else if (type == "json") {
Json::Value data;
data["type"] = "This is a JSON response";
- return context.send(data, 200);
+ return context.res.send(data, 200);
} else if (type == "redirect") {
- return context.redirect("https://appwrite.io", 301);
+ return context.res.redirect("https://appwrite.io", 301);
} else if (type == "html") {
Json::Value headers;
headers["content-type"] = "text/html";
- return context.send("<h1>This is an HTML response</h1>", 200, headers);
+ return context.res.send("<h1>This is an HTML response</h1>", 200, headers);
} else {
- return context.empty();
+ return context.res.send("This is a text response", 200);
}
}
};
@@ -1193,7 +1188,7 @@ return function ($context) {
context.log(f"This function was called with {context.req.method} method")
context.error("This is an error, use for logging errors to console")
- return context.send("Check the Appwrite Console to see logs and errors!")
+ return context.res.send("Check the Appwrite Console to see logs and errors!")
-
@@ -1204,7 +1199,7 @@ return function ($context) {
context.log("This function was called with #{context.req.method} method")
context.error("This is an error, use for logging errors to console")
- return context.send("Check the Appwrite Console to see logs and errors!")
+ return context.res.send("Check the Appwrite Console to see logs and errors!")
end
@@ -1230,7 +1225,7 @@ Future<dynamic> main(final context) async {
context.log("This function was called with ${context.req.method} method");
context.error("This is an error, use for logging errors to console");
- return context.send("Check the Appwrite Console to see logs and errors!");
+ return context.res.send("Check the Appwrite Console to see logs and errors!");
}
@@ -1244,7 +1239,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
context.log("This function was called with \(context.req.method) method")
context.error("This is an error, use for logging errors to console")
- return try context.send("Check the Appwrite Console to see logs and errors!")
+ return context.res.send("Check the Appwrite Console to see logs and errors!")
}
@@ -1260,7 +1255,7 @@ public class Handler {
Context.Log($"This function was called with {Context.Req.Method} method");
Context.Error("This is an error, use for logging errors to console");
- return await Context.Send("Check the Appwrite Console to see logs and errors!");
+ return await Context.Res.Send("Check the Appwrite Console to see logs and errors!");
}
}
@@ -1279,7 +1274,7 @@ class Main {
context.log("This function was called with ${context.req.method} method")
context.error("This is an error, use for logging errors to console")
- return context.send("Check the Appwrite Console to see logs and errors!")
+ return context.res.send("Check the Appwrite Console to see logs and errors!")
}
}
@@ -1298,7 +1293,7 @@ public class Main {
context.log("This function was called with " + context.req.method + " method");
context.error("This is an error, use for logging errors to console");
- return context.send("Check the Appwrite Console to see logs and errors!");
+ return context.getRes().send("Check the Appwrite Console to see logs and errors!");
}
}
@@ -1319,7 +1314,7 @@ namespace runtime {
context.log("This function was called with " + context.req.method + " method");
context.error("This is an error, use for logging errors to console");
- return context.send("Check the Appwrite Console to see logs and errors!");
+ return context.res.send("Check the Appwrite Console to see logs and errors!");
}
};
}
@@ -1486,7 +1481,7 @@ Future<dynamic> main(final context) async {
import Foundation
func main(context: RuntimeContext) async throws -> RuntimeOutput {
- return try await context.send(ProcessInfo.processInfo.environment["MY_VAR"], 200)
+ return await context.res.send(ProcessInfo.processInfo.environment["MY_VAR"], 200)
}
@@ -1498,7 +1493,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
public class Handler {
public async Task<RuntimeOutput> Main(RuntimeContext Context)
{
- return await Context.Send(Environment.GetEnvironmentVariable("MY_VAR"), 200);
+ return await Context.Res.Send(Environment.GetEnvironmentVariable("MY_VAR"), 200);
}
}
@@ -1513,7 +1508,7 @@ import io.openruntimes.kotlin.RuntimeOutput
class Main {
fun main(context: RuntimeContext): RuntimeOutput {
- return context.send(System.getenv("MY_VAR"), 200)
+ return context.res.send(System.getenv("MY_VAR"), 200)
}
}
@@ -1528,7 +1523,7 @@ import io.openruntimes.java.RuntimeOutput;
public class Main {
public RuntimeOutput main(RuntimeContext context) throws Exception {
- return context.send(System.getenv("MY_VAR"), 200);
+ return context.getRes().send(System.getenv("MY_VAR"), 200);
}
}
@@ -1546,7 +1541,7 @@ namespace runtime {
public:
static RuntimeOutput main(RuntimeContext &context) {
- return context.send(std::getenv("MY_VAR"), 200);
+ return context.res.send(std::getenv("MY_VAR"), 200);
};
}
@@ -1559,114 +1554,114 @@ namespace runtime {
Your function's dependencies should be managed by the package manager of each language. By default, we include the following package managers in each runtime:
-
-
+
+
+
+
+ Language
+ Package Manager
+ Commands
+
+
-
- Language
- Package Manager
- Commands
+
+
+
+ Node.js
+ npm
+ npm install
-
-
-
-
-
- Node.js
- npm
- npm install
-
-
-
-
-
- PHP
- Composer
- composer install
-
-
-
-
-
- Python
- pip
- pip install -r requirements.txt
-
-
-
-
-
- Ruby
- Bundler
- bundle install
-
-
-
-
-
- Deno
- deno
- deno cache <ENTRYPOINT_FILE>
-
-
-
-
-
- Dart
- pub
- pub get
-
-
-
-
-
- Swift
- Swift Package Manager
- N/A
-
-
-
-
-
- .NET
- NuGet
- N/A
-
-
-
-
-
- Kotlin
- Gradle
- N/A
-
-
-
-
-
- Java
- Gradle
- N/A
-
-
-
-
-
- C++
- None
- N/A
-
-
+
+
+
+
+ PHP
+ Composer
+ composer install
+
+
+
+
+
+ Python
+ pip
+ pip install -r requirements.txt
+
+
+
+
+
+ Ruby
+ Bundler
+ bundle install
+
+
+
+
+
+ Deno
+ deno
+ deno cache <ENTRYPOINT_FILE>
+
+
+
+
+
+ Dart
+ pub
+ pub get
+
+
+
+
+
+ Swift
+ Swift Package Manager
+ N/A
+
+
+
+
+
+ .NET
+ NuGet
+ N/A
+
+
+
+
+
+ Kotlin
+ Gradle
+ N/A
+
+
+
+
+
+ Java
+ Gradle
+ N/A
+
+
+
+
+
+ C++
+ None
+ N/A
+
+
-
- To install your dependencies before your function is built, you should add the relevant install command to the top your function's Build setting > Commands.
-
+
+ To install your dependencies before your function is built, you should add the relevant install command to the top your function's Build setting > Commands.
+
Using Appwrite in a Function
- Appwrite can be used in your functions by adding the relevant SDK to your function's dependencies.
- Authenticating with Appwrite is done via an API key or a JWT token.
+ Appwrite can be used in your functions by adding the relevant SDK to your function's dependencies.
+ Authenticating with Appwrite is done via an API key or a JWT token.
API keys must be generated and exported as an environment variable.
From 4dc3e51bc3ee329fdd5a38d7c9e929b3be0d76b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Tue, 29 Aug 2023 14:39:31 +0000
Subject: [PATCH 171/183] Review changes
---
app/views/docs/functions-develop.phtml | 29 +++++++++++++-------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index dc1929220..abe69d73b 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -876,7 +876,7 @@ return function ($context) {
"content-type" => "text/html"
]);
default:
- return $context->res->send("This is a text response", 200);
+ return $context->res->send("This is a text response", 200);
}
};
@@ -917,7 +917,6 @@ return function ($context) {
})
else
return context.res.send("This is a text response", 200)
-
end
end
@@ -1159,7 +1158,7 @@ namespace runtime {
export default async ({ res, log, error }) => {
log("This is a log, use for logging information to console");
- log(`This function was called with ${context.req.method} method`);
+ log(`This function was called with ${req.method} method`);
error("This is an error, use for logging errors to console");
return res.send("Check the Appwrite Console to see logs and errors!");
@@ -1428,7 +1427,7 @@ namespace runtime {
Node.js
export default async ({ req, res, log }) => {
- return res.send(process.env.MY_VAR, 200);
+ return res.send(process.env.MY_VAR);
}
@@ -1438,7 +1437,7 @@ namespace runtime {
<?php
return function ($context) {
- return $context->res->send(getenv('MY_VAR'), 200);
+ return $context->res->send(getenv('MY_VAR'));
};
@@ -1446,14 +1445,14 @@ return function ($context) {
Python
def main(context):
- return context.res.send(os.environ['MY_VAR'], 200)
+ return context.res.send(os.environ['MY_VAR'])
-
Ruby
def main(context)
- return context.res.send(ENV['MY_VAR'], 200)
+ return context.res.send(ENV['MY_VAR'])
end
@@ -1461,7 +1460,7 @@ end
Deno
export default async ({ req, res, log }) => {
- return res.send(Deno.env.get('MY_VAR'), 200);
+ return res.send(Deno.env.get('MY_VAR'));
}
@@ -1471,7 +1470,7 @@ end
import 'dart:async';
Future<dynamic> main(final context) async {
- return context.res.send(Platform.environment['MY_VAR'], 200);
+ return context.res.send(Platform.environment['MY_VAR']);
}
@@ -1481,7 +1480,7 @@ Future<dynamic> main(final context) async {
import Foundation
func main(context: RuntimeContext) async throws -> RuntimeOutput {
- return await context.res.send(ProcessInfo.processInfo.environment["MY_VAR"], 200)
+ return await context.res.send(ProcessInfo.processInfo.environment["MY_VAR"])
}
@@ -1493,7 +1492,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
public class Handler {
public async Task<RuntimeOutput> Main(RuntimeContext Context)
{
- return await Context.Res.Send(Environment.GetEnvironmentVariable("MY_VAR"), 200);
+ return await Context.Res.Send(Environment.GetEnvironmentVariable("MY_VAR"));
}
}
@@ -1508,7 +1507,7 @@ import io.openruntimes.kotlin.RuntimeOutput
class Main {
fun main(context: RuntimeContext): RuntimeOutput {
- return context.res.send(System.getenv("MY_VAR"), 200)
+ return context.res.send(System.getenv("MY_VAR"))
}
}
@@ -1523,7 +1522,7 @@ import io.openruntimes.java.RuntimeOutput;
public class Main {
public RuntimeOutput main(RuntimeContext context) throws Exception {
- return context.getRes().send(System.getenv("MY_VAR"), 200);
+ return context.getRes().send(System.getenv("MY_VAR"));
}
}
@@ -1541,7 +1540,7 @@ namespace runtime {
public:
static RuntimeOutput main(RuntimeContext &context) {
- return context.res.send(std::getenv("MY_VAR"), 200);
+ return context.res.send(std::getenv("MY_VAR"));
};
}
@@ -2348,7 +2347,7 @@ export function add(a, b) {
import { add } from './utils.js';
-export default function ({res}) {
+export default function ({ res }) {
return res.send(add(1, 2));
}
From d6d63a639440f8d59f9eb6a32c8f5553bf8cee1d Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Tue, 29 Aug 2023 15:40:11 +0100
Subject: [PATCH 172/183] fix: remove duplicate python example + add missing
php
---
app/views/docs/functions-examples.phtml | 86 +++++++++++--------------
1 file changed, 37 insertions(+), 49 deletions(-)
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index 485c4fe3b..96af6e772 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -139,6 +139,43 @@ export default async function ({ req, res }) {
+ -
+
PHP
+
+
+
+ <?php
+
+require(__DIR__ . '/../vendor/autoload.php');
+
+use Appwrite\Client;
+use Appwrite\Exception;
+use Appwrite\Services\Database;
+use GuzzleHttp\Client as GuzzleClient;
+
+return function ($context) {
+ $client = new GuzzleClient();
+
+ if ($context->req->path === '/eur') {
+ $amountInEuros = floatval($context->req->query['amount']);
+ $response = $client->get('https://api.exchangerate.host/latest?base=EUR&symbols=USD');
+ $data = $response->json();
+ $amountInDollars = $amountInEuros * $data['rates']['USD'];
+ return $context->res->send(strval($amountInDollars));
+ }
+
+ if ($context->req->path === '/inr') {
+ $amountInRupees = floatval($context->req->query['amount']);
+ $response = $client->get('https://api.exchangerate.host/latest?base=INR&symbols=USD');
+ $data = $response->json();
+ $amountInDollars = $amountInRupees * $data['rates']['USD'];
+ return $context->res->send(strval($amountInDollars));
+ }
+
+ return $context->res->send('Invalid path');
+};
+
+
-
Python
@@ -555,55 +592,6 @@ Future main(final context) async {
- -
-
Python
-
-
-
- from appwrite.client import Client
-from appwrite.services.databases import Databases
-from appwrite.query import Query
-
-import os
-
-def main(context):
- vote = {
- 'userId': context.req.query['userId'],
- 'topicId': context.req.query['topicId'],
- 'vote': context.req.query['vote']
- }
-
- if vote['vote'] != 'yes' and vote['vote'] != 'no':
- return context.res.json({'ok': False, 'message': 'You must vote yes or no.'}, 400)
-
- client = Client()
- client.set_endpoint('https://cloud.appwrite.io/v1')
- client.set_project(os.environ['APPWRITE_FUNCTION_PROJECT_ID'])
- client.set_key(os.environ['APPWRITE_API_KEY'])
-
- database = Databases(client)
-
- existing_votes = database.list_documents('[VOTES_COLLECTION_ID]', [
- Query.equal('userId', vote['userId']),
- Query.equal('topicId', vote['topicId'])
- ])
-
- if existing_votes['total'] > 0:
- return context.res.json({
- 'ok': False,
- 'message': 'You have already voted on this topic.'
- }, 400)
-
- vote_document = database.create_document('[VOTES_COLLECTION_ID]', vote)
-
- return context.res.json({
- 'ok': True,
- 'message': 'Vote cast.',
- 'vote': vote_document
- })
-
-
-
From 5e5061cb96002dcb87e9d020a7a1e1db9bf9b562 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Tue, 29 Aug 2023 15:44:45 +0100
Subject: [PATCH 173/183] chore: remove unneccessary 200 codes
---
app/views/docs/functions-develop.phtml | 42 ++++++++++++-------------
app/views/docs/functions-examples.phtml | 10 +++---
2 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index abe69d73b..77ff76a59 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -844,7 +844,7 @@ public class Main {
case 'empty':
return res.empty();
case 'json':
- return res.json({"type": "This is a JSON response"}, 200);
+ return res.json({"type": "This is a JSON response"});
case 'redirect':
return res.redirect("https://appwrite.io", 301);
case 'html':
@@ -853,7 +853,7 @@ public class Main {
"content-type": "text/html"
});
default:
- return res.send("This is a text response", 200);
+ return res.send("This is a text response");
}
}
@@ -868,7 +868,7 @@ return function ($context) {
case 'empty':
return $context->res->empty();
case 'json':
- return $context->res->json(["type" => "This is a JSON response"], 200);
+ return $context->res->json(["type" => "This is a JSON response"]);
case 'redirect':
return $context->res->redirect("https://appwrite.io", 301);
case 'html':
@@ -876,7 +876,7 @@ return function ($context) {
"content-type" => "text/html"
]);
default:
- return $context->res->send("This is a text response", 200);
+ return $context->res->send("This is a text response");
}
};
@@ -889,7 +889,7 @@ return function ($context) {
case 'empty':
return context.res.empty()
case 'json':
- return context.res.json({"type": "This is a JSON response"}, 200)
+ return context.res.json({"type": "This is a JSON response"})
case 'redirect':
return context.res.redirect("https://appwrite.io", 301)
case 'html':
@@ -897,7 +897,7 @@ return function ($context) {
"content-type": "text/html"
})
default:
- return context.res.send("This is a text response", 200)
+ return context.res.send("This is a text response")
-
@@ -908,7 +908,7 @@ return function ($context) {
when 'empty'
return context.res.empty()
when 'json'
- return context.res.json({"type": "This is a JSON response"}, 200)
+ return context.res.json({"type": "This is a JSON response"})
when 'redirect'
return context.res.redirect("https://appwrite.io", 301)
when 'html'
@@ -916,7 +916,7 @@ return function ($context) {
"content-type": "text/html"
})
else
- return context.res.send("This is a text response", 200)
+ return context.res.send("This is a text response")
end
end
@@ -930,7 +930,7 @@ end
case 'empty':
return res.empty();
case 'json':
- return res.json({type": "This is a JSON response"}, 200);
+ return res.json({type": "This is a JSON response"});
case 'redirect':
return res.redirect("https://appwrite.io", 301);
case 'html':
@@ -939,7 +939,7 @@ end
"content-type": "text/html"
});
default:
- return res.send("This is a text response", 200);
+ return res.send("This is a text response");
}
}
@@ -961,7 +961,7 @@ Future<dynamic> main(final context) async {
return context.res.send('<h1>This is an HTML response</h1>',
200, {'content-type': 'text/html'});
default:
- return context.res.send('This is a text response', 200);
+ return context.res.send('This is a text response');
}
}
@@ -976,7 +976,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
case "empty":
return try await context.res.empty()
case "json":
- return try await context.res.send(["type": "This is a JSON response"], 200)
+ return try await context.res.send(["type": "This is a JSON response"])
case "redirect":
return try await context.res.redirect("https://appwrite.io", 301)
case "html":
@@ -984,7 +984,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
"content-type": "text/html"
])
default:
- return try await context.res.send("This is a text response", 200)
+ return try await context.res.send("This is a text response")
}
}
@@ -1002,7 +1002,7 @@ public class Handler {
case "empty":
return await Context.Res.Empty();
case "json":
- return await Context.Res.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } }, 200);
+ return await Context.Res.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } });
case "redirect":
return await Context.Res.Redirect("https://appwrite.io", 301);
case "html":
@@ -1010,7 +1010,7 @@ public class Handler {
{ "content-type", "text/html" }
});
default:
- return await Context.Res.Send("This is a text response", 200);
+ return await Context.Res.Send("This is a text response");
}
}
}
@@ -1028,10 +1028,10 @@ class Main {
fun main(context: RuntimeContext): RuntimeOutput {
when (context.req.query["type"]) {
"empty" -> return context.res.empty()
- "json" -> return context.res.send(mapOf("type" to "This is a JSON response"), 200)
+ "json" -> return context.res.send(mapOf("type" to "This is a JSON response"))
"redirect" -> return context.res.redirect("https://appwrite.io", 301)
"html" -> return context.res.send("<h1>This is an HTML response</h1>", 200, mapOf("content-type" to "text/html"))
- else -> return context.res.send("This is a text response", 200)
+ else -> return context.res.send("This is a text response")
}
}
}
@@ -1055,13 +1055,13 @@ public class Main {
case "json":
HashMap<String, Object> data = new HashMap<>();
data.put("type", "This is a JSON response");
- return context.getRes().send(data, 200);
+ return context.getRes().send(data);
case "redirect":
return context.getRes().redirect("https://appwrite.io", 301);
case "html":
return context.getRes().send("<h1>This is an HTML response</h1>", 200, Map.of("content-type", "text/html"));
default:
- return context.getRes().send("This is a text response", 200);
+ return context.getRes().send("This is a text response");
}
}
}
@@ -1086,7 +1086,7 @@ namespace runtime {
} else if (type == "json") {
Json::Value data;
data["type"] = "This is a JSON response";
- return context.res.send(data, 200);
+ return context.res.send(data);
} else if (type == "redirect") {
return context.res.redirect("https://appwrite.io", 301);
} else if (type == "html") {
@@ -1094,7 +1094,7 @@ namespace runtime {
headers["content-type"] = "text/html";
return context.res.send("<h1>This is an HTML response</h1>", 200, headers);
} else {
- return context.res.send("This is a text response", 200);
+ return context.res.send("This is a text response");
}
}
};
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index 96af6e772..cc0fed6fb 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -684,7 +684,7 @@ export default async function ({ req, res }) {
const databases = new Databases(client);
const document = await databases.createDocument('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message);
- return res.send("Message sent", 200);
+ return res.send("Message sent");
}
return res.send('Not found', 404);
@@ -743,7 +743,7 @@ def main(context):
databases = Databases(client)
document = databases.create_document('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message)
- return context.res.send("Message sent", 200)
+ return context.res.send("Message sent")
return context.res.send('Not found', 404)
@@ -803,7 +803,7 @@ return function ($context) {
$databases = new Databases($client);
$document = $databases->createDocument('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID::unique(), $message);
- return $context->res->send("Message sent", 200);
+ return $context->res->send("Message sent");
}
return $context->res->send('Not found', 404);
@@ -858,7 +858,7 @@ def main(context)
databases = Appwrite::Database.new(client)
document = databases.create_document('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message)
- return context.res.send("Message sent", 200)
+ return context.res.send("Message sent")
end
return context.res.send('Not found', 404)
@@ -913,7 +913,7 @@ Future
main(final context) async {
final databases = Database(client);
final document = await databases.createDocument('[DATABASE_ID]', '[MESSAGES_COLLECTION_ID]', ID.unique(), message);
- return context.res.send("Message sent", 200);
+ return context.res.send("Message sent");
}
return context.res.send('Not found', 404);
From 5d6d411360946e31d052c4750eab508d8f51e476 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Tue, 29 Aug 2023 16:24:22 +0100
Subject: [PATCH 174/183] fix: standardise appwrite sdk setup for python
---
app/views/docs/functions-examples.phtml | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/app/views/docs/functions-examples.phtml b/app/views/docs/functions-examples.phtml
index cc0fed6fb..0fdabae89 100644
--- a/app/views/docs/functions-examples.phtml
+++ b/app/views/docs/functions-examples.phtml
@@ -398,10 +398,12 @@ def main(context):
if vote['vote'] != 'yes' and vote['vote'] != 'no':
return context.res.json({'ok': False, 'message': 'You must vote yes or no.'}, 400)
- client = Client()
- client.set_endpoint('https://cloud.appwrite.io/v1')
- client.set_project(os.environ['APPWRITE_FUNCTION_PROJECT_ID'])
- client.set_key(os.environ['APPWRITE_API_KEY'])
+ client = (
+ Client()
+ .set_endpoint("https://cloud.appwrite.io/v1")
+ .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ .set_key(os.environ["APPWRITE_API_KEY"])
+ )
database = Databases(client)
@@ -734,10 +736,10 @@ def main(context):
}
client = (
- Client()
- .set_endpoint('https://cloud.appwrite.io/v1')
- .set_project(os.environ['APPWRITE_FUNCTION_PROJECT_ID'])
- .set_key(os.environ['APPWRITE_API_KEY'])
+ Client()
+ .set_endpoint("https://cloud.appwrite.io/v1")
+ .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ .set_key(os.environ["APPWRITE_API_KEY"])
)
databases = Databases(client)
From 1678f8e58ff00b9a3c0b6e32c84dcee734c5a226 Mon Sep 17 00:00:00 2001
From: loks0n <22452787+loks0n@users.noreply.github.com>
Date: Tue, 29 Aug 2023 16:44:10 +0100
Subject: [PATCH 175/183] fix: python code splitting
---
app/views/docs/functions-develop.phtml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 77ff76a59..63664e37a 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -2383,10 +2383,10 @@ def add(a, b):
// src/main.py
-import utils
+from .utils import add
def main(context):
- return context.res.send(utils.add(1, 2))
+ return context.res.send(add(1, 2))
-
From 31598efbf8e4259a47b12c9c9f738d840ea6708a Mon Sep 17 00:00:00 2001
From: Jake Barnby
Date: Tue, 29 Aug 2023 13:19:42 -0400
Subject: [PATCH 176/183] Fix try/awaits
---
app/views/docs/functions-develop.phtml | 48 ++++++++++++--------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 63664e37a..42b8d4f19 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -171,14 +171,12 @@ def main(context)
end
# `ctx.res.json()` is a handy helper for sending JSON
- return context.res.json(
- {
- "motto": "Build Fast. Scale Big. All in One Place.",
- "learn": "https://appwrite.io/docs",
- "connect": "https://appwrite.io/discord",
- "getInspired": "https://builtwith.appwrite.io",
- }
- )
+ return context.res.json({
+ "motto": "Build Fast. Scale Big. All in One Place.",
+ "learn": "https://appwrite.io/docs",
+ "connect": "https://appwrite.io/discord",
+ "getInspired": "https://builtwith.appwrite.io",
+ })
end
@@ -286,7 +284,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
if context.req.method == "GET" {
// Send a response with the res object helpers
// `res.send()` dispatches a string back to the client
- return try context.res.send("Hello, World!")
+ return context.res.send("Hello, World!")
}
// `context.res.json()` is a handy helper for sending JSON
@@ -671,7 +669,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
context.log(context.req.queryString) // Raw query params string. For example "limit=12&offset=50"
context.log(NSJSONSerialization.jsonObject(with: context.req.query, options: [])!) // Parsed query params. For example, req.query.limit
- return try context.res.send("All the request parameters are logged to the Appwrite Console.")
+ return context.res.send("All the request parameters are logged to the Appwrite Console.")
}
@@ -974,17 +972,17 @@ Future<dynamic> main(final context) async {
func main(context: RuntimeContext) async throws -> RuntimeOutput {
switch context.req.query["type"] {
case "empty":
- return try await context.res.empty()
+ return context.res.empty()
case "json":
- return try await context.res.send(["type": "This is a JSON response"])
+ return context.res.send(["type": "This is a JSON response"])
case "redirect":
- return try await context.res.redirect("https://appwrite.io", 301)
+ return context.res.redirect("https://appwrite.io", 301)
case "html":
- return try await context.res.send("<h1>This is an HTML response</h1>", 200, [
+ return context.res.send("<h1>This is an HTML response</h1>", 200, [
"content-type": "text/html"
])
default:
- return try await context.res.send("This is a text response")
+ return context.res.send("This is a text response")
}
}
@@ -1000,17 +998,17 @@ public class Handler {
switch (Context.Request.Query["type"])
{
case "empty":
- return await Context.Res.Empty();
+ return Context.Res.Empty();
case "json":
- return await Context.Res.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } });
+ return Context.Res.Send(new Dictionary<string, object>() { { "type", "This is a JSON response" } });
case "redirect":
- return await Context.Res.Redirect("https://appwrite.io", 301);
+ return Context.Res.Redirect("https://appwrite.io", 301);
case "html":
- return await Context.Res.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
+ return Context.Res.Send("<h1>This is an HTML response</h1>", 200, new Dictionary<string, string>() {
{ "content-type", "text/html" }
});
default:
- return await Context.Res.Send("This is a text response");
+ return Context.Res.Send("This is a text response");
}
}
}
@@ -1156,7 +1154,7 @@ namespace runtime {
-
Node.js
- export default async ({ res, log, error }) => {
+ export default async ({ req, res, log, error }) => {
log("This is a log, use for logging information to console");
log(`This function was called with ${req.method} method`);
error("This is an error, use for logging errors to console");
@@ -1254,7 +1252,7 @@ public class Handler {
Context.Log($"This function was called with {Context.Req.Method} method");
Context.Error("This is an error, use for logging errors to console");
- return await Context.Res.Send("Check the Appwrite Console to see logs and errors!");
+ return Context.Res.Send("Check the Appwrite Console to see logs and errors!");
}
}
@@ -1480,7 +1478,7 @@ Future<dynamic> main(final context) async {
import Foundation
func main(context: RuntimeContext) async throws -> RuntimeOutput {
- return await context.res.send(ProcessInfo.processInfo.environment["MY_VAR"])
+ return context.res.send(ProcessInfo.processInfo.environment["MY_VAR"])
}
@@ -1492,7 +1490,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
public class Handler {
public async Task<RuntimeOutput> Main(RuntimeContext Context)
{
- return await Context.Res.Send(Environment.GetEnvironmentVariable("MY_VAR"));
+ return Context.Res.Send(Environment.GetEnvironmentVariable("MY_VAR"));
}
}
@@ -1862,7 +1860,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
try await databases.createDocument(databaseId: "[DATABASE_ID]", collectionId: "[COLLECTION_ID]", data: [:])
} catch {
context.error("Failed to create document: \(error.localizedDescription)")
- return try await context.res.send("Failed to create document")
+ return context.res.send("Failed to create document")
}
return context.res.send("Document created")
From 66ddf617a3d278614c7d5bb9b21d3b1566ba12a0 Mon Sep 17 00:00:00 2001
From: Jake Barnby
Date: Tue, 29 Aug 2023 13:23:30 -0400
Subject: [PATCH 177/183] ctx -> context
---
app/views/docs/functions-develop.phtml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 42b8d4f19..7309b25fc 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -124,13 +124,13 @@ def main(context):
# If something goes wrong, log an error
context.error("Hello, Errors!")
- # The `ctx.req` object contains the request data
+ # The `context.req` object contains the request data
if context.req.method == "GET":
# Send a response with the res object helpers
- # `ctx.res.send()` dispatches a string back to the client
+ # `context.res.send()` dispatches a string back to the client
return context.res.send("Hello, World!")
- # `ctx.res.json()` is a handy helper for sending JSON
+ # `context.res.json()` is a handy helper for sending JSON
return context.res.json(
{
"motto": "Build Fast. Scale Big. All in One Place.",
@@ -163,14 +163,14 @@ def main(context)
# If something goes wrong, log an error
context.error("Hello, Errors!")
- # The `ctx.req` object contains the request data
+ # The `context.req` object contains the request data
if (context.req.method == "GET")
# Send a response with the res object helpers
- # `ctx.res.send()` dispatches a string back to the client
+ # `context.res.send()` dispatches a string back to the client
return context.res.send("Hello, World!")
end
- # `ctx.res.json()` is a handy helper for sending JSON
+ # `context.res.json()` is a handy helper for sending JSON
return context.res.json({
"motto": "Build Fast. Scale Big. All in One Place.",
"learn": "https://appwrite.io/docs",
@@ -765,7 +765,7 @@ public class Main {
Headers
Appwrite Functions will always receive a set of headers that provide meta data about the function execution.
- These are provided along side any custom headers sent to the function.
+ These are provided alongside any custom headers sent to the function.
From 9935d70c698adedc355b52626f17735f4866fdb5 Mon Sep 17 00:00:00 2001
From: Jake Barnby
Date: Tue, 29 Aug 2023 13:23:39 -0400
Subject: [PATCH 178/183] Fix mismatched tags
---
app/views/docs/functions-develop.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index 7309b25fc..efef145bf 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -762,7 +762,7 @@ public class Main {
-Headers
+Headers
Appwrite Functions will always receive a set of headers that provide meta data about the function execution.
These are provided alongside any custom headers sent to the function.
From 81749e9eaf9ce5fce813e33cb316d8a45bae8d07 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 29 Aug 2023 20:11:44 +0000
Subject: [PATCH 179/183] Add blub about self-hosted git integration
---
app/views/docs/configuration.phtml | 49 ++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/app/views/docs/configuration.phtml b/app/views/docs/configuration.phtml
index 44f0132e1..f235bf2e1 100644
--- a/app/views/docs/configuration.phtml
+++ b/app/views/docs/configuration.phtml
@@ -19,6 +19,51 @@
+Configure GitHub App
+
+ Appwrite supports automatic deployments through Git integration.
+ In order for Appwrite to access your repos, you must configure a GitHub app to enable this integration.
+
+
+You'll have to configure the following environment variables.
+
+
+
+
+ Variable
+ Description
+
+
+
+
+ _APP_VCS_GITHUB_APP_NAME
+ Name of your GitHub app. This value should be set to your GitHub application's URL.
+
+
+ _APP_VCS_GITHUB_PRIVATE_KEY
+ GitHub app RSA private key. You can generate private keys from GitHub application settings.
+
+
+ _APP_VCS_GITHUB_APP_ID
+ GitHub application ID. You can find it in your GitHub application details.
+
+
+ _APP_VCS_GITHUB_CLIENT_ID
+ GitHub client ID. You can find it in your GitHub application details.
+
+
+ _APP_VCS_GITHUB_CLIENT_SECRET
+ GitHub client secret. You can generate secrets in your GitHub application settings.
+
+
+ _APP_VCS_GITHUB_WEBHOOK_SECRET
+ GitHub webhook secret. You can configure it in your GitHub application settings under webhook section.
+
+
+
+
+ Learn more about environment variables
+
Configure Function Runtimes
Not all function runtimes are enabled by default. Enable the runtimes that you need and disable unused runtimes to save disk space on your server.
@@ -40,7 +85,7 @@
Storage Adaptors
Appwrite's Storage Service can be configured to store files locally, or with self-hosted and cloud storage services. By default, Appwrite's Storage Service stores files on your server's local storage. If you expect large volumes of data or the need to have scalable data storage, you may choose to use a separate storage service.
-Appwrite supports AWS S3, Digital Ocean Spaces, Backblaze, Akamai Object Storage, and Wasabi as storage adaptors. Some of these services can be self-hosted, just like Appwrite.
+Appwrite supports AWS S3, Digital Ocean Spaces, Backblaze, Linode, and Wasabi as storage adaptors. Some of these services can be self-hosted, just like Appwrite.
You can select which storage adaptor to use by setting the _APP_STORAGE_DEVICE environment variable. Valid values are local, s3, dospaces, backblaze, linode and wasabi. Each storage adaptor requires its own set of additional environment variables to configure.
@@ -62,4 +107,4 @@
More Configurable Options
If you don't see something you'd like to configure on this page, try searching the complete list of environment variables.
- Learn more about environment variables
+ Learn more about environment variables
\ No newline at end of file
From 476486305e696aec78bddaca782b3250078b9b48 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 29 Aug 2023 16:13:20 -0400
Subject: [PATCH 180/183] revert change from akamai to linode
---
app/views/docs/configuration.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/configuration.phtml b/app/views/docs/configuration.phtml
index f235bf2e1..34c52eeb2 100644
--- a/app/views/docs/configuration.phtml
+++ b/app/views/docs/configuration.phtml
@@ -85,7 +85,7 @@
Storage Adaptors
Appwrite's Storage Service can be configured to store files locally, or with self-hosted and cloud storage services. By default, Appwrite's Storage Service stores files on your server's local storage. If you expect large volumes of data or the need to have scalable data storage, you may choose to use a separate storage service.
-Appwrite supports AWS S3, Digital Ocean Spaces, Backblaze, Linode, and Wasabi as storage adaptors. Some of these services can be self-hosted, just like Appwrite.
+Appwrite supports AWS S3, Digital Ocean Spaces, Backblaze, Akamai Object Storage, and Wasabi as storage adaptors. Some of these services can be self-hosted, just like Appwrite.
You can select which storage adaptor to use by setting the _APP_STORAGE_DEVICE environment variable. Valid values are local, s3, dospaces, backblaze, linode and wasabi. Each storage adaptor requires its own set of additional environment variables to configure.
From b00f36757245f3d0a63e44a341965326e0fdac98 Mon Sep 17 00:00:00 2001
From: "Vincent (Wen Yu) Ge"
Date: Tue, 29 Aug 2023 21:00:46 +0000
Subject: [PATCH 181/183] Fix width for configuration.phtml
---
app/views/docs/configuration.phtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/docs/configuration.phtml b/app/views/docs/configuration.phtml
index 34c52eeb2..9a0fc31f7 100644
--- a/app/views/docs/configuration.phtml
+++ b/app/views/docs/configuration.phtml
@@ -30,7 +30,7 @@
- Variable
+ Variable
Description
From 87a27b061c4692afcd7ca952b75096aa4886d59e Mon Sep 17 00:00:00 2001
From: Jake Barnby
Date: Tue, 29 Aug 2023 17:11:06 -0400
Subject: [PATCH 182/183] WIP fix code samples
---
app/views/docs/authentication-anonymous.phtml | 8 +-
.../docs/authentication-email-pass.phtml | 151 ++--
app/views/docs/authentication-magic.phtml | 5 +-
.../docs/authentication-management.phtml | 179 ++---
app/views/docs/authentication-oauth.phtml | 32 +-
app/views/docs/authentication-server.phtml | 225 +++---
app/views/docs/authentication-sms.phtml | 29 +-
app/views/docs/functions-develop.phtml | 658 ++++++++++--------
app/views/docs/functions-execute.phtml | 374 +++++-----
.../docs/getting-started-for-server.phtml | 6 +-
10 files changed, 859 insertions(+), 808 deletions(-)
diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml
index a64394aca..97aa74381 100644
--- a/app/views/docs/authentication-anonymous.phtml
+++ b/app/views/docs/authentication-anonymous.phtml
@@ -22,7 +22,7 @@
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -42,7 +42,7 @@ promise.then(function (response) {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -57,7 +57,7 @@ import io.appwrite.services.Account
val client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -71,7 +71,7 @@ val user = account.createAnonymousSession()
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml
index 8fde1db9a..2f6604c93 100644
--- a/app/views/docs/authentication-email-pass.phtml
+++ b/app/views/docs/authentication-email-pass.phtml
@@ -89,8 +89,7 @@ let user = try await account.create(
-
GraphQL
-
-mutation {
+ mutation {
accountCreate(userId: "unique()", email: "email@example.com", password: "password") {
_id
email
@@ -124,21 +123,18 @@ mutation {
import { Client, Account } from "appwrite";
-const client = new Client();
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
const account = new Account(client);
-client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
-;
-
const promise = account.createVerification('https://example.com');
promise.then(function (response) {
- console.log(response); // Success
+ console.log(response);
}, function (error) {
- console.log(error); // Failure
+ console.log(error);
});
@@ -147,55 +143,31 @@ promise.then(function (response) {
import 'package:appwrite/appwrite.dart';
-void main() { // Init SDK
- Client client = Client();
- Account account = Account(client);
-
- client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- ;
- Future result = account.createVerification(
+ .setProject('5df5acd0d48c2'); // Your project ID
+
+final account = Account(client);
+
+final token = await account.createVerification(
url: 'https://example.com',
- );
-
- result
- .then((response) {
- print(response);
- }).catchError((error) {
- print(error.response);
- });
-}
+);
-
Android
- import androidx.appcompat.app.AppCompatActivity
-import android.os.Bundle
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
-import io.appwrite.Client
+ import io.appwrite.Client
import io.appwrite.services.Account
-class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
-
- val client = Client(applicationContext)
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
+val client = Client(applicationContext)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
- val account = Account(client)
+val account = Account(client)
- GlobalScope.launch {
- val response = account.createVerification(
- url = "https://example.com"
- )
- val json = response.body?.string()
- }
- }
-}
+val token = account.createVerification(
+ url = "https://example.com"
+)
-
@@ -203,17 +175,15 @@ class MainActivity : AppCompatActivity() {
import Appwrite
-func main() async throws {
- let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
- let account = Account(client)
- let token = try await account.createVerification(
- url: "https://example.com"
- )
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
- print(String(describing: token)
-}
+let account = Account(client)
+
+let token = try await account.createVerification(
+ url: "https://example.com"
+)
-
@@ -252,7 +222,7 @@ func main() async throws {
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -274,26 +244,16 @@ promise.then(function (response) {
import 'package:appwrite/appwrite.dart';
-void main() { // Init SDK
- Client client = Client();
- Account account = Account(client);
-
- client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- ;
- Future result = account.updateVerification(
+ .setProject('5df5acd0d48c2'); // Your project ID
+
+final account = Account(client);
+
+final result = account.updateVerification(
userId: '[USER_ID]',
secret: '[SECRET]',
- );
-
- result
- .then((response) {
- print(response);
- }).catchError((error) {
- print(error.response);
- });
-}
+);
-
Android
@@ -303,7 +263,7 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
+ .setProject("5df5acd0d48c2") // Your project ID
val account = Account(client)
@@ -320,7 +280,7 @@ val response = account.updateVerification(
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
+ .setProject("5df5acd0d48c2") // Your project ID
let account = Account(client)
@@ -364,7 +324,7 @@ let token = try await account.updateVerification(
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -384,7 +344,7 @@ promise.then(function (response) {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -401,7 +361,7 @@ import io.appwrite.services.Account
val client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -417,7 +377,7 @@ val session = account.createEmailSession(
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
@@ -458,7 +418,7 @@ let session = try await account.createEmailSession(
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const promise = account.createRecovery('email@example.com', 'https://example.com');
@@ -476,7 +436,7 @@ promise.then(function (response) {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -493,7 +453,7 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -509,7 +469,7 @@ val response = account.createRecovery(
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
@@ -549,9 +509,14 @@ After receiving an email with the secret attached to the redirect link, submit a
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
-const promise = account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
+const promise = account.updateRecovery(
+ '[USER_ID]',
+ '[SECRET]',
+ 'password',
+ 'password'
+);
promise.then(function (response) {
console.log(response); // Success
@@ -567,7 +532,7 @@ promise.then(function (response) {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -586,7 +551,7 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -604,7 +569,7 @@ val token = account.updateRecovery(
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
@@ -638,7 +603,7 @@ let token = try await account.updateRecovery(
Security
- Appwrite's security first mindset goes beyond a securely implementated of authentication API.
+ Appwrite's security first mindset goes beyond a securely implemented of authentication API.
You can enable features like password dictionary, password history, and disallow personal data in passwords to encourage users to pick better passwords.
By enabling these features, you protect user data and teach better password choices, which helps make the internet a safer place.
diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml
index 0c25a3a0d..d126549c6 100644
--- a/app/views/docs/authentication-magic.phtml
+++ b/app/views/docs/authentication-magic.phtml
@@ -20,11 +20,10 @@
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
-
const promise = account.createMagicURLSession(ID.unique(), 'email@example.com');
promise.then(function (response) {
@@ -67,7 +66,7 @@ promise.then(function (response) {
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
diff --git a/app/views/docs/authentication-management.phtml b/app/views/docs/authentication-management.phtml
index d0b15fb2a..e9a083910 100644
--- a/app/views/docs/authentication-management.phtml
+++ b/app/views/docs/authentication-management.phtml
@@ -22,7 +22,7 @@
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -42,7 +42,7 @@ promise.then(function (response) {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -61,12 +61,15 @@ import io.appwrite.services.Account
val client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
val user = account.updatePrefs(
- prefs = mapOf("darkTheme" to true, "language" to "en")
+ prefs = mapOf(
+ "darkTheme" to true,
+ "language" to "en"
+ )
)
-
@@ -76,12 +79,15 @@ val user = account.updatePrefs(
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
let user = try await account.updatePrefs(
- prefs: ["darkTheme": true, "language": "en"]
+ prefs: [
+ "darkTheme": true,
+ "language": "en"
+ ]
)
-
@@ -112,7 +118,7 @@ let user = try await account.updatePrefs(
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -132,7 +138,7 @@ promise.then(function (response) {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -146,7 +152,7 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -159,7 +165,7 @@ val prefs = account.getPrefs()
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
@@ -207,19 +213,18 @@ let prefs = try await account.getPrefs()
Node.js
const sdk = require('node-appwrite');
-
-// Init SDK
-const client = new sdk.Client();
+
+const client = new sdk.Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
const users = new sdk.Users(client);
-client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
-;
-
-const promise = users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+const promise = users.updateLabels(
+ '[USER_ID]',
+ [ Role.label('subscriber') ]
+);
promise.then(function (response) {
console.log(response); // Success
@@ -240,17 +245,14 @@ $client = new Client();
$client
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
-;
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
$users = new Users($client);
$result = $users->updateLabels(
'[USER_ID]',
- [
- Role.label('subscriber'),
- ]
+ [ Role.label('subscriber') ]
);
@@ -265,32 +267,36 @@ client = Client()
(client
.set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('5df5acd0d48c2') # Your project ID
- .set_key('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+ .set_project('5df5acd0d48c2') # Your project ID
+ .set_key('98fd4...a2ad2') # Your secret API key
)
users = Users(client)
-result = users.update_labels('[USER_ID]', [ Role.label('subscriber') ])
+result = users.update_labels(
+ '[USER_ID]',
+ [ Role.label('subscriber') ]
+)
-
Ruby
- require 'Appwrite'
+ require 'appwrite'
include Appwrite
client = Client.new
.set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('5df5acd0d48c2') # Your project ID
- .set_key('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+ .set_project('5df5acd0d48c2') # Your project ID
+ .set_key('98fd4...a2ad2') # Your secret API key
users = Users.new(client)
-response = users.update_labels(user_id: '[USER_ID]', labels: [ Role.label('subscriber') ])
-
-puts response.inspect
+response = users.update_labels(
+ user_id: '[USER_ID]',
+ labels: [ Role.label('subscriber') ]
+)
-
@@ -298,19 +304,17 @@ puts response.inspect
import * as sdk from "https://deno.land/x/appwrite/mod.ts";
-// Init SDK
-let client = new sdk.Client();
-
-let users = new sdk.Users(client);
-
-client
+let client = new sdk.Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
-;
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
+let users = new sdk.Users(client);
-const promise = users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+const promise = users.updateLabels(
+ '[USER_ID]',
+ [ Role.label('subscriber') ]
+);
promise.then(function (response) {
console.log(response); // Success
@@ -324,50 +328,37 @@ promise.then(function (response) {
import 'package:dart_appwrite/dart_appwrite.dart';
-void main() { // Init SDK
- Client client = Client();
- Users users = Users(client);
-
- client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
- ;
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
- Future result = users.updateLabels(
+final users = Users(client);
+
+final result = await users.updateLabels(
userId: '[USER_ID]',
labels: [ Role.label('subscriber') ],
- );
-
- result
- .then((response) {
- print(response);
- }).catchError((error) {
- print(error.response);
- });
-}
+);
-
Kotlin
import io.appwrite.Client
-import io.appwrite.services.Users
import io.appwrite.Role
+import io.appwrite.services.Users
-suspend fun main() {
- val client = Client(context)
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
- .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setKey("98fd4...a2ad2") // Your secret API key
- val users = Users(client)
- val response = users.updateLabels(
- userId = "[USER_ID]",
- labels = [ Role.label('subscriber') ]
- )
- val json = response.body?.string()
-}
+val users = Users(client)
+
+val response = users.updateLabels(
+ userId = "[USER_ID]",
+ labels = [ Role.label('subscriber') ]
+)
-
@@ -375,25 +366,35 @@ suspend fun main() {
import Appwrite
-func main() async throws {
- let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
- .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
- let users = Users(client)
- let response = try await users.updateLabels(
- userId: "[USER_ID]",
- labels: [ Role.label('subscriber') ]
- )
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setKey("98fd4...a2ad2") // Your secret API key
- print(String(describing: response)
-}
+let users = Users(client)
+
+let response = try await users.updateLabels(
+ userId: "[USER_ID]",
+ labels: [ Role.label('subscriber') ]
+)
-
.NET
-
+ using Appwrite;
+
+var client = new Client()
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .SetProject("5df5acd0d48c2") // Your project ID
+ .SetKey("98fd4...a2ad2"); // Your secret API key
+
+var users = new Users(client);
+
+var response = await users.UpdateLabels(
+ userId: "[USER_ID]",
+ labels: [ Role.Label('subscriber') ]
+);
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml
index 53b77ae2d..b2937de3c 100644
--- a/app/views/docs/authentication-oauth.phtml
+++ b/app/views/docs/authentication-oauth.phtml
@@ -39,7 +39,7 @@
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -90,7 +90,7 @@ import io.appwrite.services.Account
val client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -316,25 +316,15 @@ promise.then(function (response) {
import 'package:appwrite/appwrite.dart';
-void main() { // Init SDK
- Client client = Client();
- Account account = Account(client);
-
- client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('5df5acd0d48c2') // Your project ID
- ;
- Future result = account.updateSession(
- sessionId: '[SESSION_ID]',
- );
-
- result
- .then((response) {
- print(response);
- }).catchError((error) {
- print(error.response);
- });
-}
+ .setProject('5df5acd0d48c2'); // Your project ID
+
+Account account = Account(client);
+
+final result = await account.updateSession(
+ sessionId: '[SESSION_ID]'
+);
-
@@ -345,7 +335,7 @@ import io.appwrite.services.Account
val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2") // Your project ID
+ .setProject("5df5acd0d48c2") // Your project ID
val account = Account(client)
diff --git a/app/views/docs/authentication-server.phtml b/app/views/docs/authentication-server.phtml
index de1c90211..52c2e1ff9 100644
--- a/app/views/docs/authentication-server.phtml
+++ b/app/views/docs/authentication-server.phtml
@@ -95,9 +95,7 @@ let jwt = try await account.createJWT()
const { Client } = require('node-appwrite');
-const client = new Client();
-
-client
+const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]') // Your project ID
.setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
@@ -109,9 +107,7 @@ client
use Appwrite\Client;
-$client = new Client();
-
-$client
+$client = (new Client())
->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
->setProject('[PROJECT_ID]') // Your project ID
->setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
@@ -139,8 +135,6 @@ client = Client()
include Appwrite
client = Client.new
-
-client
.set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
.set_project('[PROJECT_ID]') # Your project ID
.set_jwt('eyJJ9.eyJ...886ca') # Your secret JSON Web Token
@@ -151,9 +145,7 @@ client
import { Client } from "https://deno.land/x/appwrite/mod.ts";
-let client = new Client();
-
-client
+let client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]') // Your project ID
.setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
@@ -164,9 +156,7 @@ client
import 'package:dart_appwrite/dart_appwrite.dart';
-final client = Client();
-
-client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]') // Your project ID
.setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
@@ -178,8 +168,6 @@ client
import io.appwrite.Client
val client = Client()
-
-client
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.setProject("[PROJECT_ID]") // Your project ID
.setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
@@ -191,8 +179,6 @@ client
import Appwrite
let client = Client()
-
-client
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.setProject("[PROJECT_ID]") // Your project ID
.setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
@@ -203,9 +189,7 @@ client
using Appwrite;
-var client = new Client();
-
-client
+var client = new Client()
.SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.SetProject("[PROJECT_ID]") // Your project ID
.SetJWT("eyJJ9.eyJ...886ca"); // Your secret JSON Web Token
@@ -263,16 +247,17 @@ client
const { Client } = require('node-appwrite');
-const client = new Client();
-
-client
+const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
const databases = new sdk.Databases(client);
-const birthday = await databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1e');
+const documents = await databases.listDocuments(
+ '642f358bf4084c662590',
+ '642f3592aa5fc856ad1e'
+);
// ... More code to manipulate the results
@@ -282,16 +267,17 @@ const birthday = await databases.listDocuments('642f358bf4084c662590', '642f3592
use Appwrite\Client;
-$client = new Client();
-
-$client
+$client = (new Client())
->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
->setProject('[PROJECT_ID]') // Your project ID
->setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Tokens
$databases = new Databases($client);
-$result = $databases->listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1e');
+$documents = $databases->listDocuments(
+ databaseId: '642f358bf4084c662590',
+ collectionId: '642f3592aa5fc856ad1e'
+);
// ... More code to manipulate the results
@@ -310,7 +296,10 @@ client = Client()
databases = Databases(client)
-result = databases.list_documents('642f358bf4084c662590', '642f3592aa5fc856ad1e')
+documents = databases.list_documents(
+ database_id='642f358bf4084c662590',
+ collection_id='642f3592aa5fc856ad1e'
+)
# ... More code to manipulate the results
@@ -322,16 +311,17 @@ result = databases.list_documents('642f358bf4084c662590', '642f3592aa5fc856ad1e'
include Appwrite
-client = Client
-
-client.new
+client = Client.new
.set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
.set_project('[PROJECT_ID]') # Your project ID
.set_jwt('eyJJ9.eyJ...886ca') # Your secret JSON Web Token
databases = Databases.new(client)
-response = databases.list_documents(database_id: '642f358bf4084c662590', '642f3592aa5fc856ad1e')
+documents = databases.list_documents(
+ database_id: '642f358bf4084c662590',
+ collection_id: '642f3592aa5fc856ad1e'
+)
# ... More code to manipulate the results
@@ -340,16 +330,17 @@ response = databases.list_documents(database_id: '642f358bf4084c662590', '642f35
import { Client } from "https://deno.land/x/appwrite/mod.ts";
-let client = new Client();
-
-client
+let client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]') // Your project ID
.setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
let databases = new sdk.Databases(client);
-let promise = databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1e');
+let documents = await databases.listDocuments(
+ '642f358bf4084c662590',
+ '642f3592aa5fc856ad1e'
+);
// ... More code to manipulate the results
@@ -358,16 +349,14 @@ let promise = databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856a
import 'package:dart_appwrite/dart_appwrite.dart';
-final client = Client();
-
-client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('[PROJECT_ID]') // Your project ID
.setJWT('eyJJ9.eyJ...886ca'); // Your secret JSON Web Token
-Databases databases = Databases(client);
+final databases = Databases(client);
-Future result = databases.listDocuments(
+final documents = await databases.listDocuments(
databaseId: '642f358bf4084c662590',
collectionId: '642f3592aa5fc856ad1e',
);
@@ -380,15 +369,13 @@ Future result = databases.listDocuments(
import io.appwrite.Client
val client = Client()
-
-client
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.setProject("[PROJECT_ID]") // Your project ID
.setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
val databases = Databases(client)
-val response = databases.listDocuments(
+val documents = databases.listDocuments(
databaseId = "642f358bf4084c662590",
collectionId = "642f3592aa5fc856ad1e",
)
@@ -401,19 +388,17 @@ val response = databases.listDocuments(
import Appwrite
let client = Client()
-
-client
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.setProject("[PROJECT_ID]") // Your project ID
.setJWT("eyJJ9.eyJ...886ca") // Your secret JSON Web Token
let databases = Databases(client)
-let documentList = try await databases.listDocuments(
+let documents = try await databases.listDocuments(
databaseId: "642f358bf4084c662590",
collectionId: "642f3592aa5fc856ad1e"
)
-/ ... More code to manipulate the results
+// ... More code to manipulate the results
-
@@ -423,16 +408,14 @@ let documentList = try await databases.listDocuments(
using Appwrite.Services;
using Appwrite.Models;
-var client = new Client();
-
-client
+var client = new Client()
.SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.SetProject("[PROJECT_ID]") // Your project ID
.SetJWT("eyJJ9.eyJ...886ca"); // Your secret JSON Web Token
var databases = new Databases(client);
-var documentList = await databases.ListDocuments(
+var documents = await databases.ListDocuments(
databaseId: "642f358bf4084c662590",
collectionId: "642f3592aa5fc856ad1e");
@@ -468,16 +451,17 @@ var documentList = await databases.ListDocuments(
const { Client } = require('node-appwrite');
-const client = new Client();
-
-client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
const databases = new sdk.Databases(client);
-const birthday = await databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1e');
+const documents = await databases.listDocuments(
+ '642f358bf4084c662590',
+ '642f3592aa5fc856ad1e'
+);
// ... More code to manipulate the results
@@ -487,16 +471,17 @@ const birthday = await databases.listDocuments('642f358bf4084c662590', '642f3592
use Appwrite\Client;
-$client = new Client();
-
-$client
- ->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- ->setProject('[PROJECT_ID]') // Your project ID
- ->setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+$client = (new Client())
+ ->setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ ->setProject('[PROJECT_ID]') // Your project ID
+ ->setKey('98fd4...a2ad2'); // Your secret API key
$databases = new Databases($client);
-$result = $databases->listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1e');
+$documents = $databases->listDocuments(
+ databaseId: '642f358bf4084c662590',
+ collectionId: '642f3592aa5fc856ad1e'
+);
// ... More code to manipulate the results
@@ -508,15 +493,19 @@ $result = $databases->listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1
client = Client()
(client
- .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('[PROJECT_ID]') # Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('[PROJECT_ID]') # Your project ID
+ .set_key('98fd4...a2ad2') # Your secret API key
)
databases = Databases(client)
-result = databases.list_documents('642f358bf4084c662590', '642f3592aa5fc856ad1e')
+documents = databases.list_documents(
+ database_id='642f358bf4084c662590',
+ collection_id='642f3592aa5fc856ad1e'
+)
# ... More code to manipulate the results
+
-
@@ -526,16 +515,17 @@ result = databases.list_documents('642f358bf4084c662590', '642f3592aa5fc856ad1e'
include Appwrite
-client = Client
-
-client.new
- .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
- .set_project('[PROJECT_ID]') # Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+client = Client.new
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('[PROJECT_ID]') # Your project ID
+ .set_key('98fd4...a2ad2') # Your secret API key
databases = Databases.new(client)
-response = databases.list_documents(database_id: '642f358bf4084c662590', '642f3592aa5fc856ad1e')
+documents = databases.list_documents(
+ database_id: '642f358bf4084c662590',
+ collection_id: '642f3592aa5fc856ad1e'
+)
# ... More code to manipulate the results
@@ -544,16 +534,17 @@ response = databases.list_documents(database_id: '642f358bf4084c662590', '642f35
import { Client } from "https://deno.land/x/appwrite/mod.ts";
-let client = new Client();
-
-client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+let client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
let databases = new sdk.Databases(client);
-let promise = databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856ad1e');
+let documents = await databases.listDocuments(
+ '642f358bf4084c662590',
+ '642f3592aa5fc856ad1e'
+);
// ... More code to manipulate the results
@@ -562,16 +553,14 @@ let promise = databases.listDocuments('642f358bf4084c662590', '642f3592aa5fc856a
import 'package:dart_appwrite/dart_appwrite.dart';
-final client = Client();
-
-client
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]') // Your project ID
- .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]') // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
-Databases databases = Databases(client);
+final databases = Databases(client);
-Future result = databases.listDocuments(
+final documents = await databases.listDocuments(
databaseId: '642f358bf4084c662590',
collectionId: '642f3592aa5fc856ad1e',
);
@@ -584,15 +573,13 @@ Future result = databases.listDocuments(
import io.appwrite.Client
val client = Client()
-
-client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
val databases = Databases(client)
-val response = databases.listDocuments(
+val documents = databases.listDocuments(
databaseId = "642f358bf4084c662590",
collectionId = "642f3592aa5fc856ad1e",
)
@@ -605,19 +592,17 @@ val response = databases.listDocuments(
import Appwrite
let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+ .setKey('98fd4...a2ad2'); // Your secret API key
-client
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
- .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
-
- let databases = Databases(client)
-
- let documentList = try await databases.listDocuments(
- databaseId: "642f358bf4084c662590",
- collectionId: "642f3592aa5fc856ad1e"
- )
- // ... More code to manipulate the results
+let databases = Databases(client)
+
+let documents = try await databases.listDocuments(
+ databaseId: "642f358bf4084c662590",
+ collectionId: "642f3592aa5fc856ad1e"
+)
+// ... More code to manipulate the results
-
@@ -627,16 +612,14 @@ client
using Appwrite.Services;
using Appwrite.Models;
-var client = new Client();
-
-client
- .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .SetProject("[PROJECT_ID]") // Your project ID
- .SetKey("919c2d18fb5d4...a2ae413da83346ad2"); // Your secret API key
+var client = new Client()
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .SetProject("[PROJECT_ID]") // Your project ID
+ .SetKey('98fd4...a2ad2'); // Your secret API key
var databases = new Databases(client);
-var documentList = await databases.ListDocuments(
+var documents = await databases.ListDocuments(
databaseId: "642f358bf4084c662590",
collectionId: "642f3592aa5fc856ad1e");
diff --git a/app/views/docs/authentication-sms.phtml b/app/views/docs/authentication-sms.phtml
index 8e03e7880..8322f92b1 100644
--- a/app/views/docs/authentication-sms.phtml
+++ b/app/views/docs/authentication-sms.phtml
@@ -24,7 +24,7 @@
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
@@ -33,7 +33,7 @@ const sessionToken = await account.createPhoneSession(
'+14255550123'
);
-var userId = sessionToken.userId; // Store this somewhere to use later when logging in
+const userId = sessionToken.userId; // Store this somewhere to use later when logging in
-
@@ -43,7 +43,7 @@ var userId = sessionToken.userId; // Store this somewhere to use later when logg
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
@@ -63,7 +63,7 @@ import io.appwrite.ID
val client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
@@ -81,7 +81,7 @@ val userId = sessionToken.userId // Store this somewhere to use later when loggi
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
@@ -122,15 +122,14 @@ let userId = sessionToken.userId // Store this somewhere to use later when loggi
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
const account = new Account(client);
const session = await account.updatePhoneSession(
- userId, // From when you called createPhoneSession
+ userId, // From when you called createPhoneSession
'[SECRET]' // The 6-digit code from the SMS message
-);
-
+);
-
@@ -140,12 +139,12 @@ const session = await account.updatePhoneSession(
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
+ .setProject('[PROJECT_ID]'); // Your project ID
final account = Account(client);
final session = await account.updatePhoneSession(
- userId: userId, // From when you called createPhoneSession
+ userId: userId, // From when you called createPhoneSession
secret: '[SECRET]' // The 6-digit code from the SMS message
);
@@ -158,12 +157,12 @@ import io.appwrite.ID
val client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
val account = Account(client)
val session = account.updatePhoneSession(
- userId = userId, // From when you called createPhoneSession
+ userId = userId, // From when you called createPhoneSession
secret = "[SECRET]" // The 6-digit code from the SMS message
)
@@ -174,12 +173,12 @@ val session = account.updatePhoneSession(
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
+ .setProject("[PROJECT_ID]") // Your project ID
let account = Account(client)
let session = try await account.updatePhoneSession(
- userId: userId, // From when you called createPhoneSession
+ userId: userId, // From when you called createPhoneSession
secret: "[SECRET]" // The 6-digit code from the SMS message
)
diff --git a/app/views/docs/functions-develop.phtml b/app/views/docs/functions-develop.phtml
index efef145bf..39617c173 100644
--- a/app/views/docs/functions-develop.phtml
+++ b/app/views/docs/functions-develop.phtml
@@ -113,9 +113,9 @@ def main(context):
#
# client = (
# Client()
- # .set_endpoint("https://cloud.appwrite.io/v1")
- # .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
- # .set_key(os.environ["APPWRITE_API_KEY"])
+ # .set_endpoint("https://cloud.appwrite.io/v1")
+ # .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ # .set_key(os.environ["APPWRITE_API_KEY"])
# )
# You can log messages to the console
@@ -131,14 +131,12 @@ def main(context):
return context.res.send("Hello, World!")
# `context.res.json()` is a handy helper for sending JSON
- return context.res.json(
- {
- "motto": "Build Fast. Scale Big. All in One Place.",
- "learn": "https://appwrite.io/docs",
- "connect": "https://appwrite.io/discord",
- "getInspired": "https://builtwith.appwrite.io",
- }
- )
+ return context.res.json({
+ "motto": "Build Fast. Scale Big. All in One Place.",
+ "learn": "https://appwrite.io/docs",
+ "connect": "https://appwrite.io/discord",
+ "getInspired": "https://builtwith.appwrite.io",
+ })
-
@@ -254,6 +252,97 @@ Future
main(final context) async {
'connect': 'https://appwrite.io/discord',
'getInspired': 'https://builtwith.appwrite.io',
});
+}
+
+
+ -
+
Kotlin
+
+ package io.openruntimes.kotlin.src
+
+import io.openruntimes.kotlin.RuntimeContext
+import io.openruntimes.kotlin.RuntimeOutput
+import io.appwrite.Client
+import java.util.HashMap
+
+class Main {
+ // This is your Appwrite function
+ // It's executed each time we get a request
+ fun main(context: RuntimeContext): RuntimeOutput {
+ // Why not try the Appwrite SDK?
+ // val client = Client()
+ // .setEndpoint("https://cloud.appwrite.io/v1")
+ // .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ // .setKey(System.getenv("APPWRITE_API_KEY"))
+
+ // You can log messages to the console
+ context.log("Hello, Logs!")
+
+ // If something goes wrong, log an error
+ context.error("Hello, Errors!")
+
+ // The `context.req` object contains the request data
+ if (context.req.method == "GET") {
+ // Send a response with the res object helpers
+ // `context.res.send()` dispatches a string back to the client
+ return context.res.send("Hello, World!")
+ }
+
+ // `context.res.json()` is a handy helper for sending JSON
+ return context.res.json(mutableMapOf(
+ "motto" to "Build Fast. Scale Big. All in One Place.",
+ "learn" to "https://appwrite.io/docs",
+ "connect" to "https://appwrite.io/discord",
+ "getInspired" to "https://builtwith.appwrite.io"
+ ))
+ }
+}
+
+
+ -
+
Java
+
+ package io.openruntimes.java.src;
+
+import io.openruntimes.java.RuntimeContext;
+import io.openruntimes.java.RuntimeOutput;
+import java.util.HashMap;
+import io.appwrite.Client;
+
+public class Main {
+
+ // This is your Appwrite function
+ // It's executed each time we get a request
+ public RuntimeOutput main(RuntimeContext context) throws Exception {
+ // Why not try the Appwrite SDK?
+ //
+ // Client client = new Client()
+ // .setEndpoint("https://cloud.appwrite.io/v1")
+ // .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ // .setKey(System.getenv("APPWRITE_API_KEY"));
+
+ // You can log messages to the console
+ context.log("Hello, Logs!");
+
+ // If something goes wrong, log an error
+ context.error("Hello, Errors!");
+
+ // The `context.getReq()` object contains the request data
+ if (context.getReq().getMethod().equals("GET")) {
+ // Send a response with the res object helpers
+ // `context.getRes().send()` dispatches a string back to the client
+ return context.getRes().send("Hello, World!");
+ }
+
+ Map json = new HashMap<>();
+ json.put("motto", "Build Fast. Scale Big. All in One Place.");
+ json.put("learn", "https://appwrite.io/docs");
+ json.put("connect", "https://appwrite.io/discord");
+ json.put("getInspired", "https://builtwith.appwrite.io");
+
+ // `context.getRes().json()` is a handy helper for sending JSON
+ return context.getRes().json(json);
+ }
}
@@ -315,7 +404,7 @@ public class Handler {
// Why not try the Appwrite SDK?
//
// var client = new Client()
- // .SetEndpoint("http://cloud.appwrite.io/v1")
+ // .SetEndpoint("https://cloud.appwrite.io/v1")
// .SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
// .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"))
@@ -341,99 +430,6 @@ public class Handler {
{ "getInspired", "https://builtwith.appwrite.io" },
});
}
-}
-
-
- -
-
Kotlin
-
- package io.openruntimes.kotlin.src
-
-import io.openruntimes.kotlin.RuntimeContext
-import io.openruntimes.kotlin.RuntimeOutput
-import io.appwrite.Client
-import java.util.HashMap
-
-class Main {
- // This is your Appwrite function
- // It's executed each time we get a request
- fun main(context: RuntimeContext): RuntimeOutput {
- // Why not try the Appwrite SDK?
- // val client = Client().apply {
- // setEndpoint("https://cloud.appwrite.io/v1")
- // setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- // setKey(System.getenv("APPWRITE_API_KEY"))
- // }
-
- // You can log messages to the console
- context.log("Hello, Logs!")
-
- // If something goes wrong, log an error
- context.error("Hello, Errors!")
-
- // The `context.req` object contains the request data
- if (context.req.method == "GET") {
- // Send a response with the res object helpers
- // `context.res.send()` dispatches a string back to the client
- return context.res.send("Hello, World!")
- }
-
- // `context.res.json()` is a handy helper for sending JSON
- return context.res.json(mutableMapOf(
- "motto" to "Build Fast. Scale Big. All in One Place.",
- "learn" to "https://appwrite.io/docs",
- "connect" to "https://appwrite.io/discord",
- "getInspired" to "https://builtwith.appwrite.io"
- ))
- }
-}
-
-
- -
-
Java
-
- package io.openruntimes.java.src;
-
-import io.openruntimes.java.RuntimeContext;
-import io.openruntimes.java.RuntimeOutput;
-import java.util.HashMap;
-import io.appwrite.Client;
-
-public class Main {
-
- // This is your Appwrite function
- // It's executed each time we get a request
- public RuntimeOutput main(RuntimeContext context) throws Exception {
- // Why not try the Appwrite SDK?
- //
- // Client client = new Client();
- // client
- // .setEndpoint("https://cloud.appwrite.io/v1")
- // .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- // .setKey(System.getenv("APPWRITE_API_KEY"));
-
- // You can log messages to the console
- context.log("Hello, Logs!");
-
- // If something goes wrong, log an error
- context.error("Hello, Errors!");
-
- // The `context.getReq()` object contains the request data
- if (context.getReq().getMethod().equals("GET")) {
- // Send a response with the res object helpers
- // `context.getRes().send()` dispatches a string back to the client
- return context.getRes().send("Hello, World!");
- }
-
- Map json = new HashMap<>();
- json.put("motto", "Build Fast. Scale Big. All in One Place.");
- json.put("learn", "https://appwrite.io/docs");
- json.put("connect", "https://appwrite.io/discord");
- json.put("getInspired", "https://builtwith.appwrite.io");
-
- // `context.getRes().json()` is a handy helper for sending JSON
- return context.getRes().json(json);
- }
}
@@ -478,7 +474,7 @@ public class Main {
Destructuring Assignment
- Some languages, namely JavaScript, support destructuring. You'll see us use destructing in examples, which has the following syntax.
+ Some languages, namely JavaScript, support destructuring. You'll see us use destructuring in examples, which has the following syntax.
Learn more about destructuring assignment.
@@ -883,19 +879,20 @@ return function ($context) {
Python
def main(context):
- switch context.req.query['type']:
- case 'empty':
- return context.res.empty()
- case 'json':
- return context.res.json({"type": "This is a JSON response"})
- case 'redirect':
- return context.res.redirect("https://appwrite.io", 301)
- case 'html':
- return context.res.send("<h1>This is an HTML response</h1>", 200, {
- "content-type": "text/html"
- })
- default:
- return context.res.send("This is a text response")
+ type = context.req.query['type']
+
+ if type == 'empty':
+ return context.res.empty()
+ elif type =='json':
+ return context.res.json({"type": "This is a JSON response"})
+ elif type == 'redirect':
+ return context.res.redirect("https://appwrite.io", 301)
+ elif type == 'html':
+ return context.res.send("<h1>This is an HTML response</h1>", 200, {
+ "content-type": "text/html"
+ })
+ else:
+ return context.res.send("This is a text response")
-
@@ -971,18 +968,18 @@ Future<dynamic> main(final context) async {
func main(context: RuntimeContext) async throws -> RuntimeOutput {
switch context.req.query["type"] {
- case "empty":
- return context.res.empty()
- case "json":
- return context.res.send(["type": "This is a JSON response"])
- case "redirect":
- return context.res.redirect("https://appwrite.io", 301)
- case "html":
- return context.res.send("<h1>This is an HTML response</h1>", 200, [
- "content-type": "text/html"
- ])
- default:
- return context.res.send("This is a text response")
+ case "empty":
+ return context.res.empty()
+ case "json":
+ return context.res.send(["type": "This is a JSON response"])
+ case "redirect":
+ return context.res.redirect("https://appwrite.io", 301)
+ case "html":
+ return context.res.send("<h1>This is an HTML response</h1>", 200, [
+ "content-type": "text/html"
+ ])
+ default:
+ return context.res.send("This is a text response")
}
}
@@ -990,9 +987,7 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
-
.NET
- namespace DotNetRuntime;
-
-public class Handler {
+ public class Handler {
public async Task<RuntimeOutput> Main(RuntimeContext Context)
{
switch (Context.Request.Query["type"])
@@ -1614,7 +1609,7 @@ namespace runtime {
Swift
Swift Package Manager
- N/A
+ swift package resolve
@@ -1622,7 +1617,7 @@ namespace runtime {
.NET
NuGet
- N/A
+ dotnet restore
@@ -1671,6 +1666,7 @@ namespace runtime {
API keys have defined scopes when you create them.
They ignore permissions and operate without a sessions.
Use API keys if the function should act as an admin type role, instead of acting on behalf of a user.
+ Pass in your API key as an environment variable. Never share API keys with users.
-
@@ -1680,22 +1676,26 @@ namespace runtime {
export default async ({ req, res, log, error }) => {
- const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1')
- .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
- // Pass in your API key as an environment variable. Never share API keys with users.
- .setKey(process.env.APPWRITE_API_KEY);
+ const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1')
+ .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ .setKey(process.env.APPWRITE_API_KEY);
- const databases = new Databases(client);
+ const databases = new Databases(client);
- try {
- await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
- } catch (e) {
- error("Failed to create document: " + e.message)
- return res.send("Failed to create document")
- }
+ try {
+ await databases.createDocument(
+ '[DATABASE_ID]',
+ '[COLLECTION_ID]',
+ ID.unique(),
+ {}
+ )
+ } catch (e) {
+ error("Failed to create document: " + e.message)
+ return res.send("Failed to create document")
+ }
- return res.send("Document created")
+ return res.send("Document created")
}
@@ -1712,17 +1712,20 @@ use Appwrite\Services\Databases;
use Appwrite\ID;
return function ($context) {
- $client = new Client();
- $client
+ $client = (new Client())
->setEndpoint('https://cloud.appwrite.io/v1')
->setProject(getenv('APPWRITE_FUNCTION_PROJECT_ID'))
- // Pass in your API key as an environment variable. Never share API keys with users.
->setKey(getenv('APPWRITE_API_KEY'));
$databases = new Databases($client);
try {
- $databases->createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID::unique(), []);
+ $databases->createDocument(
+ databaseId: '[DATABASE_ID]',
+ collectionId: '[COLLECTION_ID]',
+ documentId: ID::unique(),
+ data: []
+ );
} catch (Exception $e) {
$context->error("Failed to create document: " . $e->getMessage());
return $context->res->send("Failed to create document");
@@ -1744,16 +1747,20 @@ import os
def main(context):
client = (
Client()
- .set_endpoint("https://cloud.appwrite.io/v1")
- .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
- # Pass in your API key as an environment variable. Never share API keys with users.
- .set_key(os.environ["APPWRITE_API_KEY"])
+ .set_endpoint("https://cloud.appwrite.io/v1")
+ .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ .set_key(os.environ["APPWRITE_API_KEY"])
)
databases = Databases(client)
try:
- databases.create_document("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {})
+ databases.create_document(
+ database_id="[DATABASE_ID]",
+ collection_id="[COLLECTION_ID]",
+ document_id=ID.unique(),
+ data={}
+ )
except Exception as e:
context.error("Failed to create document: " + e.message)
return context.response.send("Failed to create document")
@@ -1766,19 +1773,24 @@ def main(context):
require "appwrite"
+include Appwrite
+
def main(context)
- client = Appwrite::Client.new
- client
- .set_endpoint('https://cloud.appwrite.io/v1')
- .set_project(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
- # Pass in your API key as an environment variable. Never share API keys with users.
- .set_key(req.variables['APPWRITE_API_KEY'])
+ client = Client.new
+ .set_endpoint('https://cloud.appwrite.io/v1')
+ .set_project(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
+ .set_key(req.variables['APPWRITE_API_KEY'])
databases = Appwrite::Databases.new(client)
begin
- databases.create_document('[DATABASE_ID]', '[COLLECTION_ID]', Appwrite::ID.unique(), {})
- rescue Appwrite::Exception => e
+ databases.create_document(
+ databaseId: '[DATABASE_ID]',
+ collectionId: '[COLLECTION_ID]',
+ documentId: ID.unique(),
+ data: {}
+ )
+ rescue Exception => e
context.error("Failed to create document: " + e.message)
return context.response.send("Failed to create document")
end
@@ -1793,17 +1805,20 @@ end
import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
export default function ({req, res, error}: any){
- const client = new Client();
- client
+ const client = new Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(Deno.env.get("APPWRITE_FUNCTION_PROJECT_ID") || "")
- // Pass in your API key as an environment variable. Never share API keys with users.
.setKey(Deno.env.get("APPWRITE_API_KEY") || "");
const databases = new Databases(client);
try {
- databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {});
+ databases.createDocument(
+ "[DATABASE_ID]",
+ "[COLLECTION_ID]",
+ ID.unique(),
+ {}
+ );
} catch (e) {
error("Failed to create document: " + e.message);
return res.send("Failed to create document");
@@ -1819,18 +1834,21 @@ export default function ({req, res, error}: any){
import 'dart:async';
import 'package:dart_appwrite/dart_appwrite.dart';
-
Future<dynamic> main(final context) async {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
- // Pass in your API key as an environment variable. Never share API keys with users.
.setKey(process.env.APPWRITE_API_KEY);
final databases = Databases(client);
try {
- await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {});
+ await databases.createDocument(
+ databaseId: '[DATABASE_ID]',
+ collectionId: '[COLLECTION_ID]',
+ documentId: ID.unique(),
+ data: {}
+ );
} catch (e) {
context.error("Failed to create document: " + e.message);
return context.res.send("Failed to create document");
@@ -1851,13 +1869,17 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(ProcessInfo.processInfo.environment["APPWRITE_FUNCTION_PROJECT_ID"])
- // Pass in your API key as an environment variable. Never share API keys with users.
.setKey(ProcessInfo.processInfo.environment["APPWRITE_API_KEY"]);
let databases = Databases(client: client)
do {
- try await databases.createDocument(databaseId: "[DATABASE_ID]", collectionId: "[COLLECTION_ID]", data: [:])
+ try await databases.createDocument(
+ databaseId: "[DATABASE_ID]",
+ collectionId: "[COLLECTION_ID]",
+ documentId: ID.unique(),
+ data: [:]
+ )
} catch {
context.error("Failed to create document: \(error.localizedDescription)")
return context.res.send("Failed to create document")
@@ -1870,32 +1892,36 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
-
.NET
- namespace DotNetRuntime;
-
-using Appwrite;
+ using Appwrite;
using Appwrite.Services;
-using Appwrite.Models;
-
-public class Handler {
-
- public async Task Main(RuntimeContext Context)
+using Appwrite.Models;
+
+namespace DotNetRuntime
+{
+ public class Handler
{
- var client = new Client()
- .SetEndpoint("http://cloud.appwrite.io/v1")
- .SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
- // Pass in your API key as an environment variable. Never share API keys with users.
- .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"))
-
- var databases = new Databases(client);
-
- try {
- await databases.CreateDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.Unique(), new Dictionary<string, object>());
- } catch (Exception e) {
- Context.Error("Failed to create document: " + e.Message);
- return Context.Response.Send("Failed to create document");
+ public async Task Main(RuntimeContext Context)
+ {
+ var client = new Client()
+ .SetEndpoint("https://cloud.appwrite.io/v1")
+ .SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
+ .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"))
+
+ var databases = new Databases(client);
+
+ try {
+ await databases.CreateDocument(
+ databaseId: "[DATABASE_ID]",
+ collectionId: "[COLLECTION_ID]",
+ documentId: ID.Unique(),
+ data: new Dictionary<string, object>());
+ } catch (Exception e) {
+ Context.Error("Failed to create document: " + e.Message);
+ return Context.Response.Send("Failed to create document");
+ }
+
+ return Context.Response.Send("Document created");
}
-
- return Context.Response.Send("Document created");
}
}
@@ -1914,17 +1940,20 @@ import java.util.HashMap
class Main {
fun main(context: RuntimeContext): RuntimeOutput {
- val client = Client().apply {
- setEndpoint("https://cloud.appwrite.io/v1")
- setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- // Pass in your API key as an environment variable. Never share API keys with users.
- setKey(System.getenv("APPWRITE_API_KEY"))
- }
+ val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1")
+ .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ .setKey(System.getenv("APPWRITE_API_KEY"))
val databases = Databases(client)
try {
- databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), HashMap())
+ databases.createDocument(
+ databaseId = "[DATABASE_ID]",
+ collectionId = "[COLLECTION_ID]",
+ documentId = ID.unique()
+ data = mapOf()
+ )
} catch (e: Exception) {
context.error("Failed to create document: " + e.message)
return context.res.send("Failed to create document")
@@ -1947,24 +1976,26 @@ import io.appwrite.Client;
public class Main {
public RuntimeOutput main(RuntimeContext context) throws Exception {
- Client client = new Client();
- client
- .setEndpoint("https://cloud.appwrite.io/v1")
- .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- // Pass in your API key as an environment variable. Never share API keys with users.
- .setKey(System.getenv("APPWRITE_API_KEY"));
+ Client client = new Client()
+ .setEndpoint("https://cloud.appwrite.io/v1")
+ .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ .setKey(System.getenv("APPWRITE_API_KEY"));
Databases databases = new Databases(client);
try {
- databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), new HashMap<>());
+ databases.createDocument(
+ "[DATABASE_ID]",
+ "[COLLECTION_ID]",
+ ID.unique(),
+ new HashMap<>()
+ );
} catch (Exception e) {
context.error("Failed to create document: " + e.getMessage());
return context.res.send("Failed to create document");
}
return context.res.send("Document created");
-
}
}
@@ -1990,27 +2021,31 @@ public class Main {
import { Client, Databases, ID } from 'node-appwrite';
export default async ({ req, res, log }) => {
+ const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1')
+ .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
- const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1')
- .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
+ if (req.headers['x-appwrite-user-jwt']) {
+ client.setJWT(req.headers['x-appwrite-user-jwt'])
+ } else {
+ return res.send("Please sign in, JWT not found")
+ }
- if (req.headers['x-appwrite-user-jwt']) {
- client.setJWT(req.headers['x-appwrite-user-jwt'])
- } else {
- return res.send("Please sign in, JWT not found")
- }
-
- const databases = new Databases(client);
+ const databases = new Databases(client);
- try {
- await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {})
- } catch (e) {
- log("Failed to create document: " + e.message)
- return res.send("Failed to create document")
- }
+ try {
+ await databases.createDocument(
+ '[DATABASE_ID]',
+ '[COLLECTION_ID]',
+ ID.unique(),
+ {}
+ )
+ } catch (e) {
+ log("Failed to create document: " + e.message)
+ return res.send("Failed to create document")
+ }
- return res.send("Document created")
+ return res.send("Document created")
}
@@ -2027,8 +2062,7 @@ use Appwrite\Services\Databases;
use Appwrite\ID;
return function ($context) {
- $client = new Client();
- $client
+ $client = new (Client())
->setEndpoint('https://cloud.appwrite.io/v1')
->setProject(getenv('APPWRITE_FUNCTION_PROJECT_ID'))
@@ -2041,7 +2075,12 @@ return function ($context) {
$databases = new Databases($client);
try {
- $databases->createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID::unique(), []);
+ $databases->createDocument(
+ databaseId: '[DATABASE_ID]',
+ collectionId: '[COLLECTION_ID]',
+ documentId: ID::unique(),
+ data: []
+ );
} catch (Exception $e) {
$context->error("Failed to create document: " . $e->getMessage());
return $context->res->send("Failed to create document");
@@ -2060,12 +2099,11 @@ from appwrite.id import ID
import os
-
def main(context):
client = (
Client()
- .set_endpoint("https://cloud.appwrite.io/v1")
- .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
+ .set_endpoint("https://cloud.appwrite.io/v1")
+ .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"])
)
if "x-appwrite-user-jwt" in context.req.headers:
@@ -2076,7 +2114,12 @@ def main(context):
databases = Databases(client)
try:
- databases.create_document("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {})
+ databases.create_document(
+ database_id="[DATABASE_ID]",
+ collection_id="[COLLECTION_ID]",
+ document_id=ID.unique(),
+ data={}
+ )
except Exception as e:
context.error("Failed to create document: " + e.message)
return context.response.send("Failed to create document")
@@ -2089,12 +2132,13 @@ def main(context):
require "appwrite"
+include Appwrite
+
def main(context)
- client = Appwrite::Client.new
- client
- .set_endpoint('https://cloud.appwrite.io/v1')
- .set_project(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
-
+ client = Client.new
+ .set_endpoint('https://cloud.appwrite.io/v1')
+ .set_project(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
+
if context.request.headers['x-appwrite-user-jwt']
client.set_jwt(context.request.headers['x-appwrite-user-jwt'])
else
@@ -2120,8 +2164,7 @@ end
import { Client, Databases, ID } from "https://deno.land/x/appwrite/mod.ts";
export default function ({req, res, error}: any){
- const client = new Client();
- client
+ const client = new Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(Deno.env.get("APPWRITE_FUNCTION_PROJECT_ID") || "")
@@ -2134,7 +2177,12 @@ export default function ({req, res, error}: any){
const databases = new Databases(client);
try {
- databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), {});
+ databases.createDocument(
+ "[DATABASE_ID]",
+ "[COLLECTION_ID]",
+ ID.unique(),
+ {}
+ );
} catch (e) {
error("Failed to create document: " + e.message)
return res.send("Failed to create document");
@@ -2150,7 +2198,6 @@ export default function ({req, res, error}: any){
import 'dart:async';
import 'package:dart_appwrite/dart_appwrite.dart';
-
Future<dynamic> main(final context) async {
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
@@ -2165,7 +2212,12 @@ Future<dynamic> main(final context) async {
final databases = Databases(client);
try {
- await databases.createDocument('[DATABASE_ID]', '[COLLECTION_ID]', ID.unique(), {});
+ await databases.createDocument(
+ databaseId: '[DATABASE_ID]',
+ collectionId: '[COLLECTION_ID]',
+ documentId: ID.unique(),
+ data: {}
+ );
} catch (e) {
context.error("Failed to create document: " + e.message);
return context.res.send("Failed to create document");
@@ -2196,7 +2248,12 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
let databases = Databases(client: client)
do {
- try await databases.createDocument(databaseId: "[DATABASE_ID]", collectionId: "[COLLECTION_ID]", data: [:])
+ try await databases.createDocument(
+ databaseId: "[DATABASE_ID]",
+ collectionId: "[COLLECTION_ID]",
+ documentId: ID.unique()
+ data: [:]
+ )
} catch {
context.error("Failed to create document: \(error.localizedDescription)")
return context.res.send("Failed to create document")
@@ -2209,36 +2266,41 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
-
.NET
- namespace DotNetRuntime;
-
-using Appwrite;
+ using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
-public class Handler {
-
- public async Task Main(RuntimeContext Context)
+namespace DotNetRuntime
+{
+ public class Handler
{
- var client = new Client()
- .SetEndpoint("http://cloud.appwrite.io/v1")
- .SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
-
- if (Context.Req.Headers.ContainsKey("x-appwrite-user-jwt")) {
- client.SetJWT(Context.Req.Headers["x-appwrite-user-jwt"]);
- } else {
- return Context.Res.Send("Please sign in, JWT not found");
- }
-
- var databases = new Databases(client);
-
- try {
- await databases.CreateDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.Unique(), new Dictionary<string, object>());
- } catch (Exception e) {
- Context.Error("Failed to create document: " + e.Message);
- return Context.Res.Send("Failed to create document");
+ public async Task Main(RuntimeContext Context)
+ {
+ var client = new Client()
+ .SetEndpoint("https://cloud.appwrite.io/v1")
+ .SetProject(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_PROJECT_ID"))
+
+ if (Context.Req.Headers.ContainsKey("x-appwrite-user-jwt")) {
+ client.SetJWT(Context.Req.Headers["x-appwrite-user-jwt"]);
+ } else {
+ return Context.Res.Send("Please sign in, JWT not found");
+ }
+
+ var databases = new Databases(client);
+
+ try {
+ await databases.CreateDocument(
+ databaseId: "[DATABASE_ID]",
+ collectionId: "[COLLECTION_ID]",
+ documentId: ID.Unique(),
+ data: new Dictionary<string, object>());
+ } catch (Exception e) {
+ Context.Error("Failed to create document: " + e.Message);
+ return Context.Res.Send("Failed to create document");
+ }
+
+ return Context.Res.Send("Document created");
}
-
- return Context.Res.Send("Document created");
}
}
@@ -2257,10 +2319,9 @@ import java.util.HashMap
class Main {
fun main(context: RuntimeContext): RuntimeOutput {
- val client = Client().apply {
- setEndpoint("https://cloud.appwrite.io/v1")
- setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
- }
+ val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1")
+ .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
if (context.req.headers["x-appwrite-user-jwt"] != null) {
client.setJWT(context.req.headers["x-appwrite-user-jwt"])
@@ -2271,7 +2332,12 @@ class Main {
val databases = Databases(client)
try {
- databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), HashMap())
+ databases.createDocument(
+ databaseId = "[DATABASE_ID]",
+ collectionId = "[COLLECTION_ID]",
+ documentId = ID.unique(),
+ data = mapOf()
+ )
} catch (e: Exception) {
context.error("Failed to create document: " + e.message)
return context.res.send("Failed to create document")
@@ -2294,10 +2360,9 @@ import io.appwrite.Client;
public class Main {
public RuntimeOutput main(RuntimeContext context) throws Exception {
- Client client = new Client();
- client
- .setEndpoint("https://cloud.appwrite.io/v1")
- .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
+ Client client = new Client()
+ .setEndpoint("https://cloud.appwrite.io/v1")
+ .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
if (context.req.headers.containsKey("x-appwrite-user-jwt")) {
client.setJWT(context.req.headers.get("x-appwrite-user-jwt"));
@@ -2308,7 +2373,12 @@ public class Main {
Databases databases = new Databases(client);
try {
- databases.createDocument("[DATABASE_ID]", "[COLLECTION_ID]", ID.unique(), new HashMap<>());
+ databases.createDocument(
+ "[DATABASE_ID]",
+ "[COLLECTION_ID]",
+ ID.unique(),
+ new HashMap<>()
+ );
} catch (Exception e) {
context.error("Failed to create document: " + e.getMessage());
return context.res.send("Failed to create document");
@@ -2469,12 +2539,13 @@ func main(context: RuntimeContext) async throws -> RuntimeOutput {
// src/Utils.cs
namespace DotNetRuntime
-
-public static class Utils
{
- public static int Add(int a, int b)
+ public static class Utils
{
- return a + b;
+ public static int Add(int a, int b)
+ {
+ return a + b;
+ }
}
}
@@ -2482,11 +2553,12 @@ public static class Utils
// src/Index.cs
namespace DotNetRuntime
-
-public class Handler {
- public async Task Main(RuntimeContext Context)
- {
- return Context.Res.Send(Utils.Add(1, 2));
+{
+ public class Handler {
+ public async Task Main(RuntimeContext Context)
+ {
+ return Context.Res.Send(Utils.Add(1, 2));
+ }
}
}
@@ -2498,7 +2570,7 @@ public class Handler {
package io.openruntimes.kotlin.src
-class Utils {
+object Utils {
fun add(a: Int, b: Int): Int {
return a + b
}
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index a6e52cfcb..52facba68 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -60,20 +60,21 @@ use Appwrite\Utopia\View;
import { Client, Functions } from 'appwrite';
const client = new Client()
-
-client
.setEndpoint('https://cloud.appwrite.io/v1')
- .setProject('[PROJECT_ID]')
+ .setProject('[PROJECT_ID]');
const functions = new Functions(client)
try {
- const data = await functions.createExecution('[FUNCTION_ID]', JSON.stringify({
- 'foo': 'bar'
- }), '/', 'GET', {
- 'X-Custom-Header': '123'
- })
- console.log(data)
+ const execution = await functions.createExecution(
+ '[FUNCTION_ID]',
+ JSON.stringify({ 'foo': 'bar' }),
+ false,
+ '/',
+ 'GET',
+ { 'X-Custom-Header': '123' }
+ )
+ console.log(execution)
} catch (err) {
console.error(err.message)
}
@@ -87,20 +88,24 @@ try {
import 'package:appwrite/appwrite.dart';
import 'dart:convert';
-final client = Client();
-client
+final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
- .setProject('[PROJECT_ID]')
+ .setProject('[PROJECT_ID]');
final functions = Functions(client);
try {
- final response = await functions.createExecution('[FUNCTION_ID]', json.encode({
- 'foo': 'bar'
- }), '/', 'GET', {
- 'X-Custom-Header': '123'
- });
- print(response.data);
+ final execution = await functions.createExecution(
+ functionId: '[FUNCTION_ID]',
+ body: json.encode({ 'foo': 'bar' }),
+ async: false,
+ path: '/',
+ method: 'GET',
+ headers: {
+ 'X-Custom-Header': '123'
+ }
+ );
+ print(execution.toMap());
} catch (e) {
print(e.message);
}
@@ -115,22 +120,26 @@ try {
import io.appwrite.services.Functions;
import com.google.gson.Gson;
-val client = new Client();
-client
+val client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
-val functions = new Functions(client);
+val functions = Functions(client)
try {
- val response = await functions.createExecution('[FUNCTION_ID]', gson.toString({
- 'foo': 'bar'
- }), '/', 'GET', {
- 'X-Custom-Header': '123'
- });
- print(response.data);
-} catch (e) {
- print(e.message);
+ val execution = functions.createExecution(
+ functionId = "[FUNCTION_ID]",
+ body = gson.toJson(mapOf("foo" to "bar")),
+ async = false,
+ path = "/",
+ method = "GET",
+ headers = mapOf(
+ "X-Custom-Header" to "123"
+ )
+ )
+ print(execution.toMap())
+} catch (AppwriteException e) {
+ e.printStackTrace()
}
@@ -143,25 +152,24 @@ try {
import Foundation
let client = Client()
-client
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject("[PROJECT_ID]")
-let functions = Functions(client: client)
+let functions = Functions(client)
do {
- let response = try functions.createExecution(
+ let execution = try await functions.createExecution(
functionId: "[FUNCTION_ID]",
- data: NSJSONSerialization.jsonObject(with: ["foo": "bar"], options: [])!,
+ data: JSONSerialization.jsonObject(with: ["foo": "bar"], options: [])!,
xpath: "/",
method: "GET",
headers: [
"X-Custom-Header": "123"
]
)
- print(response)
-} catch let error {
- print(error)
+ print(execution.toMap())
+} catch {
+ print(error.localizedDescription)
}
@@ -178,26 +186,25 @@ do {
import { Client, Functions } from 'node-appwrite';
const client = new Client()
-
-client
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
- .setKey('[API_KEY]')
+ .setKey('[API_KEY]');
-const functions = new Functions(client)
+const functions = new Functions(client);
try {
- const data = await functions.createExecution('[FUNCTION_ID]', JSON.stringify({
- 'foo': 'bar'
- }), '/', 'GET', {
- 'X-Custom-Header': '123'
- })
- console.log(data)
-} catch (err) {
- console.error(err.message)
-}
-
-
+ const execution = await functions.createExecution(
+ '[FUNCTION_ID]',
+ JSON.stringify({ 'foo': 'bar' }),
+ false,
+ '/',
+ 'GET',
+ { 'X-Custom-Header': '123' }
+ )
+ console.log(execution)
+} catch (error) {
+ console.error(error.message)
+}
@@ -215,16 +222,25 @@ $client = new Client();
$client
->setEndpoint('https://cloud.appwrite.io/v1')
->setProject('[PROJECT_ID]')
- ->setKey('[API_KEY]')
-;
+ ->setKey('[API_KEY]');
$functions = new Functions($client);
-$result = $functions->createExecution('[FUNCTION_ID]', json_encode([
- 'foo' => 'bar'
-], '/', 'GET', [
- 'X-Custom-Header': '123'
-]);
+try {
+ $execution = $functions->createExecution(
+ functionId: '[FUNCTION_ID]',
+ body: json_encode([ 'foo' => 'bar' ]),
+ async: false,
+ path: '/',
+ method: 'GET',
+ headers: [
+ 'X-Custom-Header' => '123'
+ ]
+ );
+ echo $execution;
+} catch ($e) {
+ echo $e->getMessage();
+}
@@ -234,6 +250,7 @@ $result = $functions->createExecution('[FUNCTION_ID]', json_encode([
from appwrite.client import Client
from appwrite.services.functions import Functions
+
import json
client = Client()
@@ -246,11 +263,19 @@ client = Client()
functions = Functions(client)
-result = functions.create_execution('[FUNCTION_ID]', json.dumps({
- 'foo': 'bar'
-}, '/', 'GET', {
- 'X-Custom-Header': '123'
-})
+try:
+ execution = functions.create_execution(
+ functionId="[FUNCTION_ID]",
+ data=json.dumps({'foo': 'bar'}),
+ xpath='/',
+ method='GET',
+ headers=[
+ 'X-Custom-Header': '123'
+ ]
+ )
+ print(execution)
+except Exception as e:
+ print(e.message)
@@ -270,13 +295,20 @@ client = Client.new
functions = Functions.new(client)
-response = functions.create_execution(function_id: '[FUNCTION_ID]', data: JSON.generate({
- 'foo': 'bar'
-}), '/', 'GET', {
- 'X-Custom-Header': '123'
-})
-
-puts response.inspect
+begin
+ execution = functions.create_execution(
+ function_id: '[FUNCTION_ID]',
+ body: JSON.generate({ 'foo': 'bar'}),
+ async: false,
+ path: '/',
+ method: 'GET',
+ headers: {
+ 'X-Custom-Header': '123'
+ })
+ puts execution
+rescue => e
+ puts e.message
+end
@@ -287,23 +319,24 @@ puts response.inspect
import { Client, Functions } from "https://deno.land/x/appwrite/mod.ts";
const client = new Client()
-
-client
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
- .setKey('[API_KEY]')
+ .setKey('[API_KEY]');
-const functions = new Functions(client)
+const functions = new Functions(client);
try {
- const data = await functions.createExecution('[FUNCTION_ID]', JSON.stringify({
- 'foo': 'bar'
- }), '/', 'GET', {
- 'X-Custom-Header': '123'
- })
- console.log(data)
-} catch (err) {
- console.error(err.message)
+ const execution = await functions.createExecution(
+ '[FUNCTION_ID]',
+ JSON.stringify({ 'foo': 'bar' }),
+ false,
+ '/',
+ 'GET',
+ { 'X-Custom-Header': '123' }
+ )
+ console.log(execution)
+} catch (error) {
+ console.error(error.message)
}
@@ -315,34 +348,28 @@ try {
import 'package:dart_appwrite/dart_appwrite.dart';
import 'dart:convert';
-void main() {
- Client client = Client();
- Functions functions = Functions(client);
-
- client
+final client = Client();
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
- .setKey('[API_KEY]')
- ;
+ .setKey('[API_KEY]');
- Future result = functions.createExecution(
- functionId: '[FUNCTION_ID]',
- data: json.encode({
- 'foo': 'bar'
- }),
- xpath: '/',
- method: 'GET',
- headers: {
- 'X-Custom-Header': '123'
- }
- );
-
- result
- .then((response) {
- print(response);
- }).catchError((error) {
- print(error.response);
- });
+final functions = Functions(client);
+
+try {
+ final execution = await functions.createExecution(
+ functionId: '[FUNCTION_ID]',
+ body: json.encode({
+ 'foo': 'bar'
+ }),
+ async: false,
+ xpath: '/',
+ method: 'GET',
+ headers: {
+ 'X-Custom-Header': '123'
+ }
+ );
+} catch (e) {
+ print(e.message);
}
@@ -361,16 +388,21 @@ let client = Client()
let functions = Functions(client)
-let execution = try await functions.createExecution(
- functionId: "[FUNCTION_ID]",
- data: NSJSONSerialization.jsonObject(with: [
- "foo": "bar"
- ], options: [])!),
- xpath: '/',
- method: 'GET',
- headers: [
- "X-Custom-Header": "123"
-])
+do {
+ let execution = try await functions.createExecution(
+ functionId: "[FUNCTION_ID]",
+ body: JSONSerialization.jsonObject(with: ["foo": "bar"], options: [])!),
+ async: false,
+ xpath: "/",
+ method: "GET",
+ headers: [
+ "X-Custom-Header": "123"
+ ]
+ )
+ print(execution)
+catch {
+ print(error.localizedDescription)
+}
@@ -390,16 +422,26 @@ var client = new Client()
var functions = new Functions(client);
-Execution result = await functions.CreateExecution(
- functionId: "[FUNCTION_ID]",
- data: JsonSerializer.Serialize<object>(new Dictionary<string, object> {
- { "foo", "bar" }
- }),
- xpath: "/",
- method: "GET",
- headers: new Dictionary<string, object> {
- { "X-Custom-Header", "123" }
-});
+try
+{
+ var execution = await functions.CreateExecution(
+ functionId: "[FUNCTION_ID]",
+ body: JsonSerializer.Serialize<object>(new Dictionary<string, object> {
+ { "foo", "bar" }
+ }),
+ async: false,
+ xpath: "/",
+ method: "GET",
+ headers: new Dictionary<string, object> {
+ { "X-Custom-Header", "123" }
+ });
+
+ Debug.Write(execution)
+}
+catch (Exception e)
+{
+ Debug.Write(e);
+}
@@ -411,17 +453,17 @@ Execution result = await functions.CreateExecution(
import io.appwrite.services.Functions
import com.google.gson.Gson
-fun main(args: Array<String>) {
- val client = Client(context)
- .setEndpoint("https://cloud.appwrite.io/v1")
- .setProject("[PROJECT_ID]")
- .setKey("[API_KEY]")
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1")
+ .setProject("[PROJECT_ID]")
+ .setKey("[API_KEY]")
- val functions = Functions(client)
+val functions = Functions(client)
- val response = functions.createExecution(
+try {
+ val execution = functions.createExecution(
functionId = "[FUNCTION_ID]",
- data = gson.toString(mapOf(
+ body = gson.toJson(mapOf(
"foo" to "bar"
)),
xpath = "/",
@@ -430,9 +472,10 @@ fun main(args: Array<String>) {
"X-Custom-Header" to "123"
)
)
-}
-
-
+ print(execution)
+} catch (e: Exception) {
+ e.printStackTrace()
+}
@@ -446,34 +489,33 @@ import io.appwrite.services.Functions;
import java.util.HashMap;
import com.google.gson.Gson;
-public static void main(String[] args) throws Exception {
- Client client = new Client()
- .setEndpoint("https://cloud.appwrite.io/v1")
- .setProject("[PROJECT_ID]")
- .setKey("[API_KEY]");
-
- Functions functions = new Functions(client);
-
- functions.createExecution(
- "[FUNCTION_ID]",
- new CoroutineCallback<>((result, error) -> {
- if (error != null) {
- error.printStackTrace();
- return;
- }
-
- System.out.println(result);
- }),
- gson.toString(new HashMap() {{
- put("foo", "bar");
- }}),
- "/",
- "GET",
- new HashMap() {{
- put("X-Custom-Header", "123");
- }},
- );
-}
+Client client = new Client()
+ .setEndpoint("https://cloud.appwrite.io/v1")
+ .setProject("[PROJECT_ID]")
+ .setKey("[API_KEY]");
+
+Functions functions = new Functions(client);
+
+functions.createExecution(
+ "[FUNCTION_ID]",
+ gson.toJson(new HashMap() {{
+ put("foo", "bar");
+ }}),
+ false,
+ "/",
+ "GET",
+ new HashMap() {{
+ put("X-Custom-Header", "123");
+ }},
+ new CoroutineCallback<>((execution, error) -> {
+ if (error != null) {
+ error.printStackTrace();
+ return;
+ }
+
+ System.out.println(result);
+ }),
+);
diff --git a/app/views/docs/getting-started-for-server.phtml b/app/views/docs/getting-started-for-server.phtml
index b05dd86e3..b6dd13ab4 100644
--- a/app/views/docs/getting-started-for-server.phtml
+++ b/app/views/docs/getting-started-for-server.phtml
@@ -228,7 +228,7 @@ let client = Client()
using Appwrite;
var client = new Client()
- .SetEndpoint("http://cloud.appwrite.io/v1") // Your Appwrite Endpoint
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your Appwrite Endpoint
.SetProject("[PROJECT_ID]") // Your project ID
.SetKey("919c2db5d4...a2a3346ad2"); // Your secret API Key
@@ -399,7 +399,7 @@ let client = Client()
using Appwrite;
var client = new Client()
- .SetEndpoint("http://cloud.appwrite.io/v1") // Your Appwrite Endpoint
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your Appwrite Endpoint
.SetProject("[PROJECT_ID]") // Your project ID
.SetJWT("919c2db5d4...a2a3346ad2"); // Your secret JWT
@@ -763,7 +763,7 @@ using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
- .SetEndpoint("http://cloud.appwrite.io/v1") // Your Appwrite Endpoint
+ .SetEndpoint("https://cloud.appwrite.io/v1") // Your Appwrite Endpoint
.SetProject("[PROJECT_ID]") // Your project ID
.SetKey("cd868db89"); // Your secret API key
From f563606b9afe6a7f16e0161620bef8f6ac4c959e Mon Sep 17 00:00:00 2001
From: Jake Barnby
Date: Tue, 29 Aug 2023 19:54:22 -0400
Subject: [PATCH 183/183] Fix path param
---
app/views/docs/functions-execute.phtml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/app/views/docs/functions-execute.phtml b/app/views/docs/functions-execute.phtml
index 52facba68..150aa2842 100644
--- a/app/views/docs/functions-execute.phtml
+++ b/app/views/docs/functions-execute.phtml
@@ -161,7 +161,7 @@ do {
let execution = try await functions.createExecution(
functionId: "[FUNCTION_ID]",
data: JSONSerialization.jsonObject(with: ["foo": "bar"], options: [])!,
- xpath: "/",
+ path: "/",
method: "GET",
headers: [
"X-Custom-Header": "123"
@@ -267,7 +267,7 @@ try:
execution = functions.create_execution(
functionId="[FUNCTION_ID]",
data=json.dumps({'foo': 'bar'}),
- xpath='/',
+ path='/',
method='GET',
headers=[
'X-Custom-Header': '123'
@@ -362,7 +362,7 @@ try {
'foo': 'bar'
}),
async: false,
- xpath: '/',
+ path: '/',
method: 'GET',
headers: {
'X-Custom-Header': '123'
@@ -393,7 +393,7 @@ do {
functionId: "[FUNCTION_ID]",
body: JSONSerialization.jsonObject(with: ["foo": "bar"], options: [])!),
async: false,
- xpath: "/",
+ path: "/",
method: "GET",
headers: [
"X-Custom-Header": "123"
@@ -430,7 +430,7 @@ try
{ "foo", "bar" }
}),
async: false,
- xpath: "/",
+ path: "/",
method: "GET",
headers: new Dictionary<string, object> {
{ "X-Custom-Header", "123" }
@@ -466,7 +466,7 @@ try {
body = gson.toJson(mapOf(
"foo" to "bar"
)),
- xpath = "/",
+ path = "/",
method = "GET",
headers = mapOf(
"X-Custom-Header" to "123"