From 93ccfffb23626649adfcb6ac47338b95d2b599a6 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 2 Sep 2026 14:05:44 +0100 Subject: [PATCH] chore: update Python SDK to 24.0.0 --- CHANGELOG.md | 11 ++ README.md | 4 +- appwrite/client.py | 6 +- appwrite/enums/o_auth_provider.py | 2 + appwrite/enums/project_key_scopes.py | 4 + appwrite/enums/project_o_auth_provider_id.py | 2 + appwrite/models/__init__.py | 4 + appwrite/models/billing_plan.py | 3 + appwrite/models/dedicated_database.py | 5 +- .../models/dedicated_database_operation.py | 2 +- appwrite/models/framework_adapter.py | 4 +- appwrite/models/o_auth2_cloudflare.py | 26 ++++ appwrite/models/o_auth2_provider_list.py | 6 +- appwrite/models/o_auth2_resend.py | 26 ++++ appwrite/services/account.py | 2 +- appwrite/services/avatars.py | 8 +- appwrite/services/documents_db.py | 10 ++ appwrite/services/mongo.py | 9 +- appwrite/services/mysql.py | 9 +- appwrite/services/postgresql.py | 9 +- appwrite/services/project.py | 112 +++++++++++++++++- appwrite/services/tables_db.py | 4 +- appwrite/services/vectors_db.py | 10 ++ docs/examples/documentsdb/create-document.md | 3 +- docs/examples/documentsdb/create-documents.md | 3 +- docs/examples/mongo/update-credentials.md | 4 +- docs/examples/mysql/update-credentials.md | 4 +- .../examples/postgresql/update-credentials.md | 4 +- .../examples/project/get-o-auth-2-provider.md | 4 +- .../project/update-o-auth-2-cloudflare.md | 20 ++++ .../project/update-o-auth-2-resend.md | 20 ++++ ...cutover-migration.md => create-cutover.md} | 2 +- docs/examples/vectorsdb/create-document.md | 3 +- docs/examples/vectorsdb/create-documents.md | 3 +- pyproject.toml | 2 +- setup.py | 4 +- test/services/test_documents_db.py | 1 + test/services/test_mongo.py | 59 +++------ test/services/test_mysql.py | 59 +++------ test/services/test_postgresql.py | 61 +++------- test/services/test_project.py | 36 ++++++ test/services/test_tables_db.py | 5 +- test/services/test_vectors_db.py | 1 + 43 files changed, 397 insertions(+), 179 deletions(-) create mode 100644 appwrite/models/o_auth2_cloudflare.py create mode 100644 appwrite/models/o_auth2_resend.py create mode 100644 docs/examples/project/update-o-auth-2-cloudflare.md create mode 100644 docs/examples/project/update-o-auth-2-resend.md rename docs/examples/tablesdb/{cutover-migration.md => create-cutover.md} (89%) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc22931a..891eb7bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Change Log +## 24.0.0 + +* Stable release of the dedicated database APIs: `mysql`, `postgresql`, `mongo`, `documentsDB`, and `vectorsDB` services, previously released as release candidates +* Breaking: `tablesDB.cutoverMigration` is renamed to `tablesDB.createCutover` +* Breaking: `Execution.functionId` is replaced by `resourceId` and `resourceType`, covering function and site executions +* Added: Cloudflare, Resend, and Hugging Face OAuth providers +* Added: `usageAggregateOnlyMetrics` on the `BillingPlan` model +* Fixed: `transactionId` is accepted again by `documentsDB` and `vectorsDB` `createDocument` and `createDocuments` +* Updated: `X-Appwrite-Response-Format` is now `2.0.0` +* Updated: `FrameworkAdapter.fallbackFile` is now optional + ## 24.0.0rc1 * Breaking: `Execution.functionId` is replaced by `resourceId` and `resourceType`, now that executions cover both functions and sites diff --git a/README.md b/README.md index 926d11a4..e7644a3a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Appwrite Python SDK ![License](https://img.shields.io/github/license/appwrite/sdk-for-python.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-1.9.6-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-2.0.0-blue.svg?style=flat-square) [![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) [![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) -**This SDK is compatible with Appwrite server version 1.9.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-python/releases).** +**This SDK targets Appwrite server version 1.9.x as shipped on Appwrite Cloud.** Self-hosted releases can lag behind Cloud — if you run an older self-hosted build, use a matching older SDK from [previous releases](https://github.com/appwrite/sdk-for-python/releases) when APIs differ. Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Python SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) diff --git a/appwrite/client.py b/appwrite/client.py index c102cc0e..25cd33cb 100644 --- a/appwrite/client.py +++ b/appwrite/client.py @@ -18,12 +18,12 @@ def __init__(self): self._endpoint = 'https://cloud.appwrite.io/v1' self._global_headers = { 'content-type': '', - 'user-agent': f'AppwritePythonSDK/24.0.0rc1 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})', + 'user-agent': f'AppwritePythonSDK/24.0.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})', 'x-sdk-name': 'Python', 'x-sdk-platform': 'server', 'x-sdk-language': 'python', - 'x-sdk-version': '24.0.0rc1', - 'X-Appwrite-Response-Format': '1.9.6', + 'x-sdk-version': '24.0.0', + 'X-Appwrite-Response-Format': '2.0.0', } self._config = {} diff --git a/appwrite/enums/o_auth_provider.py b/appwrite/enums/o_auth_provider.py index 0337a809..8656b596 100644 --- a/appwrite/enums/o_auth_provider.py +++ b/appwrite/enums/o_auth_provider.py @@ -11,6 +11,7 @@ class OAuthProvider(Enum): BITBUCKET = "bitbucket" BITLY = "bitly" BOX = "box" + CLOUDFLARE = "cloudflare" DAILYMOTION = "dailymotion" DISCORD = "discord" DISQUS = "disqus" @@ -33,6 +34,7 @@ class OAuthProvider(Enum): PAYPAL = "paypal" PAYPALSANDBOX = "paypalSandbox" PODIO = "podio" + RESEND = "resend" SALESFORCE = "salesforce" SLACK = "slack" SPOTIFY = "spotify" diff --git a/appwrite/enums/project_key_scopes.py b/appwrite/enums/project_key_scopes.py index 83c765e3..57710319 100644 --- a/appwrite/enums/project_key_scopes.py +++ b/appwrite/enums/project_key_scopes.py @@ -50,12 +50,16 @@ class ProjectKeyScopes(Enum): DOCUMENTSDB_COLLECTIONS_WRITE = "documentsdb.collections.write" DOCUMENTSDB_DOCUMENTS_READ = "documentsdb.documents.read" DOCUMENTSDB_DOCUMENTS_WRITE = "documentsdb.documents.write" + DOCUMENTSDB_INDEXES_READ = "documentsdb.indexes.read" + DOCUMENTSDB_INDEXES_WRITE = "documentsdb.indexes.write" VECTORSDB_READ = "vectorsdb.read" VECTORSDB_WRITE = "vectorsdb.write" VECTORSDB_COLLECTIONS_READ = "vectorsdb.collections.read" VECTORSDB_COLLECTIONS_WRITE = "vectorsdb.collections.write" VECTORSDB_DOCUMENTS_READ = "vectorsdb.documents.read" VECTORSDB_DOCUMENTS_WRITE = "vectorsdb.documents.write" + VECTORSDB_INDEXES_READ = "vectorsdb.indexes.read" + VECTORSDB_INDEXES_WRITE = "vectorsdb.indexes.write" BUCKETS_READ = "buckets.read" BUCKETS_WRITE = "buckets.write" FILES_READ = "files.read" diff --git a/appwrite/enums/project_o_auth_provider_id.py b/appwrite/enums/project_o_auth_provider_id.py index 3e93dacb..ad47c234 100644 --- a/appwrite/enums/project_o_auth_provider_id.py +++ b/appwrite/enums/project_o_auth_provider_id.py @@ -11,6 +11,7 @@ class ProjectOAuthProviderId(Enum): BITBUCKET = "bitbucket" BITLY = "bitly" BOX = "box" + CLOUDFLARE = "cloudflare" DAILYMOTION = "dailymotion" DISCORD = "discord" DISQUS = "disqus" @@ -33,6 +34,7 @@ class ProjectOAuthProviderId(Enum): PAYPAL = "paypal" PAYPALSANDBOX = "paypalSandbox" PODIO = "podio" + RESEND = "resend" SALESFORCE = "salesforce" SLACK = "slack" SPOTIFY = "spotify" diff --git a/appwrite/models/__init__.py b/appwrite/models/__init__.py index 507139f4..80ced38d 100644 --- a/appwrite/models/__init__.py +++ b/appwrite/models/__init__.py @@ -157,6 +157,7 @@ from .o_auth2_notion import OAuth2Notion from .o_auth2_salesforce import OAuth2Salesforce from .o_auth2_yahoo import OAuth2Yahoo +from .o_auth2_cloudflare import OAuth2Cloudflare from .o_auth2_hugging_face import OAuth2HuggingFace from .o_auth2_linkedin import OAuth2Linkedin from .o_auth2_disqus import OAuth2Disqus @@ -176,6 +177,7 @@ from .o_auth2_kick import OAuth2Kick from .o_auth2_apple import OAuth2Apple from .o_auth2_microsoft import OAuth2Microsoft +from .o_auth2_resend import OAuth2Resend from .o_auth2_provider_list import OAuth2ProviderList from .policy_password_dictionary import PolicyPasswordDictionary from .policy_password_history import PolicyPasswordHistory @@ -458,6 +460,7 @@ 'OAuth2Notion', 'OAuth2Salesforce', 'OAuth2Yahoo', + 'OAuth2Cloudflare', 'OAuth2HuggingFace', 'OAuth2Linkedin', 'OAuth2Disqus', @@ -477,6 +480,7 @@ 'OAuth2Kick', 'OAuth2Apple', 'OAuth2Microsoft', + 'OAuth2Resend', 'OAuth2ProviderList', 'PolicyPasswordDictionary', 'PolicyPasswordHistory', diff --git a/appwrite/models/billing_plan.py b/appwrite/models/billing_plan.py index d50ea2cf..7f78aab6 100644 --- a/appwrite/models/billing_plan.py +++ b/appwrite/models/billing_plan.py @@ -91,6 +91,8 @@ class BillingPlan(AppwriteModel): Usage history days usagelogsintervals : Optional[List[Any]] Usage log time intervals allowed for this plan (e.g. 15m, 1h, 1d). + usageaggregateonlymetrics : Optional[List[Any]] + Metrics this plan only records as a total. They cannot be broken down by dimension or filtered, because the stored events cover a fraction of the real traffic. projectinactivitydays : float Number of days of console inactivity before a project is paused. 0 means pausing is disabled. alertlimit : float @@ -198,6 +200,7 @@ class BillingPlan(AppwriteModel): activitylogs: Optional[float] = Field(default=None, alias='activityLogs') usagelogs: float = Field(..., alias='usageLogs') usagelogsintervals: Optional[List[Any]] = Field(default=None, alias='usageLogsIntervals') + usageaggregateonlymetrics: Optional[List[Any]] = Field(default=None, alias='usageAggregateOnlyMetrics') projectinactivitydays: float = Field(..., alias='projectInactivityDays') alertlimit: float = Field(..., alias='alertLimit') usage: UsageBillingPlan = Field(..., alias='usage') diff --git a/appwrite/models/dedicated_database.py b/appwrite/models/dedicated_database.py index dcc072e3..45c49d03 100644 --- a/appwrite/models/dedicated_database.py +++ b/appwrite/models/dedicated_database.py @@ -29,7 +29,7 @@ class DedicatedDatabase(AppwriteModel): specification : str Specification identifier. backend : str - Database backend provider. Possible values: prisma, edge. + Database backend provider. Possible values: edge. hostname : str Database hostname for connections. connectionport : float @@ -38,6 +38,8 @@ class DedicatedDatabase(AppwriteModel): Database username for connections. connectionpassword : str Database password for connections. + credentialgeneration : float + Committed generation of the primary connection credentials. Null until the rotation contract has been initialized. connectionstring : str Full database connection string (URI format). ssl : bool @@ -122,6 +124,7 @@ class DedicatedDatabase(AppwriteModel): connectionport: float = Field(..., alias='connectionPort') connectionuser: str = Field(..., alias='connectionUser') connectionpassword: str = Field(..., alias='connectionPassword') + credentialgeneration: float = Field(..., alias='credentialGeneration') connectionstring: str = Field(..., alias='connectionString') ssl: bool = Field(..., alias='ssl') status: str = Field(..., alias='status') diff --git a/appwrite/models/dedicated_database_operation.py b/appwrite/models/dedicated_database_operation.py index 3a6c29a9..d9814c58 100644 --- a/appwrite/models/dedicated_database_operation.py +++ b/appwrite/models/dedicated_database_operation.py @@ -17,7 +17,7 @@ class DedicatedDatabaseOperation(AppwriteModel): databaseid : str Database ID the operation ran against. type : str - Operation type, such as provision, update, restore, pausing, resuming, failover, backup-create or cross-region-enable. + Operation type, such as provision, update, credentials-update, restore, pausing, resuming, failover, backup-create or cross-region-enable. status : str Operation status. Possible values: queued (accepted and waiting to resume), running (in progress), completed (finished successfully), failed (ended in an error). attempts : float diff --git a/appwrite/models/framework_adapter.py b/appwrite/models/framework_adapter.py index e2ed9299..1cfac625 100644 --- a/appwrite/models/framework_adapter.py +++ b/appwrite/models/framework_adapter.py @@ -18,7 +18,7 @@ class FrameworkAdapter(AppwriteModel): Default command to build site into output directory. outputdirectory : str Default output directory of build. - fallbackfile : str + fallbackfile : Optional[str] Name of fallback file to use instead of 404 page. If null, Appwrite 404 page will be displayed. """ @@ -26,4 +26,4 @@ class FrameworkAdapter(AppwriteModel): installcommand: str = Field(..., alias='installCommand') buildcommand: str = Field(..., alias='buildCommand') outputdirectory: str = Field(..., alias='outputDirectory') - fallbackfile: str = Field(..., alias='fallbackFile') + fallbackfile: Optional[str] = Field(default=None, alias='fallbackFile') diff --git a/appwrite/models/o_auth2_cloudflare.py b/appwrite/models/o_auth2_cloudflare.py new file mode 100644 index 00000000..5099f214 --- /dev/null +++ b/appwrite/models/o_auth2_cloudflare.py @@ -0,0 +1,26 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + + +class OAuth2Cloudflare(AppwriteModel): + """ + OAuth2Cloudflare + + Attributes + ---------- + id : str + OAuth2 provider ID. + enabled : bool + OAuth2 provider is active and can be used to create sessions. + clientid : str + Cloudflare OAuth2 client ID. + clientsecret : str + Cloudflare OAuth2 client secret. + """ + + id: str = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') + clientid: str = Field(..., alias='clientId') + clientsecret: str = Field(..., alias='clientSecret') diff --git a/appwrite/models/o_auth2_provider_list.py b/appwrite/models/o_auth2_provider_list.py index 64571e1e..09e97009 100644 --- a/appwrite/models/o_auth2_provider_list.py +++ b/appwrite/models/o_auth2_provider_list.py @@ -44,6 +44,8 @@ from .o_auth2_kick import OAuth2Kick from .o_auth2_microsoft import OAuth2Microsoft from .o_auth2_hugging_face import OAuth2HuggingFace +from .o_auth2_resend import OAuth2Resend +from .o_auth2_cloudflare import OAuth2Cloudflare class OAuth2ProviderList(AppwriteModel): @@ -54,7 +56,7 @@ class OAuth2ProviderList(AppwriteModel): ---------- total : float Total number of OAuth2 providers in the given project. - providers : List[Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Appwrite, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft, OAuth2HuggingFace]] + providers : List[Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Appwrite, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft, OAuth2HuggingFace, OAuth2Resend, OAuth2Cloudflare]] List of OAuth2 providers. """ @@ -103,5 +105,7 @@ class OAuth2ProviderList(AppwriteModel): OAuth2Kick, OAuth2Microsoft, OAuth2HuggingFace, + OAuth2Resend, + OAuth2Cloudflare, ] ] = Field(..., alias='providers') diff --git a/appwrite/models/o_auth2_resend.py b/appwrite/models/o_auth2_resend.py new file mode 100644 index 00000000..0c3efb05 --- /dev/null +++ b/appwrite/models/o_auth2_resend.py @@ -0,0 +1,26 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + + +class OAuth2Resend(AppwriteModel): + """ + OAuth2Resend + + Attributes + ---------- + id : str + OAuth2 provider ID. + enabled : bool + OAuth2 provider is active and can be used to create sessions. + clientid : str + Resend OAuth2 client ID. + clientsecret : str + Resend OAuth2 client secret. + """ + + id: str = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') + clientid: str = Field(..., alias='clientId') + clientsecret: str = Field(..., alias='clientSecret') diff --git a/appwrite/services/account.py b/appwrite/services/account.py index 286f1ee5..0b4ada93 100644 --- a/appwrite/services/account.py +++ b/appwrite/services/account.py @@ -1880,7 +1880,7 @@ def create_o_auth2_token( Parameters ---------- provider : OAuthProvider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, salesforce, slack, spotify, stripe, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. success : Optional[str] URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. failure : Optional[str] diff --git a/appwrite/services/avatars.py b/appwrite/services/avatars.py index ab7223af..27d11785 100644 --- a/appwrite/services/avatars.py +++ b/appwrite/services/avatars.py @@ -356,7 +356,7 @@ def get_photo( """ Returns the best available profile photo for a user. The endpoint tries each source in priority order and returns the first successful result: OAuth2 identity photo, Gravatar, Libravatar, Appwrite Initials, built-in static fallback. - The photo resolves for the currently authenticated user unless `userId` points at another user. Passing `emailHash` and/or `name` resolves the avatar from those values alone: the hash is looked up on Gravatar and Libravatar, the name is rendered as initials, and the user's own identity photos, email, and name leave the chain so they never shadow the avatar being asked for. Emails are only ever accepted pre-hashed, so no address ends up in a URL. + Passing `userId` — `current()` for the authenticated user — resolves the photo from everything known about that user: identity photos, email, and name. An explicit `emailHash` or `name` then overrides just that value, and the user's remaining sources stay in the chain. Without `userId`, passing `emailHash` and/or `name` resolves the avatar from those values alone: the hash is looked up on Gravatar and Libravatar, the name is rendered as initials, and the session user stays out of the chain so their own photo never shadows the avatar being asked for. When nothing is passed, the photo resolves for the currently authenticated user. Emails are only ever accepted pre-hashed, so no address ends up in a URL. Parameters ---------- @@ -371,11 +371,11 @@ def get_photo( rating : Optional[str] Maximum image rating to fetch from Gravatar/Libravatar. Defaults to 'g'. user_id : Optional[str] - User ID to resolve the photo for. Defaults to 'current()' for the currently authenticated user. + User ID to resolve the photo for. Pass 'current()' for the currently authenticated user. When omitted, the session user is used only if no emailHash and no name is passed. email_hash : Optional[str] - SHA256 hash of the lowercase, trimmed email address to look up on Gravatar and Libravatar instead of the user's own photo sources. Pass the hash, never the address itself. + SHA256 hash of the lowercase, trimmed email address to look up on Gravatar and Libravatar instead of the user's own email. Pass the hash, never the address itself. name : Optional[str] - Name to render initials from instead of the user's own photo sources. Max length: 128 chars. + Name to render initials from instead of the user's own name. Max length: 128 chars. Returns ------- bytes diff --git a/appwrite/services/documents_db.py b/appwrite/services/documents_db.py index d136fa34..d11632b2 100644 --- a/appwrite/services/documents_db.py +++ b/appwrite/services/documents_db.py @@ -949,6 +949,7 @@ def create_document( document_id: str, data: Dict[str, Any], permissions: Optional[List[str]] = None, + transaction_id: Optional[str] = None, model_type: Type[T] = dict, ) -> Document[T]: """ @@ -966,6 +967,8 @@ def create_document( Document data as JSON object. permissions : Optional[List[str]] An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + transaction_id : Optional[str] + Transaction ID for staging the operation. model_type : Type[T], optional Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. @@ -996,6 +999,8 @@ def create_document( api_params['data'] = self._normalize_value(data) if permissions is not None: api_params['permissions'] = self._normalize_value(permissions) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call( 'post', @@ -1015,6 +1020,7 @@ def create_documents( database_id: str, collection_id: str, documents: List[Dict[str, Any]], + transaction_id: Optional[str] = None, model_type: Type[T] = dict, ) -> DocumentList[T]: """ @@ -1028,6 +1034,8 @@ def create_documents( Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents. documents : List[Dict[str, Any]] Array of documents data as JSON objects. + transaction_id : Optional[str] + Transaction ID for staging the operation. model_type : Type[T], optional Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. @@ -1053,6 +1061,8 @@ def create_documents( api_path = api_path.replace('{databaseId}', str(self._normalize_value(database_id))) api_path = api_path.replace('{collectionId}', str(self._normalize_value(collection_id))) api_params['documents'] = self._normalize_value(documents) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call( 'post', diff --git a/appwrite/services/mongo.py b/appwrite/services/mongo.py index 7d0e2722..4fb19898 100644 --- a/appwrite/services/mongo.py +++ b/appwrite/services/mongo.py @@ -12,6 +12,7 @@ from ..models.backup_policy import BackupPolicy from ..models.dedicated_database_backup_storage import DedicatedDatabaseBackupStorage from ..models.dedicated_database_branch_list import DedicatedDatabaseBranchList +from ..models.dedicated_database_operation import DedicatedDatabaseOperation from ..models.dedicated_database_operation_list import DedicatedDatabaseOperationList from ..models.dedicated_database_pitr_windows import DedicatedDatabasePITRWindows from ..models.dedicated_database_replicas import DedicatedDatabaseReplicas @@ -1113,9 +1114,9 @@ def delete_branch( def update_credentials( self, database_id: str, - ) -> DedicatedDatabase: + ) -> DedicatedDatabaseOperation: """ - Rotate the primary connection credentials for a dedicated database. Generates a new password and updates the database atomically. Previous credentials stop working immediately. Returns the database with a refreshed connection string carrying the new password. + Queue a rotation of the primary connection credentials for a dedicated database. A hibernated database is woken by the worker before rotation. List database operations until the returned operation reaches a terminal status, then fetch the database again for the refreshed connection string. Parameters ---------- @@ -1123,7 +1124,7 @@ def update_credentials( Database ID. Returns ------- - DedicatedDatabase + DedicatedDatabaseOperation API response as a typed Pydantic model Raises @@ -1149,7 +1150,7 @@ def update_credentials( api_params, ) - return self._parse_response(response, model=DedicatedDatabase) + return self._parse_response(response, model=DedicatedDatabaseOperation) def create_failover( self, diff --git a/appwrite/services/mysql.py b/appwrite/services/mysql.py index aa567815..a40b04c1 100644 --- a/appwrite/services/mysql.py +++ b/appwrite/services/mysql.py @@ -12,6 +12,7 @@ from ..models.backup_policy import BackupPolicy from ..models.dedicated_database_backup_storage import DedicatedDatabaseBackupStorage from ..models.dedicated_database_branch_list import DedicatedDatabaseBranchList +from ..models.dedicated_database_operation import DedicatedDatabaseOperation from ..models.dedicated_database_execution import DedicatedDatabaseExecution from ..models.dedicated_database_operation_list import DedicatedDatabaseOperationList from ..models.dedicated_database_pitr_windows import DedicatedDatabasePITRWindows @@ -1115,9 +1116,9 @@ def delete_branch( def update_credentials( self, database_id: str, - ) -> DedicatedDatabase: + ) -> DedicatedDatabaseOperation: """ - Rotate the primary connection credentials for a dedicated database. Generates a new password and updates the database atomically. Previous credentials stop working immediately. Returns the database with a refreshed connection string carrying the new password. + Queue a rotation of the primary connection credentials for a dedicated database. A hibernated database is woken by the worker before rotation. List database operations until the returned operation reaches a terminal status, then fetch the database again for the refreshed connection string. Parameters ---------- @@ -1125,7 +1126,7 @@ def update_credentials( Database ID. Returns ------- - DedicatedDatabase + DedicatedDatabaseOperation API response as a typed Pydantic model Raises @@ -1151,7 +1152,7 @@ def update_credentials( api_params, ) - return self._parse_response(response, model=DedicatedDatabase) + return self._parse_response(response, model=DedicatedDatabaseOperation) def create_execution( self, diff --git a/appwrite/services/postgresql.py b/appwrite/services/postgresql.py index 3c1bdb7f..19d1ff74 100644 --- a/appwrite/services/postgresql.py +++ b/appwrite/services/postgresql.py @@ -12,6 +12,7 @@ from ..models.backup_policy import BackupPolicy from ..models.dedicated_database_backup_storage import DedicatedDatabaseBackupStorage from ..models.dedicated_database_branch_list import DedicatedDatabaseBranchList +from ..models.dedicated_database_operation import DedicatedDatabaseOperation from ..models.dedicated_database_execution import DedicatedDatabaseExecution from ..models.dedicated_database_extensions import DedicatedDatabaseExtensions from ..models.dedicated_database_operation_list import DedicatedDatabaseOperationList @@ -1116,9 +1117,9 @@ def delete_branch( def update_credentials( self, database_id: str, - ) -> DedicatedDatabase: + ) -> DedicatedDatabaseOperation: """ - Rotate the primary connection credentials for a dedicated database. Generates a new password and updates the database atomically. Previous credentials stop working immediately. Returns the database with a refreshed connection string carrying the new password. + Queue a rotation of the primary connection credentials for a dedicated database. A hibernated database is woken by the worker before rotation. List database operations until the returned operation reaches a terminal status, then fetch the database again for the refreshed connection string. Parameters ---------- @@ -1126,7 +1127,7 @@ def update_credentials( Database ID. Returns ------- - DedicatedDatabase + DedicatedDatabaseOperation API response as a typed Pydantic model Raises @@ -1152,7 +1153,7 @@ def update_credentials( api_params, ) - return self._parse_response(response, model=DedicatedDatabase) + return self._parse_response(response, model=DedicatedDatabaseOperation) def create_execution( self, diff --git a/appwrite/services/project.py b/appwrite/services/project.py index be5c035e..848e448c 100644 --- a/appwrite/services/project.py +++ b/appwrite/services/project.py @@ -21,6 +21,7 @@ from ..models.o_auth2_bitbucket import OAuth2Bitbucket from ..models.o_auth2_bitly import OAuth2Bitly from ..models.o_auth2_box import OAuth2Box +from ..models.o_auth2_cloudflare import OAuth2Cloudflare from ..models.o_auth2_dailymotion import OAuth2Dailymotion from ..models.o_auth2_discord import OAuth2Discord from ..models.o_auth2_disqus import OAuth2Disqus @@ -44,6 +45,7 @@ from ..models.o_auth2_okta import OAuth2Okta from ..models.o_auth2_paypal import OAuth2Paypal from ..models.o_auth2_podio import OAuth2Podio +from ..models.o_auth2_resend import OAuth2Resend from ..models.o_auth2_salesforce import OAuth2Salesforce from ..models.o_auth2_slack import OAuth2Slack from ..models.o_auth2_spotify import OAuth2Spotify @@ -1325,6 +1327,56 @@ def update_o_auth2_box( return self._parse_response(response, model=OAuth2Box) + def update_o_auth2_cloudflare( + self, + client_id: Optional[str] = None, + client_secret: Optional[str] = None, + enabled: Optional[bool] = None, + ) -> OAuth2Cloudflare: + """ + Update the project OAuth2 Cloudflare configuration. + + Parameters + ---------- + client_id : Optional[str] + 'Client ID' of Cloudflare OAuth2 app. For example: 4b866000000000000000000000c9e4e2 + client_secret : Optional[str] + 'Client Secret' of Cloudflare OAuth2 app. For example: cfoc_5Q6YRl0000000000000000000000000000000000003d214f + enabled : Optional[bool] + OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid. + Returns + ------- + OAuth2Cloudflare + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project/oauth2/cloudflare' + api_params = {} + if client_id is not None: + api_params['clientId'] = self._normalize_value(client_id) + if client_secret is not None: + api_params['clientSecret'] = self._normalize_value(client_secret) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) + + response = self.client.call( + 'patch', + api_path, + { + 'X-Appwrite-Project': self.client.get_config('project'), + 'content-type': 'application/json', + 'accept': 'application/json', + }, + api_params, + ) + + return self._parse_response(response, model=OAuth2Cloudflare) + def update_o_auth2_dailymotion( self, api_key: Optional[str] = None, @@ -2495,6 +2547,56 @@ def update_o_auth2_podio( return self._parse_response(response, model=OAuth2Podio) + def update_o_auth2_resend( + self, + client_id: Optional[str] = None, + client_secret: Optional[str] = None, + enabled: Optional[bool] = None, + ) -> OAuth2Resend: + """ + Update the project OAuth2 Resend configuration. + + Parameters + ---------- + client_id : Optional[str] + 'Client ID' of Resend OAuth2 app. For example: f47ac10b-58cc-4372-a567-0e02b2c3d479 + client_secret : Optional[str] + 'Client Secret' of Resend OAuth2 app. For example: 9c1e4b00000000000000000000000000000000000000000000000000a72d5f4 + enabled : Optional[bool] + OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid. + Returns + ------- + OAuth2Resend + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project/oauth2/resend' + api_params = {} + if client_id is not None: + api_params['clientId'] = self._normalize_value(client_id) + if client_secret is not None: + api_params['clientSecret'] = self._normalize_value(client_secret) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) + + response = self.client.call( + 'patch', + api_path, + { + 'X-Appwrite-Project': self.client.get_config('project'), + 'content-type': 'application/json', + 'accept': 'application/json', + }, + api_params, + ) + + return self._parse_response(response, model=OAuth2Resend) + def update_o_auth2_salesforce( self, customer_key: Optional[str] = None, @@ -3173,6 +3275,8 @@ def get_o_auth2_provider( OAuth2Salesforce, OAuth2Yahoo, OAuth2HuggingFace, + OAuth2Resend, + OAuth2Cloudflare, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, @@ -3200,7 +3304,7 @@ def get_o_auth2_provider( OAuth2 provider key. For example: github, google, apple. Returns ------- - Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2HuggingFace, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft] + Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2HuggingFace, OAuth2Resend, OAuth2Cloudflare, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft] API response as one of the typed response models Raises @@ -3299,6 +3403,12 @@ def get_o_auth2_provider( if response.get('$id') == 'huggingface': return self._parse_response(response, model=OAuth2HuggingFace) + if response.get('$id') == 'resend': + return self._parse_response(response, model=OAuth2Resend) + + if response.get('$id') == 'cloudflare': + return self._parse_response(response, model=OAuth2Cloudflare) + if response.get('$id') == 'linkedin': return self._parse_response(response, model=OAuth2Linkedin) diff --git a/appwrite/services/tables_db.py b/appwrite/services/tables_db.py index 808f9ad3..f7e8ed2e 100644 --- a/appwrite/services/tables_db.py +++ b/appwrite/services/tables_db.py @@ -832,7 +832,7 @@ def delete_migration( return response - def cutover_migration( + def create_cutover( self, database_id: str, migration_id: str, @@ -857,7 +857,7 @@ def cutover_migration( If API request fails """ - api_path = '/tablesdb/{databaseId}/migrations/{migrationId}/cutover' + api_path = '/tablesdb/{databaseId}/migrations/{migrationId}/cutovers' api_params = {} if database_id is None: raise AppwriteException('Missing required parameter: "database_id"') diff --git a/appwrite/services/vectors_db.py b/appwrite/services/vectors_db.py index e2fcba59..eede5fa1 100644 --- a/appwrite/services/vectors_db.py +++ b/appwrite/services/vectors_db.py @@ -945,6 +945,7 @@ def create_document( document_id: str, data: Dict[str, Any], permissions: Optional[List[str]] = None, + transaction_id: Optional[str] = None, model_type: Type[T] = dict, ) -> Document[T]: """ @@ -962,6 +963,8 @@ def create_document( Document data as JSON object. permissions : Optional[List[str]] An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + transaction_id : Optional[str] + Transaction ID for staging the operation. model_type : Type[T], optional Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. @@ -992,6 +995,8 @@ def create_document( api_params['data'] = self._normalize_value(data) if permissions is not None: api_params['permissions'] = self._normalize_value(permissions) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call( 'post', @@ -1011,6 +1016,7 @@ def create_documents( database_id: str, collection_id: str, documents: List[Dict[str, Any]], + transaction_id: Optional[str] = None, model_type: Type[T] = dict, ) -> DocumentList[T]: """ @@ -1024,6 +1030,8 @@ def create_documents( Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents. documents : List[Dict[str, Any]] Array of documents data as JSON objects. + transaction_id : Optional[str] + Transaction ID for staging the operation. model_type : Type[T], optional Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. @@ -1049,6 +1057,8 @@ def create_documents( api_path = api_path.replace('{databaseId}', str(self._normalize_value(database_id))) api_path = api_path.replace('{collectionId}', str(self._normalize_value(collection_id))) api_params['documents'] = self._normalize_value(documents) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call( 'post', diff --git a/docs/examples/documentsdb/create-document.md b/docs/examples/documentsdb/create-document.md index 1fa38033..a6a3055f 100644 --- a/docs/examples/documentsdb/create-document.md +++ b/docs/examples/documentsdb/create-document.md @@ -23,7 +23,8 @@ result: Document = documents_db.create_document( "age": 30, "isAdmin": False }, - permissions = [Permission.read(Role.any())] # optional + permissions = [Permission.read(Role.any())], # optional + transaction_id = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/documentsdb/create-documents.md b/docs/examples/documentsdb/create-documents.md index 661c32dd..2b15e560 100644 --- a/docs/examples/documentsdb/create-documents.md +++ b/docs/examples/documentsdb/create-documents.md @@ -13,7 +13,8 @@ documents_db = DocumentsDB(client) result: DocumentList = documents_db.create_documents( database_id = '', collection_id = '', - documents = [] + documents = [], + transaction_id = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/mongo/update-credentials.md b/docs/examples/mongo/update-credentials.md index e3dea54f..12d138c8 100644 --- a/docs/examples/mongo/update-credentials.md +++ b/docs/examples/mongo/update-credentials.md @@ -1,7 +1,7 @@ ```python from appwrite.client import Client from appwrite.services.mongo import Mongo -from appwrite.models import DedicatedDatabase +from appwrite.models import DedicatedDatabaseOperation client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -10,7 +10,7 @@ client.set_key('') # Your secret API key mongo = Mongo(client) -result: DedicatedDatabase = mongo.update_credentials( +result: DedicatedDatabaseOperation = mongo.update_credentials( database_id = '' ) diff --git a/docs/examples/mysql/update-credentials.md b/docs/examples/mysql/update-credentials.md index 6555afe7..e277a92d 100644 --- a/docs/examples/mysql/update-credentials.md +++ b/docs/examples/mysql/update-credentials.md @@ -1,7 +1,7 @@ ```python from appwrite.client import Client from appwrite.services.mysql import Mysql -from appwrite.models import DedicatedDatabase +from appwrite.models import DedicatedDatabaseOperation client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -10,7 +10,7 @@ client.set_key('') # Your secret API key mysql = Mysql(client) -result: DedicatedDatabase = mysql.update_credentials( +result: DedicatedDatabaseOperation = mysql.update_credentials( database_id = '' ) diff --git a/docs/examples/postgresql/update-credentials.md b/docs/examples/postgresql/update-credentials.md index b849a932..7f7b5990 100644 --- a/docs/examples/postgresql/update-credentials.md +++ b/docs/examples/postgresql/update-credentials.md @@ -1,7 +1,7 @@ ```python from appwrite.client import Client from appwrite.services.postgresql import Postgresql -from appwrite.models import DedicatedDatabase +from appwrite.models import DedicatedDatabaseOperation client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -10,7 +10,7 @@ client.set_key('') # Your secret API key postgresql = Postgresql(client) -result: DedicatedDatabase = postgresql.update_credentials( +result: DedicatedDatabaseOperation = postgresql.update_credentials( database_id = '' ) diff --git a/docs/examples/project/get-o-auth-2-provider.md b/docs/examples/project/get-o-auth-2-provider.md index 0e4ff352..e2e8f9e9 100644 --- a/docs/examples/project/get-o-auth-2-provider.md +++ b/docs/examples/project/get-o-auth-2-provider.md @@ -25,6 +25,8 @@ from appwrite.models import OAuth2Notion from appwrite.models import OAuth2Salesforce from appwrite.models import OAuth2Yahoo from appwrite.models import OAuth2HuggingFace +from appwrite.models import OAuth2Resend +from appwrite.models import OAuth2Cloudflare from appwrite.models import OAuth2Linkedin from appwrite.models import OAuth2Disqus from appwrite.models import OAuth2Amazon @@ -52,7 +54,7 @@ client.set_key('') # Your secret API key project = Project(client) -result: Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2HuggingFace, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft] = project.get_o_auth2_provider( +result: Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2HuggingFace, OAuth2Resend, OAuth2Cloudflare, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft] = project.get_o_auth2_provider( provider_id = ProjectOAuthProviderId.AMAZON ) diff --git a/docs/examples/project/update-o-auth-2-cloudflare.md b/docs/examples/project/update-o-auth-2-cloudflare.md new file mode 100644 index 00000000..1044a61b --- /dev/null +++ b/docs/examples/project/update-o-auth-2-cloudflare.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import OAuth2Cloudflare + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +project = Project(client) + +result: OAuth2Cloudflare = project.update_o_auth2_cloudflare( + client_id = '', # optional + client_secret = '', # optional + enabled = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/project/update-o-auth-2-resend.md b/docs/examples/project/update-o-auth-2-resend.md new file mode 100644 index 00000000..8ce17418 --- /dev/null +++ b/docs/examples/project/update-o-auth-2-resend.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import OAuth2Resend + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +project = Project(client) + +result: OAuth2Resend = project.update_o_auth2_resend( + client_id = '', # optional + client_secret = '', # optional + enabled = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/tablesdb/cutover-migration.md b/docs/examples/tablesdb/create-cutover.md similarity index 89% rename from docs/examples/tablesdb/cutover-migration.md rename to docs/examples/tablesdb/create-cutover.md index 1b793d63..a179bb19 100644 --- a/docs/examples/tablesdb/cutover-migration.md +++ b/docs/examples/tablesdb/create-cutover.md @@ -10,7 +10,7 @@ client.set_key('') # Your secret API key tables_db = TablesDB(client) -result: DatabaseMigration = tables_db.cutover_migration( +result: DatabaseMigration = tables_db.create_cutover( database_id = '', migration_id = '' ) diff --git a/docs/examples/vectorsdb/create-document.md b/docs/examples/vectorsdb/create-document.md index d032a991..d5675d86 100644 --- a/docs/examples/vectorsdb/create-document.md +++ b/docs/examples/vectorsdb/create-document.md @@ -27,7 +27,8 @@ result: Document = vectors_db.create_document( "key": "value" } }, - permissions = [Permission.read(Role.any())] # optional + permissions = [Permission.read(Role.any())], # optional + transaction_id = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/vectorsdb/create-documents.md b/docs/examples/vectorsdb/create-documents.md index 431aec82..b84eea6d 100644 --- a/docs/examples/vectorsdb/create-documents.md +++ b/docs/examples/vectorsdb/create-documents.md @@ -13,7 +13,8 @@ vectors_db = VectorsDB(client) result: DocumentList = vectors_db.create_documents( database_id = '', collection_id = '', - documents = [] + documents = [], + transaction_id = '' # optional ) print(result.model_dump()) diff --git a/pyproject.toml b/pyproject.toml index 17cd6a75..1f9a77a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "appwrite" -version = "24.0.0rc1" +version = "24.0.0" description = "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API" readme = "README.md" requires-python = ">=3.9" diff --git a/setup.py b/setup.py index 1d8e7ce3..1dc69c61 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name='appwrite', packages=setuptools.find_packages(), - version='24.0.0rc1', + version='24.0.0', license='BSD-3-Clause', description='Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API', long_description=long_description, @@ -18,7 +18,7 @@ maintainer='Appwrite Team', maintainer_email='team@appwrite.io', url='https://appwrite.io/support', - download_url='https://github.com/appwrite/sdk-for-python/archive/24.0.0rc1.tar.gz', + download_url='https://github.com/appwrite/sdk-for-python/archive/24.0.0.tar.gz', install_requires=[ 'requests', 'pydantic>=2,<3', diff --git a/test/services/test_documents_db.py b/test/services/test_documents_db.py index 06c50949..05ffaa0d 100644 --- a/test/services/test_documents_db.py +++ b/test/services/test_documents_db.py @@ -757,6 +757,7 @@ def test_create_failover(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", diff --git a/test/services/test_mongo.py b/test/services/test_mongo.py index 3e26ffc9..d66adcb2 100644 --- a/test/services/test_mongo.py +++ b/test/services/test_mongo.py @@ -47,6 +47,7 @@ def test_create(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -132,6 +133,7 @@ def test_get(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -194,6 +196,7 @@ def test_update(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -523,6 +526,7 @@ def test_create_branch(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -585,6 +589,7 @@ def test_delete_branch(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -636,50 +641,12 @@ def test_update_credentials(self, m): data = { "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", - "$updatedAt": "2020-10-15T06:38:00.000+00:00", - "projectId": "5e5ea5c16897e", - "name": "My Production Database", - "api": "postgresql", - "engine": "postgresql", - "version": "16", - "specification": "s-2vcpu-2gb", - "backend": "edge", - "hostname": "db-myproject-mydb.fra.appwrite.center", - "connectionPort": 5432.0, - "connectionUser": "appwrite_user", - "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", - "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", - "ssl": True, - "status": "ready", - "containerStatus": "active", - "lifecycleState": "active", - "idleTimeoutMinutes": 15.0, - "cpu": 2000.0, - "memory": 4096.0, - "storage": 100.0, - "storageClass": "ssd", - "storageMaxGb": 100.0, - "nodePool": "db-pool-4vcpu-8gb", - "replicas": 2.0, - "syncMode": "async", - "networkMaxConnections": 500.0, - "networkIdleTimeoutSeconds": 900.0, - "networkIPAllowlist": [], - "backupEnabled": True, - "pitr": True, - "pitrRetentionDays": 14.0, - "storageAutoscaling": True, - "storageAutoscalingThresholdPercent": 85.0, - "storageAutoscalingMaxGb": 500.0, - "maintenanceWindowDay": "sun", - "maintenanceWindowHourUtc": 3.0, - "metricsEnabled": True, - "sqlApiEnabled": True, - "sqlApiAllowedStatements": [], - "sqlApiMaxRows": 10000.0, - "sqlApiMaxBytes": 10485760.0, - "sqlApiTimeoutSeconds": 30.0, - "error": "", + "databaseId": "5e5ea5c16897e", + "type": "update", + "status": "completed", + "attempts": 1.0, + "errorCode": "Interrupted", + "errorMessage": "", } headers = {'Content-Type': 'application/json'} m.request( @@ -710,6 +677,7 @@ def test_create_failover(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -772,6 +740,7 @@ def test_update_maintenance(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -836,6 +805,7 @@ def test_create_migration(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -1063,6 +1033,7 @@ def test_create_upgrade(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", diff --git a/test/services/test_mysql.py b/test/services/test_mysql.py index 271b3999..74439293 100644 --- a/test/services/test_mysql.py +++ b/test/services/test_mysql.py @@ -47,6 +47,7 @@ def test_create(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -132,6 +133,7 @@ def test_get(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -194,6 +196,7 @@ def test_update(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -523,6 +526,7 @@ def test_create_branch(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -585,6 +589,7 @@ def test_delete_branch(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -636,50 +641,12 @@ def test_update_credentials(self, m): data = { "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", - "$updatedAt": "2020-10-15T06:38:00.000+00:00", - "projectId": "5e5ea5c16897e", - "name": "My Production Database", - "api": "postgresql", - "engine": "postgresql", - "version": "16", - "specification": "s-2vcpu-2gb", - "backend": "edge", - "hostname": "db-myproject-mydb.fra.appwrite.center", - "connectionPort": 5432.0, - "connectionUser": "appwrite_user", - "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", - "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", - "ssl": True, - "status": "ready", - "containerStatus": "active", - "lifecycleState": "active", - "idleTimeoutMinutes": 15.0, - "cpu": 2000.0, - "memory": 4096.0, - "storage": 100.0, - "storageClass": "ssd", - "storageMaxGb": 100.0, - "nodePool": "db-pool-4vcpu-8gb", - "replicas": 2.0, - "syncMode": "async", - "networkMaxConnections": 500.0, - "networkIdleTimeoutSeconds": 900.0, - "networkIPAllowlist": [], - "backupEnabled": True, - "pitr": True, - "pitrRetentionDays": 14.0, - "storageAutoscaling": True, - "storageAutoscalingThresholdPercent": 85.0, - "storageAutoscalingMaxGb": 500.0, - "maintenanceWindowDay": "sun", - "maintenanceWindowHourUtc": 3.0, - "metricsEnabled": True, - "sqlApiEnabled": True, - "sqlApiAllowedStatements": [], - "sqlApiMaxRows": 10000.0, - "sqlApiMaxBytes": 10485760.0, - "sqlApiTimeoutSeconds": 30.0, - "error": "", + "databaseId": "5e5ea5c16897e", + "type": "update", + "status": "completed", + "attempts": 1.0, + "errorCode": "Interrupted", + "errorMessage": "", } headers = {'Content-Type': 'application/json'} m.request( @@ -733,6 +700,7 @@ def test_create_failover(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -795,6 +763,7 @@ def test_update_maintenance(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -859,6 +828,7 @@ def test_create_migration(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -1138,6 +1108,7 @@ def test_create_upgrade(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", diff --git a/test/services/test_postgresql.py b/test/services/test_postgresql.py index b255d371..4e6beeef 100644 --- a/test/services/test_postgresql.py +++ b/test/services/test_postgresql.py @@ -47,6 +47,7 @@ def test_create(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -132,6 +133,7 @@ def test_get(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -194,6 +196,7 @@ def test_update(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -523,6 +526,7 @@ def test_create_branch(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -585,6 +589,7 @@ def test_delete_branch(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -636,50 +641,12 @@ def test_update_credentials(self, m): data = { "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", - "$updatedAt": "2020-10-15T06:38:00.000+00:00", - "projectId": "5e5ea5c16897e", - "name": "My Production Database", - "api": "postgresql", - "engine": "postgresql", - "version": "16", - "specification": "s-2vcpu-2gb", - "backend": "edge", - "hostname": "db-myproject-mydb.fra.appwrite.center", - "connectionPort": 5432.0, - "connectionUser": "appwrite_user", - "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", - "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", - "ssl": True, - "status": "ready", - "containerStatus": "active", - "lifecycleState": "active", - "idleTimeoutMinutes": 15.0, - "cpu": 2000.0, - "memory": 4096.0, - "storage": 100.0, - "storageClass": "ssd", - "storageMaxGb": 100.0, - "nodePool": "db-pool-4vcpu-8gb", - "replicas": 2.0, - "syncMode": "async", - "networkMaxConnections": 500.0, - "networkIdleTimeoutSeconds": 900.0, - "networkIPAllowlist": [], - "backupEnabled": True, - "pitr": True, - "pitrRetentionDays": 14.0, - "storageAutoscaling": True, - "storageAutoscalingThresholdPercent": 85.0, - "storageAutoscalingMaxGb": 500.0, - "maintenanceWindowDay": "sun", - "maintenanceWindowHourUtc": 3.0, - "metricsEnabled": True, - "sqlApiEnabled": True, - "sqlApiAllowedStatements": [], - "sqlApiMaxRows": 10000.0, - "sqlApiMaxBytes": 10485760.0, - "sqlApiTimeoutSeconds": 30.0, - "error": "", + "databaseId": "5e5ea5c16897e", + "type": "update", + "status": "completed", + "attempts": 1.0, + "errorCode": "Interrupted", + "errorMessage": "", } headers = {'Content-Type': 'application/json'} m.request( @@ -752,6 +719,7 @@ def test_create_extension(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -815,6 +783,7 @@ def test_delete_extension(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -878,6 +847,7 @@ def test_create_failover(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -940,6 +910,7 @@ def test_update_maintenance(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -1004,6 +975,7 @@ def test_create_migration(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -1283,6 +1255,7 @@ def test_create_upgrade(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", diff --git a/test/services/test_project.py b/test/services/test_project.py index 6ad83c58..09549bf2 100644 --- a/test/services/test_project.py +++ b/test/services/test_project.py @@ -583,6 +583,24 @@ def test_update_o_auth2_box(self, m): response = self.project.update_o_auth2_box() self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() + def test_update_o_auth2_cloudflare(self, m): + data = { + "$id": "github", + "enabled": True, + "clientId": "4b866000000000000000000000c9e4e2", + "clientSecret": "cfoc_5Q6YRl0000000000000000000000000000000000003d214f", + } + headers = {'Content-Type': 'application/json'} + m.request( + requests_mock.ANY, + requests_mock.ANY, + text=json.dumps(data), + headers=headers, + ) + response = self.project.update_o_auth2_cloudflare() + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_update_o_auth2_dailymotion(self, m): data = { @@ -992,6 +1010,24 @@ def test_update_o_auth2_podio(self, m): response = self.project.update_o_auth2_podio() self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() + def test_update_o_auth2_resend(self, m): + data = { + "$id": "github", + "enabled": True, + "clientId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", + "clientSecret": "9c1e4b00000000000000000000000000000000000000000000000000a72d5f4", + } + headers = {'Content-Type': 'application/json'} + m.request( + requests_mock.ANY, + requests_mock.ANY, + text=json.dumps(data), + headers=headers, + ) + response = self.project.update_o_auth2_resend() + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_update_o_auth2_salesforce(self, m): data = { diff --git a/test/services/test_tables_db.py b/test/services/test_tables_db.py index 51f40fc4..8c5cfa00 100644 --- a/test/services/test_tables_db.py +++ b/test/services/test_tables_db.py @@ -268,6 +268,7 @@ def test_create_failover(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready", @@ -416,7 +417,7 @@ def test_delete_migration(self, m): self.assertEqual(response, data) @requests_mock.Mocker() - def test_cutover_migration(self, m): + def test_create_cutover(self, m): data = { "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", @@ -443,7 +444,7 @@ def test_cutover_migration(self, m): text=json.dumps(data), headers=headers, ) - response = self.tables_db.cutover_migration( + response = self.tables_db.create_cutover( '', '', ) diff --git a/test/services/test_vectors_db.py b/test/services/test_vectors_db.py index 4529586d..17cc1f84 100644 --- a/test/services/test_vectors_db.py +++ b/test/services/test_vectors_db.py @@ -726,6 +726,7 @@ def test_create_failover(self, m): "connectionPort": 5432.0, "connectionUser": "appwrite_user", "connectionPassword": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", + "credentialGeneration": 1.0, "connectionString": "postgresql:\/\/user:pass@db-myproject-mydb.fra.appwrite.center:5432\/postgres?sslmode=require", "ssl": True, "status": "ready",