From 5bd34b8d6f7d1736338bafbbb948565934620e72 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 13 Jul 2026 10:47:33 +0530 Subject: [PATCH 1/2] chore: update Python SDK to 22.0.0 --- CHANGELOG.md | 24 + appwrite/client.py | 13 +- appwrite/encoders/value_class_encoder.py | 26 +- appwrite/enums/billing_plan_group.py | 6 + appwrite/enums/database_status.py | 6 + appwrite/enums/health_antivirus_status.py | 6 - appwrite/enums/health_check_status.py | 5 - appwrite/enums/health_queue_name.py | 16 - appwrite/enums/o_auth2_oidc_prompt.py | 7 + appwrite/enums/o_auth_provider.py | 1 + appwrite/enums/organization_key_scopes.py | 4 + appwrite/enums/project_key_scopes.py | 8 +- appwrite/enums/project_o_auth2_oidc_prompt.py | 7 + appwrite/enums/project_o_auth_provider_id.py | 1 + appwrite/models/__init__.py | 52 +- appwrite/models/activity_event.py | 6 - appwrite/models/additional_resource.py | 30 + appwrite/models/app.py | 3 + appwrite/models/billing_plan.py | 223 +++++ appwrite/models/billing_plan_addon.py | 19 + appwrite/models/billing_plan_addon_details.py | 36 + .../billing_plan_dedicated_database_limits.py | 69 ++ appwrite/models/billing_plan_limits.py | 18 + .../models/billing_plan_supported_addons.py | 21 + appwrite/models/block.py | 3 + appwrite/models/database.py | 4 + appwrite/models/document.py | 11 + appwrite/models/health_antivirus.py | 19 - appwrite/models/health_certificate.py | 30 - appwrite/models/health_status.py | 22 - appwrite/models/health_status_list.py | 19 - appwrite/models/health_time.py | 21 - appwrite/models/locale.py | 33 + appwrite/models/log.py | 2 +- appwrite/models/o_auth2_appwrite.py | 24 + appwrite/models/o_auth2_oidc.py | 7 + appwrite/models/o_auth2_provider_list.py | 5 +- appwrite/models/oauth2_grant.py | 3 + ...health_queue.py => oauth2_organization.py} | 10 +- appwrite/models/oauth2_organization_list.py | 19 + appwrite/models/oauth2_par.py | 18 + appwrite/models/oauth2_project.py | 21 + appwrite/models/oauth2_project_list.py | 19 + appwrite/models/organization.py | 132 +++ appwrite/models/preferences.py | 11 + appwrite/models/program.py | 39 + appwrite/models/project.py | 6 + appwrite/models/row.py | 11 + appwrite/models/usage_billing_plan.py | 46 + appwrite/models/usage_data_point.py | 60 -- appwrite/models/usage_event_list.py | 19 - appwrite/models/usage_gauge_list.py | 19 - appwrite/models/usage_metric.py | 19 - appwrite/query.py | 12 + appwrite/services/account.py | 2 +- appwrite/services/apps.py | 47 + appwrite/services/backups.py | 10 +- appwrite/services/functions.py | 25 +- appwrite/services/health.py | 882 ------------------ appwrite/services/messaging.py | 197 ---- appwrite/services/oauth2.py | 290 +++++- appwrite/services/organization.py | 357 ++++++- appwrite/services/project.py | 68 +- appwrite/services/sites.py | 14 +- appwrite/services/tables_db.py | 10 +- appwrite/services/usage.py | 202 ---- appwrite/services/users.py | 2 +- .../update-labels.md} | 11 +- docs/examples/backups/create-restoration.md | 3 +- .../functions/get-deployment-download.md | 3 +- .../examples/functions/list-specifications.md | 4 +- docs/examples/health/get-antivirus.md | 16 - docs/examples/health/get-certificate.md | 18 - docs/examples/health/get-db.md | 16 - docs/examples/health/get-failed-jobs.md | 20 - docs/examples/health/get-pub-sub.md | 16 - .../examples/health/get-queue-certificates.md | 18 - docs/examples/health/get-queue-databases.md | 19 - docs/examples/health/get-queue-deletes.md | 18 - docs/examples/health/get-queue-functions.md | 18 - docs/examples/health/get-queue-logs.md | 18 - docs/examples/health/get-queue-mails.md | 18 - docs/examples/health/get-queue-messaging.md | 18 - docs/examples/health/get-queue-migrations.md | 18 - .../health/get-queue-stats-resources.md | 18 - docs/examples/health/get-queue-usage.md | 18 - docs/examples/health/get-queue-webhooks.md | 18 - docs/examples/health/get-storage-local.md | 16 - docs/examples/health/get-storage.md | 16 - docs/examples/messaging/list-provider-logs.md | 20 - .../messaging/list-subscriber-logs.md | 20 - docs/examples/messaging/list-topic-logs.md | 20 - docs/examples/oauth2/approve.md | 3 +- docs/examples/oauth2/authorize.md | 13 +- .../oauth2/create-device-authorization.md | 4 +- docs/examples/oauth2/create-par.md | 30 + docs/examples/oauth2/create-token.md | 4 +- docs/examples/oauth2/list-organizations.md | 20 + docs/examples/oauth2/list-projects.md | 20 + .../organization/create-membership.md | 23 + .../delete-membership.md} | 11 +- .../get-time.md => organization/delete.md} | 9 +- .../get-membership.md} | 10 +- .../get-cache.md => organization/get.md} | 8 +- .../list-memberships.md} | 10 +- .../update-membership.md} | 12 +- .../update.md} | 10 +- .../project/update-o-auth-2-appwrite.md | 20 + docs/examples/project/update-o-auth-2-oidc.md | 3 + .../project/update-o-auth-2-server.md | 3 +- docs/examples/sites/list-specifications.md | 4 +- docs/examples/tablesdb/create.md | 2 +- docs/examples/usage/list-events.md | 28 - docs/examples/usage/list-gauges.md | 28 - pyproject.toml | 2 +- requirements.txt | 2 +- setup.py | 4 +- test/services/test_activities.py | 4 +- test/services/test_apps.py | 42 + test/services/test_backups.py | 4 +- test/services/test_health.py | 361 ------- test/services/test_messaging.py | 60 -- test/services/test_oauth2.py | 51 +- test/services/test_organization.py | 576 ++++++++++++ test/services/test_project.py | 39 +- test/services/test_usage.py | 45 - 126 files changed, 2633 insertions(+), 2607 deletions(-) create mode 100644 appwrite/enums/billing_plan_group.py create mode 100644 appwrite/enums/database_status.py delete mode 100644 appwrite/enums/health_antivirus_status.py delete mode 100644 appwrite/enums/health_check_status.py delete mode 100644 appwrite/enums/health_queue_name.py create mode 100644 appwrite/enums/o_auth2_oidc_prompt.py create mode 100644 appwrite/enums/project_o_auth2_oidc_prompt.py create mode 100644 appwrite/models/additional_resource.py create mode 100644 appwrite/models/billing_plan.py create mode 100644 appwrite/models/billing_plan_addon.py create mode 100644 appwrite/models/billing_plan_addon_details.py create mode 100644 appwrite/models/billing_plan_dedicated_database_limits.py create mode 100644 appwrite/models/billing_plan_limits.py create mode 100644 appwrite/models/billing_plan_supported_addons.py delete mode 100644 appwrite/models/health_antivirus.py delete mode 100644 appwrite/models/health_certificate.py delete mode 100644 appwrite/models/health_status.py delete mode 100644 appwrite/models/health_status_list.py delete mode 100644 appwrite/models/health_time.py create mode 100644 appwrite/models/o_auth2_appwrite.py rename appwrite/models/{health_queue.py => oauth2_organization.py} (55%) create mode 100644 appwrite/models/oauth2_organization_list.py create mode 100644 appwrite/models/oauth2_par.py create mode 100644 appwrite/models/oauth2_project.py create mode 100644 appwrite/models/oauth2_project_list.py create mode 100644 appwrite/models/organization.py create mode 100644 appwrite/models/program.py create mode 100644 appwrite/models/usage_billing_plan.py delete mode 100644 appwrite/models/usage_data_point.py delete mode 100644 appwrite/models/usage_event_list.py delete mode 100644 appwrite/models/usage_gauge_list.py delete mode 100644 appwrite/models/usage_metric.py delete mode 100644 appwrite/services/health.py delete mode 100644 appwrite/services/usage.py rename docs/examples/{health/get-audits-db.md => apps/update-labels.md} (63%) delete mode 100644 docs/examples/health/get-antivirus.md delete mode 100644 docs/examples/health/get-certificate.md delete mode 100644 docs/examples/health/get-db.md delete mode 100644 docs/examples/health/get-failed-jobs.md delete mode 100644 docs/examples/health/get-pub-sub.md delete mode 100644 docs/examples/health/get-queue-certificates.md delete mode 100644 docs/examples/health/get-queue-databases.md delete mode 100644 docs/examples/health/get-queue-deletes.md delete mode 100644 docs/examples/health/get-queue-functions.md delete mode 100644 docs/examples/health/get-queue-logs.md delete mode 100644 docs/examples/health/get-queue-mails.md delete mode 100644 docs/examples/health/get-queue-messaging.md delete mode 100644 docs/examples/health/get-queue-migrations.md delete mode 100644 docs/examples/health/get-queue-stats-resources.md delete mode 100644 docs/examples/health/get-queue-usage.md delete mode 100644 docs/examples/health/get-queue-webhooks.md delete mode 100644 docs/examples/health/get-storage-local.md delete mode 100644 docs/examples/health/get-storage.md delete mode 100644 docs/examples/messaging/list-provider-logs.md delete mode 100644 docs/examples/messaging/list-subscriber-logs.md delete mode 100644 docs/examples/messaging/list-topic-logs.md create mode 100644 docs/examples/oauth2/create-par.md create mode 100644 docs/examples/oauth2/list-organizations.md create mode 100644 docs/examples/oauth2/list-projects.md create mode 100644 docs/examples/organization/create-membership.md rename docs/examples/{health/get.md => organization/delete-membership.md} (60%) rename docs/examples/{health/get-time.md => organization/delete.md} (60%) rename docs/examples/{health/get-queue-audits.md => organization/get-membership.md} (57%) rename docs/examples/{health/get-cache.md => organization/get.md} (59%) rename docs/examples/{messaging/list-message-logs.md => organization/list-memberships.md} (60%) rename docs/examples/{health/get-console-pausing.md => organization/update-membership.md} (55%) rename docs/examples/{health/get-queue-builds.md => organization/update.md} (56%) create mode 100644 docs/examples/project/update-o-auth-2-appwrite.md delete mode 100644 docs/examples/usage/list-events.md delete mode 100644 docs/examples/usage/list-gauges.md delete mode 100644 test/services/test_health.py delete mode 100644 test/services/test_usage.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e7a93d..e66e10b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Change Log +## 22.0.0 + +* Breaking: removed `Health` service and all health models and enums +* Breaking: removed `Usage` service and `UsageMetric`, `UsageDataPoint`, `UsageEventList`, `UsageGaugeList` models +* Breaking: removed messaging `list_message_logs`, `list_provider_logs`, `list_subscriber_logs`, `list_topic_logs` methods +* Breaking: renamed `tables_db.create` parameter `dedicated_database_id` to `specification` +* Breaking: removed `countryCode` and `countryName` from `ActivityEvent` model +* Added: `Client.set_bearer` for OAuth access token authentication +* Added: `organization` service `get`, `update`, `delete` and membership CRUD methods +* Added: `oauth2` service `create_par`, `list_organizations`, `list_projects` methods +* Added: `resource`, `audience`, `request_uri` OAuth2 parameters; `scope` on `approve` +* Added: `appwrite` OAuth provider, `OAuth2Appwrite` model, `update_o_auth2_appwrite` method +* Added: `Query.vector_dot`, `Query.vector_cosine`, `Query.vector_euclidean` methods +* Added: `apps.update_labels` method and `labels` field on `App` model +* Added: `new_specification` parameter to `backups.create_restoration` +* Added: `type` parameter to `functions` and `sites` `list_specifications` +* Added: `token` parameter to `functions.get_deployment_download` +* Added: `prompt` and `max_age` parameters to `update_o_auth2_oidc`; `default_scopes` to `update_o_auth2_server` +* Added: `BillingPlan`, `Organization`, `Program`, `Oauth2PAR`, `DatabaseStatus`, `BillingPlanGroup` models and enums +* Added: `status` on `Database`, `mode` on `Block`, `onboarding` on `Project`, geolocation fields on `Locale` +* Added: organization, `project.oauth2`, and `stages` key scope enum values +* Fixed: booleans now serialized as `true`/`false` in flattened query parameters +* Fixed: `model_dump` on `Document`, `Row`, `Preferences` now includes dynamic `data` + ## 21.0.0 * Added: `apps` service for managing apps and app secrets diff --git a/appwrite/client.py b/appwrite/client.py index baafb0e7..83f61a8f 100644 --- a/appwrite/client.py +++ b/appwrite/client.py @@ -17,11 +17,11 @@ def __init__(self): self._endpoint = 'https://cloud.appwrite.io/v1' self._global_headers = { 'content-type': '', - 'user-agent' : f'AppwritePythonSDK/21.0.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})', + 'user-agent' : f'AppwritePythonSDK/22.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': '21.0.0', + 'x-sdk-version': '22.0.0', 'X-Appwrite-Response-Format' : '1.9.5', } self._config = {} @@ -67,6 +67,13 @@ def set_jwt(self, value): self._config['jwt'] = value return self + def set_bearer(self, value): + """The OAuth access token to authenticate with""" + + self._global_headers['authorization'] = value + self._config['bearer'] = value + return self + def set_locale(self, value): self._global_headers['x-appwrite-locale'] = value self._config['locale'] = value @@ -341,6 +348,8 @@ def flatten(self, data, prefix='', stringify=False): if isinstance(value, list) or isinstance(value, dict): output = {**output, **self.flatten(value, finalKey, stringify)} + elif isinstance(value, bool): + output[finalKey] = 'true' if value else 'false' else: if stringify: output[finalKey] = str(value) diff --git a/appwrite/encoders/value_class_encoder.py b/appwrite/encoders/value_class_encoder.py index 5a4914b1..b725fb9b 100644 --- a/appwrite/encoders/value_class_encoder.py +++ b/appwrite/encoders/value_class_encoder.py @@ -21,13 +21,13 @@ from ..enums.vcs_reference_type import VCSReferenceType from ..enums.deployment_download_type import DeploymentDownloadType from ..enums.execution_method import ExecutionMethod -from ..enums.health_queue_name import HealthQueueName from ..enums.message_priority import MessagePriority from ..enums.smtp_encryption import SmtpEncryption from ..enums.organization_key_scopes import OrganizationKeyScopes from ..enums.region import Region from ..enums.project_auth_method_id import ProjectAuthMethodId from ..enums.project_o_auth2_google_prompt import ProjectOAuth2GooglePrompt +from ..enums.project_o_auth2_oidc_prompt import ProjectOAuth2OidcPrompt from ..enums.project_o_auth_provider_id import ProjectOAuthProviderId from ..enums.project_policy_id import ProjectPolicyId from ..enums.project_protocol_id import ProjectProtocolId @@ -46,6 +46,7 @@ from ..enums.password_hash import PasswordHash from ..enums.messaging_provider_type import MessagingProviderType from ..enums.database_type import DatabaseType +from ..enums.database_status import DatabaseStatus from ..enums.attribute_status import AttributeStatus from ..enums.column_status import ColumnStatus from ..enums.index_status import IndexStatus @@ -53,12 +54,12 @@ from ..enums.execution_trigger import ExecutionTrigger from ..enums.execution_status import ExecutionStatus from ..enums.o_auth2_google_prompt import OAuth2GooglePrompt +from ..enums.o_auth2_oidc_prompt import OAuth2OidcPrompt from ..enums.platform_type import PlatformType -from ..enums.health_antivirus_status import HealthAntivirusStatus -from ..enums.health_check_status import HealthCheckStatus from ..enums.proxy_rule_deployment_resource_type import ProxyRuleDeploymentResourceType from ..enums.proxy_rule_status import ProxyRuleStatus from ..enums.message_status import MessageStatus +from ..enums.billing_plan_group import BillingPlanGroup class ValueClassEncoder(json.JSONEncoder): def default(self, o): @@ -128,9 +129,6 @@ def default(self, o): if isinstance(o, ExecutionMethod): return o.value - if isinstance(o, HealthQueueName): - return o.value - if isinstance(o, MessagePriority): return o.value @@ -149,6 +147,9 @@ def default(self, o): if isinstance(o, ProjectOAuth2GooglePrompt): return o.value + if isinstance(o, ProjectOAuth2OidcPrompt): + return o.value + if isinstance(o, ProjectOAuthProviderId): return o.value @@ -203,6 +204,9 @@ def default(self, o): if isinstance(o, DatabaseType): return o.value + if isinstance(o, DatabaseStatus): + return o.value + if isinstance(o, AttributeStatus): return o.value @@ -224,13 +228,10 @@ def default(self, o): if isinstance(o, OAuth2GooglePrompt): return o.value - if isinstance(o, PlatformType): - return o.value - - if isinstance(o, HealthAntivirusStatus): + if isinstance(o, OAuth2OidcPrompt): return o.value - if isinstance(o, HealthCheckStatus): + if isinstance(o, PlatformType): return o.value if isinstance(o, ProxyRuleDeploymentResourceType): @@ -242,4 +243,7 @@ def default(self, o): if isinstance(o, MessageStatus): return o.value + if isinstance(o, BillingPlanGroup): + return o.value + return super().default(o) diff --git a/appwrite/enums/billing_plan_group.py b/appwrite/enums/billing_plan_group.py new file mode 100644 index 00000000..5a659196 --- /dev/null +++ b/appwrite/enums/billing_plan_group.py @@ -0,0 +1,6 @@ +from enum import Enum + +class BillingPlanGroup(Enum): + STARTER = "starter" + PRO = "pro" + SCALE = "scale" diff --git a/appwrite/enums/database_status.py b/appwrite/enums/database_status.py new file mode 100644 index 00000000..7c5f888f --- /dev/null +++ b/appwrite/enums/database_status.py @@ -0,0 +1,6 @@ +from enum import Enum + +class DatabaseStatus(Enum): + PROVISIONING = "provisioning" + READY = "ready" + FAILED = "failed" diff --git a/appwrite/enums/health_antivirus_status.py b/appwrite/enums/health_antivirus_status.py deleted file mode 100644 index 38c1684b..00000000 --- a/appwrite/enums/health_antivirus_status.py +++ /dev/null @@ -1,6 +0,0 @@ -from enum import Enum - -class HealthAntivirusStatus(Enum): - DISABLED = "disabled" - OFFLINE = "offline" - ONLINE = "online" diff --git a/appwrite/enums/health_check_status.py b/appwrite/enums/health_check_status.py deleted file mode 100644 index 2cc9c113..00000000 --- a/appwrite/enums/health_check_status.py +++ /dev/null @@ -1,5 +0,0 @@ -from enum import Enum - -class HealthCheckStatus(Enum): - PASS = "pass" - FAIL = "fail" diff --git a/appwrite/enums/health_queue_name.py b/appwrite/enums/health_queue_name.py deleted file mode 100644 index a04ab15f..00000000 --- a/appwrite/enums/health_queue_name.py +++ /dev/null @@ -1,16 +0,0 @@ -from enum import Enum - -class HealthQueueName(Enum): - V1_DATABASE = "v1-database" - V1_DELETES = "v1-deletes" - V1_AUDITS = "v1-audits" - V1_MAILS = "v1-mails" - V1_FUNCTIONS = "v1-functions" - V1_STATS_RESOURCES = "v1-stats-resources" - V1_STATS_USAGE = "v1-stats-usage" - V1_WEBHOOKS = "v1-webhooks" - V1_CERTIFICATES = "v1-certificates" - V1_BUILDS = "v1-builds" - V1_SCREENSHOTS = "v1-screenshots" - V1_MESSAGING = "v1-messaging" - V1_MIGRATIONS = "v1-migrations" diff --git a/appwrite/enums/o_auth2_oidc_prompt.py b/appwrite/enums/o_auth2_oidc_prompt.py new file mode 100644 index 00000000..0c21c203 --- /dev/null +++ b/appwrite/enums/o_auth2_oidc_prompt.py @@ -0,0 +1,7 @@ +from enum import Enum + +class OAuth2OidcPrompt(Enum): + NONE = "none" + LOGIN = "login" + CONSENT = "consent" + SELECT_ACCOUNT = "select_account" diff --git a/appwrite/enums/o_auth_provider.py b/appwrite/enums/o_auth_provider.py index 18b69a49..e0aa4ea5 100644 --- a/appwrite/enums/o_auth_provider.py +++ b/appwrite/enums/o_auth_provider.py @@ -3,6 +3,7 @@ class OAuthProvider(Enum): AMAZON = "amazon" APPLE = "apple" + APPWRITE = "appwrite" AUTH0 = "auth0" AUTHENTIK = "authentik" AUTODESK = "autodesk" diff --git a/appwrite/enums/organization_key_scopes.py b/appwrite/enums/organization_key_scopes.py index aa788f1a..ab4e4526 100644 --- a/appwrite/enums/organization_key_scopes.py +++ b/appwrite/enums/organization_key_scopes.py @@ -7,6 +7,10 @@ class OrganizationKeyScopes(Enum): DEVKEYS_WRITE = "devKeys.write" ORGANIZATION_KEYS_READ = "organization.keys.read" ORGANIZATION_KEYS_WRITE = "organization.keys.write" + ORGANIZATION_MEMBERSHIPS_READ = "organization.memberships.read" + ORGANIZATION_MEMBERSHIPS_WRITE = "organization.memberships.write" + ORGANIZATION_READ = "organization.read" + ORGANIZATION_WRITE = "organization.write" DOMAINS_READ = "domains.read" DOMAINS_WRITE = "domains.write" KEYS_READ = "keys.read" diff --git a/appwrite/enums/project_key_scopes.py b/appwrite/enums/project_key_scopes.py index a0356058..10099119 100644 --- a/appwrite/enums/project_key_scopes.py +++ b/appwrite/enums/project_key_scopes.py @@ -13,10 +13,12 @@ class ProjectKeyScopes(Enum): POLICIES_WRITE = "policies.write" PROJECT_POLICIES_READ = "project.policies.read" PROJECT_POLICIES_WRITE = "project.policies.write" + PROJECT_OAUTH2_READ = "project.oauth2.read" + PROJECT_OAUTH2_WRITE = "project.oauth2.write" TEMPLATES_READ = "templates.read" TEMPLATES_WRITE = "templates.write" - OAUTH2_READ = "oauth2.read" - OAUTH2_WRITE = "oauth2.write" + STAGES_READ = "stages.read" + STAGES_WRITE = "stages.write" USERS_READ = "users.read" USERS_WRITE = "users.write" SESSIONS_READ = "sessions.read" @@ -97,4 +99,6 @@ class ProjectKeyScopes(Enum): EVENTS_READ = "events.read" APPS_READ = "apps.read" APPS_WRITE = "apps.write" + OAUTH2_READ = "oauth2.read" + OAUTH2_WRITE = "oauth2.write" USAGE_READ = "usage.read" diff --git a/appwrite/enums/project_o_auth2_oidc_prompt.py b/appwrite/enums/project_o_auth2_oidc_prompt.py new file mode 100644 index 00000000..43c64713 --- /dev/null +++ b/appwrite/enums/project_o_auth2_oidc_prompt.py @@ -0,0 +1,7 @@ +from enum import Enum + +class ProjectOAuth2OidcPrompt(Enum): + NONE = "none" + LOGIN = "login" + CONSENT = "consent" + SELECT_ACCOUNT = "select_account" diff --git a/appwrite/enums/project_o_auth_provider_id.py b/appwrite/enums/project_o_auth_provider_id.py index 71ba1213..c61f6002 100644 --- a/appwrite/enums/project_o_auth_provider_id.py +++ b/appwrite/enums/project_o_auth_provider_id.py @@ -3,6 +3,7 @@ class ProjectOAuthProviderId(Enum): AMAZON = "amazon" APPLE = "apple" + APPWRITE = "appwrite" AUTH0 = "auth0" AUTHENTIK = "authentik" AUTODESK = "autodesk" diff --git a/appwrite/models/__init__.py b/appwrite/models/__init__.py index e8267dd9..8e75504a 100644 --- a/appwrite/models/__init__.py +++ b/appwrite/models/__init__.py @@ -34,7 +34,6 @@ from .mock_number_list import MockNumberList from .policy_list import PolicyList from .email_template_list import EmailTemplateList -from .health_status_list import HealthStatusList from .proxy_rule_list import ProxyRuleList from .locale_code_list import LocaleCodeList from .provider_list import ProviderList @@ -160,6 +159,7 @@ from .o_auth2_tradeshift import OAuth2Tradeshift from .o_auth2_paypal import OAuth2Paypal from .o_auth2_gitlab import OAuth2Gitlab +from .o_auth2_appwrite import OAuth2Appwrite from .o_auth2_authentik import OAuth2Authentik from .o_auth2_auth0 import OAuth2Auth0 from .o_auth2_fusion_auth import OAuth2FusionAuth @@ -192,11 +192,6 @@ from .language import Language from .currency import Currency from .phone import Phone -from .health_antivirus import HealthAntivirus -from .health_queue import HealthQueue -from .health_status import HealthStatus -from .health_certificate import HealthCertificate -from .health_time import HealthTime from .headers import Headers from .specification import Specification from .proxy_rule import ProxyRule @@ -215,19 +210,25 @@ from .insight_cta import InsightCTA from .report import Report from .activity_event import ActivityEvent +from .additional_resource import AdditionalResource from .backup_archive import BackupArchive from .billing_limits import BillingLimits +from .billing_plan import BillingPlan +from .billing_plan_addon import BillingPlanAddon +from .billing_plan_addon_details import BillingPlanAddonDetails +from .billing_plan_limits import BillingPlanLimits +from .billing_plan_dedicated_database_limits import BillingPlanDedicatedDatabaseLimits +from .billing_plan_supported_addons import BillingPlanSupportedAddons from .block import Block +from .organization import Organization from .backup_policy import BackupPolicy from .policy_deny_aliased_email import PolicyDenyAliasedEmail from .policy_deny_disposable_email import PolicyDenyDisposableEmail from .policy_deny_free_email import PolicyDenyFreeEmail from .policy_deny_corporate_email import PolicyDenyCorporateEmail +from .program import Program from .backup_restoration import BackupRestoration -from .usage_data_point import UsageDataPoint -from .usage_event_list import UsageEventList -from .usage_gauge_list import UsageGaugeList -from .usage_metric import UsageMetric +from .usage_billing_plan import UsageBillingPlan from .app import App from .app_secret import AppSecret from .app_secret_plaintext import AppSecretPlaintext @@ -236,7 +237,12 @@ from .oauth2_reject import Oauth2Reject from .oauth2_grant import Oauth2Grant from .oauth2_device_authorization import Oauth2DeviceAuthorization +from .oauth2_par import Oauth2PAR from .oauth2_token import Oauth2Token +from .oauth2_project import Oauth2Project +from .oauth2_organization import Oauth2Organization +from .oauth2_project_list import Oauth2ProjectList +from .oauth2_organization_list import Oauth2OrganizationList from .activity_event_list import ActivityEventList from .backup_archive_list import BackupArchiveList from .backup_policy_list import BackupPolicyList @@ -281,7 +287,6 @@ 'MockNumberList', 'PolicyList', 'EmailTemplateList', - 'HealthStatusList', 'ProxyRuleList', 'LocaleCodeList', 'ProviderList', @@ -407,6 +412,7 @@ 'OAuth2Tradeshift', 'OAuth2Paypal', 'OAuth2Gitlab', + 'OAuth2Appwrite', 'OAuth2Authentik', 'OAuth2Auth0', 'OAuth2FusionAuth', @@ -439,11 +445,6 @@ 'Language', 'Currency', 'Phone', - 'HealthAntivirus', - 'HealthQueue', - 'HealthStatus', - 'HealthCertificate', - 'HealthTime', 'Headers', 'Specification', 'ProxyRule', @@ -462,19 +463,25 @@ 'InsightCTA', 'Report', 'ActivityEvent', + 'AdditionalResource', 'BackupArchive', 'BillingLimits', + 'BillingPlan', + 'BillingPlanAddon', + 'BillingPlanAddonDetails', + 'BillingPlanLimits', + 'BillingPlanDedicatedDatabaseLimits', + 'BillingPlanSupportedAddons', 'Block', + 'Organization', 'BackupPolicy', 'PolicyDenyAliasedEmail', 'PolicyDenyDisposableEmail', 'PolicyDenyFreeEmail', 'PolicyDenyCorporateEmail', + 'Program', 'BackupRestoration', - 'UsageDataPoint', - 'UsageEventList', - 'UsageGaugeList', - 'UsageMetric', + 'UsageBillingPlan', 'App', 'AppSecret', 'AppSecretPlaintext', @@ -483,7 +490,12 @@ 'Oauth2Reject', 'Oauth2Grant', 'Oauth2DeviceAuthorization', + 'Oauth2PAR', 'Oauth2Token', + 'Oauth2Project', + 'Oauth2Organization', + 'Oauth2ProjectList', + 'Oauth2OrganizationList', 'ActivityEventList', 'BackupArchiveList', 'BackupPolicyList', diff --git a/appwrite/models/activity_event.py b/appwrite/models/activity_event.py index 9e2b6313..11265c1d 100644 --- a/appwrite/models/activity_event.py +++ b/appwrite/models/activity_event.py @@ -45,10 +45,6 @@ class ActivityEvent(AppwriteModel): Team ID. hostname : str Hostname. - countrycode : str - Country two-character ISO 3166-1 alpha code. - countryname : str - Country name. """ id: str = Field(..., alias='$id') actortype: str = Field(..., alias='actorType') @@ -68,5 +64,3 @@ class ActivityEvent(AppwriteModel): projectid: str = Field(..., alias='projectId') teamid: str = Field(..., alias='teamId') hostname: str = Field(..., alias='hostname') - countrycode: str = Field(..., alias='countryCode') - countryname: str = Field(..., alias='countryName') diff --git a/appwrite/models/additional_resource.py b/appwrite/models/additional_resource.py new file mode 100644 index 00000000..63e01170 --- /dev/null +++ b/appwrite/models/additional_resource.py @@ -0,0 +1,30 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class AdditionalResource(AppwriteModel): + """ + AdditionalResource + + Attributes + ---------- + name : str + Resource name + unit : str + Resource unit + currency : str + Price currency + price : float + Price + value : float + Resource value + invoicedesc : str + Description on invoice + """ + name: str = Field(..., alias='name') + unit: str = Field(..., alias='unit') + currency: str = Field(..., alias='currency') + price: float = Field(..., alias='price') + value: float = Field(..., alias='value') + invoicedesc: str = Field(..., alias='invoiceDesc') diff --git a/appwrite/models/app.py b/appwrite/models/app.py index 189910d2..f570a66c 100644 --- a/appwrite/models/app.py +++ b/appwrite/models/app.py @@ -34,6 +34,8 @@ class App(AppwriteModel): Application tagline shown to users during OAuth2 consent. tags : List[Any] Application tags shown to users during OAuth2 consent. + labels : List[Any] + Application labels. Read-only for clients; only a server SDK using a project API key can update them. images : List[Any] Application image URLs shown to users during OAuth2 consent. supporturl : str @@ -69,6 +71,7 @@ class App(AppwriteModel): contacts: List[Any] = Field(..., alias='contacts') tagline: str = Field(..., alias='tagline') tags: List[Any] = Field(..., alias='tags') + labels: List[Any] = Field(..., alias='labels') images: List[Any] = Field(..., alias='images') supporturl: str = Field(..., alias='supportUrl') datadeletionurl: str = Field(..., alias='dataDeletionUrl') diff --git a/appwrite/models/billing_plan.py b/appwrite/models/billing_plan.py new file mode 100644 index 00000000..64db521b --- /dev/null +++ b/appwrite/models/billing_plan.py @@ -0,0 +1,223 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .usage_billing_plan import UsageBillingPlan +from .billing_plan_addon import BillingPlanAddon +from .billing_plan_supported_addons import BillingPlanSupportedAddons +from .billing_plan_limits import BillingPlanLimits +from ..enums.billing_plan_group import BillingPlanGroup +from .program import Program +from .billing_plan_dedicated_database_limits import BillingPlanDedicatedDatabaseLimits + +class BillingPlan(AppwriteModel): + """ + billingPlan + + Attributes + ---------- + id : str + Plan ID. + name : str + Plan name + desc : str + Plan description + order : float + Plan order + price : float + Price + trial : float + Trial days + bandwidth : float + Bandwidth + storage : float + Storage + imagetransformations : float + Image Transformations + screenshotsgenerated : float + Screenshots generated + members : float + Members + webhooks : float + Webhooks + projects : float + Projects + platforms : float + Platforms + users : float + Users + teams : float + Teams + databases : float + Databases + databasesreads : float + Database reads per month + databaseswrites : float + Database writes per month + databasesbatchsize : float + Database batch size limit + buckets : float + Buckets + filesize : float + File size + functions : float + Functions + sites : float + Sites + executions : float + Function executions + executionsretentioncount : float + Rolling max executions retained per function/site + gbhours : float + GB hours for functions + realtime : float + Realtime connections + realtimemessages : float + Realtime messages + messages : float + Messages per month + topics : float + Topics for messaging + authphone : float + SMS authentications per month + domains : float + Custom domains + activitylogs : float + Activity log days + usagelogs : float + Usage history days + usagelogsintervals : Optional[List[Any]] + Usage log time intervals allowed for this plan (e.g. 15m, 1h, 1d). + projectinactivitydays : float + Number of days of console inactivity before a project is paused. 0 means pausing is disabled. + alertlimit : float + Alert threshold percentage + usage : UsageBillingPlan + Additional resources + addons : BillingPlanAddon + Addons + budgetcapenabled : bool + Budget cap enabled or disabled. + customsmtp : bool + Custom SMTP + emailbranding : bool + Appwrite branding in email + requirespaymentmethod : bool + Does plan require payment method + requiresbillingaddress : bool + Does plan require billing address + isavailable : bool + Is the billing plan available + selfservice : bool + Can user change the plan themselves + premiumsupport : bool + Does plan enable premium support + budgeting : bool + Does plan support budget cap + supportsmocknumbers : bool + Does plan support mock numbers + supportsorganizationroles : bool + Does plan support organization roles + supportscredits : bool + Does plan support credit + supportsdisposableemailvalidation : bool + Does plan support blocking disposable email addresses. + supportscanonicalemailvalidation : bool + Does plan support requiring canonical email addresses. + supportsfreeemailvalidation : bool + Does plan support blocking free email addresses. + supportscorporateemailvalidation : bool + Does plan support restricting sign-ups to corporate email addresses only. + supportsprojectspecificroles : bool + Does plan support project-specific member roles. + backupsenabled : bool + Does plan support backup policies. + usageperproject : bool + Whether usage addons are calculated per project. + supportedaddons : BillingPlanSupportedAddons + Supported addons for this plan + backuppolicies : float + How many policies does plan support + deploymentsize : float + Maximum function and site deployment size in MB + buildsize : float + Maximum function and site deployment size in MB + databasesallowencrypt : bool + Does the plan support encrypted string attributes or not. + limits : Optional[BillingPlanLimits] + Plan specific limits + group : BillingPlanGroup + Group of this billing plan for variants + program : Optional[Program] + Details of the program this plan is a part of. + dedicateddatabases : Optional[BillingPlanDedicatedDatabaseLimits] + Dedicated database limits available to this plan. + """ + id: str = Field(..., alias='$id') + name: str = Field(..., alias='name') + desc: str = Field(..., alias='desc') + order: float = Field(..., alias='order') + price: float = Field(..., alias='price') + trial: float = Field(..., alias='trial') + bandwidth: float = Field(..., alias='bandwidth') + storage: float = Field(..., alias='storage') + imagetransformations: float = Field(..., alias='imageTransformations') + screenshotsgenerated: float = Field(..., alias='screenshotsGenerated') + members: float = Field(..., alias='members') + webhooks: float = Field(..., alias='webhooks') + projects: float = Field(..., alias='projects') + platforms: float = Field(..., alias='platforms') + users: float = Field(..., alias='users') + teams: float = Field(..., alias='teams') + databases: float = Field(..., alias='databases') + databasesreads: float = Field(..., alias='databasesReads') + databaseswrites: float = Field(..., alias='databasesWrites') + databasesbatchsize: float = Field(..., alias='databasesBatchSize') + buckets: float = Field(..., alias='buckets') + filesize: float = Field(..., alias='fileSize') + functions: float = Field(..., alias='functions') + sites: float = Field(..., alias='sites') + executions: float = Field(..., alias='executions') + executionsretentioncount: float = Field(..., alias='executionsRetentionCount') + gbhours: float = Field(..., alias='GBHours') + realtime: float = Field(..., alias='realtime') + realtimemessages: float = Field(..., alias='realtimeMessages') + messages: float = Field(..., alias='messages') + topics: float = Field(..., alias='topics') + authphone: float = Field(..., alias='authPhone') + domains: float = Field(..., alias='domains') + activitylogs: float = Field(..., alias='activityLogs') + usagelogs: float = Field(..., alias='usageLogs') + usagelogsintervals: Optional[List[Any]] = Field(default=None, alias='usageLogsIntervals') + projectinactivitydays: float = Field(..., alias='projectInactivityDays') + alertlimit: float = Field(..., alias='alertLimit') + usage: UsageBillingPlan = Field(..., alias='usage') + addons: BillingPlanAddon = Field(..., alias='addons') + budgetcapenabled: bool = Field(..., alias='budgetCapEnabled') + customsmtp: bool = Field(..., alias='customSmtp') + emailbranding: bool = Field(..., alias='emailBranding') + requirespaymentmethod: bool = Field(..., alias='requiresPaymentMethod') + requiresbillingaddress: bool = Field(..., alias='requiresBillingAddress') + isavailable: bool = Field(..., alias='isAvailable') + selfservice: bool = Field(..., alias='selfService') + premiumsupport: bool = Field(..., alias='premiumSupport') + budgeting: bool = Field(..., alias='budgeting') + supportsmocknumbers: bool = Field(..., alias='supportsMockNumbers') + supportsorganizationroles: bool = Field(..., alias='supportsOrganizationRoles') + supportscredits: bool = Field(..., alias='supportsCredits') + supportsdisposableemailvalidation: bool = Field(..., alias='supportsDisposableEmailValidation') + supportscanonicalemailvalidation: bool = Field(..., alias='supportsCanonicalEmailValidation') + supportsfreeemailvalidation: bool = Field(..., alias='supportsFreeEmailValidation') + supportscorporateemailvalidation: bool = Field(..., alias='supportsCorporateEmailValidation') + supportsprojectspecificroles: bool = Field(..., alias='supportsProjectSpecificRoles') + backupsenabled: bool = Field(..., alias='backupsEnabled') + usageperproject: bool = Field(..., alias='usagePerProject') + supportedaddons: BillingPlanSupportedAddons = Field(..., alias='supportedAddons') + backuppolicies: float = Field(..., alias='backupPolicies') + deploymentsize: float = Field(..., alias='deploymentSize') + buildsize: float = Field(..., alias='buildSize') + databasesallowencrypt: bool = Field(..., alias='databasesAllowEncrypt') + limits: Optional[BillingPlanLimits] = Field(default=None, alias='limits') + group: BillingPlanGroup = Field(..., alias='group') + program: Optional[Program] = Field(default=None, alias='program') + dedicateddatabases: Optional[BillingPlanDedicatedDatabaseLimits] = Field(default=None, alias='dedicatedDatabases') diff --git a/appwrite/models/billing_plan_addon.py b/appwrite/models/billing_plan_addon.py new file mode 100644 index 00000000..b1d75b34 --- /dev/null +++ b/appwrite/models/billing_plan_addon.py @@ -0,0 +1,19 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .billing_plan_addon_details import BillingPlanAddonDetails + +class BillingPlanAddon(AppwriteModel): + """ + Addon + + Attributes + ---------- + seats : BillingPlanAddonDetails + Addon seats + projects : BillingPlanAddonDetails + Addon projects + """ + seats: BillingPlanAddonDetails = Field(..., alias='seats') + projects: BillingPlanAddonDetails = Field(..., alias='projects') diff --git a/appwrite/models/billing_plan_addon_details.py b/appwrite/models/billing_plan_addon_details.py new file mode 100644 index 00000000..8acd360c --- /dev/null +++ b/appwrite/models/billing_plan_addon_details.py @@ -0,0 +1,36 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class BillingPlanAddonDetails(AppwriteModel): + """ + Details + + Attributes + ---------- + supported : bool + Is the addon supported in the plan? + planincluded : float + Addon plan included value + limit : float + Addon limit + type : str + Addon type + currency : str + Price currency + price : float + Price + value : float + Resource value + invoicedesc : str + Description on invoice + """ + supported: bool = Field(..., alias='supported') + planincluded: float = Field(..., alias='planIncluded') + limit: float = Field(..., alias='limit') + type: str = Field(..., alias='type') + currency: str = Field(..., alias='currency') + price: float = Field(..., alias='price') + value: float = Field(..., alias='value') + invoicedesc: str = Field(..., alias='invoiceDesc') diff --git a/appwrite/models/billing_plan_dedicated_database_limits.py b/appwrite/models/billing_plan_dedicated_database_limits.py new file mode 100644 index 00000000..754c1666 --- /dev/null +++ b/appwrite/models/billing_plan_dedicated_database_limits.py @@ -0,0 +1,69 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class BillingPlanDedicatedDatabaseLimits(AppwriteModel): + """ + dedicatedDatabaseLimits + + Attributes + ---------- + mincpu : Optional[float] + Minimum CPU allocation in millicores. + maxcpu : Optional[float] + Maximum CPU allocation in millicores. + minmemorymb : Optional[float] + Minimum memory allocation in megabytes. + maxmemorymb : Optional[float] + Maximum memory allocation in megabytes. + minstoragegb : Optional[float] + Minimum storage allocation in gigabytes. + maxstoragegb : Optional[float] + Maximum storage allocation in gigabytes. + maxreplicas : Optional[float] + Maximum number of high-availability replicas per dedicated database. + maxconnections : Optional[float] + Maximum number of client connections. + maxipallowlistsize : Optional[float] + Maximum number of entries allowed in the IP allowlist. + maxextensions : Optional[float] + Maximum number of database extensions that can be enabled. + maxbackupretentiondays : Optional[float] + Maximum number of days a backup can be retained. + maxpitrretentiondays : Optional[float] + Maximum number of days of point-in-time recovery data that can be retained. + maxsqlapimaxrows : Optional[float] + Maximum number of rows a single SQL API query can return. + maxsqlapimaxbytes : Optional[float] + Maximum response size in bytes for a single SQL API query. + maxsqlapitimeoutseconds : Optional[float] + Maximum execution time in seconds for a single SQL API query. + maxsqlapiallowedstatements : Optional[float] + Maximum number of SQL statement types that can be permitted through the SQL API. + allowedsqlstatements : Optional[List[Any]] + SQL statement types permitted through the SQL API. + allowedstorageclasses : Optional[List[Any]] + Storage classes available for dedicated databases. + allowedsyncmodes : Optional[List[Any]] + Replica synchronization modes available for dedicated databases. + """ + mincpu: Optional[float] = Field(default=None, alias='minCpu') + maxcpu: Optional[float] = Field(default=None, alias='maxCpu') + minmemorymb: Optional[float] = Field(default=None, alias='minMemoryMb') + maxmemorymb: Optional[float] = Field(default=None, alias='maxMemoryMb') + minstoragegb: Optional[float] = Field(default=None, alias='minStorageGb') + maxstoragegb: Optional[float] = Field(default=None, alias='maxStorageGb') + maxreplicas: Optional[float] = Field(default=None, alias='maxReplicas') + maxconnections: Optional[float] = Field(default=None, alias='maxConnections') + maxipallowlistsize: Optional[float] = Field(default=None, alias='maxIpAllowlistSize') + maxextensions: Optional[float] = Field(default=None, alias='maxExtensions') + maxbackupretentiondays: Optional[float] = Field(default=None, alias='maxBackupRetentionDays') + maxpitrretentiondays: Optional[float] = Field(default=None, alias='maxPitrRetentionDays') + maxsqlapimaxrows: Optional[float] = Field(default=None, alias='maxSqlApiMaxRows') + maxsqlapimaxbytes: Optional[float] = Field(default=None, alias='maxSqlApiMaxBytes') + maxsqlapitimeoutseconds: Optional[float] = Field(default=None, alias='maxSqlApiTimeoutSeconds') + maxsqlapiallowedstatements: Optional[float] = Field(default=None, alias='maxSqlApiAllowedStatements') + allowedsqlstatements: Optional[List[Any]] = Field(default=None, alias='allowedSqlStatements') + allowedstorageclasses: Optional[List[Any]] = Field(default=None, alias='allowedStorageClasses') + allowedsyncmodes: Optional[List[Any]] = Field(default=None, alias='allowedSyncModes') diff --git a/appwrite/models/billing_plan_limits.py b/appwrite/models/billing_plan_limits.py new file mode 100644 index 00000000..4a5abbd9 --- /dev/null +++ b/appwrite/models/billing_plan_limits.py @@ -0,0 +1,18 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class BillingPlanLimits(AppwriteModel): + """ + PlanLimits + + Attributes + ---------- + credits : Optional[float] + Credits limit per billing cycle + dailycredits : Optional[float] + Daily credits limit (if applicable) + """ + credits: Optional[float] = Field(default=None, alias='credits') + dailycredits: Optional[float] = Field(default=None, alias='dailyCredits') diff --git a/appwrite/models/billing_plan_supported_addons.py b/appwrite/models/billing_plan_supported_addons.py new file mode 100644 index 00000000..be64dde3 --- /dev/null +++ b/appwrite/models/billing_plan_supported_addons.py @@ -0,0 +1,21 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class BillingPlanSupportedAddons(AppwriteModel): + """ + BillingPlanSupportedAddons + + Attributes + ---------- + baa : bool + Whether the plan supports BAA (Business Associate Agreement) addon + premiumgeodb : bool + Whether the plan supports Premium Geo DB addon (project-level) + premiumgeodborg : bool + Whether the plan supports Premium Geo DB addon (organization-level) + """ + baa: bool = Field(..., alias='baa') + premiumgeodb: bool = Field(..., alias='premiumGeoDB') + premiumgeodborg: bool = Field(..., alias='premiumGeoDBOrg') diff --git a/appwrite/models/block.py b/appwrite/models/block.py index 4e11336d..95ba2075 100644 --- a/appwrite/models/block.py +++ b/appwrite/models/block.py @@ -15,6 +15,8 @@ class Block(AppwriteModel): Resource type that is blocked resourceid : str Resource identifier that is blocked + mode : str + Block mode. full blocks reads and writes; readOnly blocks writes only. reason : Optional[str] Reason for the block. Can be null if no reason was provided. expiredat : Optional[str] @@ -33,6 +35,7 @@ class Block(AppwriteModel): createdat: str = Field(..., alias='$createdAt') resourcetype: str = Field(..., alias='resourceType') resourceid: str = Field(..., alias='resourceId') + mode: str = Field(..., alias='mode') reason: Optional[str] = Field(default=None, alias='reason') expiredat: Optional[str] = Field(default=None, alias='expiredAt') projectname: str = Field(..., alias='projectName') diff --git a/appwrite/models/database.py b/appwrite/models/database.py index 784fc2a7..b491a89a 100644 --- a/appwrite/models/database.py +++ b/appwrite/models/database.py @@ -3,6 +3,7 @@ from .base_model import AppwriteModel from ..enums.database_type import DatabaseType +from ..enums.database_status import DatabaseStatus from .backup_policy import BackupPolicy from .backup_archive import BackupArchive @@ -24,6 +25,8 @@ class Database(AppwriteModel): If database is enabled. Can be 'enabled' or 'disabled'. When disabled, the database is inaccessible to users, but remains accessible to Server SDKs using API keys. type : DatabaseType Database type. + status : Optional[DatabaseStatus] + Database status. Possible values: `provisioning`, `ready` or `failed` policies : List[BackupPolicy] Database backup policies. archives : List[BackupArchive] @@ -35,5 +38,6 @@ class Database(AppwriteModel): updatedat: str = Field(..., alias='$updatedAt') enabled: bool = Field(..., alias='enabled') type: DatabaseType = Field(..., alias='type') + status: Optional[DatabaseStatus] = Field(default=None, alias='status') policies: List[BackupPolicy] = Field(..., alias='policies') archives: List[BackupArchive] = Field(..., alias='archives') diff --git a/appwrite/models/document.py b/appwrite/models/document.py index dcff339a..4df880fc 100644 --- a/appwrite/models/document.py +++ b/appwrite/models/document.py @@ -57,6 +57,17 @@ def data(self) -> T: def data(self, value: T) -> None: object.__setattr__(self, '_data', value) + def model_dump(self, **kwargs) -> Dict[str, Any]: + result = super().model_dump(**kwargs) + if hasattr(self, '_data'): + if isinstance(self._data, dict): + result['data'] = self._data + elif hasattr(self._data, 'model_dump'): + result['data'] = self._data.model_dump(**kwargs) + else: + result['data'] = self._data + return result + def to_dict(self) -> Dict[str, Any]: result = super().to_dict() if hasattr(self, '_data'): diff --git a/appwrite/models/health_antivirus.py b/appwrite/models/health_antivirus.py deleted file mode 100644 index 4e15043d..00000000 --- a/appwrite/models/health_antivirus.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel -from ..enums.health_antivirus_status import HealthAntivirusStatus - -class HealthAntivirus(AppwriteModel): - """ - Health Antivirus - - Attributes - ---------- - version : str - Antivirus version. - status : HealthAntivirusStatus - Antivirus status. Possible values are: `disabled`, `offline`, `online` - """ - version: str = Field(..., alias='version') - status: HealthAntivirusStatus = Field(..., alias='status') diff --git a/appwrite/models/health_certificate.py b/appwrite/models/health_certificate.py deleted file mode 100644 index 58999e72..00000000 --- a/appwrite/models/health_certificate.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel - -class HealthCertificate(AppwriteModel): - """ - Health Certificate - - Attributes - ---------- - name : str - Certificate name - subjectsn : str - Subject SN - issuerorganisation : str - Issuer organisation - validfrom : str - Valid from - validto : str - Valid to - signaturetypesn : str - Signature type SN - """ - name: str = Field(..., alias='name') - subjectsn: str = Field(..., alias='subjectSN') - issuerorganisation: str = Field(..., alias='issuerOrganisation') - validfrom: str = Field(..., alias='validFrom') - validto: str = Field(..., alias='validTo') - signaturetypesn: str = Field(..., alias='signatureTypeSN') diff --git a/appwrite/models/health_status.py b/appwrite/models/health_status.py deleted file mode 100644 index 0ae11466..00000000 --- a/appwrite/models/health_status.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel -from ..enums.health_check_status import HealthCheckStatus - -class HealthStatus(AppwriteModel): - """ - Health Status - - Attributes - ---------- - name : str - Name of the service. - ping : float - Duration in milliseconds how long the health check took. - status : HealthCheckStatus - Service status. Possible values are: `pass`, `fail` - """ - name: str = Field(..., alias='name') - ping: float = Field(..., alias='ping') - status: HealthCheckStatus = Field(..., alias='status') diff --git a/appwrite/models/health_status_list.py b/appwrite/models/health_status_list.py deleted file mode 100644 index 26904371..00000000 --- a/appwrite/models/health_status_list.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel -from .health_status import HealthStatus - -class HealthStatusList(AppwriteModel): - """ - Status List - - Attributes - ---------- - total : float - Total number of statuses that matched your query. - statuses : List[HealthStatus] - List of statuses. - """ - total: float = Field(..., alias='total') - statuses: List[HealthStatus] = Field(..., alias='statuses') diff --git a/appwrite/models/health_time.py b/appwrite/models/health_time.py deleted file mode 100644 index 240694d9..00000000 --- a/appwrite/models/health_time.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel - -class HealthTime(AppwriteModel): - """ - Health Time - - Attributes - ---------- - remotetime : float - Current unix timestamp on trustful remote server. - localtime : float - Current unix timestamp of local server where Appwrite runs. - diff : float - Difference of unix remote and local timestamps in milliseconds. - """ - remotetime: float = Field(..., alias='remoteTime') - localtime: float = Field(..., alias='localTime') - diff: float = Field(..., alias='diff') diff --git a/appwrite/models/locale.py b/appwrite/models/locale.py index 95952e14..f8aa6de8 100644 --- a/appwrite/models/locale.py +++ b/appwrite/models/locale.py @@ -23,6 +23,28 @@ class Locale(AppwriteModel): True if country is part of the European Union. currency : str Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) three-character format + city : Optional[str] + City + timezone : Optional[str] + Name of timezone + postalcode : Optional[str] + Postal code + latitude : Optional[float] + Latitude + longitude : Optional[float] + Longitude + autonomoussystemnumber : Optional[str] + Autonomous System Number (ASN) of the IP + autonomoussystemorganization : Optional[str] + Organization that owns the ASN + isp : Optional[str] + Internet service provider of the IP + connectiontype : Optional[str] + Connection type of the IP (e.g. cable, cellular, corporate) + connectionusagetype : Optional[str] + User type classification of the IP (e.g. residential, business, hosting) + connectionorganization : Optional[str] + Registered organization of the IP """ ip: str = Field(..., alias='ip') countrycode: str = Field(..., alias='countryCode') @@ -31,3 +53,14 @@ class Locale(AppwriteModel): continent: str = Field(..., alias='continent') eu: bool = Field(..., alias='eu') currency: str = Field(..., alias='currency') + city: Optional[str] = Field(default=None, alias='city') + timezone: Optional[str] = Field(default=None, alias='timeZone') + postalcode: Optional[str] = Field(default=None, alias='postalCode') + latitude: Optional[float] = Field(default=None, alias='latitude') + longitude: Optional[float] = Field(default=None, alias='longitude') + autonomoussystemnumber: Optional[str] = Field(default=None, alias='autonomousSystemNumber') + autonomoussystemorganization: Optional[str] = Field(default=None, alias='autonomousSystemOrganization') + isp: Optional[str] = Field(default=None, alias='isp') + connectiontype: Optional[str] = Field(default=None, alias='connectionType') + connectionusagetype: Optional[str] = Field(default=None, alias='connectionUsageType') + connectionorganization: Optional[str] = Field(default=None, alias='connectionOrganization') diff --git a/appwrite/models/log.py b/appwrite/models/log.py index dc0e0c67..6824028e 100644 --- a/appwrite/models/log.py +++ b/appwrite/models/log.py @@ -20,7 +20,7 @@ class Log(AppwriteModel): mode : str API mode when event triggered. usertype : str - User type who triggered the audit log. Possible values: user, admin, guest, keyProject, keyAccount, keyOrganization. + User type who triggered the audit log. Possible values: user, admin, guest, hidden, keyProject, keyAccount, keyOrganization. ip : str IP session in use when the session was created. time : str diff --git a/appwrite/models/o_auth2_appwrite.py b/appwrite/models/o_auth2_appwrite.py new file mode 100644 index 00000000..002a8408 --- /dev/null +++ b/appwrite/models/o_auth2_appwrite.py @@ -0,0 +1,24 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class OAuth2Appwrite(AppwriteModel): + """ + OAuth2Appwrite + + Attributes + ---------- + id : str + OAuth2 provider ID. + enabled : bool + OAuth2 provider is active and can be used to create sessions. + clientid : str + Appwrite OAuth2 client ID. + clientsecret : str + Appwrite 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_oidc.py b/appwrite/models/o_auth2_oidc.py index 6b896196..0ad06fef 100644 --- a/appwrite/models/o_auth2_oidc.py +++ b/appwrite/models/o_auth2_oidc.py @@ -2,6 +2,7 @@ from pydantic import Field, PrivateAttr from .base_model import AppwriteModel +from ..enums.o_auth2_oidc_prompt import OAuth2OidcPrompt class OAuth2Oidc(AppwriteModel): """ @@ -25,6 +26,10 @@ class OAuth2Oidc(AppwriteModel): OpenID Connect token endpoint URL. userinfourl : str OpenID Connect user info endpoint URL. + prompt : List[OAuth2OidcPrompt] + OpenID Connect prompt values controlling the authentication and consent screens. + maxage : Optional[float] + Maximum authentication age in seconds. When set, the user must have authenticated within this many seconds. """ id: str = Field(..., alias='$id') enabled: bool = Field(..., alias='enabled') @@ -34,3 +39,5 @@ class OAuth2Oidc(AppwriteModel): authorizationurl: str = Field(..., alias='authorizationURL') tokenurl: str = Field(..., alias='tokenURL') userinfourl: str = Field(..., alias='userInfoURL') + prompt: List[OAuth2OidcPrompt] = Field(..., alias='prompt') + maxage: Optional[float] = Field(default=None, alias='maxAge') diff --git a/appwrite/models/o_auth2_provider_list.py b/appwrite/models/o_auth2_provider_list.py index b07ce754..e13f865a 100644 --- a/appwrite/models/o_auth2_provider_list.py +++ b/appwrite/models/o_auth2_provider_list.py @@ -33,6 +33,7 @@ from .o_auth2_tradeshift import OAuth2Tradeshift from .o_auth2_paypal import OAuth2Paypal from .o_auth2_gitlab import OAuth2Gitlab +from .o_auth2_appwrite import OAuth2Appwrite from .o_auth2_authentik import OAuth2Authentik from .o_auth2_auth0 import OAuth2Auth0 from .o_auth2_fusion_auth import OAuth2FusionAuth @@ -51,8 +52,8 @@ 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, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft]] + 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]] List of OAuth2 providers. """ total: float = Field(..., alias='total') - 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, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft]] = Field(..., alias='providers') + 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]] = Field(..., alias='providers') diff --git a/appwrite/models/oauth2_grant.py b/appwrite/models/oauth2_grant.py index a17a74fd..58676082 100644 --- a/appwrite/models/oauth2_grant.py +++ b/appwrite/models/oauth2_grant.py @@ -21,6 +21,8 @@ class Oauth2Grant(AppwriteModel): ID of the OAuth2 client (app) the grant was requested for. scopes : List[Any] Requested OAuth2 scopes the user is being asked to consent to. + resources : List[Any] + Requested RFC 8707 resource indicators the user is being asked to consent to. authorizationdetails : str Requested authorization_details the user is being asked to consent to, as a JSON string. Each entry has a `type` plus project-defined fields. prompt : str @@ -38,6 +40,7 @@ class Oauth2Grant(AppwriteModel): userid: str = Field(..., alias='userId') appid: str = Field(..., alias='appId') scopes: List[Any] = Field(..., alias='scopes') + resources: List[Any] = Field(..., alias='resources') authorizationdetails: str = Field(..., alias='authorizationDetails') prompt: str = Field(..., alias='prompt') redirecturi: str = Field(..., alias='redirectUri') diff --git a/appwrite/models/health_queue.py b/appwrite/models/oauth2_organization.py similarity index 55% rename from appwrite/models/health_queue.py rename to appwrite/models/oauth2_organization.py index f9dcf66f..4481c4b2 100644 --- a/appwrite/models/health_queue.py +++ b/appwrite/models/oauth2_organization.py @@ -3,13 +3,13 @@ from .base_model import AppwriteModel -class HealthQueue(AppwriteModel): +class Oauth2Organization(AppwriteModel): """ - Health Queue + OAuth2 Organization Attributes ---------- - size : float - Amount of actions in the queue. + id : str + Organization ID. """ - size: float = Field(..., alias='size') + id: str = Field(..., alias='$id') diff --git a/appwrite/models/oauth2_organization_list.py b/appwrite/models/oauth2_organization_list.py new file mode 100644 index 00000000..aee823a0 --- /dev/null +++ b/appwrite/models/oauth2_organization_list.py @@ -0,0 +1,19 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .oauth2_organization import Oauth2Organization + +class Oauth2OrganizationList(AppwriteModel): + """ + OAuth2 accessible organizations list + + Attributes + ---------- + total : float + Total number of organizations that matched your query. + organizations : List[Oauth2Organization] + List of organizations. + """ + total: float = Field(..., alias='total') + organizations: List[Oauth2Organization] = Field(..., alias='organizations') diff --git a/appwrite/models/oauth2_par.py b/appwrite/models/oauth2_par.py new file mode 100644 index 00000000..a5942c86 --- /dev/null +++ b/appwrite/models/oauth2_par.py @@ -0,0 +1,18 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class Oauth2PAR(AppwriteModel): + """ + OAuth2 PAR + + Attributes + ---------- + request_uri : str + Authorization request handle to pass to the authorize endpoint. + expires_in : float + Lifetime of the authorization request handle in seconds. + """ + request_uri: str = Field(..., alias='request_uri') + expires_in: float = Field(..., alias='expires_in') diff --git a/appwrite/models/oauth2_project.py b/appwrite/models/oauth2_project.py new file mode 100644 index 00000000..f7bac058 --- /dev/null +++ b/appwrite/models/oauth2_project.py @@ -0,0 +1,21 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class Oauth2Project(AppwriteModel): + """ + OAuth2 Project + + Attributes + ---------- + id : str + Project ID. + region : str + Region ID the project is deployed in. + endpoint : str + API endpoint of the region the project is deployed in. Empty when the region has no public hostname configured. + """ + id: str = Field(..., alias='$id') + region: str = Field(..., alias='region') + endpoint: str = Field(..., alias='endpoint') diff --git a/appwrite/models/oauth2_project_list.py b/appwrite/models/oauth2_project_list.py new file mode 100644 index 00000000..e67b8929 --- /dev/null +++ b/appwrite/models/oauth2_project_list.py @@ -0,0 +1,19 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .oauth2_project import Oauth2Project + +class Oauth2ProjectList(AppwriteModel): + """ + OAuth2 accessible projects list + + Attributes + ---------- + total : float + Total number of projects that matched your query. + projects : List[Oauth2Project] + List of projects. + """ + total: float = Field(..., alias='total') + projects: List[Oauth2Project] = Field(..., alias='projects') diff --git a/appwrite/models/organization.py b/appwrite/models/organization.py new file mode 100644 index 00000000..95f4bdef --- /dev/null +++ b/appwrite/models/organization.py @@ -0,0 +1,132 @@ +from typing import Any, Dict, List, Optional, Union, cast, Generic, TypeVar, Type +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .preferences import Preferences +from .billing_plan import BillingPlan +from .billing_limits import BillingLimits + +T = TypeVar('T') + +class Organization(AppwriteModel, Generic[T]): + """ + Organization + + Attributes + ---------- + id : str + Team ID. + createdat : str + Team creation date in ISO 8601 format. + updatedat : str + Team update date in ISO 8601 format. + name : str + Team name. + total : float + Total number of team members. + prefs : Preferences[T] + Team preferences as a key-value object + billingbudget : float + Project budget limit + budgetalerts : List[Any] + Project budget limit + billingplan : str + Organization's billing plan ID. + billingplanid : str + Organization's billing plan ID. + billingplandetails : BillingPlan + Organization's billing plan. + billingemail : str + Billing email set for the organization. + billingstartdate : str + Billing cycle start date. + billingcurrentinvoicedate : str + Current invoice cycle start date. + billingnextinvoicedate : str + Next invoice cycle start date. + billingtrialstartdate : str + Start date of trial. + billingtrialdays : float + Number of trial days. + billingaggregationid : str + Current active aggregation id. + billinginvoiceid : str + Current active aggregation id. + paymentmethodid : str + Default payment method. + billingaddressid : str + Default payment method. + backuppaymentmethodid : str + Backup payment method. + status : str + Team status. + remarks : str + Remarks on team status. + agreementbaa : str + Organization agreements + programmanagername : str + Program manager's name. + programmanagercalendar : str + Program manager's calendar link. + programdiscordchannelname : str + Program's discord channel name. + programdiscordchannelurl : str + Program's discord channel URL. + billinglimits : Optional[BillingLimits] + Billing limits reached + billingplandowngrade : str + Billing plan selected for downgrade. + billingtaxid : str + Tax Id + markedfordeletion : bool + Marked for deletion + platform : str + Product with which the organization is associated (appwrite or imagine) + projects : List[Any] + Selected projects + """ + id: str = Field(..., alias='$id') + createdat: str = Field(..., alias='$createdAt') + updatedat: str = Field(..., alias='$updatedAt') + name: str = Field(..., alias='name') + total: float = Field(..., alias='total') + prefs: Preferences[T] = Field(..., alias='prefs') + billingbudget: float = Field(..., alias='billingBudget') + budgetalerts: List[Any] = Field(..., alias='budgetAlerts') + billingplan: str = Field(..., alias='billingPlan') + billingplanid: str = Field(..., alias='billingPlanId') + billingplandetails: BillingPlan = Field(..., alias='billingPlanDetails') + billingemail: str = Field(..., alias='billingEmail') + billingstartdate: str = Field(..., alias='billingStartDate') + billingcurrentinvoicedate: str = Field(..., alias='billingCurrentInvoiceDate') + billingnextinvoicedate: str = Field(..., alias='billingNextInvoiceDate') + billingtrialstartdate: str = Field(..., alias='billingTrialStartDate') + billingtrialdays: float = Field(..., alias='billingTrialDays') + billingaggregationid: str = Field(..., alias='billingAggregationId') + billinginvoiceid: str = Field(..., alias='billingInvoiceId') + paymentmethodid: str = Field(..., alias='paymentMethodId') + billingaddressid: str = Field(..., alias='billingAddressId') + backuppaymentmethodid: str = Field(..., alias='backupPaymentMethodId') + status: str = Field(..., alias='status') + remarks: str = Field(..., alias='remarks') + agreementbaa: str = Field(..., alias='agreementBAA') + programmanagername: str = Field(..., alias='programManagerName') + programmanagercalendar: str = Field(..., alias='programManagerCalendar') + programdiscordchannelname: str = Field(..., alias='programDiscordChannelName') + programdiscordchannelurl: str = Field(..., alias='programDiscordChannelUrl') + billinglimits: Optional[BillingLimits] = Field(default=None, alias='billingLimits') + billingplandowngrade: str = Field(..., alias='billingPlanDowngrade') + billingtaxid: str = Field(..., alias='billingTaxId') + markedfordeletion: bool = Field(..., alias='markedForDeletion') + platform: str = Field(..., alias='platform') + projects: List[Any] = Field(..., alias='projects') + + @classmethod + def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Organization[T]': + """Create Organization instance with typed data.""" + instance = cls.model_validate(data) + if 'prefs' in data and data['prefs'] is not None: + instance.prefs = Preferences.with_data( + data['prefs'], model_type + ) + return instance diff --git a/appwrite/models/preferences.py b/appwrite/models/preferences.py index ce469590..73a68a21 100644 --- a/appwrite/models/preferences.py +++ b/appwrite/models/preferences.py @@ -29,6 +29,17 @@ def data(self) -> T: def data(self, value: T) -> None: object.__setattr__(self, '_data', value) + def model_dump(self, **kwargs) -> Dict[str, Any]: + result = super().model_dump(**kwargs) + if hasattr(self, '_data'): + if isinstance(self._data, dict): + result['data'] = self._data + elif hasattr(self._data, 'model_dump'): + result['data'] = self._data.model_dump(**kwargs) + else: + result['data'] = self._data + return result + def to_dict(self) -> Dict[str, Any]: result = super().to_dict() if hasattr(self, '_data'): diff --git a/appwrite/models/program.py b/appwrite/models/program.py new file mode 100644 index 00000000..49f068e9 --- /dev/null +++ b/appwrite/models/program.py @@ -0,0 +1,39 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class Program(AppwriteModel): + """ + Program + + Attributes + ---------- + id : str + Program ID + title : str + Program title + description : str + Program description + tag : str + Program tag for highlighting on console + icon : str + Program icon for highlighting on console + url : str + URL for more information on this program + active : bool + Whether this program is active + external : bool + Whether this program is external + billingplanid : str + Billing plan ID that this is program is associated with. + """ + id: str = Field(..., alias='$id') + title: str = Field(..., alias='title') + description: str = Field(..., alias='description') + tag: str = Field(..., alias='tag') + icon: str = Field(..., alias='icon') + url: str = Field(..., alias='url') + active: bool = Field(..., alias='active') + external: bool = Field(..., alias='external') + billingplanid: str = Field(..., alias='billingPlanId') diff --git a/appwrite/models/project.py b/appwrite/models/project.py index afd4b5a5..38e41404 100644 --- a/appwrite/models/project.py +++ b/appwrite/models/project.py @@ -57,6 +57,8 @@ class Project(AppwriteModel): Labels for the project. status : str Project status + onboarding : Dict[str, Any] + Stage progress (completed or skipped) with timestamps and actor types, keyed by stage id. authmethods : List[ProjectAuthMethod] List of auth methods. services : List[ProjectService] @@ -75,6 +77,8 @@ class Project(AppwriteModel): OAuth2 server authorization URL oauth2serverscopes : Optional[List[Any]] OAuth2 server allowed scopes + oauth2serverdefaultscopes : Optional[List[Any]] + OAuth2 server scopes used when an authorization request omits the scope parameter oauth2serverauthorizationdetailstypes : Optional[List[Any]] OAuth2 server accepted RFC 9396 authorization_details types oauth2serveraccesstokenduration : Optional[float] @@ -119,6 +123,7 @@ class Project(AppwriteModel): pingedat: str = Field(..., alias='pingedAt') labels: List[Any] = Field(..., alias='labels') status: str = Field(..., alias='status') + onboarding: Dict[str, Any] = Field(..., alias='onboarding') authmethods: List[ProjectAuthMethod] = Field(..., alias='authMethods') services: List[ProjectService] = Field(..., alias='services') protocols: List[ProjectProtocol] = Field(..., alias='protocols') @@ -128,6 +133,7 @@ class Project(AppwriteModel): oauth2serverenabled: Optional[bool] = Field(default=None, alias='oAuth2ServerEnabled') oauth2serverauthorizationurl: Optional[str] = Field(default=None, alias='oAuth2ServerAuthorizationUrl') oauth2serverscopes: Optional[List[Any]] = Field(default=None, alias='oAuth2ServerScopes') + oauth2serverdefaultscopes: Optional[List[Any]] = Field(default=None, alias='oAuth2ServerDefaultScopes') oauth2serverauthorizationdetailstypes: Optional[List[Any]] = Field(default=None, alias='oAuth2ServerAuthorizationDetailsTypes') oauth2serveraccesstokenduration: Optional[float] = Field(default=None, alias='oAuth2ServerAccessTokenDuration') oauth2serverrefreshtokenduration: Optional[float] = Field(default=None, alias='oAuth2ServerRefreshTokenDuration') diff --git a/appwrite/models/row.py b/appwrite/models/row.py index 8ccc97e4..e6e15976 100644 --- a/appwrite/models/row.py +++ b/appwrite/models/row.py @@ -57,6 +57,17 @@ def data(self) -> T: def data(self, value: T) -> None: object.__setattr__(self, '_data', value) + def model_dump(self, **kwargs) -> Dict[str, Any]: + result = super().model_dump(**kwargs) + if hasattr(self, '_data'): + if isinstance(self._data, dict): + result['data'] = self._data + elif hasattr(self._data, 'model_dump'): + result['data'] = self._data.model_dump(**kwargs) + else: + result['data'] = self._data + return result + def to_dict(self) -> Dict[str, Any]: result = super().to_dict() if hasattr(self, '_data'): diff --git a/appwrite/models/usage_billing_plan.py b/appwrite/models/usage_billing_plan.py new file mode 100644 index 00000000..a078e726 --- /dev/null +++ b/appwrite/models/usage_billing_plan.py @@ -0,0 +1,46 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .additional_resource import AdditionalResource + +class UsageBillingPlan(AppwriteModel): + """ + usageBillingPlan + + Attributes + ---------- + bandwidth : AdditionalResource + Bandwidth additional resources + executions : AdditionalResource + Executions additional resources + member : AdditionalResource + Member additional resources + realtime : AdditionalResource + Realtime additional resources + realtimemessages : AdditionalResource + Realtime messages additional resources + realtimebandwidth : AdditionalResource + Realtime bandwidth additional resources + storage : AdditionalResource + Storage additional resources + users : AdditionalResource + User additional resources + gbhours : AdditionalResource + GBHour additional resources + imagetransformations : AdditionalResource + Image transformation additional resources + credits : AdditionalResource + Credits additional resources + """ + bandwidth: AdditionalResource = Field(..., alias='bandwidth') + executions: AdditionalResource = Field(..., alias='executions') + member: AdditionalResource = Field(..., alias='member') + realtime: AdditionalResource = Field(..., alias='realtime') + realtimemessages: AdditionalResource = Field(..., alias='realtimeMessages') + realtimebandwidth: AdditionalResource = Field(..., alias='realtimeBandwidth') + storage: AdditionalResource = Field(..., alias='storage') + users: AdditionalResource = Field(..., alias='users') + gbhours: AdditionalResource = Field(..., alias='GBHours') + imagetransformations: AdditionalResource = Field(..., alias='imageTransformations') + credits: AdditionalResource = Field(..., alias='credits') diff --git a/appwrite/models/usage_data_point.py b/appwrite/models/usage_data_point.py deleted file mode 100644 index a314956c..00000000 --- a/appwrite/models/usage_data_point.py +++ /dev/null @@ -1,60 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel - -class UsageDataPoint(AppwriteModel): - """ - usageDataPoint - - Attributes - ---------- - time : str - Bucket start timestamp (ISO 8601). When `interval` is omitted this is the request end time, marking the aggregate as-of moment. - value : float - Aggregated value for the bucket. - path : Optional[str] - API endpoint path when broken down by `path`. - method : Optional[str] - HTTP method when broken down by `method`. - status : Optional[str] - HTTP status code when broken down by `status`. - service : Optional[str] - API service segment when broken down by `service`. - country : Optional[str] - Country code when broken down by `country`. - region : Optional[str] - Appwrite region when broken down by `region`. - hostname : Optional[str] - Caller origin hostname when broken down by `hostname`. - osname : Optional[str] - Operating system name when broken down by `osName`. - clienttype : Optional[str] - Client type when broken down by `clientType`. - clientname : Optional[str] - Client name when broken down by `clientName`. - devicename : Optional[str] - Device classification when broken down by `deviceName`. - teamid : Optional[str] - Owning team ID when broken down by `teamId`. - resourceid : Optional[str] - External resource ID when broken down by `resourceId`. - resource : Optional[str] - Resource type when broken down by `resource` (gauges only). - """ - time: str = Field(..., alias='time') - value: float = Field(..., alias='value') - path: Optional[str] = Field(default=None, alias='path') - method: Optional[str] = Field(default=None, alias='method') - status: Optional[str] = Field(default=None, alias='status') - service: Optional[str] = Field(default=None, alias='service') - country: Optional[str] = Field(default=None, alias='country') - region: Optional[str] = Field(default=None, alias='region') - hostname: Optional[str] = Field(default=None, alias='hostname') - osname: Optional[str] = Field(default=None, alias='osName') - clienttype: Optional[str] = Field(default=None, alias='clientType') - clientname: Optional[str] = Field(default=None, alias='clientName') - devicename: Optional[str] = Field(default=None, alias='deviceName') - teamid: Optional[str] = Field(default=None, alias='teamId') - resourceid: Optional[str] = Field(default=None, alias='resourceId') - resource: Optional[str] = Field(default=None, alias='resource') diff --git a/appwrite/models/usage_event_list.py b/appwrite/models/usage_event_list.py deleted file mode 100644 index c183c3e4..00000000 --- a/appwrite/models/usage_event_list.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel -from .usage_metric import UsageMetric - -class UsageEventList(AppwriteModel): - """ - usageEventList - - Attributes - ---------- - interval : str - Time interval size (1h or 1d). Empty when the request omits `interval` — points then carry the request end time as their as-of marker. - metrics : List[UsageMetric] - One entry per requested metric, each carrying its own points[] time series (sums per bucket / dimension over time). - """ - interval: str = Field(..., alias='interval') - metrics: List[UsageMetric] = Field(..., alias='metrics') diff --git a/appwrite/models/usage_gauge_list.py b/appwrite/models/usage_gauge_list.py deleted file mode 100644 index ee3727ae..00000000 --- a/appwrite/models/usage_gauge_list.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel -from .usage_metric import UsageMetric - -class UsageGaugeList(AppwriteModel): - """ - usageGaugeList - - Attributes - ---------- - interval : str - Time interval size (1h or 1d). Empty when the request omits `interval` — points then carry the request end time as their as-of marker. - metrics : List[UsageMetric] - One entry per requested metric, each carrying its own points[] time series (latest-snapshot per bucket / dimension via argMax over time). - """ - interval: str = Field(..., alias='interval') - metrics: List[UsageMetric] = Field(..., alias='metrics') diff --git a/appwrite/models/usage_metric.py b/appwrite/models/usage_metric.py deleted file mode 100644 index 3cd15d47..00000000 --- a/appwrite/models/usage_metric.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel -from .usage_data_point import UsageDataPoint - -class UsageMetric(AppwriteModel): - """ - usageMetric - - Attributes - ---------- - metric : str - Metric key this series describes. - points : List[UsageDataPoint] - Data points for this metric, ordered by time ascending. With `interval`, each entry is one bucket; without, each entry is one row of the dimensional or aggregate breakdown. - """ - metric: str = Field(..., alias='metric') - points: List[UsageDataPoint] = Field(..., alias='points') diff --git a/appwrite/query.py b/appwrite/query.py index c223a4e1..3dafd4aa 100644 --- a/appwrite/query.py +++ b/appwrite/query.py @@ -248,6 +248,18 @@ def distance_greater_than(attribute, values, distance, meters=True): def distance_less_than(attribute, values, distance, meters=True): return str(Query("distanceLessThan", attribute, [[values, distance, meters]])) + @staticmethod + def vector_dot(attribute, vector): + return str(Query("vectorDot", attribute, [vector])) + + @staticmethod + def vector_cosine(attribute, vector): + return str(Query("vectorCosine", attribute, [vector])) + + @staticmethod + def vector_euclidean(attribute, vector): + return str(Query("vectorEuclidean", attribute, [vector])) + @staticmethod def intersects(attribute, values): return str(Query("intersects", attribute, [values])) diff --git a/appwrite/services/account.py b/appwrite/services/account.py index 21b734d1..5af533a9 100644 --- a/appwrite/services/account.py +++ b/appwrite/services/account.py @@ -1606,7 +1606,7 @@ def create_o_auth2_token( Parameters ---------- provider : OAuthProvider - OAuth2 Provider. Currently, supported providers are: amazon, apple, auth0, authentik, autodesk, bitbucket, bitly, box, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, 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, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, 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/apps.py b/appwrite/services/apps.py index da3c25d3..ab3e9110 100644 --- a/appwrite/services/apps.py +++ b/appwrite/services/apps.py @@ -396,6 +396,53 @@ def delete( return response + def update_labels( + self, + app_id: str, + labels: List[str] + ) -> App: + """ + Update the labels of an application. Labels are read-only for clients; only a server SDK using a project API key can set them. Replaces the previous labels. + + Parameters + ---------- + app_id : str + Application unique ID. + labels : List[str] + Array of application labels. Replaces the previous labels. Maximum of 1000 labels are allowed, each up to 36 alphanumeric characters long. + + Returns + ------- + App + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/apps/{appId}/labels' + api_params = {} + if app_id is None: + raise AppwriteException('Missing required parameter: "app_id"') + + if labels is None: + raise AppwriteException('Missing required parameter: "labels"') + + api_path = api_path.replace('{appId}', str(self._normalize_value(app_id))) + + api_params['labels'] = self._normalize_value(labels) + + response = self.client.call('put', 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=App) + + def list_secrets( self, app_id: str, diff --git a/appwrite/services/backups.py b/appwrite/services/backups.py index a13743d6..fda14881 100644 --- a/appwrite/services/backups.py +++ b/appwrite/services/backups.py @@ -429,10 +429,14 @@ def create_restoration( archive_id: str, services: List[BackupServices], new_resource_id: Optional[str] = None, - new_resource_name: Optional[str] = None + new_resource_name: Optional[str] = None, + new_specification: Optional[str] = None ) -> BackupRestoration: """ Create and trigger a new restoration for a backup on a project. + + When restoring a DocumentsDB or VectorsDB database to a new resource, pass `newSpecification` to provision the restored database on a different specification than the archived one (for example, restoring onto a larger or smaller dedicated database). Use `serverless` to restore onto the shared pool, or a dedicated specification slug to restore onto a dedicated database of that size. The specification must be permitted by the organization's plan. `newSpecification` is not supported for legacy/TablesDB databases or for bucket restores. + Parameters ---------- @@ -444,6 +448,8 @@ def create_restoration( Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. new_resource_name : Optional[str] Database name. Max length: 128 chars. + new_specification : Optional[str] + Specification to provision the restored database on, when restoring a DocumentsDB or VectorsDB database to a new resource. Defaults to the archived database's specification. Use `serverless` for the shared pool or a dedicated specification slug. Returns ------- @@ -471,6 +477,8 @@ def create_restoration( api_params['newResourceId'] = self._normalize_value(new_resource_id) if new_resource_name is not None: api_params['newResourceName'] = self._normalize_value(new_resource_name) + if new_specification is not None: + api_params['newSpecification'] = self._normalize_value(new_specification) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/functions.py b/appwrite/services/functions.py index 7d9a0f14..18709fb2 100644 --- a/appwrite/services/functions.py +++ b/appwrite/services/functions.py @@ -126,7 +126,7 @@ def create( commands : Optional[str] Build Commands. scopes : Optional[List[ProjectKeyScopes]] - List of scopes allowed for API key auto-generated for every execution. Maximum of 100 scopes are allowed. + List of scopes allowed for API key auto-generated for every execution. Maximum of 200 scopes are allowed. installation_id : Optional[str] Appwrite Installation ID for VCS (Version Control System) deployment. provider_repository_id : Optional[str] @@ -251,11 +251,17 @@ def list_runtimes( def list_specifications( - self + self, + type: Optional[str] = None ) -> SpecificationList: """ List allowed function specifications for this instance. + Parameters + ---------- + type : Optional[str] + Specification type to list. Can be one of: runtimes, builds. + Returns ------- SpecificationList @@ -270,6 +276,9 @@ def list_specifications( api_path = '/functions/specifications' api_params = {} + if type is not None: + api_params['type'] = self._normalize_value(type) + response = self.client.call('get', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), 'accept': 'application/json', @@ -370,7 +379,7 @@ def update( commands : Optional[str] Build Commands. scopes : Optional[List[ProjectKeyScopes]] - List of scopes allowed for API Key auto-generated for every execution. Maximum of 100 scopes are allowed. + List of scopes allowed for API Key auto-generated for every execution. Maximum of 200 scopes are allowed. installation_id : Optional[str] Appwrite Installation ID for VCS (Version Controle System) deployment. provider_repository_id : Optional[str] @@ -445,8 +454,7 @@ def update( api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) api_params['providerBranches'] = self._normalize_value(provider_branches) api_params['providerPaths'] = self._normalize_value(provider_paths) - if build_specification is not None: - api_params['buildSpecification'] = self._normalize_value(build_specification) + api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: api_params['runtimeSpecification'] = self._normalize_value(runtime_specification) if deployment_retention is not None: @@ -968,7 +976,8 @@ def get_deployment_download( self, function_id: str, deployment_id: str, - type: Optional[DeploymentDownloadType] = None + type: Optional[DeploymentDownloadType] = None, + token: Optional[str] = None ) -> bytes: """ Get a function deployment content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory. @@ -981,6 +990,8 @@ def get_deployment_download( Deployment ID. type : Optional[DeploymentDownloadType] Deployment file to download. Can be: "source", "output". + token : Optional[str] + Presigned source-download token for accessing this deployment without a session (jobs-service). Returns ------- @@ -1006,6 +1017,8 @@ def get_deployment_download( if type is not None: api_params['type'] = self._normalize_value(type) + if token is not None: + api_params['token'] = self._normalize_value(token) response = self.client.call('get', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/health.py b/appwrite/services/health.py deleted file mode 100644 index bbf93903..00000000 --- a/appwrite/services/health.py +++ /dev/null @@ -1,882 +0,0 @@ -from ..service import Service -from urllib.parse import quote -from typing import Any, Dict, List, Optional, Union -from ..exception import AppwriteException -from appwrite.utils.deprecated import deprecated -from ..models.health_status import HealthStatus -from ..models.health_antivirus import HealthAntivirus -from ..models.health_status_list import HealthStatusList -from ..models.health_certificate import HealthCertificate -from ..models.health_queue import HealthQueue -from ..enums.health_queue_name import HealthQueueName -from ..models.health_time import HealthTime - -class Health(Service): - - def __init__(self, client) -> None: - super(Health, self).__init__(client) - - def get( - self - ) -> HealthStatus: - """ - Check the Appwrite HTTP server is up and responsive. - - Returns - ------- - HealthStatus - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatus) - - - def get_antivirus( - self - ) -> HealthAntivirus: - """ - Check the Appwrite Antivirus server is up and connection is successful. - - Returns - ------- - HealthAntivirus - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/anti-virus' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthAntivirus) - - - def get_audits_db( - self - ) -> HealthStatusList: - """ - Check the database that backs the audit and activity store. When the connection is reachable the endpoint returns a passing status with its response time. - - - Returns - ------- - HealthStatusList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/audits-db' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatusList) - - - def get_cache( - self - ) -> HealthStatusList: - """ - Check the Appwrite in-memory cache servers are up and connection is successful. - - Returns - ------- - HealthStatusList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/cache' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatusList) - - - def get_certificate( - self, - domain: Optional[str] = None - ) -> HealthCertificate: - """ - Get the SSL certificate for a domain - - Parameters - ---------- - domain : Optional[str] - string - - Returns - ------- - HealthCertificate - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/certificate' - api_params = {} - - if domain is not None: - api_params['domain'] = self._normalize_value(domain) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthCertificate) - - - def get_console_pausing( - self, - threshold: Optional[float] = None, - inactivity_days: Optional[float] = None - ) -> HealthStatus: - """ - Get console pausing health status. Monitors projects approaching the pause threshold to detect potential issues with console access tracking. - - - Parameters - ---------- - threshold : Optional[float] - Percentage threshold of projects approaching pause. When hit (equal or higher), endpoint returns server error. Default value is 10. - inactivity_days : Optional[float] - Number of days of inactivity before a project is paused. Should match the plan's projectInactivityDays setting. Default value is 7. - - Returns - ------- - HealthStatus - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/console-pausing' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - if inactivity_days is not None: - api_params['inactivityDays'] = self._normalize_value(inactivity_days) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatus) - - - def get_db( - self - ) -> HealthStatusList: - """ - Check the Appwrite database servers are up and connection is successful. - - Returns - ------- - HealthStatusList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/db' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatusList) - - - def get_pub_sub( - self - ) -> HealthStatusList: - """ - Check the Appwrite pub-sub servers are up and connection is successful. - - Returns - ------- - HealthStatusList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/pubsub' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatusList) - - - def get_queue_audits( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of audit logs that are waiting to be processed in the Appwrite internal queue server. - - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/audits' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_builds( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of builds that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/builds' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_certificates( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/certificates' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_databases( - self, - name: Optional[str] = None, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of database changes that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - name : Optional[str] - Queue name for which to check the queue size - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/databases' - api_params = {} - - if name is not None: - api_params['name'] = self._normalize_value(name) - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_deletes( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of background destructive changes that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/deletes' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_failed_jobs( - self, - name: HealthQueueName, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Returns the amount of failed jobs in a given queue. - - - Parameters - ---------- - name : HealthQueueName - The name of the queue - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/failed/{name}' - api_params = {} - if name is None: - raise AppwriteException('Missing required parameter: "name"') - - api_path = api_path.replace('{name}', str(self._normalize_value(name))) - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_functions( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of function executions that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/functions' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_logs( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of logs that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/logs' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_mails( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of mails that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/mails' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_messaging( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of messages that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/messaging' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_migrations( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of migrations that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/migrations' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_stats_resources( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of metrics that are waiting to be processed in the Appwrite stats resources queue. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/stats-resources' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_usage( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of metrics that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/stats-usage' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_queue_webhooks( - self, - threshold: Optional[float] = None - ) -> HealthQueue: - """ - Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server. - - Parameters - ---------- - threshold : Optional[float] - Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. - - Returns - ------- - HealthQueue - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/queue/webhooks' - api_params = {} - - if threshold is not None: - api_params['threshold'] = self._normalize_value(threshold) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthQueue) - - - def get_storage( - self - ) -> HealthStatus: - """ - Check the Appwrite storage device is up and connection is successful. - - Returns - ------- - HealthStatus - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/storage' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatus) - - - def get_storage_local( - self - ) -> HealthStatus: - """ - Check the Appwrite local storage device is up and connection is successful. - - Returns - ------- - HealthStatus - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/storage/local' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthStatus) - - - def get_time( - self - ) -> HealthTime: - """ - Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP. - - Returns - ------- - HealthTime - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/health/time' - api_params = {} - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=HealthTime) - diff --git a/appwrite/services/messaging.py b/appwrite/services/messaging.py index 065a9537..3abb1004 100644 --- a/appwrite/services/messaging.py +++ b/appwrite/services/messaging.py @@ -6,7 +6,6 @@ from ..models.message_list import MessageList from ..models.message import Message from ..enums.message_priority import MessagePriority -from ..models.log_list import LogList from ..models.target_list import TargetList from ..models.provider_list import ProviderList from ..models.provider import Provider @@ -707,55 +706,6 @@ def delete( return response - def list_message_logs( - self, - message_id: str, - queries: Optional[List[str]] = None, - total: Optional[bool] = None - ) -> LogList: - """ - Get the message activity logs listed by its unique ID. - - Parameters - ---------- - message_id : str - Message ID. - queries : Optional[List[str]] - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset - total : Optional[bool] - When set to false, the total count returned will be 0 and will not be calculated. - - Returns - ------- - LogList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/messaging/messages/{messageId}/logs' - api_params = {} - if message_id is None: - raise AppwriteException('Missing required parameter: "message_id"') - - api_path = api_path.replace('{messageId}', str(self._normalize_value(message_id))) - - if queries is not None: - api_params['queries'] = self._normalize_value(queries) - if total is not None: - api_params['total'] = self._normalize_value(total) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=LogList) - - def list_targets( self, message_id: str, @@ -2686,104 +2636,6 @@ def delete_provider( return response - def list_provider_logs( - self, - provider_id: str, - queries: Optional[List[str]] = None, - total: Optional[bool] = None - ) -> LogList: - """ - Get the provider activity logs listed by its unique ID. - - Parameters - ---------- - provider_id : str - Provider ID. - queries : Optional[List[str]] - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset - total : Optional[bool] - When set to false, the total count returned will be 0 and will not be calculated. - - Returns - ------- - LogList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/messaging/providers/{providerId}/logs' - api_params = {} - if provider_id is None: - raise AppwriteException('Missing required parameter: "provider_id"') - - api_path = api_path.replace('{providerId}', str(self._normalize_value(provider_id))) - - if queries is not None: - api_params['queries'] = self._normalize_value(queries) - if total is not None: - api_params['total'] = self._normalize_value(total) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=LogList) - - - def list_subscriber_logs( - self, - subscriber_id: str, - queries: Optional[List[str]] = None, - total: Optional[bool] = None - ) -> LogList: - """ - Get the subscriber activity logs listed by its unique ID. - - Parameters - ---------- - subscriber_id : str - Subscriber ID. - queries : Optional[List[str]] - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset - total : Optional[bool] - When set to false, the total count returned will be 0 and will not be calculated. - - Returns - ------- - LogList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/messaging/subscribers/{subscriberId}/logs' - api_params = {} - if subscriber_id is None: - raise AppwriteException('Missing required parameter: "subscriber_id"') - - api_path = api_path.replace('{subscriberId}', str(self._normalize_value(subscriber_id))) - - if queries is not None: - api_params['queries'] = self._normalize_value(queries) - if total is not None: - api_params['total'] = self._normalize_value(total) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=LogList) - - def list_topics( self, queries: Optional[List[str]] = None, @@ -3011,55 +2863,6 @@ def delete_topic( return response - def list_topic_logs( - self, - topic_id: str, - queries: Optional[List[str]] = None, - total: Optional[bool] = None - ) -> LogList: - """ - Get the topic activity logs listed by its unique ID. - - Parameters - ---------- - topic_id : str - Topic ID. - queries : Optional[List[str]] - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset - total : Optional[bool] - When set to false, the total count returned will be 0 and will not be calculated. - - Returns - ------- - LogList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/messaging/topics/{topicId}/logs' - api_params = {} - if topic_id is None: - raise AppwriteException('Missing required parameter: "topic_id"') - - api_path = api_path.replace('{topicId}', str(self._normalize_value(topic_id))) - - if queries is not None: - api_params['queries'] = self._normalize_value(queries) - if total is not None: - api_params['total'] = self._normalize_value(total) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=LogList) - - def list_subscribers( self, topic_id: str, diff --git a/appwrite/services/oauth2.py b/appwrite/services/oauth2.py index 581d4e4e..272fbc73 100644 --- a/appwrite/services/oauth2.py +++ b/appwrite/services/oauth2.py @@ -7,6 +7,9 @@ from ..models.oauth2_authorize import Oauth2Authorize from ..models.oauth2_device_authorization import Oauth2DeviceAuthorization from ..models.oauth2_grant import Oauth2Grant +from ..models.oauth2_organization_list import Oauth2OrganizationList +from ..models.oauth2_par import Oauth2PAR +from ..models.oauth2_project_list import Oauth2ProjectList from ..models.oauth2_reject import Oauth2Reject from ..models.oauth2_token import Oauth2Token @@ -18,7 +21,8 @@ def __init__(self, client) -> None: def approve( self, grant_id: str, - authorization_details: Optional[str] = None + authorization_details: Optional[str] = None, + scope: Optional[str] = None ) -> Oauth2Approve: """ Approve an OAuth2 grant after the user gives consent. Returns the `redirectUrl` the end user should be sent to. The consent screen may optionally pass enriched `authorization_details` to record the concrete resources the user selected. You can pass Accept header of `application/json` to receive a JSON response instead of a redirect. @@ -29,6 +33,8 @@ def approve( Grant ID made during authorization, provided to consent screen in URL search params. authorization_details : Optional[str] Enriched `authorization_details` the user consented to, replacing what the client requested. Each entry must use a `type` the project accepts. Optional; omit to keep the originally requested details. + scope : Optional[str] + Space-separated scopes the user consented to. Must be a subset of the scopes originally requested; identity scopes such as `openid` are always retained. Optional; omit to keep the originally requested scopes. Returns ------- @@ -51,6 +57,8 @@ def approve( api_params['grant_id'] = self._normalize_value(grant_id) if authorization_details is not None: api_params['authorization_details'] = self._normalize_value(authorization_details) + if scope is not None: + api_params['scope'] = self._normalize_value(scope) response = self.client.call('post', api_path, { 'content-type': 'application/json', @@ -62,31 +70,34 @@ def approve( def authorize( self, - client_id: str, - redirect_uri: str, - response_type: str, - scope: str, + client_id: Optional[str] = None, + redirect_uri: Optional[str] = None, + response_type: Optional[str] = None, + scope: Optional[str] = None, state: Optional[str] = None, nonce: Optional[str] = None, code_challenge: Optional[str] = None, code_challenge_method: Optional[str] = None, prompt: Optional[str] = None, max_age: Optional[float] = None, - authorization_details: Optional[str] = None + authorization_details: Optional[str] = None, + resource: Optional[str] = None, + audience: Optional[str] = None, + request_uri: Optional[str] = None ) -> Oauth2Authorize: """ Begin the OAuth2 authorization flow. When called without a session, the user is redirected to the consent screen without grant ID. When called with a session, the redirect URL includes param for grant ID. You can pass Accept header of `application/json` to receive a JSON response instead of a redirect. Parameters ---------- - client_id : str + client_id : Optional[str] OAuth2 client ID. - redirect_uri : str + redirect_uri : Optional[str] Redirect URI where visitor will be redirected after authorization, whether successful or not. - response_type : str + response_type : Optional[str] OAuth2 / OIDC response type. One of `code` (Authorization Code Flow), `id_token` (Implicit Flow, OIDC login only), or `code id_token` (Hybrid Flow). - scope : str - Space-separated OAuth2 scopes. Can include project scopes, and built-in scopes: `openid`, `email`, `profile`. + scope : Optional[str] + Space-separated OAuth2 scopes. Can include project scopes, and built-in scopes: `openid`, `email`, `profile`, `phone`. state : Optional[str] OAuth2 state. You receive this back in the redirect URI. nonce : Optional[str] @@ -101,6 +112,12 @@ def authorize( OIDC max_age paraleter for customization of consent screen. Maximum allowable elapsed time in seconds since the user last authenticated. If exceeded, re-authentication is required. authorization_details : Optional[str] Rich authorization request. JSON array of objects, each with a `type` and project-defined fields + resource : Optional[str] + RFC 8707 resource indicator URI or URI list. Each value must be an absolute URI without a fragment. + audience : Optional[str] + Compatibility alias for a single OAuth2 resource indicator URI. + request_uri : Optional[str] + OAuth2 authorization request handle returned by the pushed authorization request endpoint. Returns ------- @@ -115,24 +132,16 @@ def authorize( api_path = '/oauth2/{project_id}/authorize' api_params = {} - if client_id is None: - raise AppwriteException('Missing required parameter: "client_id"') - - if redirect_uri is None: - raise AppwriteException('Missing required parameter: "redirect_uri"') - - if response_type is None: - raise AppwriteException('Missing required parameter: "response_type"') - - if scope is None: - raise AppwriteException('Missing required parameter: "scope"') - api_path = api_path.replace('{project_id}', str(self._normalize_value(self.client.get_config('project')))) - api_params['client_id'] = self._normalize_value(client_id) - api_params['redirect_uri'] = self._normalize_value(redirect_uri) - api_params['response_type'] = self._normalize_value(response_type) - api_params['scope'] = self._normalize_value(scope) + if client_id is not None: + api_params['client_id'] = self._normalize_value(client_id) + if redirect_uri is not None: + api_params['redirect_uri'] = self._normalize_value(redirect_uri) + if response_type is not None: + api_params['response_type'] = self._normalize_value(response_type) + if scope is not None: + api_params['scope'] = self._normalize_value(scope) if state is not None: api_params['state'] = self._normalize_value(state) if nonce is not None: @@ -147,6 +156,12 @@ def authorize( api_params['max_age'] = self._normalize_value(max_age) if authorization_details is not None: api_params['authorization_details'] = self._normalize_value(authorization_details) + if resource is not None: + api_params['resource'] = self._normalize_value(resource) + if audience is not None: + api_params['audience'] = self._normalize_value(audience) + if request_uri is not None: + api_params['request_uri'] = self._normalize_value(request_uri) response = self.client.call('get', api_path, { 'accept': 'application/json', @@ -159,7 +174,9 @@ def create_device_authorization( self, client_id: Optional[str] = None, scope: Optional[str] = None, - authorization_details: Optional[str] = None + authorization_details: Optional[str] = None, + resource: Optional[str] = None, + audience: Optional[str] = None ) -> Oauth2DeviceAuthorization: """ Start the OAuth2 Device Authorization Grant. Returns the device code, user code, verification URL, expiration, and polling interval. @@ -172,6 +189,10 @@ def create_device_authorization( Space-separated OAuth2 scopes. Can include project scopes, and built-in scopes: `openid`, `email`, `profile`. authorization_details : Optional[str] Rich authorization request. JSON array of objects, each with a `type` and project-defined fields + resource : Optional[str] + RFC 8707 resource indicator URI or URI list. Each value must be an absolute URI without a fragment. + audience : Optional[str] + Compatibility alias for a single OAuth2 resource indicator URI. Returns ------- @@ -194,6 +215,10 @@ def create_device_authorization( api_params['scope'] = self._normalize_value(scope) if authorization_details is not None: api_params['authorization_details'] = self._normalize_value(authorization_details) + if resource is not None: + api_params['resource'] = self._normalize_value(resource) + if audience is not None: + api_params['audience'] = self._normalize_value(audience) response = self.client.call('post', api_path, { 'content-type': 'application/json', @@ -282,6 +307,203 @@ def get_grant( return self._parse_response(response, model=Oauth2Grant) + def list_organizations( + self, + limit: Optional[float] = None, + offset: Optional[float] = None, + search: Optional[str] = None + ) -> Oauth2OrganizationList: + """ + List the organizations the OAuth2 access token can access. Resolves the token's `organization` authorization details, expanding the `*` wildcard into the concrete set of organizations the user can see. + + Parameters + ---------- + limit : Optional[float] + Maximum number of organizations to return. Between 1 and 5000. + offset : Optional[float] + Number of organizations to skip before returning results. Used for pagination. + search : Optional[str] + Search term to filter your list results. Max length: 256 chars. + + Returns + ------- + Oauth2OrganizationList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/oauth2/{project_id}/organizations' + api_params = {} + api_path = api_path.replace('{project_id}', str(self._normalize_value(self.client.get_config('project')))) + + if limit is not None: + api_params['limit'] = self._normalize_value(limit) + if offset is not None: + api_params['offset'] = self._normalize_value(offset) + if search is not None: + api_params['search'] = self._normalize_value(search) + + response = self.client.call('get', api_path, { + 'accept': 'application/json', + }, api_params) + + return self._parse_response(response, model=Oauth2OrganizationList) + + + def create_par( + self, + client_id: str, + redirect_uri: str, + response_type: str, + scope: Optional[str] = None, + state: Optional[str] = None, + nonce: Optional[str] = None, + code_challenge: Optional[str] = None, + code_challenge_method: Optional[str] = None, + prompt: Optional[str] = None, + max_age: Optional[float] = None, + authorization_details: Optional[str] = None, + resource: Optional[str] = None, + audience: Optional[str] = None + ) -> Oauth2PAR: + """ + Store an OAuth2 authorization request server-side and receive a short-lived request_uri handle for the authorize endpoint. + + Parameters + ---------- + client_id : str + OAuth2 client ID. + redirect_uri : str + Redirect URI where visitor will be redirected after authorization, whether successful or not. + response_type : str + OAuth2 / OIDC response type. + scope : Optional[str] + Space-separated OAuth2 scopes. Can include project scopes, and built-in scopes: `openid`, `email`, `profile`, `phone`. + state : Optional[str] + OAuth2 state. You receive this back in the redirect URI. + nonce : Optional[str] + OIDC nonce parameter to prevent replay attacks. Required when response_type includes `id_token`. + code_challenge : Optional[str] + PKCE code challenge. Required when OAuth2 app is public. + code_challenge_method : Optional[str] + PKCE code challenge method. Required when OAuth2 app is public. + prompt : Optional[str] + OIDC prompt parameter for customization of consent screen. Space-separated list of: none, login, consent, select_account. + max_age : Optional[float] + OIDC max_age parameter for customization of consent screen. + authorization_details : Optional[str] + Rich authorization request. JSON array of objects, each with a `type` and project-defined fields + resource : Optional[str] + RFC 8707 resource indicator URI or URI list. Each value must be an absolute URI without a fragment. + audience : Optional[str] + Compatibility alias for a single OAuth2 resource indicator URI. + + Returns + ------- + Oauth2PAR + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/oauth2/{project_id}/par' + api_params = {} + if client_id is None: + raise AppwriteException('Missing required parameter: "client_id"') + + if redirect_uri is None: + raise AppwriteException('Missing required parameter: "redirect_uri"') + + if response_type is None: + raise AppwriteException('Missing required parameter: "response_type"') + + api_path = api_path.replace('{project_id}', str(self._normalize_value(self.client.get_config('project')))) + + api_params['client_id'] = self._normalize_value(client_id) + api_params['redirect_uri'] = self._normalize_value(redirect_uri) + api_params['response_type'] = self._normalize_value(response_type) + if scope is not None: + api_params['scope'] = self._normalize_value(scope) + if state is not None: + api_params['state'] = self._normalize_value(state) + if nonce is not None: + api_params['nonce'] = self._normalize_value(nonce) + if code_challenge is not None: + api_params['code_challenge'] = self._normalize_value(code_challenge) + if code_challenge_method is not None: + api_params['code_challenge_method'] = self._normalize_value(code_challenge_method) + if prompt is not None: + api_params['prompt'] = self._normalize_value(prompt) + api_params['max_age'] = self._normalize_value(max_age) + if authorization_details is not None: + api_params['authorization_details'] = self._normalize_value(authorization_details) + if resource is not None: + api_params['resource'] = self._normalize_value(resource) + if audience is not None: + api_params['audience'] = self._normalize_value(audience) + + response = self.client.call('post', api_path, { + 'content-type': 'application/json', + 'accept': 'application/json', + }, api_params) + + return self._parse_response(response, model=Oauth2PAR) + + + def list_projects( + self, + limit: Optional[float] = None, + offset: Optional[float] = None, + search: Optional[str] = None + ) -> Oauth2ProjectList: + """ + List the projects the OAuth2 access token can access. Resolves the token's `project` authorization details, expanding the `*` wildcard into the concrete set of projects the user can see. + + Parameters + ---------- + limit : Optional[float] + Maximum number of projects to return. Between 1 and 5000. + offset : Optional[float] + Number of projects to skip before returning results. Used for pagination. + search : Optional[str] + Search term to filter your list results. Max length: 256 chars. + + Returns + ------- + Oauth2ProjectList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/oauth2/{project_id}/projects' + api_params = {} + api_path = api_path.replace('{project_id}', str(self._normalize_value(self.client.get_config('project')))) + + if limit is not None: + api_params['limit'] = self._normalize_value(limit) + if offset is not None: + api_params['offset'] = self._normalize_value(offset) + if search is not None: + api_params['search'] = self._normalize_value(search) + + response = self.client.call('get', api_path, { + 'accept': 'application/json', + }, api_params) + + return self._parse_response(response, model=Oauth2ProjectList) + + def reject( self, grant_id: str @@ -386,7 +608,9 @@ def create_token( client_id: Optional[str] = None, client_secret: Optional[str] = None, code_verifier: Optional[str] = None, - redirect_uri: Optional[str] = None + redirect_uri: Optional[str] = None, + resource: Optional[str] = None, + audience: Optional[str] = None ) -> Oauth2Token: """ Exchange an OAuth2 authorization code, refresh token, or device code for access and refresh tokens. @@ -409,6 +633,10 @@ def create_token( PKCE code verifier. Required for public apps. redirect_uri : Optional[str] Redirect URI. Required for `authorization_code` grant type. + resource : Optional[str] + RFC 8707 resource indicator URI or URI list. Each value must be an absolute URI without a fragment. + audience : Optional[str] + Compatibility alias for a single OAuth2 resource indicator URI. Returns ------- @@ -443,6 +671,10 @@ def create_token( api_params['code_verifier'] = self._normalize_value(code_verifier) if redirect_uri is not None: api_params['redirect_uri'] = self._normalize_value(redirect_uri) + if resource is not None: + api_params['resource'] = self._normalize_value(resource) + if audience is not None: + api_params['audience'] = self._normalize_value(audience) response = self.client.call('post', api_path, { 'content-type': 'application/json', diff --git a/appwrite/services/organization.py b/appwrite/services/organization.py index 7c63003a..eaf0ca88 100644 --- a/appwrite/services/organization.py +++ b/appwrite/services/organization.py @@ -1,20 +1,132 @@ from ..service import Service from urllib.parse import quote -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated +from ..models.organization import Organization as OrganizationModel from ..models.key_list import KeyList from ..enums.organization_key_scopes import OrganizationKeyScopes from ..models.key import Key +from ..models.membership_list import MembershipList +from ..models.membership import Membership from ..models.project_list import ProjectList from ..enums.region import Region from ..models.project import Project +T = TypeVar('T') + class Organization(Service): def __init__(self, client) -> None: super(Organization, self).__init__(client) + def get( + self, + model_type: Type[T] = dict + ) -> OrganizationModel[T]: + """ + Get the current organization. + + Parameters + ---------- + + model_type : Type[T], optional + Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. + + Returns + ------- + OrganizationModel[T] + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization' + api_params = {} + + response = self.client.call('get', api_path, { + 'X-Appwrite-Project': self.client.get_config('project'), + 'accept': 'application/json', + }, api_params) + + return OrganizationModel.with_data(response, model_type) + + + def update( + self, + name: str, + model_type: Type[T] = dict + ) -> OrganizationModel[T]: + """ + Update the current organization's name. + + Parameters + ---------- + name : str + New organization name. Max length: 128 chars. + + model_type : Type[T], optional + Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. + + Returns + ------- + OrganizationModel[T] + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization' + api_params = {} + if name is None: + raise AppwriteException('Missing required parameter: "name"') + + + api_params['name'] = self._normalize_value(name) + + response = self.client.call('put', api_path, { + 'X-Appwrite-Project': self.client.get_config('project'), + 'content-type': 'application/json', + 'accept': 'application/json', + }, api_params) + + return OrganizationModel.with_data(response, model_type) + + + def delete( + self + ) -> Dict[str, Any]: + """ + Delete the current organization. All projects that belong to the organization are deleted as well. + + Returns + ------- + Dict[str, Any] + API response as a dictionary + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization' + api_params = {} + + response = self.client.call('delete', api_path, { + 'X-Appwrite-Project': self.client.get_config('project'), + 'content-type': 'application/json', + }, api_params) + + return response + + def list_keys( self, queries: Optional[List[str]] = None, @@ -74,7 +186,7 @@ def create_key( name : str Key name. Max length: 128 chars. scopes : List[OrganizationKeyScopes] - Key scopes list. Maximum of 100 scopes are allowed. + Key scopes list. Maximum of 200 scopes are allowed. expire : Optional[str] Expiration time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Use null for unlimited expiration. @@ -171,7 +283,7 @@ def update_key( name : str Key name. Max length: 128 chars. scopes : List[OrganizationKeyScopes] - Key scopes list. Maximum of 100 scopes are allowed. + Key scopes list. Maximum of 200 scopes are allowed. expire : Optional[str] Expiration time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Use null for unlimited expiration. @@ -251,6 +363,243 @@ def delete_key( return response + def list_memberships( + self, + queries: Optional[List[str]] = None, + search: Optional[str] = None, + total: Optional[bool] = None + ) -> MembershipList: + """ + Get a list of all memberships from the current organization. + + Parameters + ---------- + queries : Optional[List[str]] + Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles + search : Optional[str] + Search term to filter your list results. Max length: 256 chars. + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + MembershipList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/memberships' + api_params = {} + + if queries is not None: + api_params['queries'] = self._normalize_value(queries) + if search is not None: + api_params['search'] = self._normalize_value(search) + if total is not None: + api_params['total'] = self._normalize_value(total) + + response = self.client.call('get', api_path, { + 'X-Appwrite-Project': self.client.get_config('project'), + 'accept': 'application/json', + }, api_params) + + return self._parse_response(response, model=MembershipList) + + + def create_membership( + self, + roles: List[str], + email: Optional[str] = None, + user_id: Optional[str] = None, + phone: Optional[str] = None, + url: Optional[str] = None, + name: Optional[str] = None + ) -> Membership: + """ + Invite a new member to join the current organization. An email with a link to join the organization will be sent to the new member's email address. If member doesn't exist in the project it will be automatically created. + + Parameters + ---------- + roles : List[str] + Array of strings. Use this param to set the user roles in the organization. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. + email : Optional[str] + Email of the new organization member. + user_id : Optional[str] + ID of the user to be added to the organization. + phone : Optional[str] + Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + url : Optional[str] + URL to redirect the user back to your app from the invitation email. This parameter is not required when an API key is supplied. + name : Optional[str] + Name of the new organization member. Max length: 128 chars. + + Returns + ------- + Membership + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/memberships' + api_params = {} + if roles is None: + raise AppwriteException('Missing required parameter: "roles"') + + + if email is not None: + api_params['email'] = self._normalize_value(email) + if user_id is not None: + api_params['userId'] = self._normalize_value(user_id) + if phone is not None: + api_params['phone'] = self._normalize_value(phone) + api_params['roles'] = self._normalize_value(roles) + if url is not None: + api_params['url'] = self._normalize_value(url) + if name is not None: + api_params['name'] = self._normalize_value(name) + + response = self.client.call('post', 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=Membership) + + + def get_membership( + self, + membership_id: str + ) -> Membership: + """ + Get a membership from the current organization by its unique ID. + + Parameters + ---------- + membership_id : str + Membership ID. + + Returns + ------- + Membership + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/memberships/{membershipId}' + api_params = {} + if membership_id is None: + raise AppwriteException('Missing required parameter: "membership_id"') + + api_path = api_path.replace('{membershipId}', str(self._normalize_value(membership_id))) + + + response = self.client.call('get', api_path, { + 'X-Appwrite-Project': self.client.get_config('project'), + 'accept': 'application/json', + }, api_params) + + return self._parse_response(response, model=Membership) + + + def update_membership( + self, + membership_id: str, + roles: List[str] + ) -> Membership: + """ + Modify the roles of a member in the current organization. + + Parameters + ---------- + membership_id : str + Membership ID. + roles : List[str] + An array of strings. Use this param to set the user's roles in the organization. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. + + Returns + ------- + Membership + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/memberships/{membershipId}' + api_params = {} + if membership_id is None: + raise AppwriteException('Missing required parameter: "membership_id"') + + if roles is None: + raise AppwriteException('Missing required parameter: "roles"') + + api_path = api_path.replace('{membershipId}', str(self._normalize_value(membership_id))) + + api_params['roles'] = self._normalize_value(roles) + + 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=Membership) + + + def delete_membership( + self, + membership_id: str + ) -> Dict[str, Any]: + """ + Remove a member from the current organization. The member is removed whether they accepted the invitation or not; a pending invitation is revoked. + + Parameters + ---------- + membership_id : str + Membership ID. + + Returns + ------- + Dict[str, Any] + API response as a dictionary + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/memberships/{membershipId}' + api_params = {} + if membership_id is None: + raise AppwriteException('Missing required parameter: "membership_id"') + + api_path = api_path.replace('{membershipId}', str(self._normalize_value(membership_id))) + + + response = self.client.call('delete', api_path, { + 'X-Appwrite-Project': self.client.get_config('project'), + 'content-type': 'application/json', + }, api_params) + + return response + + def list_projects( self, queries: Optional[List[str]] = None, @@ -263,7 +612,7 @@ def list_projects( Parameters ---------- queries : Optional[List[str]] - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, teamId, labels, search + Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, teamId, labels, search, accessedAt search : Optional[str] Search term to filter your list results. Max length: 256 chars. total : Optional[bool] diff --git a/appwrite/services/project.py b/appwrite/services/project.py index cccde7a9..c9d5c9d4 100644 --- a/appwrite/services/project.py +++ b/appwrite/services/project.py @@ -14,6 +14,7 @@ from ..models.o_auth2_provider_list import OAuth2ProviderList from ..models.o_auth2_amazon import OAuth2Amazon from ..models.o_auth2_apple import OAuth2Apple +from ..models.o_auth2_appwrite import OAuth2Appwrite from ..models.o_auth2_auth0 import OAuth2Auth0 from ..models.o_auth2_authentik import OAuth2Authentik from ..models.o_auth2_autodesk import OAuth2Autodesk @@ -37,6 +38,7 @@ from ..models.o_auth2_linkedin import OAuth2Linkedin from ..models.o_auth2_microsoft import OAuth2Microsoft from ..models.o_auth2_notion import OAuth2Notion +from ..enums.project_o_auth2_oidc_prompt import ProjectOAuth2OidcPrompt from ..models.o_auth2_oidc import OAuth2Oidc from ..models.o_auth2_okta import OAuth2Okta from ..models.o_auth2_paypal import OAuth2Paypal @@ -254,7 +256,7 @@ def create_key( name : str Key name. Max length: 128 chars. scopes : List[ProjectKeyScopes] - Key scopes list. Maximum of 100 scopes are allowed. + Key scopes list. Maximum of 200 scopes are allowed. expire : Optional[str] Expiration time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Use null for unlimited expiration. @@ -308,7 +310,7 @@ def create_ephemeral_key( Parameters ---------- scopes : List[ProjectKeyScopes] - Key scopes list. Maximum of 100 scopes are allowed. + Key scopes list. Maximum of 200 scopes are allowed. duration : float Time in seconds before ephemeral key expires. Maximum duration is 3600 seconds. @@ -400,7 +402,7 @@ def update_key( name : str Key name. Max length: 128 chars. scopes : List[ProjectKeyScopes] - Key scopes list. Maximum of 100 scopes are allowed. + Key scopes list. Maximum of 200 scopes are allowed. expire : Optional[str] Expiration time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Use null for unlimited expiration. @@ -790,7 +792,8 @@ def update_o_auth2_server( verification_url: Optional[str] = None, user_code_length: Optional[float] = None, user_code_format: Optional[str] = None, - device_code_duration: Optional[float] = None + device_code_duration: Optional[float] = None, + default_scopes: Optional[List[str]] = None ) -> ProjectModel: """ Update the OAuth2 server (OIDC provider) configuration. @@ -823,6 +826,8 @@ def update_o_auth2_server( Character set for device flow user codes: `numeric` (digits only — best for numeric keypads and TV remotes), `alphabetic` (letters only), or `alphanumeric` (letters and digits — highest entropy per character). Defaults to `alphanumeric`. device_code_duration : Optional[float] Lifetime in seconds of device flow device codes and user codes. Device codes are intentionally short-lived. Leave empty to use default 600. + default_scopes : Optional[List[str]] + List of OAuth2 scopes used when an authorization request omits the scope parameter. Every default scope must also be allowed by the OAuth2 server. Maximum of 100 scopes are allowed, each up to 128 characters long. Returns ------- @@ -861,6 +866,8 @@ def update_o_auth2_server( if user_code_format is not None: api_params['userCodeFormat'] = self._normalize_value(user_code_format) api_params['deviceCodeDuration'] = self._normalize_value(device_code_duration) + if default_scopes is not None: + api_params['defaultScopes'] = self._normalize_value(default_scopes) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -969,6 +976,51 @@ def update_o_auth2_apple( return self._parse_response(response, model=OAuth2Apple) + def update_o_auth2_appwrite( + self, + client_id: Optional[str] = None, + client_secret: Optional[str] = None, + enabled: Optional[bool] = None + ) -> OAuth2Appwrite: + """ + Update the project OAuth2 Appwrite configuration. + + Parameters + ---------- + client_id : Optional[str] + 'Client ID' of Appwrite OAuth2 app. For example: 6a42000000000000b5a0 + client_secret : Optional[str] + 'Client Secret' of Appwrite OAuth2 app. For example: b86afd000000000000000000000000000000000000000000000000000ced5f93 + 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 + ------- + OAuth2Appwrite + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project/oauth2/appwrite' + api_params = {} + + api_params['clientId'] = self._normalize_value(client_id) + api_params['clientSecret'] = self._normalize_value(client_secret) + 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=OAuth2Appwrite) + + def update_o_auth2_auth0( self, client_id: Optional[str] = None, @@ -1999,6 +2051,8 @@ def update_o_auth2_oidc( authorization_url: Optional[str] = None, token_url: Optional[str] = None, user_info_url: Optional[str] = None, + prompt: Optional[List[ProjectOAuth2OidcPrompt]] = None, + max_age: Optional[float] = None, enabled: Optional[bool] = None ) -> OAuth2Oidc: """ @@ -2018,6 +2072,10 @@ def update_o_auth2_oidc( OpenID Connect token endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/token user_info_url : Optional[str] OpenID Connect user info endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/userinfo + prompt : Optional[List[ProjectOAuth2OidcPrompt]] + Array of OpenID Connect prompt values controlling the authentication and consent screens. If "none" is included, it must be the only element. "none" means: don't display any authentication or consent screens. "login" means: prompt the user to re-authenticate. "consent" means: prompt the user for consent. "select_account" means: prompt the user to select an account. + max_age : Optional[float] + Maximum authentication age in seconds. When set, the user must have authenticated within this many seconds, otherwise they are prompted to re-authenticate. 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. @@ -2041,6 +2099,8 @@ def update_o_auth2_oidc( api_params['authorizationURL'] = self._normalize_value(authorization_url) api_params['tokenURL'] = self._normalize_value(token_url) api_params['userInfoURL'] = self._normalize_value(user_info_url) + api_params['prompt'] = self._normalize_value(prompt) + api_params['maxAge'] = self._normalize_value(max_age) api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('patch', api_path, { diff --git a/appwrite/services/sites.py b/appwrite/services/sites.py index ce0c23f1..4daf161f 100644 --- a/appwrite/services/sites.py +++ b/appwrite/services/sites.py @@ -258,11 +258,17 @@ def list_frameworks( def list_specifications( - self + self, + type: Optional[str] = None ) -> SpecificationList: """ List allowed site specifications for this instance. + Parameters + ---------- + type : Optional[str] + Specification type to list. Can be one of: runtimes, builds. + Returns ------- SpecificationList @@ -277,6 +283,9 @@ def list_specifications( api_path = '/sites/specifications' api_params = {} + if type is not None: + api_params['type'] = self._normalize_value(type) + response = self.client.call('get', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), 'accept': 'application/json', @@ -460,8 +469,7 @@ def update( api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) api_params['providerBranches'] = self._normalize_value(provider_branches) api_params['providerPaths'] = self._normalize_value(provider_paths) - if build_specification is not None: - api_params['buildSpecification'] = self._normalize_value(build_specification) + api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: api_params['runtimeSpecification'] = self._normalize_value(runtime_specification) if deployment_retention is not None: diff --git a/appwrite/services/tables_db.py b/appwrite/services/tables_db.py index 7ea86989..9733bc96 100644 --- a/appwrite/services/tables_db.py +++ b/appwrite/services/tables_db.py @@ -96,7 +96,7 @@ def create( database_id: str, name: str, enabled: Optional[bool] = None, - dedicated_database_id: Optional[str] = None + specification: Optional[str] = None ) -> Database: """ Create a new Database. @@ -110,8 +110,8 @@ def create( Database name. Max length: 128 chars. enabled : Optional[bool] Is the database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. - dedicated_database_id : Optional[str] - Optional dedicated database (compute) ID to attach this database to. Leave empty to create a database on the shared pool. + specification : Optional[str] + Database specification. Defaults to `serverless`, which creates the database on the shared pool. Any other value provisions a dedicated database on that specification. Returns ------- @@ -137,8 +137,8 @@ def create( api_params['name'] = self._normalize_value(name) if enabled is not None: api_params['enabled'] = self._normalize_value(enabled) - if dedicated_database_id is not None: - api_params['dedicatedDatabaseId'] = self._normalize_value(dedicated_database_id) + if specification is not None: + api_params['specification'] = self._normalize_value(specification) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/usage.py b/appwrite/services/usage.py deleted file mode 100644 index de300c7f..00000000 --- a/appwrite/services/usage.py +++ /dev/null @@ -1,202 +0,0 @@ -from ..service import Service -from urllib.parse import quote -from typing import Any, Dict, List, Optional, Union -from ..exception import AppwriteException -from appwrite.utils.deprecated import deprecated -from ..models.usage_event_list import UsageEventList -from ..models.usage_gauge_list import UsageGaugeList - -class Usage(Service): - - def __init__(self, client) -> None: - super(Usage, self).__init__(client) - - def list_events( - self, - metrics: List[str], - resource: Optional[str] = None, - resource_id: Optional[str] = None, - interval: Optional[str] = None, - dimensions: Optional[List[str]] = None, - start_at: Optional[str] = None, - end_at: Optional[str] = None, - order_by: Optional[str] = None, - order_dir: Optional[str] = None, - limit: Optional[float] = None, - offset: Optional[float] = None - ) -> UsageEventList: - """ - Aggregate usage event metrics. `metrics[]` (1-10) is required; the response always contains one entry per requested metric, each with its own `points[]` time series. - - **Two response shapes**: - - Omit `interval` for a flat top-N table — one point per dimension combination, no time axis. Useful for "top 10 paths by bandwidth in the last 7 days". - - Pass `interval` (`1m`, `15m`, `30m`, `1h`, `1d`) for a time series — one point per (time bucket × dimension combination). - - `dimensions[]` breaks each point down by one or more attributes (service, path, status, country, …). Pass multiple metrics to render stacked charts in one round-trip. `resource` and `resourceId` filter the underlying events. `orderBy=value`+`orderDir=desc`+`limit=N` returns the top-N by aggregated value. When `startAt` is omitted, the default window adapts to `interval` (or 7d when interval is omitted). - - Parameters - ---------- - metrics : List[str] - One to ten metric names. Single-metric callers pass a one-element array. Example: `metrics[]=executions` or `metrics[]=executions&metrics[]=executions.compute` for stacked charts. - resource : Optional[str] - Resource type filter (singular form). Common values: function, site, database, bucket, file, webhook, team, user, project. - resource_id : Optional[str] - Resource id filter. - interval : Optional[str] - Time interval size. Omit (null) for a flat aggregate over the whole window. Allowed: 1m, 15m, 30m, 1h, 1d. - dimensions : Optional[List[str]] - Break-down dimensions (max 10). Allowed: path, method, status, service, country, region, hostname, osName, clientType, clientName, deviceName, teamId, resourceId. - start_at : Optional[str] - Range start in ISO 8601. Defaults adapt to interval (7d for the no-interval aggregate). - end_at : Optional[str] - Range end in ISO 8601. Defaults to the current time. - order_by : Optional[str] - Column to order by. Allowed: time, value. Default time when an interval is set; otherwise value. - order_dir : Optional[str] - Sort direction: asc or desc. Default desc — paired with the default limit, returns the most recent / highest-value groups first. - limit : Optional[float] - Maximum rows to return (1-5000). - offset : Optional[float] - Pagination offset (0-100000). - - Returns - ------- - UsageEventList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/usage/events' - api_params = {} - if metrics is None: - raise AppwriteException('Missing required parameter: "metrics"') - - - api_params['metrics'] = self._normalize_value(metrics) - if resource is not None: - api_params['resource'] = self._normalize_value(resource) - if resource_id is not None: - api_params['resourceId'] = self._normalize_value(resource_id) - if interval is not None: - api_params['interval'] = self._normalize_value(interval) - if dimensions is not None: - api_params['dimensions'] = self._normalize_value(dimensions) - if start_at is not None: - api_params['startAt'] = self._normalize_value(start_at) - if end_at is not None: - api_params['endAt'] = self._normalize_value(end_at) - if order_by is not None: - api_params['orderBy'] = self._normalize_value(order_by) - if order_dir is not None: - api_params['orderDir'] = self._normalize_value(order_dir) - if limit is not None: - api_params['limit'] = self._normalize_value(limit) - if offset is not None: - api_params['offset'] = self._normalize_value(offset) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=UsageEventList) - - - def list_gauges( - self, - metrics: List[str], - resource_id: Optional[str] = None, - team_id: Optional[str] = None, - interval: Optional[str] = None, - dimensions: Optional[List[str]] = None, - start_at: Optional[str] = None, - end_at: Optional[str] = None, - order_by: Optional[str] = None, - order_dir: Optional[str] = None, - limit: Optional[float] = None, - offset: Optional[float] = None - ) -> UsageGaugeList: - """ - Aggregate usage gauge snapshots. Gauges are point-in-time values (storage totals, resource counts, …); each point carries the latest snapshot in its interval via `argMax(value, time)`. `metrics[]` (1-10) is required; the response always contains one entry per requested metric, each with its own `points[]` time series. - - **Two response shapes**: - - Omit `interval` for a flat top-N table — `argMax(value, time)` per dimension combination over the whole window, no time axis. Useful for "top 10 resources by current storage". - - Pass `interval` (`1m`, `15m`, `30m`, `1h`, `1d`) for a time series — one snapshot per (time bucket × dimension combination). - - `dimensions[]` breaks each point down further. Supported on gauges: `resourceId`, `teamId`, `service`, `resource`. `service` and `resource` enable per-service / per-resource-type panels (e.g. storage-by-service: group `files.storage`, `deployments.storage`, `builds.storage`, `databases.storage` by `service`). Pass multiple metrics to render stacked charts in one round-trip. `resourceId` and `teamId` parameters filter the underlying rows. `orderBy=value`+`orderDir=desc`+`limit=N` returns the top-N. When `startAt` is omitted, the default window adapts to interval (or 7d when interval is omitted). - - Parameters - ---------- - metrics : List[str] - One to ten metric names. Single-metric callers pass a one-element array. Example: `metrics[]=files.storage` or `metrics[]=files.storage&metrics[]=deployments.storage` for stacked charts. - resource_id : Optional[str] - Resource id filter. - team_id : Optional[str] - Team id filter. - interval : Optional[str] - Time interval size. Omit (null) for a flat aggregate over the whole window. Allowed: 1m, 15m, 30m, 1h, 1d. - dimensions : Optional[List[str]] - Break-down dimensions. Allowed: resourceId, teamId, service, resource. - start_at : Optional[str] - Range start in ISO 8601. Defaults to endAt - 7d. - end_at : Optional[str] - Range end in ISO 8601. Defaults to the current time. - order_by : Optional[str] - Column to order by. Allowed: time, value. Default time. - order_dir : Optional[str] - Sort direction: asc or desc. Default desc — paired with the default limit, this returns the most recent groups first. Pass asc for chronological charting. - limit : Optional[float] - Maximum rows to return (1-5000). - offset : Optional[float] - Pagination offset (0-100000). - - Returns - ------- - UsageGaugeList - API response as a typed Pydantic model - - Raises - ------ - AppwriteException - If API request fails - """ - - api_path = '/usage/gauges' - api_params = {} - if metrics is None: - raise AppwriteException('Missing required parameter: "metrics"') - - - api_params['metrics'] = self._normalize_value(metrics) - if resource_id is not None: - api_params['resourceId'] = self._normalize_value(resource_id) - if team_id is not None: - api_params['teamId'] = self._normalize_value(team_id) - if interval is not None: - api_params['interval'] = self._normalize_value(interval) - if dimensions is not None: - api_params['dimensions'] = self._normalize_value(dimensions) - if start_at is not None: - api_params['startAt'] = self._normalize_value(start_at) - if end_at is not None: - api_params['endAt'] = self._normalize_value(end_at) - if order_by is not None: - api_params['orderBy'] = self._normalize_value(order_by) - if order_dir is not None: - api_params['orderDir'] = self._normalize_value(order_dir) - if limit is not None: - api_params['limit'] = self._normalize_value(limit) - if offset is not None: - api_params['offset'] = self._normalize_value(offset) - - response = self.client.call('get', api_path, { - 'X-Appwrite-Project': self.client.get_config('project'), - 'accept': 'application/json', - }, api_params) - - return self._parse_response(response, model=UsageGaugeList) - diff --git a/appwrite/services/users.py b/appwrite/services/users.py index 00bd630f..c0e282e6 100644 --- a/appwrite/services/users.py +++ b/appwrite/services/users.py @@ -41,7 +41,7 @@ def list( Parameters ---------- queries : Optional[List[str]] - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels, impersonator + Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels, impersonator, accessedAt search : Optional[str] Search term to filter your list results. Max length: 256 chars. total : Optional[bool] diff --git a/docs/examples/health/get-audits-db.md b/docs/examples/apps/update-labels.md similarity index 63% rename from docs/examples/health/get-audits-db.md rename to docs/examples/apps/update-labels.md index 774edec1..0601df3f 100644 --- a/docs/examples/health/get-audits-db.md +++ b/docs/examples/apps/update-labels.md @@ -1,16 +1,19 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatusList +from appwrite.services.apps import Apps +from appwrite.models import App 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 -health = Health(client) +apps = Apps(client) -result: HealthStatusList = health.get_audits_db() +result: App = apps.update_labels( + app_id = '', + labels = [] +) print(result.model_dump()) ``` diff --git a/docs/examples/backups/create-restoration.md b/docs/examples/backups/create-restoration.md index e2966caa..03f3f0a9 100644 --- a/docs/examples/backups/create-restoration.md +++ b/docs/examples/backups/create-restoration.md @@ -15,7 +15,8 @@ result: BackupRestoration = backups.create_restoration( archive_id = '', services = [BackupServices.DATABASES], new_resource_id = '', # optional - new_resource_name = '' # optional + new_resource_name = '', # optional + new_specification = 'serverless' # optional ) print(result.model_dump()) diff --git a/docs/examples/functions/get-deployment-download.md b/docs/examples/functions/get-deployment-download.md index 7f6b2f6b..49df861b 100644 --- a/docs/examples/functions/get-deployment-download.md +++ b/docs/examples/functions/get-deployment-download.md @@ -13,6 +13,7 @@ functions = Functions(client) result: bytes = functions.get_deployment_download( function_id = '', deployment_id = '', - type = DeploymentDownloadType.SOURCE # optional + type = DeploymentDownloadType.SOURCE, # optional + token = '' # optional ) ``` diff --git a/docs/examples/functions/list-specifications.md b/docs/examples/functions/list-specifications.md index 5b76860d..7cf529a9 100644 --- a/docs/examples/functions/list-specifications.md +++ b/docs/examples/functions/list-specifications.md @@ -10,7 +10,9 @@ client.set_key('') # Your secret API key functions = Functions(client) -result: SpecificationList = functions.list_specifications() +result: SpecificationList = functions.list_specifications( + type = 'runtimes' # optional +) print(result.model_dump()) ``` diff --git a/docs/examples/health/get-antivirus.md b/docs/examples/health/get-antivirus.md deleted file mode 100644 index 1ab51503..00000000 --- a/docs/examples/health/get-antivirus.md +++ /dev/null @@ -1,16 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthAntivirus - -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 - -health = Health(client) - -result: HealthAntivirus = health.get_antivirus() - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-certificate.md b/docs/examples/health/get-certificate.md deleted file mode 100644 index 53dde7fb..00000000 --- a/docs/examples/health/get-certificate.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthCertificate - -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 - -health = Health(client) - -result: HealthCertificate = health.get_certificate( - domain = '' # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-db.md b/docs/examples/health/get-db.md deleted file mode 100644 index 47b6dd98..00000000 --- a/docs/examples/health/get-db.md +++ /dev/null @@ -1,16 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatusList - -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 - -health = Health(client) - -result: HealthStatusList = health.get_db() - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-failed-jobs.md b/docs/examples/health/get-failed-jobs.md deleted file mode 100644 index da08c619..00000000 --- a/docs/examples/health/get-failed-jobs.md +++ /dev/null @@ -1,20 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue -from appwrite.enums import HealthQueueName - -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 - -health = Health(client) - -result: HealthQueue = health.get_failed_jobs( - name = HealthQueueName.V1_DATABASE, - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-pub-sub.md b/docs/examples/health/get-pub-sub.md deleted file mode 100644 index 588a2bac..00000000 --- a/docs/examples/health/get-pub-sub.md +++ /dev/null @@ -1,16 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatusList - -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 - -health = Health(client) - -result: HealthStatusList = health.get_pub_sub() - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-certificates.md b/docs/examples/health/get-queue-certificates.md deleted file mode 100644 index 6666463f..00000000 --- a/docs/examples/health/get-queue-certificates.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_certificates( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-databases.md b/docs/examples/health/get-queue-databases.md deleted file mode 100644 index 44e165ed..00000000 --- a/docs/examples/health/get-queue-databases.md +++ /dev/null @@ -1,19 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_databases( - name = '', # optional - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-deletes.md b/docs/examples/health/get-queue-deletes.md deleted file mode 100644 index fece6301..00000000 --- a/docs/examples/health/get-queue-deletes.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_deletes( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-functions.md b/docs/examples/health/get-queue-functions.md deleted file mode 100644 index 03d9afe8..00000000 --- a/docs/examples/health/get-queue-functions.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_functions( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-logs.md b/docs/examples/health/get-queue-logs.md deleted file mode 100644 index 5191fa5a..00000000 --- a/docs/examples/health/get-queue-logs.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_logs( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-mails.md b/docs/examples/health/get-queue-mails.md deleted file mode 100644 index aed05e1d..00000000 --- a/docs/examples/health/get-queue-mails.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_mails( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-messaging.md b/docs/examples/health/get-queue-messaging.md deleted file mode 100644 index 5da876a6..00000000 --- a/docs/examples/health/get-queue-messaging.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_messaging( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-migrations.md b/docs/examples/health/get-queue-migrations.md deleted file mode 100644 index 749675d7..00000000 --- a/docs/examples/health/get-queue-migrations.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_migrations( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-stats-resources.md b/docs/examples/health/get-queue-stats-resources.md deleted file mode 100644 index 60c0dd57..00000000 --- a/docs/examples/health/get-queue-stats-resources.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_stats_resources( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-usage.md b/docs/examples/health/get-queue-usage.md deleted file mode 100644 index 10fa4a0f..00000000 --- a/docs/examples/health/get-queue-usage.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_usage( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-queue-webhooks.md b/docs/examples/health/get-queue-webhooks.md deleted file mode 100644 index 24423761..00000000 --- a/docs/examples/health/get-queue-webhooks.md +++ /dev/null @@ -1,18 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue - -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 - -health = Health(client) - -result: HealthQueue = health.get_queue_webhooks( - threshold = None # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-storage-local.md b/docs/examples/health/get-storage-local.md deleted file mode 100644 index 57b8ec40..00000000 --- a/docs/examples/health/get-storage-local.md +++ /dev/null @@ -1,16 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatus - -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 - -health = Health(client) - -result: HealthStatus = health.get_storage_local() - -print(result.model_dump()) -``` diff --git a/docs/examples/health/get-storage.md b/docs/examples/health/get-storage.md deleted file mode 100644 index a17ee4e3..00000000 --- a/docs/examples/health/get-storage.md +++ /dev/null @@ -1,16 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatus - -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 - -health = Health(client) - -result: HealthStatus = health.get_storage() - -print(result.model_dump()) -``` diff --git a/docs/examples/messaging/list-provider-logs.md b/docs/examples/messaging/list-provider-logs.md deleted file mode 100644 index ad271428..00000000 --- a/docs/examples/messaging/list-provider-logs.md +++ /dev/null @@ -1,20 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.messaging import Messaging -from appwrite.models import LogList - -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 - -messaging = Messaging(client) - -result: LogList = messaging.list_provider_logs( - provider_id = '', - queries = [], # optional - total = False # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/messaging/list-subscriber-logs.md b/docs/examples/messaging/list-subscriber-logs.md deleted file mode 100644 index b02c2b1b..00000000 --- a/docs/examples/messaging/list-subscriber-logs.md +++ /dev/null @@ -1,20 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.messaging import Messaging -from appwrite.models import LogList - -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 - -messaging = Messaging(client) - -result: LogList = messaging.list_subscriber_logs( - subscriber_id = '', - queries = [], # optional - total = False # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/messaging/list-topic-logs.md b/docs/examples/messaging/list-topic-logs.md deleted file mode 100644 index 3ed2d7e3..00000000 --- a/docs/examples/messaging/list-topic-logs.md +++ /dev/null @@ -1,20 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.messaging import Messaging -from appwrite.models import LogList - -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 - -messaging = Messaging(client) - -result: LogList = messaging.list_topic_logs( - topic_id = '', - queries = [], # optional - total = False # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/oauth2/approve.md b/docs/examples/oauth2/approve.md index b3313599..12bc9c0d 100644 --- a/docs/examples/oauth2/approve.md +++ b/docs/examples/oauth2/approve.md @@ -12,7 +12,8 @@ oauth2 = Oauth2(client) result: Oauth2Approve = oauth2.approve( grant_id = '', - authorization_details = '' # optional + authorization_details = '', # optional + scope = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/oauth2/authorize.md b/docs/examples/oauth2/authorize.md index 3ea83a66..9d7bb486 100644 --- a/docs/examples/oauth2/authorize.md +++ b/docs/examples/oauth2/authorize.md @@ -11,17 +11,20 @@ client.set_project('') # Your project ID oauth2 = Oauth2(client) result: Oauth2Authorize = oauth2.authorize( - client_id = '', - redirect_uri = 'https://example.com', - response_type = 'code', - scope = '', + client_id = '', # optional + redirect_uri = 'https://example.com', # optional + response_type = '', # optional + scope = '', # optional state = '', # optional nonce = '', # optional code_challenge = '', # optional code_challenge_method = 's256', # optional prompt = '', # optional max_age = 0, # optional - authorization_details = '' # optional + authorization_details = '', # optional + resource = '', # optional + audience = '', # optional + request_uri = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/oauth2/create-device-authorization.md b/docs/examples/oauth2/create-device-authorization.md index 4ba20f77..0fa3852d 100644 --- a/docs/examples/oauth2/create-device-authorization.md +++ b/docs/examples/oauth2/create-device-authorization.md @@ -13,7 +13,9 @@ oauth2 = Oauth2(client) result: Oauth2DeviceAuthorization = oauth2.create_device_authorization( client_id = '', # optional scope = '', # optional - authorization_details = '' # optional + authorization_details = '', # optional + resource = '', # optional + audience = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/oauth2/create-par.md b/docs/examples/oauth2/create-par.md new file mode 100644 index 00000000..2018794c --- /dev/null +++ b/docs/examples/oauth2/create-par.md @@ -0,0 +1,30 @@ +```python +from appwrite.client import Client +from appwrite.services.oauth2 import Oauth2 +from appwrite.models import Oauth2PAR + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_session('') # The user session to authenticate with +client.set_project('') # Your project ID + +oauth2 = Oauth2(client) + +result: Oauth2PAR = oauth2.create_par( + client_id = '', + redirect_uri = 'https://example.com', + response_type = 'code', + scope = '', # optional + state = '', # optional + nonce = '', # optional + code_challenge = '', # optional + code_challenge_method = 's256', # optional + prompt = '', # optional + max_age = 0, # optional + authorization_details = '', # optional + resource = '', # optional + audience = '' # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/oauth2/create-token.md b/docs/examples/oauth2/create-token.md index ac698593..1d52bbc9 100644 --- a/docs/examples/oauth2/create-token.md +++ b/docs/examples/oauth2/create-token.md @@ -18,7 +18,9 @@ result: Oauth2Token = oauth2.create_token( client_id = '', # optional client_secret = '', # optional code_verifier = '', # optional - redirect_uri = 'https://example.com' # optional + redirect_uri = 'https://example.com', # optional + resource = '', # optional + audience = '' # optional ) print(result.model_dump()) diff --git a/docs/examples/oauth2/list-organizations.md b/docs/examples/oauth2/list-organizations.md new file mode 100644 index 00000000..42ece3a8 --- /dev/null +++ b/docs/examples/oauth2/list-organizations.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.oauth2 import Oauth2 +from appwrite.models import Oauth2OrganizationList + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_session('') # The user session to authenticate with +client.set_project('') # Your project ID + +oauth2 = Oauth2(client) + +result: Oauth2OrganizationList = oauth2.list_organizations( + limit = 1, # optional + offset = 0, # optional + search = '' # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/oauth2/list-projects.md b/docs/examples/oauth2/list-projects.md new file mode 100644 index 00000000..97a58b7b --- /dev/null +++ b/docs/examples/oauth2/list-projects.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.oauth2 import Oauth2 +from appwrite.models import Oauth2ProjectList + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_session('') # The user session to authenticate with +client.set_project('') # Your project ID + +oauth2 = Oauth2(client) + +result: Oauth2ProjectList = oauth2.list_projects( + limit = 1, # optional + offset = 0, # optional + search = '' # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/create-membership.md b/docs/examples/organization/create-membership.md new file mode 100644 index 00000000..0801bdd7 --- /dev/null +++ b/docs/examples/organization/create-membership.md @@ -0,0 +1,23 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Membership + +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 + +organization = Organization(client) + +result: Membership = organization.create_membership( + roles = [], + email = 'email@example.com', # optional + user_id = '', # optional + phone = '+12065550100', # optional + url = 'https://example.com', # optional + name = '' # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/health/get.md b/docs/examples/organization/delete-membership.md similarity index 60% rename from docs/examples/health/get.md rename to docs/examples/organization/delete-membership.md index 5a3b3d06..dee81d19 100644 --- a/docs/examples/health/get.md +++ b/docs/examples/organization/delete-membership.md @@ -1,16 +1,15 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatus +from appwrite.services.organization import Organization 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 -health = Health(client) +organization = Organization(client) -result: HealthStatus = health.get() - -print(result.model_dump()) +result = organization.delete_membership( + membership_id = '' +) ``` diff --git a/docs/examples/health/get-time.md b/docs/examples/organization/delete.md similarity index 60% rename from docs/examples/health/get-time.md rename to docs/examples/organization/delete.md index 5ffae25e..94b7c2a7 100644 --- a/docs/examples/health/get-time.md +++ b/docs/examples/organization/delete.md @@ -1,16 +1,13 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthTime +from appwrite.services.organization import Organization 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 -health = Health(client) +organization = Organization(client) -result: HealthTime = health.get_time() - -print(result.model_dump()) +result = organization.delete() ``` diff --git a/docs/examples/health/get-queue-audits.md b/docs/examples/organization/get-membership.md similarity index 57% rename from docs/examples/health/get-queue-audits.md rename to docs/examples/organization/get-membership.md index a892ca25..b3fcd9de 100644 --- a/docs/examples/health/get-queue-audits.md +++ b/docs/examples/organization/get-membership.md @@ -1,17 +1,17 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue +from appwrite.services.organization import Organization +from appwrite.models import Membership 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 -health = Health(client) +organization = Organization(client) -result: HealthQueue = health.get_queue_audits( - threshold = None # optional +result: Membership = organization.get_membership( + membership_id = '' ) print(result.model_dump()) diff --git a/docs/examples/health/get-cache.md b/docs/examples/organization/get.md similarity index 59% rename from docs/examples/health/get-cache.md rename to docs/examples/organization/get.md index 39050878..b99b6a7f 100644 --- a/docs/examples/health/get-cache.md +++ b/docs/examples/organization/get.md @@ -1,16 +1,16 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatusList +from appwrite.services.organization import Organization +from appwrite.models import Organization as OrganizationModel 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 -health = Health(client) +organization = Organization(client) -result: HealthStatusList = health.get_cache() +result: OrganizationModel = organization.get() print(result.model_dump()) ``` diff --git a/docs/examples/messaging/list-message-logs.md b/docs/examples/organization/list-memberships.md similarity index 60% rename from docs/examples/messaging/list-message-logs.md rename to docs/examples/organization/list-memberships.md index 27d6b9b6..e49e1793 100644 --- a/docs/examples/messaging/list-message-logs.md +++ b/docs/examples/organization/list-memberships.md @@ -1,18 +1,18 @@ ```python from appwrite.client import Client -from appwrite.services.messaging import Messaging -from appwrite.models import LogList +from appwrite.services.organization import Organization +from appwrite.models import MembershipList 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 -messaging = Messaging(client) +organization = Organization(client) -result: LogList = messaging.list_message_logs( - message_id = '', +result: MembershipList = organization.list_memberships( queries = [], # optional + search = '', # optional total = False # optional ) diff --git a/docs/examples/health/get-console-pausing.md b/docs/examples/organization/update-membership.md similarity index 55% rename from docs/examples/health/get-console-pausing.md rename to docs/examples/organization/update-membership.md index 633c175a..a4f9c5a0 100644 --- a/docs/examples/health/get-console-pausing.md +++ b/docs/examples/organization/update-membership.md @@ -1,18 +1,18 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthStatus +from appwrite.services.organization import Organization +from appwrite.models import Membership 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 -health = Health(client) +organization = Organization(client) -result: HealthStatus = health.get_console_pausing( - threshold = None, # optional - inactivity_days = None # optional +result: Membership = organization.update_membership( + membership_id = '', + roles = [] ) print(result.model_dump()) diff --git a/docs/examples/health/get-queue-builds.md b/docs/examples/organization/update.md similarity index 56% rename from docs/examples/health/get-queue-builds.md rename to docs/examples/organization/update.md index 0ae87b2c..6d456c57 100644 --- a/docs/examples/health/get-queue-builds.md +++ b/docs/examples/organization/update.md @@ -1,17 +1,17 @@ ```python from appwrite.client import Client -from appwrite.services.health import Health -from appwrite.models import HealthQueue +from appwrite.services.organization import Organization +from appwrite.models import Organization as OrganizationModel 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 -health = Health(client) +organization = Organization(client) -result: HealthQueue = health.get_queue_builds( - threshold = None # optional +result: OrganizationModel = organization.update( + name = '' ) print(result.model_dump()) diff --git a/docs/examples/project/update-o-auth-2-appwrite.md b/docs/examples/project/update-o-auth-2-appwrite.md new file mode 100644 index 00000000..7b765921 --- /dev/null +++ b/docs/examples/project/update-o-auth-2-appwrite.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import OAuth2Appwrite + +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: OAuth2Appwrite = project.update_o_auth2_appwrite( + client_id = '', # optional + client_secret = '', # optional + enabled = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/project/update-o-auth-2-oidc.md b/docs/examples/project/update-o-auth-2-oidc.md index 3913262d..e2df2e3c 100644 --- a/docs/examples/project/update-o-auth-2-oidc.md +++ b/docs/examples/project/update-o-auth-2-oidc.md @@ -2,6 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import OAuth2Oidc +from appwrite.enums import ProjectOAuth2OidcPrompt client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -17,6 +18,8 @@ result: OAuth2Oidc = project.update_o_auth2_oidc( authorization_url = 'https://example.com', # optional token_url = 'https://example.com', # optional user_info_url = 'https://example.com', # optional + prompt = [ProjectOAuth2OidcPrompt.NONE], # optional + max_age = 0, # optional enabled = False # optional ) diff --git a/docs/examples/project/update-o-auth-2-server.md b/docs/examples/project/update-o-auth-2-server.md index 6c5b2578..6be24c54 100644 --- a/docs/examples/project/update-o-auth-2-server.md +++ b/docs/examples/project/update-o-auth-2-server.md @@ -23,7 +23,8 @@ result: ProjectModel = project.update_o_auth2_server( verification_url = 'https://example.com', # optional user_code_length = 6, # optional user_code_format = 'numeric', # optional - device_code_duration = 60 # optional + device_code_duration = 60, # optional + default_scopes = [] # optional ) print(result.model_dump()) diff --git a/docs/examples/sites/list-specifications.md b/docs/examples/sites/list-specifications.md index c1229a30..2f04ddf4 100644 --- a/docs/examples/sites/list-specifications.md +++ b/docs/examples/sites/list-specifications.md @@ -10,7 +10,9 @@ client.set_key('') # Your secret API key sites = Sites(client) -result: SpecificationList = sites.list_specifications() +result: SpecificationList = sites.list_specifications( + type = 'runtimes' # optional +) print(result.model_dump()) ``` diff --git a/docs/examples/tablesdb/create.md b/docs/examples/tablesdb/create.md index c50f28e7..a816905f 100644 --- a/docs/examples/tablesdb/create.md +++ b/docs/examples/tablesdb/create.md @@ -14,7 +14,7 @@ result: Database = tables_db.create( database_id = '', name = '', enabled = False, # optional - dedicated_database_id = '' # optional + specification = 'serverless' # optional ) print(result.model_dump()) diff --git a/docs/examples/usage/list-events.md b/docs/examples/usage/list-events.md deleted file mode 100644 index 83f8d725..00000000 --- a/docs/examples/usage/list-events.md +++ /dev/null @@ -1,28 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.usage import Usage -from appwrite.models import UsageEventList - -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 - -usage = Usage(client) - -result: UsageEventList = usage.list_events( - metrics = [], - resource = '', # optional - resource_id = '', # optional - interval = '1m', # optional - dimensions = [], # optional - start_at = '2020-10-15T06:38:00.000+00:00', # optional - end_at = '2020-10-15T06:38:00.000+00:00', # optional - order_by = 'time', # optional - order_dir = 'asc', # optional - limit = 1, # optional - offset = 0 # optional -) - -print(result.model_dump()) -``` diff --git a/docs/examples/usage/list-gauges.md b/docs/examples/usage/list-gauges.md deleted file mode 100644 index fb221f9a..00000000 --- a/docs/examples/usage/list-gauges.md +++ /dev/null @@ -1,28 +0,0 @@ -```python -from appwrite.client import Client -from appwrite.services.usage import Usage -from appwrite.models import UsageGaugeList - -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 - -usage = Usage(client) - -result: UsageGaugeList = usage.list_gauges( - metrics = [], - resource_id = '', # optional - team_id = '', # optional - interval = '1m', # optional - dimensions = [], # optional - start_at = '2020-10-15T06:38:00.000+00:00', # optional - end_at = '2020-10-15T06:38:00.000+00:00', # optional - order_by = 'time', # optional - order_dir = 'asc', # optional - limit = 1, # optional - offset = 0 # optional -) - -print(result.model_dump()) -``` diff --git a/pyproject.toml b/pyproject.toml index 64acd0d7..10559426 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "appwrite" -version = "21.0.0" +version = "22.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/requirements.txt b/requirements.txt index 43f14202..b3386211 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ requests>=2.31,<3 -requests_mock==1.11.0 +requests_mock==1.12.1 pydantic>=2,<3 diff --git a/setup.py b/setup.py index bedddde5..9557066e 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name = 'appwrite', packages = setuptools.find_packages(), - version = '21.0.0', + version = '22.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/21.0.0.tar.gz', + download_url='https://github.com/appwrite/sdk-for-python/archive/22.0.0.tar.gz', install_requires=[ 'requests', 'pydantic>=2,<3', diff --git a/test/services/test_activities.py b/test/services/test_activities.py index 41d9d8b1..9fcc5e4d 100644 --- a/test/services/test_activities.py +++ b/test/services/test_activities.py @@ -47,9 +47,7 @@ def test_get_event(self, m): "time": "2020-10-15T06:38:00.000+00:00", "projectId": "610fc2f985ee0", "teamId": "610fc2f985ee0", - "hostname": "appwrite.io", - "countryCode": "US", - "countryName": "United States" + "hostname": "appwrite.io" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) diff --git a/test/services/test_apps.py b/test/services/test_apps.py index a8d5984d..4520a42b 100644 --- a/test/services/test_apps.py +++ b/test/services/test_apps.py @@ -42,6 +42,7 @@ def test_create(self, m): "contacts": [], "tagline": "Automate your workspace.", "tags": [], + "labels": [], "images": [], "supportUrl": "https:\/\/example.com\/support", "dataDeletionUrl": "https:\/\/example.com\/data-deletion", @@ -80,6 +81,7 @@ def test_get(self, m): "contacts": [], "tagline": "Automate your workspace.", "tags": [], + "labels": [], "images": [], "supportUrl": "https:\/\/example.com\/support", "dataDeletionUrl": "https:\/\/example.com\/data-deletion", @@ -116,6 +118,7 @@ def test_update(self, m): "contacts": [], "tagline": "Automate your workspace.", "tags": [], + "labels": [], "images": [], "supportUrl": "https:\/\/example.com\/support", "dataDeletionUrl": "https:\/\/example.com\/data-deletion", @@ -150,6 +153,44 @@ def test_delete(self, m): self.assertEqual(response, data) + @requests_mock.Mocker() + def test_update_labels(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "My Application", + "description": "Connect your workspace to My Application.", + "clientUri": "https:\/\/example.com", + "logoUri": "https:\/\/example.com\/logo.png", + "privacyPolicyUrl": "https:\/\/example.com\/privacy", + "termsUrl": "https:\/\/example.com\/terms", + "contacts": [], + "tagline": "Automate your workspace.", + "tags": [], + "labels": [], + "images": [], + "supportUrl": "https:\/\/example.com\/support", + "dataDeletionUrl": "https:\/\/example.com\/data-deletion", + "redirectUris": [], + "postLogoutRedirectUris": [], + "enabled": True, + "type": "confidential", + "deviceFlow": True, + "teamId": "5e5ea5c16897e", + "userId": "5e5ea5c16897e", + "secrets": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.apps.update_labels( + '', + [], + ) + + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_list_secrets(self, m): data = { @@ -236,6 +277,7 @@ def test_update_team(self, m): "contacts": [], "tagline": "Automate your workspace.", "tags": [], + "labels": [], "images": [], "supportUrl": "https:\/\/example.com\/support", "dataDeletionUrl": "https:\/\/example.com\/data-deletion", diff --git a/test/services/test_backups.py b/test/services/test_backups.py index 83c59835..dfa1f5a2 100644 --- a/test/services/test_backups.py +++ b/test/services/test_backups.py @@ -196,7 +196,7 @@ def test_create_restoration(self, m): "migrationId": "did8jx6ws45jana098ab7", "services": [], "resources": [], - "options": "{databases.database[{oldId, newId, newName}]}" + "options": "{databases.database[{oldId, newId, newName, newSpecification}]}" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -235,7 +235,7 @@ def test_get_restoration(self, m): "migrationId": "did8jx6ws45jana098ab7", "services": [], "resources": [], - "options": "{databases.database[{oldId, newId, newName}]}" + "options": "{databases.database[{oldId, newId, newName, newSpecification}]}" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) diff --git a/test/services/test_health.py b/test/services/test_health.py deleted file mode 100644 index 930aeb62..00000000 --- a/test/services/test_health.py +++ /dev/null @@ -1,361 +0,0 @@ -import json -import requests_mock -import unittest - -from appwrite.client import Client -from appwrite.input_file import InputFile -from appwrite.models import * -from appwrite.services.health import Health - -class HealthServiceTest(unittest.TestCase): - - def setUp(self): - self.client = Client() - self.health = Health(self.client) - - @requests_mock.Mocker() - def test_get(self, m): - data = { - "name": "database", - "ping": 128.0, - "status": "pass" -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_antivirus(self, m): - data = { - "version": "1.0.0", - "status": "online" -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_antivirus( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_audits_db(self, m): - data = { - "total": 5.0, - "statuses": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_audits_db( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_cache(self, m): - data = { - "total": 5.0, - "statuses": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_cache( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_certificate(self, m): - data = { - "name": "\/CN=www.google.com", - "subjectSN": "", - "issuerOrganisation": "", - "validFrom": "1704200998", - "validTo": "1711458597", - "signatureTypeSN": "RSA-SHA256" -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_certificate( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_console_pausing(self, m): - data = { - "name": "database", - "ping": 128.0, - "status": "pass" -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_console_pausing( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_db(self, m): - data = { - "total": 5.0, - "statuses": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_db( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_pub_sub(self, m): - data = { - "total": 5.0, - "statuses": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_pub_sub( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_audits(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_audits( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_builds(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_builds( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_certificates(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_certificates( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_databases(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_databases( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_deletes(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_deletes( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_failed_jobs(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_failed_jobs( - 'v1-database', - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_functions(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_functions( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_logs(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_logs( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_mails(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_mails( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_messaging(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_messaging( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_migrations(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_migrations( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_stats_resources(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_stats_resources( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_usage(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_usage( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_queue_webhooks(self, m): - data = { - "size": 8.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_queue_webhooks( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_storage(self, m): - data = { - "name": "database", - "ping": 128.0, - "status": "pass" -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_storage( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_storage_local(self, m): - data = { - "name": "database", - "ping": 128.0, - "status": "pass" -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_storage_local( - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_get_time(self, m): - data = { - "remoteTime": 1639490751.0, - "localTime": 1639490844.0, - "diff": 93.0 -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.health.get_time( - ) - - self.assertEqual(response.to_dict(), data) - diff --git a/test/services/test_messaging.py b/test/services/test_messaging.py index 1424b6a1..ef6d618d 100644 --- a/test/services/test_messaging.py +++ b/test/services/test_messaging.py @@ -250,21 +250,6 @@ def test_delete(self, m): self.assertEqual(response, data) - @requests_mock.Mocker() - def test_list_message_logs(self, m): - data = { - "total": 5.0, - "logs": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.messaging.list_message_logs( - '', - ) - - self.assertEqual(response.to_dict(), data) - @requests_mock.Mocker() def test_list_targets(self, m): data = { @@ -974,36 +959,6 @@ def test_delete_provider(self, m): self.assertEqual(response, data) - @requests_mock.Mocker() - def test_list_provider_logs(self, m): - data = { - "total": 5.0, - "logs": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.messaging.list_provider_logs( - '', - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_list_subscriber_logs(self, m): - data = { - "total": 5.0, - "logs": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.messaging.list_subscriber_logs( - '', - ) - - self.assertEqual(response.to_dict(), data) - @requests_mock.Mocker() def test_list_topics(self, m): data = { @@ -1094,21 +1049,6 @@ def test_delete_topic(self, m): self.assertEqual(response, data) - @requests_mock.Mocker() - def test_list_topic_logs(self, m): - data = { - "total": 5.0, - "logs": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.messaging.list_topic_logs( - '', - ) - - self.assertEqual(response.to_dict(), data) - @requests_mock.Mocker() def test_list_subscribers(self, m): data = { diff --git a/test/services/test_oauth2.py b/test/services/test_oauth2.py index 4096d693..3b0bc38e 100644 --- a/test/services/test_oauth2.py +++ b/test/services/test_oauth2.py @@ -37,10 +37,6 @@ def test_authorize(self, m): m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) response = self.oauth2.authorize( - '', - 'https://example.com', - 'code', - '', ) self.assertEqual(response.to_dict(), data) @@ -72,6 +68,7 @@ def test_create_grant(self, m): "userId": "5e5ea5c16897e", "appId": "5e5ea5c16897e", "scopes": [], + "resources": [], "authorizationDetails": "[{\"type\":\"calendar\",\"identifier\":\"primary\",\"actions\":[\"read_events\",\"create_event\"]}]", "prompt": "login", "redirectUri": "https:\/\/example.com\/callback", @@ -96,6 +93,7 @@ def test_get_grant(self, m): "userId": "5e5ea5c16897e", "appId": "5e5ea5c16897e", "scopes": [], + "resources": [], "authorizationDetails": "[{\"type\":\"calendar\",\"identifier\":\"primary\",\"actions\":[\"read_events\",\"create_event\"]}]", "prompt": "login", "redirectUri": "https:\/\/example.com\/callback", @@ -111,6 +109,51 @@ def test_get_grant(self, m): self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() + def test_list_organizations(self, m): + data = { + "total": 5.0, + "organizations": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.oauth2.list_organizations( + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_create_par(self, m): + data = { + "request_uri": "urn:appwrite:oauth2:request:5e5ea5c16897e", + "expires_in": 600.0 +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.oauth2.create_par( + '', + 'https://example.com', + 'code', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_list_projects(self, m): + data = { + "total": 5.0, + "projects": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.oauth2.list_projects( + ) + + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_reject(self, m): data = { diff --git a/test/services/test_organization.py b/test/services/test_organization.py index a4e32d24..7cd67f61 100644 --- a/test/services/test_organization.py +++ b/test/services/test_organization.py @@ -13,6 +13,468 @@ def setUp(self): self.client = Client() self.organization = Organization(self.client) + @requests_mock.Mocker() + def test_get(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "VIP", + "total": 7.0, + "prefs": {}, + "billingBudget": 50.0, + "budgetAlerts": [], + "billingPlan": "tier-1", + "billingPlanId": "tier-1", + "billingPlanDetails": { + "$id": "tier-0", + "name": "Hobby", + "desc": "Hobby plan", + "order": 0.0, + "price": 25, + "trial": 14.0, + "bandwidth": 25.0, + "storage": 25.0, + "imageTransformations": 100.0, + "screenshotsGenerated": 50.0, + "members": 25.0, + "webhooks": 25.0, + "projects": 2.0, + "platforms": 3.0, + "users": 25.0, + "teams": 25.0, + "databases": 25.0, + "databasesReads": 500000.0, + "databasesWrites": 250000.0, + "databasesBatchSize": 100.0, + "buckets": 25.0, + "fileSize": 25.0, + "functions": 25.0, + "sites": 1.0, + "executions": 25.0, + "executionsRetentionCount": 10000.0, + "GBHours": 100.0, + "realtime": 25.0, + "realtimeMessages": 100000.0, + "messages": 1000.0, + "topics": 1.0, + "authPhone": 10.0, + "domains": 5.0, + "activityLogs": 7.0, + "usageLogs": 30.0, + "projectInactivityDays": 7.0, + "alertLimit": 80.0, + "usage": { + "bandwidth": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "executions": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "member": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "realtime": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "realtimeMessages": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "realtimeBandwidth": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "storage": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "users": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "GBHours": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "imageTransformations": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "credits": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + } + }, + "addons": { + "seats": { + "supported": True, + "planIncluded": 1.0, + "limit": 5.0, + "type": "numeric", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "projects": { + "supported": True, + "planIncluded": 1.0, + "limit": 5.0, + "type": "numeric", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + } + }, + "budgetCapEnabled": True, + "customSmtp": True, + "emailBranding": True, + "requiresPaymentMethod": True, + "requiresBillingAddress": True, + "isAvailable": True, + "selfService": True, + "premiumSupport": True, + "budgeting": True, + "supportsMockNumbers": True, + "supportsOrganizationRoles": True, + "supportsCredits": True, + "supportsDisposableEmailValidation": True, + "supportsCanonicalEmailValidation": True, + "supportsFreeEmailValidation": True, + "supportsCorporateEmailValidation": True, + "supportsProjectSpecificRoles": True, + "backupsEnabled": True, + "usagePerProject": True, + "supportedAddons": { + "baa": True, + "premiumGeoDB": True, + "premiumGeoDBOrg": True + }, + "backupPolicies": 1.0, + "deploymentSize": 30.0, + "buildSize": 2000.0, + "databasesAllowEncrypt": True, + "group": "pro" + }, + "billingEmail": "billing@org.example", + "billingStartDate": "2020-10-15T06:38:00.000+00:00", + "billingCurrentInvoiceDate": "2020-10-15T06:38:00.000+00:00", + "billingNextInvoiceDate": "2020-10-15T06:38:00.000+00:00", + "billingTrialStartDate": "2020-10-15T06:38:00.000+00:00", + "billingTrialDays": 14.0, + "billingAggregationId": "adbc3de4rddfsd", + "billingInvoiceId": "adbc3de4rddfsd", + "paymentMethodId": "adbc3de4rddfsd", + "billingAddressId": "adbc3de4rddfsd", + "backupPaymentMethodId": "adbc3de4rddfsd", + "status": "active", + "remarks": "Pending initial payment", + "agreementBAA": "", + "programManagerName": "", + "programManagerCalendar": "", + "programDiscordChannelName": "", + "programDiscordChannelUrl": "", + "billingPlanDowngrade": "tier-1", + "billingTaxId": "", + "markedForDeletion": True, + "platform": "imagine", + "projects": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.get( + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "VIP", + "total": 7.0, + "prefs": {}, + "billingBudget": 50.0, + "budgetAlerts": [], + "billingPlan": "tier-1", + "billingPlanId": "tier-1", + "billingPlanDetails": { + "$id": "tier-0", + "name": "Hobby", + "desc": "Hobby plan", + "order": 0.0, + "price": 25, + "trial": 14.0, + "bandwidth": 25.0, + "storage": 25.0, + "imageTransformations": 100.0, + "screenshotsGenerated": 50.0, + "members": 25.0, + "webhooks": 25.0, + "projects": 2.0, + "platforms": 3.0, + "users": 25.0, + "teams": 25.0, + "databases": 25.0, + "databasesReads": 500000.0, + "databasesWrites": 250000.0, + "databasesBatchSize": 100.0, + "buckets": 25.0, + "fileSize": 25.0, + "functions": 25.0, + "sites": 1.0, + "executions": 25.0, + "executionsRetentionCount": 10000.0, + "GBHours": 100.0, + "realtime": 25.0, + "realtimeMessages": 100000.0, + "messages": 1000.0, + "topics": 1.0, + "authPhone": 10.0, + "domains": 5.0, + "activityLogs": 7.0, + "usageLogs": 30.0, + "projectInactivityDays": 7.0, + "alertLimit": 80.0, + "usage": { + "bandwidth": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "executions": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "member": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "realtime": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "realtimeMessages": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "realtimeBandwidth": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "storage": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "users": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "GBHours": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "imageTransformations": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "credits": { + "name": "", + "unit": "GB", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + } + }, + "addons": { + "seats": { + "supported": True, + "planIncluded": 1.0, + "limit": 5.0, + "type": "numeric", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + }, + "projects": { + "supported": True, + "planIncluded": 1.0, + "limit": 5.0, + "type": "numeric", + "currency": "USD", + "price": 5, + "value": 25.0, + "invoiceDesc": "" + } + }, + "budgetCapEnabled": True, + "customSmtp": True, + "emailBranding": True, + "requiresPaymentMethod": True, + "requiresBillingAddress": True, + "isAvailable": True, + "selfService": True, + "premiumSupport": True, + "budgeting": True, + "supportsMockNumbers": True, + "supportsOrganizationRoles": True, + "supportsCredits": True, + "supportsDisposableEmailValidation": True, + "supportsCanonicalEmailValidation": True, + "supportsFreeEmailValidation": True, + "supportsCorporateEmailValidation": True, + "supportsProjectSpecificRoles": True, + "backupsEnabled": True, + "usagePerProject": True, + "supportedAddons": { + "baa": True, + "premiumGeoDB": True, + "premiumGeoDBOrg": True + }, + "backupPolicies": 1.0, + "deploymentSize": 30.0, + "buildSize": 2000.0, + "databasesAllowEncrypt": True, + "group": "pro" + }, + "billingEmail": "billing@org.example", + "billingStartDate": "2020-10-15T06:38:00.000+00:00", + "billingCurrentInvoiceDate": "2020-10-15T06:38:00.000+00:00", + "billingNextInvoiceDate": "2020-10-15T06:38:00.000+00:00", + "billingTrialStartDate": "2020-10-15T06:38:00.000+00:00", + "billingTrialDays": 14.0, + "billingAggregationId": "adbc3de4rddfsd", + "billingInvoiceId": "adbc3de4rddfsd", + "paymentMethodId": "adbc3de4rddfsd", + "billingAddressId": "adbc3de4rddfsd", + "backupPaymentMethodId": "adbc3de4rddfsd", + "status": "active", + "remarks": "Pending initial payment", + "agreementBAA": "", + "programManagerName": "", + "programManagerCalendar": "", + "programDiscordChannelName": "", + "programDiscordChannelUrl": "", + "billingPlanDowngrade": "tier-1", + "billingTaxId": "", + "markedForDeletion": True, + "platform": "imagine", + "projects": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.update( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_delete(self, m): + data = '' + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.delete( + ) + + self.assertEqual(response, data) + @requests_mock.Mocker() def test_list_keys(self, m): data = { @@ -109,6 +571,117 @@ def test_delete_key(self, m): self.assertEqual(response, data) + @requests_mock.Mocker() + def test_list_memberships(self, m): + data = { + "total": 5.0, + "memberships": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.list_memberships( + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_create_membership(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "userId": "5e5ea5c16897e", + "userName": "John Doe", + "userEmail": "john@appwrite.io", + "userPhone": "+1 555 555 5555", + "teamId": "5e5ea5c16897e", + "teamName": "VIP", + "invited": "2020-10-15T06:38:00.000+00:00", + "joined": "2020-10-15T06:38:00.000+00:00", + "confirm": True, + "mfa": True, + "userAccessedAt": "2020-10-15T06:38:00.000+00:00", + "roles": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.create_membership( + [], + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_get_membership(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "userId": "5e5ea5c16897e", + "userName": "John Doe", + "userEmail": "john@appwrite.io", + "userPhone": "+1 555 555 5555", + "teamId": "5e5ea5c16897e", + "teamName": "VIP", + "invited": "2020-10-15T06:38:00.000+00:00", + "joined": "2020-10-15T06:38:00.000+00:00", + "confirm": True, + "mfa": True, + "userAccessedAt": "2020-10-15T06:38:00.000+00:00", + "roles": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.get_membership( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update_membership(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "userId": "5e5ea5c16897e", + "userName": "John Doe", + "userEmail": "john@appwrite.io", + "userPhone": "+1 555 555 5555", + "teamId": "5e5ea5c16897e", + "teamName": "VIP", + "invited": "2020-10-15T06:38:00.000+00:00", + "joined": "2020-10-15T06:38:00.000+00:00", + "confirm": True, + "mfa": True, + "userAccessedAt": "2020-10-15T06:38:00.000+00:00", + "roles": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.update_membership( + '', + [], + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_delete_membership(self, m): + data = '' + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.delete_membership( + '', + ) + + self.assertEqual(response, data) + @requests_mock.Mocker() def test_list_projects(self, m): data = { @@ -147,6 +720,7 @@ def test_create_project(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -187,6 +761,7 @@ def test_get_project(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -226,6 +801,7 @@ def test_update_project(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], diff --git a/test/services/test_project.py b/test/services/test_project.py index 9440e29e..c3e87cf3 100644 --- a/test/services/test_project.py +++ b/test/services/test_project.py @@ -37,6 +37,7 @@ def test_get(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -86,6 +87,7 @@ def test_update_auth_method(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -245,6 +247,7 @@ def test_update_labels(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -377,6 +380,7 @@ def test_update_o_auth2_server(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -427,6 +431,22 @@ def test_update_o_auth2_apple(self, m): self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() + def test_update_o_auth2_appwrite(self, m): + data = { + "$id": "github", + "enabled": True, + "clientId": "6a42000000000000b5a0", + "clientSecret": "b86afd000000000000000000000000000000000000000000000000000ced5f93" +} + 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_appwrite( + ) + + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_update_o_auth2_auth0(self, m): data = { @@ -797,7 +817,8 @@ def test_update_o_auth2_oidc(self, m): "wellKnownURL": "https:\/\/myoauth.com\/.well-known\/openid-configuration", "authorizationURL": "https:\/\/myoauth.com\/oauth2\/authorize", "tokenURL": "https:\/\/myoauth.com\/oauth2\/token", - "userInfoURL": "https:\/\/myoauth.com\/oauth2\/userinfo" + "userInfoURL": "https:\/\/myoauth.com\/oauth2\/userinfo", + "prompt": [] } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1391,6 +1412,7 @@ def test_update_deny_aliased_email_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1430,6 +1452,7 @@ def test_update_deny_corporate_email_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1469,6 +1492,7 @@ def test_update_deny_disposable_email_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1508,6 +1532,7 @@ def test_update_deny_free_email_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1547,6 +1572,7 @@ def test_update_membership_privacy_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1585,6 +1611,7 @@ def test_update_password_dictionary_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1624,6 +1651,7 @@ def test_update_password_history_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1663,6 +1691,7 @@ def test_update_password_personal_data_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1720,6 +1749,7 @@ def test_update_session_alert_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1759,6 +1789,7 @@ def test_update_session_duration_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1798,6 +1829,7 @@ def test_update_session_invalidation_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1837,6 +1869,7 @@ def test_update_session_limit_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1876,6 +1909,7 @@ def test_update_user_limit_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1930,6 +1964,7 @@ def test_update_protocol(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -1970,6 +2005,7 @@ def test_update_service(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], @@ -2010,6 +2046,7 @@ def test_update_smtp(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", + "onboarding": {}, "authMethods": [], "services": [], "protocols": [], diff --git a/test/services/test_usage.py b/test/services/test_usage.py deleted file mode 100644 index d54ff32f..00000000 --- a/test/services/test_usage.py +++ /dev/null @@ -1,45 +0,0 @@ -import json -import requests_mock -import unittest - -from appwrite.client import Client -from appwrite.input_file import InputFile -from appwrite.models import * -from appwrite.services.usage import Usage - -class UsageServiceTest(unittest.TestCase): - - def setUp(self): - self.client = Client() - self.usage = Usage(self.client) - - @requests_mock.Mocker() - def test_list_events(self, m): - data = { - "interval": "1d", - "metrics": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.usage.list_events( - [], - ) - - self.assertEqual(response.to_dict(), data) - - @requests_mock.Mocker() - def test_list_gauges(self, m): - data = { - "interval": "1d", - "metrics": [] -} - headers = {'Content-Type': 'application/json'} - m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - - response = self.usage.list_gauges( - [], - ) - - self.assertEqual(response.to_dict(), data) - From 0f3c9d2a792f2066c689d4581b0965139b39b188 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 13 Jul 2026 12:11:04 +0530 Subject: [PATCH 2/2] chore: update Python SDK to 22.0.0 --- appwrite/client.py | 2 +- appwrite/services/backups.py | 15 +- appwrite/services/databases.py | 207 ++++++++---- appwrite/services/functions.py | 24 +- appwrite/services/messaging.py | 216 ++++++++---- appwrite/services/oauth2.py | 3 +- appwrite/services/organization.py | 6 +- appwrite/services/project.py | 525 ++++++++++++++++++++---------- appwrite/services/sites.py | 18 +- appwrite/services/storage.py | 9 +- appwrite/services/tables_db.py | 210 ++++++++---- appwrite/services/tokens.py | 6 +- appwrite/services/users.py | 6 +- appwrite/services/webhooks.py | 6 +- 14 files changed, 835 insertions(+), 418 deletions(-) diff --git a/appwrite/client.py b/appwrite/client.py index 83f61a8f..0fc438b7 100644 --- a/appwrite/client.py +++ b/appwrite/client.py @@ -70,7 +70,7 @@ def set_jwt(self, value): def set_bearer(self, value): """The OAuth access token to authenticate with""" - self._global_headers['authorization'] = value + self._global_headers['authorization'] = 'Bearer ' + value self._config['bearer'] = value return self diff --git a/appwrite/services/backups.py b/appwrite/services/backups.py index fda14881..5aac7329 100644 --- a/appwrite/services/backups.py +++ b/appwrite/services/backups.py @@ -86,7 +86,8 @@ def create_archive( api_params['services'] = self._normalize_value(services) - api_params['resourceId'] = self._normalize_value(resource_id) + if resource_id is not None: + api_params['resourceId'] = self._normalize_value(resource_id) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -273,7 +274,8 @@ def create_policy( if name is not None: api_params['name'] = self._normalize_value(name) api_params['services'] = self._normalize_value(services) - api_params['resourceId'] = self._normalize_value(resource_id) + if resource_id is not None: + api_params['resourceId'] = self._normalize_value(resource_id) if enabled is not None: api_params['enabled'] = self._normalize_value(enabled) api_params['retention'] = self._normalize_value(retention) @@ -369,11 +371,14 @@ def update_policy( api_path = api_path.replace('{policyId}', str(self._normalize_value(policy_id))) - api_params['name'] = self._normalize_value(name) - api_params['retention'] = self._normalize_value(retention) + if name is not None: + api_params['name'] = self._normalize_value(name) + if retention is not None: + api_params['retention'] = self._normalize_value(retention) if schedule is not None: api_params['schedule'] = self._normalize_value(schedule) - api_params['enabled'] = self._normalize_value(enabled) + 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'), diff --git a/appwrite/services/databases.py b/appwrite/services/databases.py index fdc30428..51831aec 100644 --- a/appwrite/services/databases.py +++ b/appwrite/services/databases.py @@ -672,7 +672,8 @@ def create_collection( api_params['collectionId'] = self._normalize_value(collection_id) api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) if document_security is not None: api_params['documentSecurity'] = self._normalize_value(document_security) if enabled is not None: @@ -797,7 +798,8 @@ def update_collection( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) if document_security is not None: api_params['documentSecurity'] = self._normalize_value(document_security) if enabled is not None: @@ -989,9 +991,12 @@ def create_big_int_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) - api_params['default'] = self._normalize_value(default) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1071,10 +1076,13 @@ def update_big_int_attribute( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1146,7 +1154,8 @@ def create_boolean_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1220,7 +1229,8 @@ def update_boolean_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1291,7 +1301,8 @@ def create_datetime_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1365,7 +1376,8 @@ def update_datetime_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1437,7 +1449,8 @@ def create_email_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1512,7 +1525,8 @@ def update_email_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1591,7 +1605,8 @@ def create_enum_attribute( api_params['key'] = self._normalize_value(key) api_params['elements'] = self._normalize_value(elements) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1673,7 +1688,8 @@ def update_enum_attribute( api_params['elements'] = self._normalize_value(elements) api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1751,9 +1767,12 @@ def create_float_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) - api_params['default'] = self._normalize_value(default) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1833,10 +1852,13 @@ def update_float_attribute( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1914,9 +1936,12 @@ def create_integer_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) - api_params['default'] = self._normalize_value(default) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1996,10 +2021,13 @@ def update_integer_attribute( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2071,7 +2099,8 @@ def create_ip_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -2146,7 +2175,8 @@ def update_ip_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2214,7 +2244,8 @@ def create_line_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2285,8 +2316,10 @@ def update_line_attribute( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if default is not None: + api_params['default'] = self._normalize_value(default) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2361,7 +2394,8 @@ def create_longtext_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -2438,7 +2472,8 @@ def update_longtext_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2513,7 +2548,8 @@ def create_mediumtext_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -2590,7 +2626,8 @@ def update_mediumtext_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2658,7 +2695,8 @@ def create_point_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2729,8 +2767,10 @@ def update_point_attribute( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if default is not None: + api_params['default'] = self._normalize_value(default) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2798,7 +2838,8 @@ def create_polygon_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2869,8 +2910,10 @@ def update_polygon_attribute( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if default is not None: + api_params['default'] = self._normalize_value(default) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2950,8 +2993,10 @@ def create_relationship_attribute( api_params['type'] = self._normalize_value(type) if two_way is not None: api_params['twoWay'] = self._normalize_value(two_way) - api_params['key'] = self._normalize_value(key) - api_params['twoWayKey'] = self._normalize_value(two_way_key) + if key is not None: + api_params['key'] = self._normalize_value(key) + if two_way_key is not None: + api_params['twoWayKey'] = self._normalize_value(two_way_key) if on_delete is not None: api_params['onDelete'] = self._normalize_value(on_delete) @@ -3020,7 +3065,8 @@ def update_relationship_attribute( if on_delete is not None: api_params['onDelete'] = self._normalize_value(on_delete) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3102,7 +3148,8 @@ def create_string_attribute( api_params['key'] = self._normalize_value(key) api_params['size'] = self._normalize_value(size) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -3182,8 +3229,10 @@ def update_string_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['size'] = self._normalize_value(size) - api_params['newKey'] = self._normalize_value(new_key) + if size is not None: + api_params['size'] = self._normalize_value(size) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3258,7 +3307,8 @@ def create_text_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -3335,7 +3385,8 @@ def update_text_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3407,7 +3458,8 @@ def create_url_attribute( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -3482,7 +3534,8 @@ def update_url_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3564,7 +3617,8 @@ def create_varchar_attribute( api_params['key'] = self._normalize_value(key) api_params['size'] = self._normalize_value(size) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -3644,8 +3698,10 @@ def update_varchar_attribute( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['size'] = self._normalize_value(size) - api_params['newKey'] = self._normalize_value(new_key) + if size is not None: + api_params['size'] = self._normalize_value(size) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3937,8 +3993,10 @@ def create_document( api_params['documentId'] = self._normalize_value(document_id) api_params['data'] = self._normalize_value(data) - api_params['permissions'] = self._normalize_value(permissions) - api_params['transactionId'] = self._normalize_value(transaction_id) + 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', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4003,7 +4061,8 @@ def create_documents( api_path = api_path.replace('{collectionId}', str(self._normalize_value(collection_id))) api_params['documents'] = self._normalize_value(documents) - api_params['transactionId'] = self._normalize_value(transaction_id) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4069,7 +4128,8 @@ def upsert_documents( api_path = api_path.replace('{collectionId}', str(self._normalize_value(collection_id))) api_params['documents'] = self._normalize_value(documents) - api_params['transactionId'] = self._normalize_value(transaction_id) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4137,7 +4197,8 @@ def update_documents( api_params['data'] = self._normalize_value(data) if queries is not None: api_params['queries'] = self._normalize_value(queries) - api_params['transactionId'] = self._normalize_value(transaction_id) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4344,8 +4405,10 @@ def upsert_document( if data is not None: api_params['data'] = self._normalize_value(data) - api_params['permissions'] = self._normalize_value(permissions) - api_params['transactionId'] = self._normalize_value(transaction_id) + 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('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4418,8 +4481,10 @@ def update_document( if data is not None: api_params['data'] = self._normalize_value(data) - api_params['permissions'] = self._normalize_value(permissions) - api_params['transactionId'] = self._normalize_value(transaction_id) + 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('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4560,8 +4625,10 @@ def decrement_document_attribute( if value is not None: api_params['value'] = self._normalize_value(value) - api_params['min'] = self._normalize_value(min) - api_params['transactionId'] = self._normalize_value(transaction_id) + if min is not None: + api_params['min'] = self._normalize_value(min) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4641,8 +4708,10 @@ def increment_document_attribute( if value is not None: api_params['value'] = self._normalize_value(value) - api_params['max'] = self._normalize_value(max) - api_params['transactionId'] = self._normalize_value(transaction_id) + if max is not None: + api_params['max'] = self._normalize_value(max) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/functions.py b/appwrite/services/functions.py index 18709fb2..4b0f552f 100644 --- a/appwrite/services/functions.py +++ b/appwrite/services/functions.py @@ -445,16 +445,20 @@ def update( api_params['scopes'] = self._normalize_value(scopes) if installation_id is not None: api_params['installationId'] = self._normalize_value(installation_id) - api_params['providerRepositoryId'] = self._normalize_value(provider_repository_id) + if provider_repository_id is not None: + api_params['providerRepositoryId'] = self._normalize_value(provider_repository_id) if provider_branch is not None: api_params['providerBranch'] = self._normalize_value(provider_branch) if provider_silent_mode is not None: api_params['providerSilentMode'] = self._normalize_value(provider_silent_mode) if provider_root_directory is not None: api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) - api_params['providerBranches'] = self._normalize_value(provider_branches) - api_params['providerPaths'] = self._normalize_value(provider_paths) - api_params['buildSpecification'] = self._normalize_value(build_specification) + if provider_branches is not None: + api_params['providerBranches'] = self._normalize_value(provider_branches) + if provider_paths is not None: + api_params['providerPaths'] = self._normalize_value(provider_paths) + if build_specification is not None: + api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: api_params['runtimeSpecification'] = self._normalize_value(runtime_specification) if deployment_retention is not None: @@ -1182,7 +1186,8 @@ def create_execution( api_params['method'] = self._normalize_value(method) if headers is not None: api_params['headers'] = self._normalize_value(headers) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1492,9 +1497,12 @@ def update_variable( api_path = api_path.replace('{functionId}', str(self._normalize_value(function_id))) api_path = api_path.replace('{variableId}', str(self._normalize_value(variable_id))) - api_params['key'] = self._normalize_value(key) - api_params['value'] = self._normalize_value(value) - api_params['secret'] = self._normalize_value(secret) + if key is not None: + api_params['key'] = self._normalize_value(key) + if value is not None: + api_params['value'] = self._normalize_value(value) + if secret is not None: + api_params['secret'] = self._normalize_value(secret) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/messaging.py b/appwrite/services/messaging.py index 3abb1004..2ebe2bd6 100644 --- a/appwrite/services/messaging.py +++ b/appwrite/services/messaging.py @@ -154,7 +154,8 @@ def create_email( api_params['draft'] = self._normalize_value(draft) if html is not None: api_params['html'] = self._normalize_value(html) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -229,17 +230,28 @@ def update_email( api_path = api_path.replace('{messageId}', str(self._normalize_value(message_id))) - api_params['topics'] = self._normalize_value(topics) - api_params['users'] = self._normalize_value(users) - api_params['targets'] = self._normalize_value(targets) - api_params['subject'] = self._normalize_value(subject) - api_params['content'] = self._normalize_value(content) - api_params['draft'] = self._normalize_value(draft) - api_params['html'] = self._normalize_value(html) - api_params['cc'] = self._normalize_value(cc) - api_params['bcc'] = self._normalize_value(bcc) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) - api_params['attachments'] = self._normalize_value(attachments) + if topics is not None: + api_params['topics'] = self._normalize_value(topics) + if users is not None: + api_params['users'] = self._normalize_value(users) + if targets is not None: + api_params['targets'] = self._normalize_value(targets) + if subject is not None: + api_params['subject'] = self._normalize_value(subject) + if content is not None: + api_params['content'] = self._normalize_value(content) + if draft is not None: + api_params['draft'] = self._normalize_value(draft) + if html is not None: + api_params['html'] = self._normalize_value(html) + if cc is not None: + api_params['cc'] = self._normalize_value(cc) + if bcc is not None: + api_params['bcc'] = self._normalize_value(bcc) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if attachments is not None: + api_params['attachments'] = self._normalize_value(attachments) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -344,7 +356,8 @@ def create_push( api_params['users'] = self._normalize_value(users) if targets is not None: api_params['targets'] = self._normalize_value(targets) - api_params['data'] = self._normalize_value(data) + if data is not None: + api_params['data'] = self._normalize_value(data) if action is not None: api_params['action'] = self._normalize_value(action) if image is not None: @@ -361,7 +374,8 @@ def create_push( api_params['badge'] = self._normalize_value(badge) if draft is not None: api_params['draft'] = self._normalize_value(draft) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) if content_available is not None: api_params['contentAvailable'] = self._normalize_value(content_available) if critical is not None: @@ -463,24 +477,42 @@ def update_push( api_path = api_path.replace('{messageId}', str(self._normalize_value(message_id))) - api_params['topics'] = self._normalize_value(topics) - api_params['users'] = self._normalize_value(users) - api_params['targets'] = self._normalize_value(targets) - api_params['title'] = self._normalize_value(title) - api_params['body'] = self._normalize_value(body) - api_params['data'] = self._normalize_value(data) - api_params['action'] = self._normalize_value(action) - api_params['image'] = self._normalize_value(image) - api_params['icon'] = self._normalize_value(icon) - api_params['sound'] = self._normalize_value(sound) - api_params['color'] = self._normalize_value(color) - api_params['tag'] = self._normalize_value(tag) - api_params['badge'] = self._normalize_value(badge) - api_params['draft'] = self._normalize_value(draft) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) - api_params['contentAvailable'] = self._normalize_value(content_available) - api_params['critical'] = self._normalize_value(critical) - api_params['priority'] = self._normalize_value(priority) + if topics is not None: + api_params['topics'] = self._normalize_value(topics) + if users is not None: + api_params['users'] = self._normalize_value(users) + if targets is not None: + api_params['targets'] = self._normalize_value(targets) + if title is not None: + api_params['title'] = self._normalize_value(title) + if body is not None: + api_params['body'] = self._normalize_value(body) + if data is not None: + api_params['data'] = self._normalize_value(data) + if action is not None: + api_params['action'] = self._normalize_value(action) + if image is not None: + api_params['image'] = self._normalize_value(image) + if icon is not None: + api_params['icon'] = self._normalize_value(icon) + if sound is not None: + api_params['sound'] = self._normalize_value(sound) + if color is not None: + api_params['color'] = self._normalize_value(color) + if tag is not None: + api_params['tag'] = self._normalize_value(tag) + if badge is not None: + api_params['badge'] = self._normalize_value(badge) + if draft is not None: + api_params['draft'] = self._normalize_value(draft) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if content_available is not None: + api_params['contentAvailable'] = self._normalize_value(content_available) + if critical is not None: + api_params['critical'] = self._normalize_value(critical) + if priority is not None: + api_params['priority'] = self._normalize_value(priority) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -551,7 +583,8 @@ def create_sms( api_params['targets'] = self._normalize_value(targets) if draft is not None: api_params['draft'] = self._normalize_value(draft) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -611,12 +644,18 @@ def update_sms( api_path = api_path.replace('{messageId}', str(self._normalize_value(message_id))) - api_params['topics'] = self._normalize_value(topics) - api_params['users'] = self._normalize_value(users) - api_params['targets'] = self._normalize_value(targets) - api_params['content'] = self._normalize_value(content) - api_params['draft'] = self._normalize_value(draft) - api_params['scheduledAt'] = self._normalize_value(scheduled_at) + if topics is not None: + api_params['topics'] = self._normalize_value(topics) + if users is not None: + api_params['users'] = self._normalize_value(users) + if targets is not None: + api_params['targets'] = self._normalize_value(targets) + if content is not None: + api_params['content'] = self._normalize_value(content) + if draft is not None: + api_params['draft'] = self._normalize_value(draft) + if scheduled_at is not None: + api_params['scheduledAt'] = self._normalize_value(scheduled_at) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -867,7 +906,8 @@ def create_apns_provider( api_params['bundleId'] = self._normalize_value(bundle_id) if sandbox is not None: api_params['sandbox'] = self._normalize_value(sandbox) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -931,7 +971,8 @@ def update_apns_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if auth_key is not None: api_params['authKey'] = self._normalize_value(auth_key) if auth_key_id is not None: @@ -940,7 +981,8 @@ def update_apns_provider( api_params['teamId'] = self._normalize_value(team_id) if bundle_id is not None: api_params['bundleId'] = self._normalize_value(bundle_id) - api_params['sandbox'] = self._normalize_value(sandbox) + if sandbox is not None: + api_params['sandbox'] = self._normalize_value(sandbox) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -994,8 +1036,10 @@ def create_fcm_provider( api_params['providerId'] = self._normalize_value(provider_id) api_params['name'] = self._normalize_value(name) - api_params['serviceAccountJSON'] = self._normalize_value(service_account_json) - api_params['enabled'] = self._normalize_value(enabled) + if service_account_json is not None: + api_params['serviceAccountJSON'] = self._normalize_value(service_account_json) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1047,8 +1091,10 @@ def update_fcm_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) - api_params['serviceAccountJSON'] = self._normalize_value(service_account_json) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) + if service_account_json is not None: + api_params['serviceAccountJSON'] = self._normalize_value(service_account_json) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1124,7 +1170,8 @@ def create_mailgun_provider( api_params['apiKey'] = self._normalize_value(api_key) if domain is not None: api_params['domain'] = self._normalize_value(domain) - api_params['isEuRegion'] = self._normalize_value(is_eu_region) + if is_eu_region is not None: + api_params['isEuRegion'] = self._normalize_value(is_eu_region) if from_name is not None: api_params['fromName'] = self._normalize_value(from_name) if from_email is not None: @@ -1133,7 +1180,8 @@ def create_mailgun_provider( api_params['replyToName'] = self._normalize_value(reply_to_name) if reply_to_email is not None: api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1207,8 +1255,10 @@ def update_mailgun_provider( api_params['apiKey'] = self._normalize_value(api_key) if domain is not None: api_params['domain'] = self._normalize_value(domain) - api_params['isEuRegion'] = self._normalize_value(is_eu_region) - api_params['enabled'] = self._normalize_value(enabled) + if is_eu_region is not None: + api_params['isEuRegion'] = self._normalize_value(is_eu_region) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if from_name is not None: api_params['fromName'] = self._normalize_value(from_name) if from_email is not None: @@ -1282,7 +1332,8 @@ def create_msg91_provider( api_params['senderId'] = self._normalize_value(sender_id) if auth_key is not None: api_params['authKey'] = self._normalize_value(auth_key) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1340,7 +1391,8 @@ def update_msg91_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if template_id is not None: api_params['templateId'] = self._normalize_value(template_id) if sender_id is not None: @@ -1422,7 +1474,8 @@ def create_resend_provider( api_params['replyToName'] = self._normalize_value(reply_to_name) if reply_to_email is not None: api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1486,7 +1539,8 @@ def update_resend_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if api_key is not None: api_params['apiKey'] = self._normalize_value(api_key) if from_name is not None: @@ -1572,7 +1626,8 @@ def create_sendgrid_provider( api_params['replyToName'] = self._normalize_value(reply_to_name) if reply_to_email is not None: api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1636,7 +1691,8 @@ def update_sendgrid_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if api_key is not None: api_params['apiKey'] = self._normalize_value(api_key) if from_name is not None: @@ -1732,7 +1788,8 @@ def create_ses_provider( api_params['replyToName'] = self._normalize_value(reply_to_name) if reply_to_email is not None: api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1802,7 +1859,8 @@ def update_ses_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if access_key is not None: api_params['accessKey'] = self._normalize_value(access_key) if secret_key is not None: @@ -1924,7 +1982,8 @@ def create_smtp_provider( api_params['replyToName'] = self._normalize_value(reply_to_name) if reply_to_email is not None: api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2008,14 +2067,16 @@ def update_smtp_provider( api_params['name'] = self._normalize_value(name) if host is not None: api_params['host'] = self._normalize_value(host) - api_params['port'] = self._normalize_value(port) + if port is not None: + api_params['port'] = self._normalize_value(port) if username is not None: api_params['username'] = self._normalize_value(username) if password is not None: api_params['password'] = self._normalize_value(password) if encryption is not None: api_params['encryption'] = self._normalize_value(encryption) - api_params['autoTLS'] = self._normalize_value(auto_tls) + if auto_tls is not None: + api_params['autoTLS'] = self._normalize_value(auto_tls) if mailer is not None: api_params['mailer'] = self._normalize_value(mailer) if from_name is not None: @@ -2026,7 +2087,8 @@ def update_smtp_provider( api_params['replyToName'] = self._normalize_value(reply_to_name) if reply_to_email is not None: api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2092,7 +2154,8 @@ def create_telesign_provider( api_params['customerId'] = self._normalize_value(customer_id) if api_key is not None: api_params['apiKey'] = self._normalize_value(api_key) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2150,7 +2213,8 @@ def update_telesign_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if customer_id is not None: api_params['customerId'] = self._normalize_value(customer_id) if api_key is not None: @@ -2222,7 +2286,8 @@ def create_textmagic_provider( api_params['username'] = self._normalize_value(username) if api_key is not None: api_params['apiKey'] = self._normalize_value(api_key) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2280,7 +2345,8 @@ def update_textmagic_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if username is not None: api_params['username'] = self._normalize_value(username) if api_key is not None: @@ -2352,7 +2418,8 @@ def create_twilio_provider( api_params['accountSid'] = self._normalize_value(account_sid) if auth_token is not None: api_params['authToken'] = self._normalize_value(auth_token) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2410,7 +2477,8 @@ def update_twilio_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if account_sid is not None: api_params['accountSid'] = self._normalize_value(account_sid) if auth_token is not None: @@ -2482,7 +2550,8 @@ def create_vonage_provider( api_params['apiKey'] = self._normalize_value(api_key) if api_secret is not None: api_params['apiSecret'] = self._normalize_value(api_secret) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2540,7 +2609,8 @@ def update_vonage_provider( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['enabled'] = self._normalize_value(enabled) + if enabled is not None: + api_params['enabled'] = self._normalize_value(enabled) if api_key is not None: api_params['apiKey'] = self._normalize_value(api_key) if api_secret is not None: @@ -2812,8 +2882,10 @@ def update_topic( api_path = api_path.replace('{topicId}', str(self._normalize_value(topic_id))) - api_params['name'] = self._normalize_value(name) - api_params['subscribe'] = self._normalize_value(subscribe) + if name is not None: + api_params['name'] = self._normalize_value(name) + if subscribe is not None: + api_params['subscribe'] = self._normalize_value(subscribe) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/oauth2.py b/appwrite/services/oauth2.py index 272fbc73..21612207 100644 --- a/appwrite/services/oauth2.py +++ b/appwrite/services/oauth2.py @@ -441,7 +441,8 @@ def create_par( api_params['code_challenge_method'] = self._normalize_value(code_challenge_method) if prompt is not None: api_params['prompt'] = self._normalize_value(prompt) - api_params['max_age'] = self._normalize_value(max_age) + if max_age is not None: + api_params['max_age'] = self._normalize_value(max_age) if authorization_details is not None: api_params['authorization_details'] = self._normalize_value(authorization_details) if resource is not None: diff --git a/appwrite/services/organization.py b/appwrite/services/organization.py index eaf0ca88..e3f11e50 100644 --- a/appwrite/services/organization.py +++ b/appwrite/services/organization.py @@ -216,7 +216,8 @@ def create_key( api_params['keyId'] = self._normalize_value(key_id) api_params['name'] = self._normalize_value(name) api_params['scopes'] = self._normalize_value(scopes) - api_params['expire'] = self._normalize_value(expire) + if expire is not None: + api_params['expire'] = self._normalize_value(expire) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -313,7 +314,8 @@ def update_key( api_params['name'] = self._normalize_value(name) api_params['scopes'] = self._normalize_value(scopes) - api_params['expire'] = self._normalize_value(expire) + if expire is not None: + api_params['expire'] = self._normalize_value(expire) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/project.py b/appwrite/services/project.py index c9d5c9d4..573abdae 100644 --- a/appwrite/services/project.py +++ b/appwrite/services/project.py @@ -286,7 +286,8 @@ def create_key( api_params['keyId'] = self._normalize_value(key_id) api_params['name'] = self._normalize_value(name) api_params['scopes'] = self._normalize_value(scopes) - api_params['expire'] = self._normalize_value(expire) + if expire is not None: + api_params['expire'] = self._normalize_value(expire) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -432,7 +433,8 @@ def update_key( api_params['name'] = self._normalize_value(name) api_params['scopes'] = self._normalize_value(scopes) - api_params['expire'] = self._normalize_value(expire) + if expire is not None: + api_params['expire'] = self._normalize_value(expire) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -855,17 +857,24 @@ def update_o_auth2_server( api_params['scopes'] = self._normalize_value(scopes) if authorization_details_types is not None: api_params['authorizationDetailsTypes'] = self._normalize_value(authorization_details_types) - api_params['accessTokenDuration'] = self._normalize_value(access_token_duration) - api_params['refreshTokenDuration'] = self._normalize_value(refresh_token_duration) - api_params['publicAccessTokenDuration'] = self._normalize_value(public_access_token_duration) - api_params['publicRefreshTokenDuration'] = self._normalize_value(public_refresh_token_duration) - api_params['confidentialPkce'] = self._normalize_value(confidential_pkce) + if access_token_duration is not None: + api_params['accessTokenDuration'] = self._normalize_value(access_token_duration) + if refresh_token_duration is not None: + api_params['refreshTokenDuration'] = self._normalize_value(refresh_token_duration) + if public_access_token_duration is not None: + api_params['publicAccessTokenDuration'] = self._normalize_value(public_access_token_duration) + if public_refresh_token_duration is not None: + api_params['publicRefreshTokenDuration'] = self._normalize_value(public_refresh_token_duration) + if confidential_pkce is not None: + api_params['confidentialPkce'] = self._normalize_value(confidential_pkce) if verification_url is not None: api_params['verificationUrl'] = self._normalize_value(verification_url) - api_params['userCodeLength'] = self._normalize_value(user_code_length) + if user_code_length is not None: + api_params['userCodeLength'] = self._normalize_value(user_code_length) if user_code_format is not None: api_params['userCodeFormat'] = self._normalize_value(user_code_format) - api_params['deviceCodeDuration'] = self._normalize_value(device_code_duration) + if device_code_duration is not None: + api_params['deviceCodeDuration'] = self._normalize_value(device_code_duration) if default_scopes is not None: api_params['defaultScopes'] = self._normalize_value(default_scopes) @@ -910,9 +919,12 @@ def update_o_auth2_amazon( api_path = '/project/oauth2/amazon' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -961,11 +973,16 @@ def update_o_auth2_apple( api_path = '/project/oauth2/apple' api_params = {} - api_params['serviceId'] = self._normalize_value(service_id) - api_params['keyId'] = self._normalize_value(key_id) - api_params['teamId'] = self._normalize_value(team_id) - api_params['p8File'] = self._normalize_value(p8_file) - api_params['enabled'] = self._normalize_value(enabled) + if service_id is not None: + api_params['serviceId'] = self._normalize_value(service_id) + if key_id is not None: + api_params['keyId'] = self._normalize_value(key_id) + if team_id is not None: + api_params['teamId'] = self._normalize_value(team_id) + if p8_file is not None: + api_params['p8File'] = self._normalize_value(p8_file) + 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'), @@ -1008,9 +1025,12 @@ def update_o_auth2_appwrite( api_path = '/project/oauth2/appwrite' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1056,10 +1076,14 @@ def update_o_auth2_auth0( api_path = '/project/oauth2/auth0' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['endpoint'] = self._normalize_value(endpoint) - api_params['enabled'] = self._normalize_value(enabled) + 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 endpoint is not None: + api_params['endpoint'] = self._normalize_value(endpoint) + 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'), @@ -1105,10 +1129,14 @@ def update_o_auth2_authentik( api_path = '/project/oauth2/authentik' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['endpoint'] = self._normalize_value(endpoint) - api_params['enabled'] = self._normalize_value(enabled) + 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 endpoint is not None: + api_params['endpoint'] = self._normalize_value(endpoint) + 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'), @@ -1151,9 +1179,12 @@ def update_o_auth2_autodesk( api_path = '/project/oauth2/autodesk' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1196,9 +1227,12 @@ def update_o_auth2_bitbucket( api_path = '/project/oauth2/bitbucket' api_params = {} - api_params['key'] = self._normalize_value(key) - api_params['secret'] = self._normalize_value(secret) - api_params['enabled'] = self._normalize_value(enabled) + if key is not None: + api_params['key'] = self._normalize_value(key) + if secret is not None: + api_params['secret'] = self._normalize_value(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'), @@ -1241,9 +1275,12 @@ def update_o_auth2_bitly( api_path = '/project/oauth2/bitly' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1286,9 +1323,12 @@ def update_o_auth2_box( api_path = '/project/oauth2/box' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1331,9 +1371,12 @@ def update_o_auth2_dailymotion( api_path = '/project/oauth2/dailymotion' api_params = {} - api_params['apiKey'] = self._normalize_value(api_key) - api_params['apiSecret'] = self._normalize_value(api_secret) - api_params['enabled'] = self._normalize_value(enabled) + if api_key is not None: + api_params['apiKey'] = self._normalize_value(api_key) + if api_secret is not None: + api_params['apiSecret'] = self._normalize_value(api_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'), @@ -1376,9 +1419,12 @@ def update_o_auth2_discord( api_path = '/project/oauth2/discord' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1421,9 +1467,12 @@ def update_o_auth2_disqus( api_path = '/project/oauth2/disqus' api_params = {} - api_params['publicKey'] = self._normalize_value(public_key) - api_params['secretKey'] = self._normalize_value(secret_key) - api_params['enabled'] = self._normalize_value(enabled) + if public_key is not None: + api_params['publicKey'] = self._normalize_value(public_key) + if secret_key is not None: + api_params['secretKey'] = self._normalize_value(secret_key) + 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'), @@ -1466,9 +1515,12 @@ def update_o_auth2_dropbox( api_path = '/project/oauth2/dropbox' api_params = {} - api_params['appKey'] = self._normalize_value(app_key) - api_params['appSecret'] = self._normalize_value(app_secret) - api_params['enabled'] = self._normalize_value(enabled) + if app_key is not None: + api_params['appKey'] = self._normalize_value(app_key) + if app_secret is not None: + api_params['appSecret'] = self._normalize_value(app_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'), @@ -1511,9 +1563,12 @@ def update_o_auth2_etsy( api_path = '/project/oauth2/etsy' api_params = {} - api_params['keyString'] = self._normalize_value(key_string) - api_params['sharedSecret'] = self._normalize_value(shared_secret) - api_params['enabled'] = self._normalize_value(enabled) + if key_string is not None: + api_params['keyString'] = self._normalize_value(key_string) + if shared_secret is not None: + api_params['sharedSecret'] = self._normalize_value(shared_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'), @@ -1556,9 +1611,12 @@ def update_o_auth2_facebook( api_path = '/project/oauth2/facebook' api_params = {} - api_params['appId'] = self._normalize_value(app_id) - api_params['appSecret'] = self._normalize_value(app_secret) - api_params['enabled'] = self._normalize_value(enabled) + if app_id is not None: + api_params['appId'] = self._normalize_value(app_id) + if app_secret is not None: + api_params['appSecret'] = self._normalize_value(app_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'), @@ -1601,9 +1659,12 @@ def update_o_auth2_figma( api_path = '/project/oauth2/figma' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1649,10 +1710,14 @@ def update_o_auth2_fusion_auth( api_path = '/project/oauth2/fusionauth' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['endpoint'] = self._normalize_value(endpoint) - api_params['enabled'] = self._normalize_value(enabled) + 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 endpoint is not None: + api_params['endpoint'] = self._normalize_value(endpoint) + 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'), @@ -1695,9 +1760,12 @@ def update_o_auth2_git_hub( api_path = '/project/oauth2/github' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1743,10 +1811,14 @@ def update_o_auth2_gitlab( api_path = '/project/oauth2/gitlab' api_params = {} - api_params['applicationId'] = self._normalize_value(application_id) - api_params['secret'] = self._normalize_value(secret) - api_params['endpoint'] = self._normalize_value(endpoint) - api_params['enabled'] = self._normalize_value(enabled) + if application_id is not None: + api_params['applicationId'] = self._normalize_value(application_id) + if secret is not None: + api_params['secret'] = self._normalize_value(secret) + if endpoint is not None: + api_params['endpoint'] = self._normalize_value(endpoint) + 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'), @@ -1792,10 +1864,14 @@ def update_o_auth2_google( api_path = '/project/oauth2/google' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['prompt'] = self._normalize_value(prompt) - api_params['enabled'] = self._normalize_value(enabled) + 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 prompt is not None: + api_params['prompt'] = self._normalize_value(prompt) + 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'), @@ -1844,11 +1920,16 @@ def update_o_auth2_keycloak( api_path = '/project/oauth2/keycloak' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['endpoint'] = self._normalize_value(endpoint) - api_params['realmName'] = self._normalize_value(realm_name) - api_params['enabled'] = self._normalize_value(enabled) + 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 endpoint is not None: + api_params['endpoint'] = self._normalize_value(endpoint) + if realm_name is not None: + api_params['realmName'] = self._normalize_value(realm_name) + 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'), @@ -1891,9 +1972,12 @@ def update_o_auth2_kick( api_path = '/project/oauth2/kick' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -1936,9 +2020,12 @@ def update_o_auth2_linkedin( api_path = '/project/oauth2/linkedin' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['primaryClientSecret'] = self._normalize_value(primary_client_secret) - api_params['enabled'] = self._normalize_value(enabled) + if client_id is not None: + api_params['clientId'] = self._normalize_value(client_id) + if primary_client_secret is not None: + api_params['primaryClientSecret'] = self._normalize_value(primary_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'), @@ -1984,10 +2071,14 @@ def update_o_auth2_microsoft( api_path = '/project/oauth2/microsoft' api_params = {} - api_params['applicationId'] = self._normalize_value(application_id) - api_params['applicationSecret'] = self._normalize_value(application_secret) - api_params['tenant'] = self._normalize_value(tenant) - api_params['enabled'] = self._normalize_value(enabled) + if application_id is not None: + api_params['applicationId'] = self._normalize_value(application_id) + if application_secret is not None: + api_params['applicationSecret'] = self._normalize_value(application_secret) + if tenant is not None: + api_params['tenant'] = self._normalize_value(tenant) + 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'), @@ -2030,9 +2121,12 @@ def update_o_auth2_notion( api_path = '/project/oauth2/notion' api_params = {} - api_params['oauthClientId'] = self._normalize_value(oauth_client_id) - api_params['oauthClientSecret'] = self._normalize_value(oauth_client_secret) - api_params['enabled'] = self._normalize_value(enabled) + if oauth_client_id is not None: + api_params['oauthClientId'] = self._normalize_value(oauth_client_id) + if oauth_client_secret is not None: + api_params['oauthClientSecret'] = self._normalize_value(oauth_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'), @@ -2093,15 +2187,24 @@ def update_o_auth2_oidc( api_path = '/project/oauth2/oidc' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['wellKnownURL'] = self._normalize_value(well_known_url) - api_params['authorizationURL'] = self._normalize_value(authorization_url) - api_params['tokenURL'] = self._normalize_value(token_url) - api_params['userInfoURL'] = self._normalize_value(user_info_url) - api_params['prompt'] = self._normalize_value(prompt) - api_params['maxAge'] = self._normalize_value(max_age) - api_params['enabled'] = self._normalize_value(enabled) + 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 well_known_url is not None: + api_params['wellKnownURL'] = self._normalize_value(well_known_url) + if authorization_url is not None: + api_params['authorizationURL'] = self._normalize_value(authorization_url) + if token_url is not None: + api_params['tokenURL'] = self._normalize_value(token_url) + if user_info_url is not None: + api_params['userInfoURL'] = self._normalize_value(user_info_url) + if prompt is not None: + api_params['prompt'] = self._normalize_value(prompt) + if max_age is not None: + api_params['maxAge'] = self._normalize_value(max_age) + 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'), @@ -2150,11 +2253,16 @@ def update_o_auth2_okta( api_path = '/project/oauth2/okta' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['domain'] = self._normalize_value(domain) - api_params['authorizationServerId'] = self._normalize_value(authorization_server_id) - api_params['enabled'] = self._normalize_value(enabled) + 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 domain is not None: + api_params['domain'] = self._normalize_value(domain) + if authorization_server_id is not None: + api_params['authorizationServerId'] = self._normalize_value(authorization_server_id) + 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'), @@ -2197,9 +2305,12 @@ def update_o_auth2_paypal( api_path = '/project/oauth2/paypal' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['secretKey'] = self._normalize_value(secret_key) - api_params['enabled'] = self._normalize_value(enabled) + if client_id is not None: + api_params['clientId'] = self._normalize_value(client_id) + if secret_key is not None: + api_params['secretKey'] = self._normalize_value(secret_key) + 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'), @@ -2242,9 +2353,12 @@ def update_o_auth2_paypal_sandbox( api_path = '/project/oauth2/paypalSandbox' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['secretKey'] = self._normalize_value(secret_key) - api_params['enabled'] = self._normalize_value(enabled) + if client_id is not None: + api_params['clientId'] = self._normalize_value(client_id) + if secret_key is not None: + api_params['secretKey'] = self._normalize_value(secret_key) + 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'), @@ -2287,9 +2401,12 @@ def update_o_auth2_podio( api_path = '/project/oauth2/podio' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2332,9 +2449,12 @@ def update_o_auth2_salesforce( api_path = '/project/oauth2/salesforce' api_params = {} - api_params['customerKey'] = self._normalize_value(customer_key) - api_params['customerSecret'] = self._normalize_value(customer_secret) - api_params['enabled'] = self._normalize_value(enabled) + if customer_key is not None: + api_params['customerKey'] = self._normalize_value(customer_key) + if customer_secret is not None: + api_params['customerSecret'] = self._normalize_value(customer_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'), @@ -2377,9 +2497,12 @@ def update_o_auth2_slack( api_path = '/project/oauth2/slack' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2422,9 +2545,12 @@ def update_o_auth2_spotify( api_path = '/project/oauth2/spotify' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2467,9 +2593,12 @@ def update_o_auth2_stripe( api_path = '/project/oauth2/stripe' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['apiSecretKey'] = self._normalize_value(api_secret_key) - api_params['enabled'] = self._normalize_value(enabled) + if client_id is not None: + api_params['clientId'] = self._normalize_value(client_id) + if api_secret_key is not None: + api_params['apiSecretKey'] = self._normalize_value(api_secret_key) + 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'), @@ -2512,9 +2641,12 @@ def update_o_auth2_tradeshift( api_path = '/project/oauth2/tradeshift' api_params = {} - api_params['oauth2ClientId'] = self._normalize_value(oauth2_client_id) - api_params['oauth2ClientSecret'] = self._normalize_value(oauth2_client_secret) - api_params['enabled'] = self._normalize_value(enabled) + if oauth2_client_id is not None: + api_params['oauth2ClientId'] = self._normalize_value(oauth2_client_id) + if oauth2_client_secret is not None: + api_params['oauth2ClientSecret'] = self._normalize_value(oauth2_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'), @@ -2557,9 +2689,12 @@ def update_o_auth2_tradeshift_sandbox( api_path = '/project/oauth2/tradeshiftBox' api_params = {} - api_params['oauth2ClientId'] = self._normalize_value(oauth2_client_id) - api_params['oauth2ClientSecret'] = self._normalize_value(oauth2_client_secret) - api_params['enabled'] = self._normalize_value(enabled) + if oauth2_client_id is not None: + api_params['oauth2ClientId'] = self._normalize_value(oauth2_client_id) + if oauth2_client_secret is not None: + api_params['oauth2ClientSecret'] = self._normalize_value(oauth2_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'), @@ -2602,9 +2737,12 @@ def update_o_auth2_twitch( api_path = '/project/oauth2/twitch' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2647,9 +2785,12 @@ def update_o_auth2_word_press( api_path = '/project/oauth2/wordpress' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2692,9 +2833,12 @@ def update_o_auth2_x( api_path = '/project/oauth2/x' api_params = {} - api_params['customerKey'] = self._normalize_value(customer_key) - api_params['secretKey'] = self._normalize_value(secret_key) - api_params['enabled'] = self._normalize_value(enabled) + if customer_key is not None: + api_params['customerKey'] = self._normalize_value(customer_key) + if secret_key is not None: + api_params['secretKey'] = self._normalize_value(secret_key) + 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'), @@ -2737,9 +2881,12 @@ def update_o_auth2_yahoo( api_path = '/project/oauth2/yahoo' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2782,9 +2929,12 @@ def update_o_auth2_yandex( api_path = '/project/oauth2/yandex' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2827,9 +2977,12 @@ def update_o_auth2_zoho( api_path = '/project/oauth2/zoho' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -2872,9 +3025,12 @@ def update_o_auth2_zoom( api_path = '/project/oauth2/zoom' api_params = {} - api_params['clientId'] = self._normalize_value(client_id) - api_params['clientSecret'] = self._normalize_value(client_secret) - api_params['enabled'] = self._normalize_value(enabled) + 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'), @@ -4589,16 +4745,26 @@ def update_smtp( api_path = '/project/smtp' api_params = {} - api_params['host'] = self._normalize_value(host) - api_params['port'] = self._normalize_value(port) - api_params['username'] = self._normalize_value(username) - api_params['password'] = self._normalize_value(password) - api_params['senderEmail'] = self._normalize_value(sender_email) - api_params['senderName'] = self._normalize_value(sender_name) - api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['replyToName'] = self._normalize_value(reply_to_name) - api_params['secure'] = self._normalize_value(secure) - api_params['enabled'] = self._normalize_value(enabled) + if host is not None: + api_params['host'] = self._normalize_value(host) + if port is not None: + api_params['port'] = self._normalize_value(port) + if username is not None: + api_params['username'] = self._normalize_value(username) + if password is not None: + api_params['password'] = self._normalize_value(password) + if sender_email is not None: + api_params['senderEmail'] = self._normalize_value(sender_email) + if sender_name is not None: + api_params['senderName'] = self._normalize_value(sender_name) + if reply_to_email is not None: + api_params['replyToEmail'] = self._normalize_value(reply_to_email) + if reply_to_name is not None: + api_params['replyToName'] = self._normalize_value(reply_to_name) + if secure is not None: + api_params['secure'] = self._normalize_value(secure) + 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'), @@ -4743,12 +4909,18 @@ def update_email_template( api_params['templateId'] = self._normalize_value(template_id) if locale is not None: api_params['locale'] = self._normalize_value(locale) - api_params['subject'] = self._normalize_value(subject) - api_params['message'] = self._normalize_value(message) - api_params['senderName'] = self._normalize_value(sender_name) - api_params['senderEmail'] = self._normalize_value(sender_email) - api_params['replyToEmail'] = self._normalize_value(reply_to_email) - api_params['replyToName'] = self._normalize_value(reply_to_name) + if subject is not None: + api_params['subject'] = self._normalize_value(subject) + if message is not None: + api_params['message'] = self._normalize_value(message) + if sender_name is not None: + api_params['senderName'] = self._normalize_value(sender_name) + if sender_email is not None: + api_params['senderEmail'] = self._normalize_value(sender_email) + if reply_to_email is not None: + api_params['replyToEmail'] = self._normalize_value(reply_to_email) + if reply_to_name is not None: + api_params['replyToName'] = self._normalize_value(reply_to_name) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4982,9 +5154,12 @@ def update_variable( api_path = api_path.replace('{variableId}', str(self._normalize_value(variable_id))) - api_params['key'] = self._normalize_value(key) - api_params['value'] = self._normalize_value(value) - api_params['secret'] = self._normalize_value(secret) + if key is not None: + api_params['key'] = self._normalize_value(key) + if value is not None: + api_params['value'] = self._normalize_value(value) + if secret is not None: + api_params['secret'] = self._normalize_value(secret) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/sites.py b/appwrite/services/sites.py index 4daf161f..611dcb02 100644 --- a/appwrite/services/sites.py +++ b/appwrite/services/sites.py @@ -467,9 +467,12 @@ def update( api_params['providerSilentMode'] = self._normalize_value(provider_silent_mode) if provider_root_directory is not None: api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) - api_params['providerBranches'] = self._normalize_value(provider_branches) - api_params['providerPaths'] = self._normalize_value(provider_paths) - api_params['buildSpecification'] = self._normalize_value(build_specification) + if provider_branches is not None: + api_params['providerBranches'] = self._normalize_value(provider_branches) + if provider_paths is not None: + api_params['providerPaths'] = self._normalize_value(provider_paths) + if build_specification is not None: + api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: api_params['runtimeSpecification'] = self._normalize_value(runtime_specification) if deployment_retention is not None: @@ -1428,9 +1431,12 @@ def update_variable( api_path = api_path.replace('{siteId}', str(self._normalize_value(site_id))) api_path = api_path.replace('{variableId}', str(self._normalize_value(variable_id))) - api_params['key'] = self._normalize_value(key) - api_params['value'] = self._normalize_value(value) - api_params['secret'] = self._normalize_value(secret) + if key is not None: + api_params['key'] = self._normalize_value(key) + if value is not None: + api_params['value'] = self._normalize_value(value) + if secret is not None: + api_params['secret'] = self._normalize_value(secret) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/storage.py b/appwrite/services/storage.py index 7d1a1eaf..a450e58b 100644 --- a/appwrite/services/storage.py +++ b/appwrite/services/storage.py @@ -128,7 +128,8 @@ def create_bucket( api_params['bucketId'] = self._normalize_value(bucket_id) api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) if file_security is not None: api_params['fileSecurity'] = self._normalize_value(file_security) if enabled is not None: @@ -258,7 +259,8 @@ def update_bucket( api_path = api_path.replace('{bucketId}', str(self._normalize_value(bucket_id))) api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) if file_security is not None: api_params['fileSecurity'] = self._normalize_value(file_security) if enabled is not None: @@ -544,7 +546,8 @@ def update_file( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/tables_db.py b/appwrite/services/tables_db.py index 9733bc96..806bdc84 100644 --- a/appwrite/services/tables_db.py +++ b/appwrite/services/tables_db.py @@ -638,7 +638,8 @@ def create_table( api_params['tableId'] = self._normalize_value(table_id) api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) if row_security is not None: api_params['rowSecurity'] = self._normalize_value(row_security) if enabled is not None: @@ -757,7 +758,8 @@ def update_table( if name is not None: api_params['name'] = self._normalize_value(name) - api_params['permissions'] = self._normalize_value(permissions) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) if row_security is not None: api_params['rowSecurity'] = self._normalize_value(row_security) if enabled is not None: @@ -940,9 +942,12 @@ def create_big_int_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) - api_params['default'] = self._normalize_value(default) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1019,10 +1024,13 @@ def update_big_int_column( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1091,7 +1099,8 @@ def create_boolean_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1162,7 +1171,8 @@ def update_boolean_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1230,7 +1240,8 @@ def create_datetime_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1301,7 +1312,8 @@ def update_datetime_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1370,7 +1382,8 @@ def create_email_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1442,7 +1455,8 @@ def update_email_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1517,7 +1531,8 @@ def create_enum_column( api_params['key'] = self._normalize_value(key) api_params['elements'] = self._normalize_value(elements) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1596,7 +1611,8 @@ def update_enum_column( api_params['elements'] = self._normalize_value(elements) api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1671,9 +1687,12 @@ def create_float_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) - api_params['default'] = self._normalize_value(default) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1750,10 +1769,13 @@ def update_float_column( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1828,9 +1850,12 @@ def create_integer_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) - api_params['default'] = self._normalize_value(default) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -1907,10 +1932,13 @@ def update_integer_column( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['min'] = self._normalize_value(min) - api_params['max'] = self._normalize_value(max) + if min is not None: + api_params['min'] = self._normalize_value(min) + if max is not None: + api_params['max'] = self._normalize_value(max) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -1979,7 +2007,8 @@ def create_ip_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -2051,7 +2080,8 @@ def update_ip_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2116,7 +2146,8 @@ def create_line_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2184,8 +2215,10 @@ def update_line_column( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if default is not None: + api_params['default'] = self._normalize_value(default) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2257,7 +2290,8 @@ def create_longtext_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -2331,7 +2365,8 @@ def update_longtext_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2403,7 +2438,8 @@ def create_mediumtext_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -2477,7 +2513,8 @@ def update_mediumtext_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2542,7 +2579,8 @@ def create_point_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2610,8 +2648,10 @@ def update_point_column( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if default is not None: + api_params['default'] = self._normalize_value(default) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2676,7 +2716,8 @@ def create_polygon_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2744,8 +2785,10 @@ def update_polygon_column( api_path = api_path.replace('{key}', str(self._normalize_value(key))) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if default is not None: + api_params['default'] = self._normalize_value(default) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -2822,8 +2865,10 @@ def create_relationship_column( api_params['type'] = self._normalize_value(type) if two_way is not None: api_params['twoWay'] = self._normalize_value(two_way) - api_params['key'] = self._normalize_value(key) - api_params['twoWayKey'] = self._normalize_value(two_way_key) + if key is not None: + api_params['key'] = self._normalize_value(key) + if two_way_key is not None: + api_params['twoWayKey'] = self._normalize_value(two_way_key) if on_delete is not None: api_params['onDelete'] = self._normalize_value(on_delete) @@ -2907,7 +2952,8 @@ def create_string_column( api_params['key'] = self._normalize_value(key) api_params['size'] = self._normalize_value(size) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -2987,8 +3033,10 @@ def update_string_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['size'] = self._normalize_value(size) - api_params['newKey'] = self._normalize_value(new_key) + if size is not None: + api_params['size'] = self._normalize_value(size) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3060,7 +3108,8 @@ def create_text_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -3134,7 +3183,8 @@ def update_text_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3203,7 +3253,8 @@ def create_url_column( api_params['key'] = self._normalize_value(key) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) @@ -3275,7 +3326,8 @@ def update_url_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['newKey'] = self._normalize_value(new_key) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3354,7 +3406,8 @@ def create_varchar_column( api_params['key'] = self._normalize_value(key) api_params['size'] = self._normalize_value(size) api_params['required'] = self._normalize_value(required) - api_params['default'] = self._normalize_value(default) + if default is not None: + api_params['default'] = self._normalize_value(default) if array is not None: api_params['array'] = self._normalize_value(array) if encrypt is not None: @@ -3431,8 +3484,10 @@ def update_varchar_column( api_params['required'] = self._normalize_value(required) api_params['default'] = self._normalize_value(default) - api_params['size'] = self._normalize_value(size) - api_params['newKey'] = self._normalize_value(new_key) + if size is not None: + api_params['size'] = self._normalize_value(size) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -3632,8 +3687,10 @@ def update_relationship_column( api_path = api_path.replace('{tableId}', str(self._normalize_value(table_id))) api_path = api_path.replace('{key}', str(self._normalize_value(key))) - api_params['onDelete'] = self._normalize_value(on_delete) - api_params['newKey'] = self._normalize_value(new_key) + if on_delete is not None: + api_params['onDelete'] = self._normalize_value(on_delete) + if new_key is not None: + api_params['newKey'] = self._normalize_value(new_key) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4016,8 +4073,10 @@ def create_row( api_params['rowId'] = self._normalize_value(row_id) api_params['data'] = self._normalize_value(data) - api_params['permissions'] = self._normalize_value(permissions) - api_params['transactionId'] = self._normalize_value(transaction_id) + 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', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4079,7 +4138,8 @@ def create_rows( api_path = api_path.replace('{tableId}', str(self._normalize_value(table_id))) api_params['rows'] = self._normalize_value(rows) - api_params['transactionId'] = self._normalize_value(transaction_id) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4142,7 +4202,8 @@ def upsert_rows( api_path = api_path.replace('{tableId}', str(self._normalize_value(table_id))) api_params['rows'] = self._normalize_value(rows) - api_params['transactionId'] = self._normalize_value(transaction_id) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4207,7 +4268,8 @@ def update_rows( api_params['data'] = self._normalize_value(data) if queries is not None: api_params['queries'] = self._normalize_value(queries) - api_params['transactionId'] = self._normalize_value(transaction_id) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4405,8 +4467,10 @@ def upsert_row( if data is not None: api_params['data'] = self._normalize_value(data) - api_params['permissions'] = self._normalize_value(permissions) - api_params['transactionId'] = self._normalize_value(transaction_id) + 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('put', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4476,8 +4540,10 @@ def update_row( if data is not None: api_params['data'] = self._normalize_value(data) - api_params['permissions'] = self._normalize_value(permissions) - api_params['transactionId'] = self._normalize_value(transaction_id) + 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('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4612,8 +4678,10 @@ def decrement_row_column( if value is not None: api_params['value'] = self._normalize_value(value) - api_params['min'] = self._normalize_value(min) - api_params['transactionId'] = self._normalize_value(transaction_id) + if min is not None: + api_params['min'] = self._normalize_value(min) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -4690,8 +4758,10 @@ def increment_row_column( if value is not None: api_params['value'] = self._normalize_value(value) - api_params['max'] = self._normalize_value(max) - api_params['transactionId'] = self._normalize_value(transaction_id) + if max is not None: + api_params['max'] = self._normalize_value(max) + if transaction_id is not None: + api_params['transactionId'] = self._normalize_value(transaction_id) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/tokens.py b/appwrite/services/tokens.py index 0c04dfe3..bdff3a61 100644 --- a/appwrite/services/tokens.py +++ b/appwrite/services/tokens.py @@ -107,7 +107,8 @@ def create_file_token( api_path = api_path.replace('{bucketId}', str(self._normalize_value(bucket_id))) api_path = api_path.replace('{fileId}', str(self._normalize_value(file_id))) - api_params['expire'] = self._normalize_value(expire) + if expire is not None: + api_params['expire'] = self._normalize_value(expire) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -190,7 +191,8 @@ def update( api_path = api_path.replace('{tokenId}', str(self._normalize_value(token_id))) - api_params['expire'] = self._normalize_value(expire) + if expire is not None: + api_params['expire'] = self._normalize_value(expire) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), diff --git a/appwrite/services/users.py b/appwrite/services/users.py index c0e282e6..8eab2dc7 100644 --- a/appwrite/services/users.py +++ b/appwrite/services/users.py @@ -125,8 +125,10 @@ def create( api_params['userId'] = self._normalize_value(user_id) - api_params['email'] = self._normalize_value(email) - api_params['phone'] = self._normalize_value(phone) + if email is not None: + api_params['email'] = self._normalize_value(email) + if phone is not None: + api_params['phone'] = self._normalize_value(phone) if password is not None: api_params['password'] = self._normalize_value(password) if name is not None: diff --git a/appwrite/services/webhooks.py b/appwrite/services/webhooks.py index b9c99e8e..9e998f36 100644 --- a/appwrite/services/webhooks.py +++ b/appwrite/services/webhooks.py @@ -127,7 +127,8 @@ def create( api_params['authUsername'] = self._normalize_value(auth_username) if auth_password is not None: api_params['authPassword'] = self._normalize_value(auth_password) - api_params['secret'] = self._normalize_value(secret) + if secret is not None: + api_params['secret'] = self._normalize_value(secret) response = self.client.call('post', api_path, { 'X-Appwrite-Project': self.client.get_config('project'), @@ -330,7 +331,8 @@ def update_secret( api_path = api_path.replace('{webhookId}', str(self._normalize_value(webhook_id))) - api_params['secret'] = self._normalize_value(secret) + if secret is not None: + api_params['secret'] = self._normalize_value(secret) response = self.client.call('patch', api_path, { 'X-Appwrite-Project': self.client.get_config('project'),