From ca9a4bcb25ee456ecde2146dafaf50a744c455b5 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 18 May 2026 12:31:40 +0000 Subject: [PATCH 1/3] chore: update Python SDK to 19.0.0 --- .github/workflows/publish.yml | 4 +- CHANGELOG.md | 16 + README.md | 2 +- appwrite/client.py | 6 +- appwrite/encoders/value_class_encoder.py | 44 +- appwrite/enums/o_auth2_google_prompt.py | 6 + appwrite/enums/o_auth_provider.py | 2 - ...th_method.py => project_auth_method_id.py} | 2 +- ...e_type.py => project_email_template_id.py} | 2 +- ...le.py => project_email_template_locale.py} | 2 +- appwrite/enums/project_key_scopes.py | 97 ++ .../enums/project_o_auth2_google_prompt.py | 6 + appwrite/enums/project_o_auth_provider_id.py | 48 + ...project_policy.py => project_policy_id.py} | 2 +- ...{protocol_id.py => project_protocol_id.py} | 2 +- .../{service_id.py => project_service_id.py} | 3 +- .../{secure.py => project_smtp_secure.py} | 2 +- appwrite/enums/scopes.py | 7 + appwrite/models/__init__.py | 30 +- appwrite/models/auth_provider.py | 27 - appwrite/models/database.py | 12 +- appwrite/models/insight.py | 64 + appwrite/models/insight_cta.py | 24 + appwrite/models/insight_list.py | 19 + appwrite/models/o_auth2_google.py | 4 + appwrite/models/presence.py | 68 + appwrite/models/presence_list.py | 32 + appwrite/models/project.py | 194 +-- appwrite/models/project_auth_method.py | 19 + appwrite/models/project_protocol.py | 19 + appwrite/models/project_service.py | 19 + appwrite/models/report.py | 49 + appwrite/models/report_list.py | 19 + appwrite/models/usage_event.py | 42 + appwrite/models/usage_event_list.py | 19 + appwrite/models/usage_gauge.py | 21 + appwrite/models/usage_gauge_list.py | 19 + appwrite/services/advisor.py | 224 ++++ appwrite/services/presences.py | 291 +++++ appwrite/services/project.py | 299 +++-- appwrite/services/usage.py | 91 ++ docs/examples/advisor/delete-report.md | 15 + docs/examples/advisor/get-insight.md | 19 + docs/examples/advisor/get-report.md | 18 + docs/examples/advisor/list-insights.md | 20 + docs/examples/advisor/list-reports.md | 19 + docs/examples/presences/delete.md | 15 + docs/examples/presences/get.md | 18 + docs/examples/presences/list.md | 20 + docs/examples/presences/update-presence.md | 26 + docs/examples/presences/upsert.md | 25 + docs/examples/project/create-ephemeral-key.md | 4 +- docs/examples/project/create-key.md | 4 +- docs/examples/project/get-email-template.md | 8 +- .../examples/project/get-o-auth-2-provider.md | 4 +- docs/examples/project/get-policy.md | 4 +- docs/examples/project/get.md | 16 + docs/examples/project/update-auth-method.md | 4 +- .../update-deny-aliased-email-policy.md | 18 + .../update-deny-disposable-email-policy.md | 18 + .../project/update-deny-free-email-policy.md | 18 + .../examples/project/update-email-template.md | 8 +- docs/examples/project/update-key.md | 4 +- .../project/update-o-auth-2-google.md | 2 + docs/examples/project/update-protocol.md | 4 +- docs/examples/project/update-service.md | 4 +- docs/examples/project/update-smtp.md | 4 +- docs/examples/usage/list-events.md | 19 + docs/examples/usage/list-gauges.md | 19 + pyproject.toml | 2 +- setup.py | 4 +- test/services/test_advisor.py | 108 ++ test/services/test_presences.py | 101 ++ test/services/test_project.py | 1120 +++++------------ test/services/test_usage.py | 43 + 75 files changed, 2402 insertions(+), 1191 deletions(-) create mode 100644 appwrite/enums/o_auth2_google_prompt.py rename appwrite/enums/{auth_method.py => project_auth_method_id.py} (86%) rename appwrite/enums/{email_template_type.py => project_email_template_id.py} (87%) rename appwrite/enums/{email_template_locale.py => project_email_template_locale.py} (98%) create mode 100644 appwrite/enums/project_key_scopes.py create mode 100644 appwrite/enums/project_o_auth2_google_prompt.py create mode 100644 appwrite/enums/project_o_auth_provider_id.py rename appwrite/enums/{project_policy.py => project_policy_id.py} (93%) rename appwrite/enums/{protocol_id.py => project_protocol_id.py} (75%) rename appwrite/enums/{service_id.py => project_service_id.py} (88%) rename appwrite/enums/{secure.py => project_smtp_secure.py} (63%) delete mode 100644 appwrite/models/auth_provider.py create mode 100644 appwrite/models/insight.py create mode 100644 appwrite/models/insight_cta.py create mode 100644 appwrite/models/insight_list.py create mode 100644 appwrite/models/presence.py create mode 100644 appwrite/models/presence_list.py create mode 100644 appwrite/models/project_auth_method.py create mode 100644 appwrite/models/project_protocol.py create mode 100644 appwrite/models/project_service.py create mode 100644 appwrite/models/report.py create mode 100644 appwrite/models/report_list.py create mode 100644 appwrite/models/usage_event.py create mode 100644 appwrite/models/usage_event_list.py create mode 100644 appwrite/models/usage_gauge.py create mode 100644 appwrite/models/usage_gauge_list.py create mode 100644 appwrite/services/advisor.py create mode 100644 appwrite/services/presences.py create mode 100644 appwrite/services/usage.py create mode 100644 docs/examples/advisor/delete-report.md create mode 100644 docs/examples/advisor/get-insight.md create mode 100644 docs/examples/advisor/get-report.md create mode 100644 docs/examples/advisor/list-insights.md create mode 100644 docs/examples/advisor/list-reports.md create mode 100644 docs/examples/presences/delete.md create mode 100644 docs/examples/presences/get.md create mode 100644 docs/examples/presences/list.md create mode 100644 docs/examples/presences/update-presence.md create mode 100644 docs/examples/presences/upsert.md create mode 100644 docs/examples/project/get.md create mode 100644 docs/examples/project/update-deny-aliased-email-policy.md create mode 100644 docs/examples/project/update-deny-disposable-email-policy.md create mode 100644 docs/examples/project/update-deny-free-email-policy.md create mode 100644 docs/examples/usage/list-events.md create mode 100644 docs/examples/usage/list-gauges.md create mode 100644 test/services/test_advisor.py create mode 100644 test/services/test_presences.py create mode 100644 test/services/test_usage.py diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1bf432be..f0e30cb5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,10 +9,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.9' diff --git a/CHANGELOG.md b/CHANGELOG.md index fae7025a..2ddce6e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Change Log +## 19.0.0 + +* Breaking: Renamed `AuthMethod` enum to `ProjectAuthMethodId` +* Breaking: Renamed `EmailTemplateType` to `ProjectEmailTemplateId` and `EmailTemplateLocale` to `ProjectEmailTemplateLocale` +* Breaking: Renamed `ServiceId` to `ProjectServiceId`, `ProtocolId` to `ProjectProtocolId`, `Secure` to `ProjectSMTPSecure`, `ProjectPolicy` to `ProjectPolicyId` +* Breaking: Replaced `Scopes` enum with `ProjectKeyScopes` for project key endpoints +* Breaking: Removed `update_deny_canonical_email_policy`; replaced with `update_deny_aliased_email_policy`, `update_deny_disposable_email_policy`, and `update_deny_free_email_policy` +* Breaking: Removed `AuthProvider` model; use new `ProjectOAuthProviderId` enum instead +* Added: `Project.get` method to fetch current project details +* Added: `Advisor`, `Presences`, and `Usage` services +* Added: `Insight`, `Presence`, `Report`, `UsageEvent`, and `UsageGauge` models with list variants +* Added: `ProjectAuthMethod`, `ProjectProtocol`, and `ProjectService` models +* Added: `ProjectOAuthProviderId` and `ProjectOAuth2GooglePrompt` enums +* Updated: `Project`, `Database`, and `OAuth2Google` model schemas +* Updated: `X-Appwrite-Response-Format` header to `1.9.5` + ## 18.1.0 * Added: Introduced `bigint` create/update APIs for legacy Databases attributes diff --git a/README.md b/README.md index 58f370de..60a89373 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Appwrite Python SDK ![License](https://img.shields.io/github/license/appwrite/sdk-for-python.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-1.9.4-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-1.9.5-blue.svg?style=flat-square) [![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) [![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) diff --git a/appwrite/client.py b/appwrite/client.py index cebc8d0a..51534387 100644 --- a/appwrite/client.py +++ b/appwrite/client.py @@ -15,12 +15,12 @@ def __init__(self): self._endpoint = 'https://cloud.appwrite.io/v1' self._global_headers = { 'content-type': '', - 'user-agent' : f'AppwritePythonSDK/18.1.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})', + 'user-agent' : f'AppwritePythonSDK/19.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': '18.1.0', - 'X-Appwrite-Response-Format' : '1.9.4', + 'x-sdk-version': '19.0.0', + 'X-Appwrite-Response-Format' : '1.9.5', } def set_self_signed(self, status=True): diff --git a/appwrite/encoders/value_class_encoder.py b/appwrite/encoders/value_class_encoder.py index ce089308..b894901d 100644 --- a/appwrite/encoders/value_class_encoder.py +++ b/appwrite/encoders/value_class_encoder.py @@ -24,13 +24,16 @@ from ..enums.name import Name from ..enums.message_priority import MessagePriority from ..enums.smtp_encryption import SmtpEncryption -from ..enums.auth_method import AuthMethod -from ..enums.project_policy import ProjectPolicy -from ..enums.protocol_id import ProtocolId -from ..enums.service_id import ServiceId -from ..enums.secure import Secure -from ..enums.email_template_type import EmailTemplateType -from ..enums.email_template_locale import EmailTemplateLocale +from ..enums.project_auth_method_id import ProjectAuthMethodId +from ..enums.project_key_scopes import ProjectKeyScopes +from ..enums.project_o_auth2_google_prompt import ProjectOAuth2GooglePrompt +from ..enums.project_o_auth_provider_id import ProjectOAuthProviderId +from ..enums.project_policy_id import ProjectPolicyId +from ..enums.project_protocol_id import ProjectProtocolId +from ..enums.project_service_id import ProjectServiceId +from ..enums.project_smtp_secure import ProjectSMTPSecure +from ..enums.project_email_template_id import ProjectEmailTemplateId +from ..enums.project_email_template_locale import ProjectEmailTemplateLocale from ..enums.status_code import StatusCode from ..enums.proxy_resource_type import ProxyResourceType from ..enums.framework import Framework @@ -48,6 +51,7 @@ from ..enums.deployment_status import DeploymentStatus from ..enums.execution_trigger import ExecutionTrigger from ..enums.execution_status import ExecutionStatus +from ..enums.o_auth2_google_prompt import OAuth2GooglePrompt from ..enums.platform_type import PlatformType from ..enums.health_antivirus_status import HealthAntivirusStatus from ..enums.health_check_status import HealthCheckStatus @@ -132,25 +136,34 @@ def default(self, o): if isinstance(o, SmtpEncryption): return o.value - if isinstance(o, AuthMethod): + if isinstance(o, ProjectAuthMethodId): return o.value - if isinstance(o, ProjectPolicy): + if isinstance(o, ProjectKeyScopes): return o.value - if isinstance(o, ProtocolId): + if isinstance(o, ProjectOAuth2GooglePrompt): return o.value - if isinstance(o, ServiceId): + if isinstance(o, ProjectOAuthProviderId): return o.value - if isinstance(o, Secure): + if isinstance(o, ProjectPolicyId): return o.value - if isinstance(o, EmailTemplateType): + if isinstance(o, ProjectProtocolId): return o.value - if isinstance(o, EmailTemplateLocale): + if isinstance(o, ProjectServiceId): + return o.value + + if isinstance(o, ProjectSMTPSecure): + return o.value + + if isinstance(o, ProjectEmailTemplateId): + return o.value + + if isinstance(o, ProjectEmailTemplateLocale): return o.value if isinstance(o, StatusCode): @@ -204,6 +217,9 @@ def default(self, o): if isinstance(o, ExecutionStatus): return o.value + if isinstance(o, OAuth2GooglePrompt): + return o.value + if isinstance(o, PlatformType): return o.value diff --git a/appwrite/enums/o_auth2_google_prompt.py b/appwrite/enums/o_auth2_google_prompt.py new file mode 100644 index 00000000..6b98ee62 --- /dev/null +++ b/appwrite/enums/o_auth2_google_prompt.py @@ -0,0 +1,6 @@ +from enum import Enum + +class OAuth2GooglePrompt(Enum): + NONE = "none" + CONSENT = "consent" + SELECT_ACCOUNT = "select_account" diff --git a/appwrite/enums/o_auth_provider.py b/appwrite/enums/o_auth_provider.py index a7d10df1..18b69a49 100644 --- a/appwrite/enums/o_auth_provider.py +++ b/appwrite/enums/o_auth_provider.py @@ -44,5 +44,3 @@ class OAuthProvider(Enum): YANDEX = "yandex" ZOHO = "zoho" ZOOM = "zoom" - GITHUBIMAGINE = "githubImagine" - GOOGLEIMAGINE = "googleImagine" diff --git a/appwrite/enums/auth_method.py b/appwrite/enums/project_auth_method_id.py similarity index 86% rename from appwrite/enums/auth_method.py rename to appwrite/enums/project_auth_method_id.py index 6ba6d3e8..c022f9a0 100644 --- a/appwrite/enums/auth_method.py +++ b/appwrite/enums/project_auth_method_id.py @@ -1,6 +1,6 @@ from enum import Enum -class AuthMethod(Enum): +class ProjectAuthMethodId(Enum): EMAIL_PASSWORD = "email-password" MAGIC_URL = "magic-url" EMAIL_OTP = "email-otp" diff --git a/appwrite/enums/email_template_type.py b/appwrite/enums/project_email_template_id.py similarity index 87% rename from appwrite/enums/email_template_type.py rename to appwrite/enums/project_email_template_id.py index 67f6d997..3803eaf1 100644 --- a/appwrite/enums/email_template_type.py +++ b/appwrite/enums/project_email_template_id.py @@ -1,6 +1,6 @@ from enum import Enum -class EmailTemplateType(Enum): +class ProjectEmailTemplateId(Enum): VERIFICATION = "verification" MAGICSESSION = "magicSession" RECOVERY = "recovery" diff --git a/appwrite/enums/email_template_locale.py b/appwrite/enums/project_email_template_locale.py similarity index 98% rename from appwrite/enums/email_template_locale.py rename to appwrite/enums/project_email_template_locale.py index 668169cf..79f15945 100644 --- a/appwrite/enums/email_template_locale.py +++ b/appwrite/enums/project_email_template_locale.py @@ -1,6 +1,6 @@ from enum import Enum -class EmailTemplateLocale(Enum): +class ProjectEmailTemplateLocale(Enum): AF = "af" AR_AE = "ar-ae" AR_BH = "ar-bh" diff --git a/appwrite/enums/project_key_scopes.py b/appwrite/enums/project_key_scopes.py new file mode 100644 index 00000000..961d32f8 --- /dev/null +++ b/appwrite/enums/project_key_scopes.py @@ -0,0 +1,97 @@ +from enum import Enum + +class ProjectKeyScopes(Enum): + PROJECT_READ = "project.read" + PROJECT_WRITE = "project.write" + KEYS_READ = "keys.read" + KEYS_WRITE = "keys.write" + PLATFORMS_READ = "platforms.read" + PLATFORMS_WRITE = "platforms.write" + MOCKS_READ = "mocks.read" + MOCKS_WRITE = "mocks.write" + POLICIES_READ = "policies.read" + POLICIES_WRITE = "policies.write" + PROJECT_POLICIES_READ = "project.policies.read" + PROJECT_POLICIES_WRITE = "project.policies.write" + TEMPLATES_READ = "templates.read" + TEMPLATES_WRITE = "templates.write" + OAUTH2_READ = "oauth2.read" + OAUTH2_WRITE = "oauth2.write" + USERS_READ = "users.read" + USERS_WRITE = "users.write" + SESSIONS_READ = "sessions.read" + SESSIONS_WRITE = "sessions.write" + TEAMS_READ = "teams.read" + TEAMS_WRITE = "teams.write" + DATABASES_READ = "databases.read" + DATABASES_WRITE = "databases.write" + TABLES_READ = "tables.read" + TABLES_WRITE = "tables.write" + COLUMNS_READ = "columns.read" + COLUMNS_WRITE = "columns.write" + INDEXES_READ = "indexes.read" + INDEXES_WRITE = "indexes.write" + ROWS_READ = "rows.read" + ROWS_WRITE = "rows.write" + COLLECTIONS_READ = "collections.read" + COLLECTIONS_WRITE = "collections.write" + ATTRIBUTES_READ = "attributes.read" + ATTRIBUTES_WRITE = "attributes.write" + DOCUMENTS_READ = "documents.read" + DOCUMENTS_WRITE = "documents.write" + BUCKETS_READ = "buckets.read" + BUCKETS_WRITE = "buckets.write" + FILES_READ = "files.read" + FILES_WRITE = "files.write" + TOKENS_READ = "tokens.read" + TOKENS_WRITE = "tokens.write" + FUNCTIONS_READ = "functions.read" + FUNCTIONS_WRITE = "functions.write" + EXECUTIONS_READ = "executions.read" + EXECUTIONS_WRITE = "executions.write" + EXECUTION_READ = "execution.read" + EXECUTION_WRITE = "execution.write" + SITES_READ = "sites.read" + SITES_WRITE = "sites.write" + LOG_READ = "log.read" + LOG_WRITE = "log.write" + PROVIDERS_READ = "providers.read" + PROVIDERS_WRITE = "providers.write" + TOPICS_READ = "topics.read" + TOPICS_WRITE = "topics.write" + SUBSCRIBERS_READ = "subscribers.read" + SUBSCRIBERS_WRITE = "subscribers.write" + TARGETS_READ = "targets.read" + TARGETS_WRITE = "targets.write" + MESSAGES_READ = "messages.read" + MESSAGES_WRITE = "messages.write" + RULES_READ = "rules.read" + RULES_WRITE = "rules.write" + WEBHOOKS_READ = "webhooks.read" + WEBHOOKS_WRITE = "webhooks.write" + LOCALE_READ = "locale.read" + AVATARS_READ = "avatars.read" + HEALTH_READ = "health.read" + ASSISTANT_READ = "assistant.read" + MIGRATIONS_READ = "migrations.read" + MIGRATIONS_WRITE = "migrations.write" + SCHEDULES_READ = "schedules.read" + SCHEDULES_WRITE = "schedules.write" + VCS_READ = "vcs.read" + VCS_WRITE = "vcs.write" + INSIGHTS_READ = "insights.read" + INSIGHTS_WRITE = "insights.write" + REPORTS_READ = "reports.read" + REPORTS_WRITE = "reports.write" + PRESENCES_READ = "presences.read" + PRESENCES_WRITE = "presences.write" + BACKUPS_POLICIES_READ = "backups.policies.read" + BACKUPS_POLICIES_WRITE = "backups.policies.write" + ARCHIVES_READ = "archives.read" + ARCHIVES_WRITE = "archives.write" + RESTORATIONS_READ = "restorations.read" + RESTORATIONS_WRITE = "restorations.write" + DOMAINS_READ = "domains.read" + DOMAINS_WRITE = "domains.write" + EVENTS_READ = "events.read" + USAGE_READ = "usage.read" diff --git a/appwrite/enums/project_o_auth2_google_prompt.py b/appwrite/enums/project_o_auth2_google_prompt.py new file mode 100644 index 00000000..126e3760 --- /dev/null +++ b/appwrite/enums/project_o_auth2_google_prompt.py @@ -0,0 +1,6 @@ +from enum import Enum + +class ProjectOAuth2GooglePrompt(Enum): + NONE = "none" + 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 new file mode 100644 index 00000000..b22ea44c --- /dev/null +++ b/appwrite/enums/project_o_auth_provider_id.py @@ -0,0 +1,48 @@ +from enum import Enum + +class ProjectOAuthProviderId(Enum): + AMAZON = "amazon" + APPLE = "apple" + AUTH0 = "auth0" + AUTHENTIK = "authentik" + AUTODESK = "autodesk" + BITBUCKET = "bitbucket" + BITLY = "bitly" + BOX = "box" + DAILYMOTION = "dailymotion" + DISCORD = "discord" + DISQUS = "disqus" + DROPBOX = "dropbox" + ETSY = "etsy" + FACEBOOK = "facebook" + FIGMA = "figma" + FUSIONAUTH = "fusionauth" + GITHUB = "github" + GITLAB = "gitlab" + GOOGLE = "google" + KEYCLOAK = "keycloak" + KICK = "kick" + LINKEDIN = "linkedin" + MICROSOFT = "microsoft" + NOTION = "notion" + OIDC = "oidc" + OKTA = "okta" + PAYPAL = "paypal" + PAYPALSANDBOX = "paypalSandbox" + PODIO = "podio" + SALESFORCE = "salesforce" + SLACK = "slack" + SPOTIFY = "spotify" + STRIPE = "stripe" + TRADESHIFT = "tradeshift" + TRADESHIFTBOX = "tradeshiftBox" + TWITCH = "twitch" + WORDPRESS = "wordpress" + X = "x" + YAHOO = "yahoo" + YAMMER = "yammer" + YANDEX = "yandex" + ZOHO = "zoho" + ZOOM = "zoom" + GITHUBIMAGINE = "githubImagine" + GOOGLEIMAGINE = "googleImagine" diff --git a/appwrite/enums/project_policy.py b/appwrite/enums/project_policy_id.py similarity index 93% rename from appwrite/enums/project_policy.py rename to appwrite/enums/project_policy_id.py index ea9c527a..7c7a0c50 100644 --- a/appwrite/enums/project_policy.py +++ b/appwrite/enums/project_policy_id.py @@ -1,6 +1,6 @@ from enum import Enum -class ProjectPolicy(Enum): +class ProjectPolicyId(Enum): PASSWORD_DICTIONARY = "password-dictionary" PASSWORD_HISTORY = "password-history" PASSWORD_PERSONAL_DATA = "password-personal-data" diff --git a/appwrite/enums/protocol_id.py b/appwrite/enums/project_protocol_id.py similarity index 75% rename from appwrite/enums/protocol_id.py rename to appwrite/enums/project_protocol_id.py index 9ec98f64..5ccc6a68 100644 --- a/appwrite/enums/protocol_id.py +++ b/appwrite/enums/project_protocol_id.py @@ -1,6 +1,6 @@ from enum import Enum -class ProtocolId(Enum): +class ProjectProtocolId(Enum): REST = "rest" GRAPHQL = "graphql" WEBSOCKET = "websocket" diff --git a/appwrite/enums/service_id.py b/appwrite/enums/project_service_id.py similarity index 88% rename from appwrite/enums/service_id.py rename to appwrite/enums/project_service_id.py index 54fddf6a..2ab5a4b8 100644 --- a/appwrite/enums/service_id.py +++ b/appwrite/enums/project_service_id.py @@ -1,6 +1,6 @@ from enum import Enum -class ServiceId(Enum): +class ProjectServiceId(Enum): ACCOUNT = "account" AVATARS = "avatars" DATABASES = "databases" @@ -18,3 +18,4 @@ class ServiceId(Enum): GRAPHQL = "graphql" MIGRATIONS = "migrations" MESSAGING = "messaging" + ADVISOR = "advisor" diff --git a/appwrite/enums/secure.py b/appwrite/enums/project_smtp_secure.py similarity index 63% rename from appwrite/enums/secure.py rename to appwrite/enums/project_smtp_secure.py index 41a04f36..8c165ea5 100644 --- a/appwrite/enums/secure.py +++ b/appwrite/enums/project_smtp_secure.py @@ -1,5 +1,5 @@ from enum import Enum -class Secure(Enum): +class ProjectSMTPSecure(Enum): TLS = "tls" SSL = "ssl" diff --git a/appwrite/enums/scopes.py b/appwrite/enums/scopes.py index 7739b048..d3784f33 100644 --- a/appwrite/enums/scopes.py +++ b/appwrite/enums/scopes.py @@ -79,6 +79,12 @@ class Scopes(Enum): SCHEDULES_WRITE = "schedules.write" VCS_READ = "vcs.read" VCS_WRITE = "vcs.write" + INSIGHTS_READ = "insights.read" + INSIGHTS_WRITE = "insights.write" + REPORTS_READ = "reports.read" + REPORTS_WRITE = "reports.write" + PRESENCES_READ = "presences.read" + PRESENCES_WRITE = "presences.write" BACKUPS_POLICIES_READ = "backups.policies.read" BACKUPS_POLICIES_WRITE = "backups.policies.write" ARCHIVES_READ = "archives.read" @@ -88,3 +94,4 @@ class Scopes(Enum): DOMAINS_READ = "domains.read" DOMAINS_WRITE = "domains.write" EVENTS_READ = "events.read" + USAGE_READ = "usage.read" diff --git a/appwrite/models/__init__.py b/appwrite/models/__init__.py index ab97831e..734b280e 100644 --- a/appwrite/models/__init__.py +++ b/appwrite/models/__init__.py @@ -1,6 +1,7 @@ from .base_model import AppwriteModel from .row_list import RowList from .document_list import DocumentList +from .presence_list import PresenceList from .table_list import TableList from .collection_list import CollectionList from .database_list import DatabaseList @@ -42,6 +43,8 @@ from .target_list import TargetList from .transaction_list import TransactionList from .specification_list import SpecificationList +from .insight_list import InsightList +from .report_list import ReportList from .database import Database from .collection import Collection from .attribute_list import AttributeList @@ -87,6 +90,7 @@ from .column_index import ColumnIndex from .row import Row from .document import Document +from .presence import Presence from .log import Log from .user import User from .algo_md5 import AlgoMd5 @@ -116,6 +120,9 @@ from .deployment import Deployment from .execution import Execution from .project import Project +from .project_auth_method import ProjectAuthMethod +from .project_service import ProjectService +from .project_protocol import ProjectProtocol from .webhook import Webhook from .key import Key from .ephemeral_key import EphemeralKey @@ -171,7 +178,6 @@ from .policy_session_limit import PolicySessionLimit from .policy_user_limit import PolicyUserLimit from .policy_membership_privacy import PolicyMembershipPrivacy -from .auth_provider import AuthProvider from .platform_web import PlatformWeb from .platform_apple import PlatformApple from .platform_android import PlatformAndroid @@ -203,12 +209,19 @@ from .transaction import Transaction from .subscriber import Subscriber from .target import Target +from .insight import Insight +from .insight_cta import InsightCTA +from .report import Report from .activity_event import ActivityEvent from .backup_archive import BackupArchive from .billing_limits import BillingLimits from .block import Block from .backup_policy import BackupPolicy from .backup_restoration import BackupRestoration +from .usage_event import UsageEvent +from .usage_event_list import UsageEventList +from .usage_gauge import UsageGauge +from .usage_gauge_list import UsageGaugeList from .activity_event_list import ActivityEventList from .backup_archive_list import BackupArchiveList from .backup_policy_list import BackupPolicyList @@ -218,6 +231,7 @@ 'AppwriteModel', 'RowList', 'DocumentList', + 'PresenceList', 'TableList', 'CollectionList', 'DatabaseList', @@ -259,6 +273,8 @@ 'TargetList', 'TransactionList', 'SpecificationList', + 'InsightList', + 'ReportList', 'Database', 'Collection', 'AttributeList', @@ -304,6 +320,7 @@ 'ColumnIndex', 'Row', 'Document', + 'Presence', 'Log', 'User', 'AlgoMd5', @@ -333,6 +350,9 @@ 'Deployment', 'Execution', 'Project', + 'ProjectAuthMethod', + 'ProjectService', + 'ProjectProtocol', 'Webhook', 'Key', 'EphemeralKey', @@ -388,7 +408,6 @@ 'PolicySessionLimit', 'PolicyUserLimit', 'PolicyMembershipPrivacy', - 'AuthProvider', 'PlatformWeb', 'PlatformApple', 'PlatformAndroid', @@ -420,12 +439,19 @@ 'Transaction', 'Subscriber', 'Target', + 'Insight', + 'InsightCTA', + 'Report', 'ActivityEvent', 'BackupArchive', 'BillingLimits', 'Block', 'BackupPolicy', 'BackupRestoration', + 'UsageEvent', + 'UsageEventList', + 'UsageGauge', + 'UsageGaugeList', 'ActivityEventList', 'BackupArchiveList', 'BackupPolicyList', diff --git a/appwrite/models/auth_provider.py b/appwrite/models/auth_provider.py deleted file mode 100644 index 88b0f249..00000000 --- a/appwrite/models/auth_provider.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Any, Dict, List, Optional, Union, cast -from pydantic import Field, PrivateAttr - -from .base_model import AppwriteModel - -class AuthProvider(AppwriteModel): - """ - AuthProvider - - Attributes - ---------- - key : str - Auth Provider. - name : str - Auth Provider name. - appid : str - OAuth 2.0 application ID. - secret : str - OAuth 2.0 application secret. Might be JSON string if provider requires extra configuration. This property is write-only and always returned empty. - enabled : bool - Auth Provider is active and can be used to create session. - """ - key: str = Field(..., alias='key') - name: str = Field(..., alias='name') - appid: str = Field(..., alias='appId') - secret: str = Field(..., alias='secret') - enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/database.py b/appwrite/models/database.py index 6ae78b57..784fc2a7 100644 --- a/appwrite/models/database.py +++ b/appwrite/models/database.py @@ -3,8 +3,8 @@ from .base_model import AppwriteModel from ..enums.database_type import DatabaseType -from .index import Index -from .collection import Collection +from .backup_policy import BackupPolicy +from .backup_archive import BackupArchive class Database(AppwriteModel): """ @@ -24,9 +24,9 @@ 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. - policies : List[Index] + policies : List[BackupPolicy] Database backup policies. - archives : List[Collection] + archives : List[BackupArchive] Database backup archives. """ id: str = Field(..., alias='$id') @@ -35,5 +35,5 @@ class Database(AppwriteModel): updatedat: str = Field(..., alias='$updatedAt') enabled: bool = Field(..., alias='enabled') type: DatabaseType = Field(..., alias='type') - policies: List[Index] = Field(..., alias='policies') - archives: List[Collection] = Field(..., alias='archives') + policies: List[BackupPolicy] = Field(..., alias='policies') + archives: List[BackupArchive] = Field(..., alias='archives') diff --git a/appwrite/models/insight.py b/appwrite/models/insight.py new file mode 100644 index 00000000..d0d263b9 --- /dev/null +++ b/appwrite/models/insight.py @@ -0,0 +1,64 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .insight_cta import InsightCTA + +class Insight(AppwriteModel): + """ + Insight + + Attributes + ---------- + id : str + Insight ID. + createdat : str + Insight creation date in ISO 8601 format. + updatedat : str + Insight update date in ISO 8601 format. + reportid : str + Parent report ID. Insights always belong to a report. + type : str + Insight type. One of databaseIndex (legacy), tablesDBIndex, documentsDBIndex, vectorsDBIndex, databasePerformance, sitePerformance, siteAccessibility, siteSeo, functionPerformance. The index types are engine-specific so each CTA can pair the right service+method (databases.createIndex, tablesDB.createIndex, documentsDB.createIndex, or vectorsDB.createIndex). + severity : str + Insight severity. One of info, warning, critical. + status : str + Insight status. One of active, dismissed. + resourcetype : str + Type of the resource the insight is about. Plural noun, e.g. databases, sites, functions. + resourceid : str + ID of the resource the insight is about. + parentresourcetype : str + Plural noun for the parent resource that contains the insight's resource, e.g. an insight about a column index on a table → resourceType=indexes, parentResourceType=tables. Empty when the resource has no parent. + parentresourceid : str + ID of the parent resource. Empty when the resource has no parent. + title : str + Insight title. + summary : str + Short markdown summary describing the insight. + ctas : List[InsightCTA] + List of call-to-action buttons attached to this insight. + analyzedat : Optional[str] + Time the insight was analyzed in ISO 8601 format. + dismissedat : Optional[str] + Time the insight was dismissed in ISO 8601 format. Empty when not dismissed. + dismissedby : Optional[str] + User ID that dismissed the insight. Empty when not dismissed. + """ + id: str = Field(..., alias='$id') + createdat: str = Field(..., alias='$createdAt') + updatedat: str = Field(..., alias='$updatedAt') + reportid: str = Field(..., alias='reportId') + type: str = Field(..., alias='type') + severity: str = Field(..., alias='severity') + status: str = Field(..., alias='status') + resourcetype: str = Field(..., alias='resourceType') + resourceid: str = Field(..., alias='resourceId') + parentresourcetype: str = Field(..., alias='parentResourceType') + parentresourceid: str = Field(..., alias='parentResourceId') + title: str = Field(..., alias='title') + summary: str = Field(..., alias='summary') + ctas: List[InsightCTA] = Field(..., alias='ctas') + analyzedat: Optional[str] = Field(default=None, alias='analyzedAt') + dismissedat: Optional[str] = Field(default=None, alias='dismissedAt') + dismissedby: Optional[str] = Field(default=None, alias='dismissedBy') diff --git a/appwrite/models/insight_cta.py b/appwrite/models/insight_cta.py new file mode 100644 index 00000000..2c74929b --- /dev/null +++ b/appwrite/models/insight_cta.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 InsightCTA(AppwriteModel): + """ + InsightCTA + + Attributes + ---------- + label : str + Human-readable label for the CTA, used in UI. + service : str + Public API service (SDK namespace) the client should invoke. Must match the engine that owns the resource — for index suggestions: databases (legacy), tablesDB, documentsDB, or vectorsDB. + method : str + Public API method on the chosen service the client should invoke when this CTA is triggered. + params : Dict[str, Any] + Parameter map the client should pass to the service method when this CTA is triggered. Keys match the target API's parameter names (e.g. databaseId/tableId/columns for tablesDB, databaseId/collectionId/attributes for the legacy Databases API). + """ + label: str = Field(..., alias='label') + service: str = Field(..., alias='service') + method: str = Field(..., alias='method') + params: Dict[str, Any] = Field(..., alias='params') diff --git a/appwrite/models/insight_list.py b/appwrite/models/insight_list.py new file mode 100644 index 00000000..4837a3d0 --- /dev/null +++ b/appwrite/models/insight_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 .insight import Insight + +class InsightList(AppwriteModel): + """ + Insights List + + Attributes + ---------- + total : float + Total number of insights that matched your query. + insights : List[Insight] + List of insights. + """ + total: float = Field(..., alias='total') + insights: List[Insight] = Field(..., alias='insights') diff --git a/appwrite/models/o_auth2_google.py b/appwrite/models/o_auth2_google.py index cc130d36..8dcc33bd 100644 --- a/appwrite/models/o_auth2_google.py +++ b/appwrite/models/o_auth2_google.py @@ -2,6 +2,7 @@ from pydantic import Field, PrivateAttr from .base_model import AppwriteModel +from ..enums.o_auth2_google_prompt import OAuth2GooglePrompt class OAuth2Google(AppwriteModel): """ @@ -17,8 +18,11 @@ class OAuth2Google(AppwriteModel): Google OAuth2 client ID. clientsecret : str Google OAuth2 client secret. + prompt : List[OAuth2GooglePrompt] + Google OAuth2 prompt values. """ id: str = Field(..., alias='$id') enabled: bool = Field(..., alias='enabled') clientid: str = Field(..., alias='clientId') clientsecret: str = Field(..., alias='clientSecret') + prompt: List[OAuth2GooglePrompt] = Field(..., alias='prompt') diff --git a/appwrite/models/presence.py b/appwrite/models/presence.py new file mode 100644 index 00000000..336c63fb --- /dev/null +++ b/appwrite/models/presence.py @@ -0,0 +1,68 @@ +from typing import Any, Dict, List, Optional, Union, cast, Generic, TypeVar, Type +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +T = TypeVar('T') + +class Presence(AppwriteModel, Generic[T]): + """ + Presence + + Attributes + ---------- + id : str + Presence ID. + createdat : str + Presence creation date in ISO 8601 format. + updatedat : str + Presence update date in ISO 8601 format. + permissions : List[Any] + Presence permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + userid : str + User ID. + status : Optional[str] + Presence status. + source : str + Presence source. + expiresat : Optional[str] + Presence expiry date in ISO 8601 format. + """ + id: str = Field(..., alias='$id') + createdat: str = Field(..., alias='$createdAt') + updatedat: str = Field(..., alias='$updatedAt') + permissions: List[Any] = Field(..., alias='$permissions') + userid: str = Field(..., alias='userId') + status: Optional[str] = Field(default=None, alias='status') + source: str = Field(..., alias='source') + expiresat: Optional[str] = Field(default=None, alias='expiresAt') + + @classmethod + def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Presence[T]': + """Create Presence instance with typed data.""" + internal_fields = {k: v for k, v in data.items() if k.startswith('$')} + user_data = {k: v for k, v in data.items() if not k.startswith('$')} + instance = cls.model_validate(internal_fields) + instance._metadata = model_type(**user_data) if model_type is not dict else user_data + return instance + + _metadata: Any = PrivateAttr(default_factory=dict) + + @property + def metadata(self) -> T: + return cast(T, self._metadata) + + @metadata.setter + def metadata(self, value: T) -> None: + object.__setattr__(self, '_metadata', value) + + def to_dict(self) -> Dict[str, Any]: + result = super().to_dict() + if hasattr(self, '_metadata'): + if isinstance(self._metadata, dict): + result['metadata'] = self._metadata + elif hasattr(self._metadata, 'model_dump'): + result['metadata'] = self._metadata.model_dump(mode='json') + else: + result['metadata'] = self._metadata + return result diff --git a/appwrite/models/presence_list.py b/appwrite/models/presence_list.py new file mode 100644 index 00000000..516db718 --- /dev/null +++ b/appwrite/models/presence_list.py @@ -0,0 +1,32 @@ +from typing import Any, Dict, List, Optional, Union, cast, Generic, TypeVar, Type +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .presence import Presence + +T = TypeVar('T') + +class PresenceList(AppwriteModel, Generic[T]): + """ + Presences List + + Attributes + ---------- + total : float + Total number of presences that matched your query. + presences : List[Presence[T]] + List of presences. + """ + total: float = Field(..., alias='total') + presences: List[Presence[T]] = Field(..., alias='presences') + + @classmethod + def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'PresenceList[T]': + """Create PresenceList instance with typed data.""" + instance = cls.model_validate(data) + if 'presences' in data and data['presences'] is not None: + instance.presences = [ + Presence.with_data(row, model_type) + for row in data['presences'] + ] + return instance diff --git a/appwrite/models/project.py b/appwrite/models/project.py index c593ebdf..cb402862 100644 --- a/appwrite/models/project.py +++ b/appwrite/models/project.py @@ -2,16 +2,10 @@ from pydantic import Field, PrivateAttr from .base_model import AppwriteModel -from .mock_number import MockNumber -from .auth_provider import AuthProvider -from .platform_web import PlatformWeb -from .platform_apple import PlatformApple -from .platform_android import PlatformAndroid -from .platform_windows import PlatformWindows -from .platform_linux import PlatformLinux -from .webhook import Webhook -from .key import Key from .dev_key import DevKey +from .project_auth_method import ProjectAuthMethod +from .project_service import ProjectService +from .project_protocol import ProjectProtocol from .billing_limits import BillingLimits from .block import Block @@ -29,70 +23,10 @@ class Project(AppwriteModel): Project update date in ISO 8601 format. name : str Project name. - description : str - Project description. teamid : str Project team ID. - logo : str - Project logo file ID. - url : str - Project website URL. - legalname : str - Company legal name. - legalcountry : str - Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) two-character format. - legalstate : str - State name. - legalcity : str - City name. - legaladdress : str - Company Address. - legaltaxid : str - Company Tax ID. - authduration : float - Session duration in seconds. - authlimit : float - Max users allowed. 0 is unlimited. - authsessionslimit : float - Max sessions allowed per user. 100 maximum. - authpasswordhistory : float - Max allowed passwords in the history list per user. Max passwords limit allowed in history is 20. Use 0 for disabling password history. - authpassworddictionary : bool - Whether or not to check user's password against most commonly used passwords. - authpersonaldatacheck : bool - Whether or not to check the user password for similarity with their personal data. - authdisposableemails : bool - Whether or not to disallow disposable email addresses during signup and email updates. - authcanonicalemails : bool - Whether or not to require canonical email addresses during signup and email updates. - authfreeemails : bool - Whether or not to disallow free email addresses during signup and email updates. - authmocknumbers : List[MockNumber] - An array of mock numbers and their corresponding verification codes (OTPs). - authsessionalerts : bool - Whether or not to send session alert emails to users. - authmembershipsusername : bool - Whether or not to show user names in the teams membership response. - authmembershipsuseremail : bool - Whether or not to show user emails in the teams membership response. - authmembershipsmfa : bool - Whether or not to show user MFA status in the teams membership response. - authmembershipsuserid : bool - Whether or not to show user IDs in the teams membership response. - authmembershipsuserphone : bool - Whether or not to show user phone numbers in the teams membership response. - authinvalidatesessions : bool - Whether or not all existing sessions should be invalidated on password change - oauthproviders : List[AuthProvider] - List of Auth Providers. - platforms : List[Union[PlatformWeb, PlatformApple, PlatformAndroid, PlatformWindows, PlatformLinux]] - List of Platforms. - webhooks : List[Webhook] - List of Webhooks. - keys : List[Key] - List of API Keys. devkeys : List[DevKey] - List of dev keys. + Deprecated since 1.9.5: List of dev keys. smtpenabled : bool Status for custom SMTP smtpsendername : str @@ -121,60 +55,12 @@ class Project(AppwriteModel): Labels for the project. status : str Project status - authemailpassword : bool - Email/Password auth method status - authusersauthmagicurl : bool - Magic URL auth method status - authemailotp : bool - Email (OTP) auth method status - authanonymous : bool - Anonymous auth method status - authinvites : bool - Invites auth method status - authjwt : bool - JWT auth method status - authphone : bool - Phone auth method status - servicestatusforaccount : bool - Account service status - servicestatusforavatars : bool - Avatars service status - servicestatusfordatabases : bool - Databases (legacy) service status - servicestatusfortablesdb : bool - TablesDB service status - servicestatusforlocale : bool - Locale service status - servicestatusforhealth : bool - Health service status - servicestatusforproject : bool - Project service status - servicestatusforstorage : bool - Storage service status - servicestatusforteams : bool - Teams service status - servicestatusforusers : bool - Users service status - servicestatusforvcs : bool - VCS service status - servicestatusforsites : bool - Sites service status - servicestatusforfunctions : bool - Functions service status - servicestatusforproxy : bool - Proxy service status - servicestatusforgraphql : bool - GraphQL service status - servicestatusformigrations : bool - Migrations service status - servicestatusformessaging : bool - Messaging service status - protocolstatusforrest : bool - REST protocol status - protocolstatusforgraphql : bool - GraphQL protocol status - protocolstatusforwebsocket : bool - Websocket protocol status + authmethods : List[ProjectAuthMethod] + List of auth methods. + services : List[ProjectService] + List of services. + protocols : List[ProjectProtocol] + List of protocols. region : str Project region billinglimits : BillingLimits @@ -188,37 +74,7 @@ class Project(AppwriteModel): createdat: str = Field(..., alias='$createdAt') updatedat: str = Field(..., alias='$updatedAt') name: str = Field(..., alias='name') - description: str = Field(..., alias='description') teamid: str = Field(..., alias='teamId') - logo: str = Field(..., alias='logo') - url: str = Field(..., alias='url') - legalname: str = Field(..., alias='legalName') - legalcountry: str = Field(..., alias='legalCountry') - legalstate: str = Field(..., alias='legalState') - legalcity: str = Field(..., alias='legalCity') - legaladdress: str = Field(..., alias='legalAddress') - legaltaxid: str = Field(..., alias='legalTaxId') - authduration: float = Field(..., alias='authDuration') - authlimit: float = Field(..., alias='authLimit') - authsessionslimit: float = Field(..., alias='authSessionsLimit') - authpasswordhistory: float = Field(..., alias='authPasswordHistory') - authpassworddictionary: bool = Field(..., alias='authPasswordDictionary') - authpersonaldatacheck: bool = Field(..., alias='authPersonalDataCheck') - authdisposableemails: bool = Field(..., alias='authDisposableEmails') - authcanonicalemails: bool = Field(..., alias='authCanonicalEmails') - authfreeemails: bool = Field(..., alias='authFreeEmails') - authmocknumbers: List[MockNumber] = Field(..., alias='authMockNumbers') - authsessionalerts: bool = Field(..., alias='authSessionAlerts') - authmembershipsusername: bool = Field(..., alias='authMembershipsUserName') - authmembershipsuseremail: bool = Field(..., alias='authMembershipsUserEmail') - authmembershipsmfa: bool = Field(..., alias='authMembershipsMfa') - authmembershipsuserid: bool = Field(..., alias='authMembershipsUserId') - authmembershipsuserphone: bool = Field(..., alias='authMembershipsUserPhone') - authinvalidatesessions: bool = Field(..., alias='authInvalidateSessions') - oauthproviders: List[AuthProvider] = Field(..., alias='oAuthProviders') - platforms: List[Union[PlatformWeb, PlatformApple, PlatformAndroid, PlatformWindows, PlatformLinux]] = Field(..., alias='platforms') - webhooks: List[Webhook] = Field(..., alias='webhooks') - keys: List[Key] = Field(..., alias='keys') devkeys: List[DevKey] = Field(..., alias='devKeys') smtpenabled: bool = Field(..., alias='smtpEnabled') smtpsendername: str = Field(..., alias='smtpSenderName') @@ -234,33 +90,9 @@ class Project(AppwriteModel): pingedat: str = Field(..., alias='pingedAt') labels: List[Any] = Field(..., alias='labels') status: str = Field(..., alias='status') - authemailpassword: bool = Field(..., alias='authEmailPassword') - authusersauthmagicurl: bool = Field(..., alias='authUsersAuthMagicURL') - authemailotp: bool = Field(..., alias='authEmailOtp') - authanonymous: bool = Field(..., alias='authAnonymous') - authinvites: bool = Field(..., alias='authInvites') - authjwt: bool = Field(..., alias='authJWT') - authphone: bool = Field(..., alias='authPhone') - servicestatusforaccount: bool = Field(..., alias='serviceStatusForAccount') - servicestatusforavatars: bool = Field(..., alias='serviceStatusForAvatars') - servicestatusfordatabases: bool = Field(..., alias='serviceStatusForDatabases') - servicestatusfortablesdb: bool = Field(..., alias='serviceStatusForTablesdb') - servicestatusforlocale: bool = Field(..., alias='serviceStatusForLocale') - servicestatusforhealth: bool = Field(..., alias='serviceStatusForHealth') - servicestatusforproject: bool = Field(..., alias='serviceStatusForProject') - servicestatusforstorage: bool = Field(..., alias='serviceStatusForStorage') - servicestatusforteams: bool = Field(..., alias='serviceStatusForTeams') - servicestatusforusers: bool = Field(..., alias='serviceStatusForUsers') - servicestatusforvcs: bool = Field(..., alias='serviceStatusForVcs') - servicestatusforsites: bool = Field(..., alias='serviceStatusForSites') - servicestatusforfunctions: bool = Field(..., alias='serviceStatusForFunctions') - servicestatusforproxy: bool = Field(..., alias='serviceStatusForProxy') - servicestatusforgraphql: bool = Field(..., alias='serviceStatusForGraphql') - servicestatusformigrations: bool = Field(..., alias='serviceStatusForMigrations') - servicestatusformessaging: bool = Field(..., alias='serviceStatusForMessaging') - protocolstatusforrest: bool = Field(..., alias='protocolStatusForRest') - protocolstatusforgraphql: bool = Field(..., alias='protocolStatusForGraphql') - protocolstatusforwebsocket: bool = Field(..., alias='protocolStatusForWebsocket') + authmethods: List[ProjectAuthMethod] = Field(..., alias='authMethods') + services: List[ProjectService] = Field(..., alias='services') + protocols: List[ProjectProtocol] = Field(..., alias='protocols') region: str = Field(..., alias='region') billinglimits: BillingLimits = Field(..., alias='billingLimits') blocks: List[Block] = Field(..., alias='blocks') diff --git a/appwrite/models/project_auth_method.py b/appwrite/models/project_auth_method.py new file mode 100644 index 00000000..92db259c --- /dev/null +++ b/appwrite/models/project_auth_method.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 ..enums.project_auth_method_id import ProjectAuthMethodId + +class ProjectAuthMethod(AppwriteModel): + """ + ProjectAuthMethod + + Attributes + ---------- + id : ProjectAuthMethodId + Auth method ID. + enabled : bool + Auth method status. + """ + id: ProjectAuthMethodId = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/project_protocol.py b/appwrite/models/project_protocol.py new file mode 100644 index 00000000..be2374fb --- /dev/null +++ b/appwrite/models/project_protocol.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 ..enums.project_protocol_id import ProjectProtocolId + +class ProjectProtocol(AppwriteModel): + """ + ProjectProtocol + + Attributes + ---------- + id : ProjectProtocolId + Protocol ID. + enabled : bool + Protocol status. + """ + id: ProjectProtocolId = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/project_service.py b/appwrite/models/project_service.py new file mode 100644 index 00000000..99e0ed88 --- /dev/null +++ b/appwrite/models/project_service.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 ..enums.project_service_id import ProjectServiceId + +class ProjectService(AppwriteModel): + """ + ProjectService + + Attributes + ---------- + id : ProjectServiceId + Service ID. + enabled : bool + Service status. + """ + id: ProjectServiceId = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/report.py b/appwrite/models/report.py new file mode 100644 index 00000000..fe10e4e8 --- /dev/null +++ b/appwrite/models/report.py @@ -0,0 +1,49 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .insight import Insight + +class Report(AppwriteModel): + """ + Report + + Attributes + ---------- + id : str + Report ID. + createdat : str + Report creation date in ISO 8601 format. + updatedat : str + Report update date in ISO 8601 format. + appid : str + ID of the third-party app that submitted the report. + type : str + Analyzer that produced this report. e.g. lighthouse, audit, databaseAnalyzer. + title : str + Short, human-readable title for the report. + summary : str + Markdown summary describing the report. + targettype : str + Plural noun describing what the report analyzes, e.g. databases, sites, urls. + target : str + Free-form target identifier (URL for lighthouse, resource ID for db). + categories : List[Any] + Categories covered by the report, e.g. performance, accessibility. + insights : List[Insight] + Insights nested under this report. + analyzedat : Optional[str] + Time the report was analyzed in ISO 8601 format. + """ + id: str = Field(..., alias='$id') + createdat: str = Field(..., alias='$createdAt') + updatedat: str = Field(..., alias='$updatedAt') + appid: str = Field(..., alias='appId') + type: str = Field(..., alias='type') + title: str = Field(..., alias='title') + summary: str = Field(..., alias='summary') + targettype: str = Field(..., alias='targetType') + target: str = Field(..., alias='target') + categories: List[Any] = Field(..., alias='categories') + insights: List[Insight] = Field(..., alias='insights') + analyzedat: Optional[str] = Field(default=None, alias='analyzedAt') diff --git a/appwrite/models/report_list.py b/appwrite/models/report_list.py new file mode 100644 index 00000000..05fe12f9 --- /dev/null +++ b/appwrite/models/report_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 .report import Report + +class ReportList(AppwriteModel): + """ + Reports List + + Attributes + ---------- + total : float + Total number of reports that matched your query. + reports : List[Report] + List of reports. + """ + total: float = Field(..., alias='total') + reports: List[Report] = Field(..., alias='reports') diff --git a/appwrite/models/usage_event.py b/appwrite/models/usage_event.py new file mode 100644 index 00000000..81d05834 --- /dev/null +++ b/appwrite/models/usage_event.py @@ -0,0 +1,42 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class UsageEvent(AppwriteModel): + """ + usageEvent + + Attributes + ---------- + metric : str + The metric key. + value : float + The metric value. + time : str + The event timestamp. + path : str + The API endpoint path. + method : str + The HTTP method. + status : str + HTTP status code. Stored as string to preserve unset state (empty string = not available). + resourcetype : str + The resource type. + resourceid : str + The resource ID. + countrycode : str + Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) two-character format. + useragent : str + The user agent string. + """ + metric: str = Field(..., alias='metric') + value: float = Field(..., alias='value') + time: str = Field(..., alias='time') + path: str = Field(..., alias='path') + method: str = Field(..., alias='method') + status: str = Field(..., alias='status') + resourcetype: str = Field(..., alias='resourceType') + resourceid: str = Field(..., alias='resourceId') + countrycode: str = Field(..., alias='countryCode') + useragent: str = Field(..., alias='userAgent') diff --git a/appwrite/models/usage_event_list.py b/appwrite/models/usage_event_list.py new file mode 100644 index 00000000..4845b7c6 --- /dev/null +++ b/appwrite/models/usage_event_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 .usage_event import UsageEvent + +class UsageEventList(AppwriteModel): + """ + Usage events list + + Attributes + ---------- + total : float + Total number of events that matched your query. + events : List[UsageEvent] + List of events. + """ + total: float = Field(..., alias='total') + events: List[UsageEvent] = Field(..., alias='events') diff --git a/appwrite/models/usage_gauge.py b/appwrite/models/usage_gauge.py new file mode 100644 index 00000000..3808eccc --- /dev/null +++ b/appwrite/models/usage_gauge.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 UsageGauge(AppwriteModel): + """ + usageGauge + + Attributes + ---------- + metric : str + The metric key. + value : float + The current snapshot value. + time : str + The snapshot timestamp. + """ + metric: str = Field(..., alias='metric') + value: float = Field(..., alias='value') + time: str = Field(..., alias='time') diff --git a/appwrite/models/usage_gauge_list.py b/appwrite/models/usage_gauge_list.py new file mode 100644 index 00000000..a0f2df72 --- /dev/null +++ b/appwrite/models/usage_gauge_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 .usage_gauge import UsageGauge + +class UsageGaugeList(AppwriteModel): + """ + Usage gauges list + + Attributes + ---------- + total : float + Total number of gauges that matched your query. + gauges : List[UsageGauge] + List of gauges. + """ + total: float = Field(..., alias='total') + gauges: List[UsageGauge] = Field(..., alias='gauges') diff --git a/appwrite/services/advisor.py b/appwrite/services/advisor.py new file mode 100644 index 00000000..af8d578a --- /dev/null +++ b/appwrite/services/advisor.py @@ -0,0 +1,224 @@ +from ..service import Service +from typing import Any, Dict, List, Optional, Union +from ..exception import AppwriteException +from appwrite.utils.deprecated import deprecated +from ..models.report_list import ReportList; +from ..models.report import Report; +from ..models.insight_list import InsightList; +from ..models.insight import Insight; + +class Advisor(Service): + + def __init__(self, client) -> None: + super(Advisor, self).__init__(client) + + def list_reports( + self, + queries: Optional[List[str]] = None, + total: Optional[bool] = None + ) -> ReportList: + """ + Get a list of all the project's analyzer reports. You can use the query params to filter your results. + + + 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: appId, type, targetType, target, analyzedAt + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + ReportList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/reports' + api_params = {} + + 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, { + }, api_params) + + return self._parse_response(response, model=ReportList) + + + def get_report( + self, + report_id: str + ) -> Report: + """ + Get an analyzer report by its unique ID. The response includes the report's metadata and the nested insights it produced. + + + Parameters + ---------- + report_id : str + Report ID. + + Returns + ------- + Report + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/reports/{reportId}' + api_params = {} + if report_id is None: + raise AppwriteException('Missing required parameter: "report_id"') + + api_path = api_path.replace('{reportId}', str(self._normalize_value(report_id))) + + + response = self.client.call('get', api_path, { + }, api_params) + + return self._parse_response(response, model=Report) + + + def delete_report( + self, + report_id: str + ) -> Dict[str, Any]: + """ + Delete an analyzer report by its unique ID. Nested insights and CTA metadata are removed asynchronously by the deletes worker. + + + Parameters + ---------- + report_id : str + Report ID. + + Returns + ------- + Dict[str, Any] + API response as a dictionary + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/reports/{reportId}' + api_params = {} + if report_id is None: + raise AppwriteException('Missing required parameter: "report_id"') + + api_path = api_path.replace('{reportId}', str(self._normalize_value(report_id))) + + + response = self.client.call('delete', api_path, { + 'content-type': 'application/json', + }, api_params) + + return response + + + def list_insights( + self, + report_id: str, + queries: Optional[List[str]] = None, + total: Optional[bool] = None + ) -> InsightList: + """ + List the insights produced under a single analyzer report. You can use the query params to filter your results further. + + + Parameters + ---------- + report_id : str + Parent report 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). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: type, severity, status, resourceType, resourceId, parentResourceType, parentResourceId, analyzedAt, dismissedAt, dismissedBy + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + InsightList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/reports/{reportId}/insights' + api_params = {} + if report_id is None: + raise AppwriteException('Missing required parameter: "report_id"') + + api_path = api_path.replace('{reportId}', str(self._normalize_value(report_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, { + }, api_params) + + return self._parse_response(response, model=InsightList) + + + def get_insight( + self, + report_id: str, + insight_id: str + ) -> Insight: + """ + Get an insight by its unique ID, scoped to its parent report. + + + Parameters + ---------- + report_id : str + Parent report ID. + insight_id : str + Insight ID. + + Returns + ------- + Insight + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/reports/{reportId}/insights/{insightId}' + api_params = {} + if report_id is None: + raise AppwriteException('Missing required parameter: "report_id"') + + if insight_id is None: + raise AppwriteException('Missing required parameter: "insight_id"') + + api_path = api_path.replace('{reportId}', str(self._normalize_value(report_id))) + api_path = api_path.replace('{insightId}', str(self._normalize_value(insight_id))) + + + response = self.client.call('get', api_path, { + }, api_params) + + return self._parse_response(response, model=Insight) + diff --git a/appwrite/services/presences.py b/appwrite/services/presences.py new file mode 100644 index 00000000..0566623e --- /dev/null +++ b/appwrite/services/presences.py @@ -0,0 +1,291 @@ +from ..service import Service +from typing import Any, Dict, List, Optional, Union, Type, TypeVar +from ..exception import AppwriteException +from appwrite.utils.deprecated import deprecated +from ..models.presence_list import PresenceList; +from ..models.presence import Presence; + +T = TypeVar('T') + +class Presences(Service): + + def __init__(self, client) -> None: + super(Presences, self).__init__(client) + + def list( + self, + queries: Optional[List[str]] = None, + total: Optional[bool] = None, + ttl: Optional[float] = None, + model_type: Type[T] = dict + ) -> PresenceList[T]: + """ + List presence logs. Expired entries are filtered out automatically. + + + Parameters + ---------- + queries : Optional[List[str]] + Array of query strings generated using the Query class provided by the SDK. + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + ttl : Optional[float] + TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, collection, schema version (attributes and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; document writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours). + + model_type : Type[T], optional + Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. + + Returns + ------- + PresenceList[T] + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/presences' + api_params = {} + + if queries is not None: + api_params['queries'] = self._normalize_value(queries) + if total is not None: + api_params['total'] = self._normalize_value(total) + if ttl is not None: + api_params['ttl'] = self._normalize_value(ttl) + + response = self.client.call('get', api_path, { + }, api_params) + + return PresenceList.with_data(response, model_type) + + + def get( + self, + presence_id: str, + model_type: Type[T] = dict + ) -> Presence[T]: + """ + Get a presence log by its unique ID. Entries whose `expiresAt` is in the past are treated as not found. + + + Parameters + ---------- + presence_id : str + Presence unique ID. + + model_type : Type[T], optional + Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. + + Returns + ------- + Presence[T] + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/presences/{presenceId}' + api_params = {} + if presence_id is None: + raise AppwriteException('Missing required parameter: "presence_id"') + + api_path = api_path.replace('{presenceId}', str(self._normalize_value(presence_id))) + + + response = self.client.call('get', api_path, { + }, api_params) + + return Presence.with_data(response, model_type) + + + def upsert( + self, + presence_id: str, + user_id: str, + status: str, + permissions: Optional[List[str]] = None, + expires_at: Optional[str] = None, + metadata: Optional[Dict[str, Any]] = None, + model_type: Type[T] = dict + ) -> Presence[T]: + """ + Create or update a presence log by its user ID. + + + Parameters + ---------- + presence_id : str + Presence unique ID. + user_id : str + User ID. + status : str + Presence status. + permissions : Optional[List[str]] + An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + expires_at : Optional[str] + Presence expiry datetime. + metadata : Optional[Dict[str, Any]] + Presence metadata object. + + model_type : Type[T], optional + Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. + + Returns + ------- + Presence[T] + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/presences/{presenceId}' + api_params = {} + if presence_id is None: + raise AppwriteException('Missing required parameter: "presence_id"') + + if user_id is None: + raise AppwriteException('Missing required parameter: "user_id"') + + if status is None: + raise AppwriteException('Missing required parameter: "status"') + + api_path = api_path.replace('{presenceId}', str(self._normalize_value(presence_id))) + + api_params['userId'] = self._normalize_value(user_id) + api_params['status'] = self._normalize_value(status) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) + if expires_at is not None: + api_params['expiresAt'] = self._normalize_value(expires_at) + if metadata is not None: + api_params['metadata'] = self._normalize_value(metadata) + + response = self.client.call('put', api_path, { + 'content-type': 'application/json', + }, api_params) + + return Presence.with_data(response, model_type) + + + def update_presence( + self, + presence_id: str, + user_id: str, + status: Optional[str] = None, + expires_at: Optional[str] = None, + metadata: Optional[Dict[str, Any]] = None, + permissions: Optional[List[str]] = None, + purge: Optional[bool] = None, + model_type: Type[T] = dict + ) -> Presence[T]: + """ + Update a presence log by its unique ID. Using the patch method you can pass only specific fields that will get updated. + + + Parameters + ---------- + presence_id : str + Presence unique ID. + user_id : str + User ID. + status : Optional[str] + Presence status. + expires_at : Optional[str] + Presence expiry datetime. + metadata : Optional[Dict[str, Any]] + Presence metadata object. + permissions : Optional[List[str]] + An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + purge : Optional[bool] + When true, purge cached responses used by list presences endpoint. + + model_type : Type[T], optional + Pydantic model class for the user-defined data. Defaults to dict for backward compatibility. + + Returns + ------- + Presence[T] + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/presences/{presenceId}' + api_params = {} + if presence_id is None: + raise AppwriteException('Missing required parameter: "presence_id"') + + if user_id is None: + raise AppwriteException('Missing required parameter: "user_id"') + + api_path = api_path.replace('{presenceId}', str(self._normalize_value(presence_id))) + + api_params['userId'] = self._normalize_value(user_id) + if status is not None: + api_params['status'] = self._normalize_value(status) + if expires_at is not None: + api_params['expiresAt'] = self._normalize_value(expires_at) + if metadata is not None: + api_params['metadata'] = self._normalize_value(metadata) + if permissions is not None: + api_params['permissions'] = self._normalize_value(permissions) + if purge is not None: + api_params['purge'] = self._normalize_value(purge) + + response = self.client.call('patch', api_path, { + 'content-type': 'application/json', + }, api_params) + + return Presence.with_data(response, model_type) + + + def delete( + self, + presence_id: str + ) -> Dict[str, Any]: + """ + Delete a presence log by its unique ID. + + + Parameters + ---------- + presence_id : str + Presence unique ID. + + Returns + ------- + Dict[str, Any] + API response as a dictionary + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/presences/{presenceId}' + api_params = {} + if presence_id is None: + raise AppwriteException('Missing required parameter: "presence_id"') + + api_path = api_path.replace('{presenceId}', str(self._normalize_value(presence_id))) + + + response = self.client.call('delete', api_path, { + 'content-type': 'application/json', + }, api_params) + + return response + diff --git a/appwrite/services/project.py b/appwrite/services/project.py index 4b69c3cc..44fed54b 100644 --- a/appwrite/services/project.py +++ b/appwrite/services/project.py @@ -2,10 +2,10 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..enums.auth_method import AuthMethod; from ..models.project import Project as ProjectModel; +from ..enums.project_auth_method_id import ProjectAuthMethodId; from ..models.key_list import KeyList; -from ..enums.scopes import Scopes; +from ..enums.project_key_scopes import ProjectKeyScopes; from ..models.key import Key; from ..models.ephemeral_key import EphemeralKey; from ..models.mock_number_list import MockNumberList; @@ -29,6 +29,7 @@ from ..models.o_auth2_fusion_auth import OAuth2FusionAuth; from ..models.o_auth2_github import OAuth2Github; from ..models.o_auth2_gitlab import OAuth2Gitlab; +from ..enums.project_o_auth2_google_prompt import ProjectOAuth2GooglePrompt; from ..models.o_auth2_google import OAuth2Google; from ..models.o_auth2_keycloak import OAuth2Keycloak; from ..models.o_auth2_kick import OAuth2Kick; @@ -51,7 +52,7 @@ from ..models.o_auth2_yandex import OAuth2Yandex; from ..models.o_auth2_zoho import OAuth2Zoho; from ..models.o_auth2_zoom import OAuth2Zoom; -from ..enums.o_auth_provider import OAuthProvider; +from ..enums.project_o_auth_provider_id import ProjectOAuthProviderId; from ..models.platform_list import PlatformList; from ..models.platform_android import PlatformAndroid; from ..models.platform_apple import PlatformApple; @@ -59,7 +60,7 @@ from ..models.platform_web import PlatformWeb; from ..models.platform_windows import PlatformWindows; from ..models.policy_list import PolicyList; -from ..enums.project_policy import ProjectPolicy; +from ..enums.project_policy_id import ProjectPolicyId; from ..models.policy_password_dictionary import PolicyPasswordDictionary; from ..models.policy_password_history import PolicyPasswordHistory; from ..models.policy_password_personal_data import PolicyPasswordPersonalData; @@ -69,12 +70,12 @@ from ..models.policy_session_limit import PolicySessionLimit; from ..models.policy_user_limit import PolicyUserLimit; from ..models.policy_membership_privacy import PolicyMembershipPrivacy; -from ..enums.protocol_id import ProtocolId; -from ..enums.service_id import ServiceId; -from ..enums.secure import Secure; +from ..enums.project_protocol_id import ProjectProtocolId; +from ..enums.project_service_id import ProjectServiceId; +from ..enums.project_smtp_secure import ProjectSMTPSecure; from ..models.email_template_list import EmailTemplateList; -from ..enums.email_template_type import EmailTemplateType; -from ..enums.email_template_locale import EmailTemplateLocale; +from ..enums.project_email_template_id import ProjectEmailTemplateId; +from ..enums.project_email_template_locale import ProjectEmailTemplateLocale; from ..models.email_template import EmailTemplate; from ..models.variable_list import VariableList; from ..models.variable import Variable; @@ -84,6 +85,32 @@ class Project(Service): def __init__(self, client) -> None: super(Project, self).__init__(client) + def get( + self + ) -> ProjectModel: + """ + Get a project. + + Returns + ------- + ProjectModel + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project' + api_params = {} + + response = self.client.call('get', api_path, { + }, api_params) + + return self._parse_response(response, model=ProjectModel) + + def delete( self ) -> Dict[str, Any]: @@ -113,7 +140,7 @@ def delete( def update_auth_method( self, - method_id: AuthMethod, + method_id: ProjectAuthMethodId, enabled: bool ) -> ProjectModel: """ @@ -121,7 +148,7 @@ def update_auth_method( Parameters ---------- - method_id : AuthMethod + method_id : ProjectAuthMethodId Auth Method ID. Possible values: email-password,magic-url,email-otp,anonymous,invites,jwt,phone enabled : bool Auth method status. @@ -200,7 +227,7 @@ def create_key( self, key_id: str, name: str, - scopes: List[Scopes], + scopes: List[ProjectKeyScopes], expire: Optional[str] = None ) -> Key: """ @@ -214,7 +241,7 @@ def create_key( Key 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. name : str Key name. Max length: 128 chars. - scopes : List[Scopes] + scopes : List[ProjectKeyScopes] Key scopes list. Maximum of 100 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. @@ -256,7 +283,7 @@ def create_key( def create_ephemeral_key( self, - scopes: List[Scopes], + scopes: List[ProjectKeyScopes], duration: float ) -> EphemeralKey: """ @@ -266,7 +293,7 @@ def create_ephemeral_key( Parameters ---------- - scopes : List[Scopes] + scopes : List[ProjectKeyScopes] Key scopes list. Maximum of 100 scopes are allowed. duration : float Time in seconds before ephemeral key expires. Maximum duration is 3600 seconds. @@ -342,7 +369,7 @@ def update_key( self, key_id: str, name: str, - scopes: List[Scopes], + scopes: List[ProjectKeyScopes], expire: Optional[str] = None ) -> Key: """ @@ -354,7 +381,7 @@ def update_key( Key ID. name : str Key name. Max length: 128 chars. - scopes : List[Scopes] + scopes : List[ProjectKeyScopes] Key scopes list. Maximum of 100 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. @@ -729,7 +756,7 @@ def update_o_auth2_amazon( client_id : Optional[str] 'Client ID' of Amazon OAuth2 app. For example: amzn1.application-oa2-client.87400c00000000000000000000063d5b2 client_secret : Optional[str] - 'Client Secret' of Amazon OAuth2 app. For example: + 'Client Secret' of Amazon OAuth2 app. For example: 79ffe4000000000000000000000000000000000000000000000000000002de55 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. @@ -824,7 +851,7 @@ def update_o_auth2_auth0( client_id : Optional[str] 'Client ID' of Auth0 OAuth2 app. For example: OaOkIA000000000000000000005KLSYq client_secret : Optional[str] - 'Client Secret' of Auth0 OAuth2 app. For example: + 'Client Secret' of Auth0 OAuth2 app. For example: zXz0000-00000000000000000000000000000-00000000000000000000PJafnF endpoint : Optional[str] Domain of Auth0 instance. For example: example.us.auth0.com enabled : Optional[bool] @@ -871,7 +898,7 @@ def update_o_auth2_authentik( client_id : Optional[str] 'Client ID' of Authentik OAuth2 app. For example: dTKOPa0000000000000000000000000000e7G8hv client_secret : Optional[str] - 'Client Secret' of Authentik OAuth2 app. For example: + 'Client Secret' of Authentik OAuth2 app. For example: ntQadq000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Hp5WK endpoint : Optional[str] Domain of Authentik instance. For example: example.authentik.com enabled : Optional[bool] @@ -917,7 +944,7 @@ def update_o_auth2_autodesk( client_id : Optional[str] 'Client ID' of Autodesk OAuth2 app. For example: 5zw90v00000000000000000000kVYXN7 client_secret : Optional[str] - 'Client Secret' of Autodesk OAuth2 app. For example: + 'Client Secret' of Autodesk OAuth2 app. For example: 7I000000000000MW 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. @@ -960,7 +987,7 @@ def update_o_auth2_bitbucket( key : Optional[str] 'Key' of Bitbucket OAuth2 app. For example: Knt70000000000ByRc secret : Optional[str] - 'Secret' of Bitbucket OAuth2 app. For example: + 'Secret' of Bitbucket OAuth2 app. For example: NMfLZJ00000000000000000000TLQdDx 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. @@ -1003,7 +1030,7 @@ def update_o_auth2_bitly( client_id : Optional[str] 'Client ID' of Bitly OAuth2 app. For example: d95151000000000000000000000000000067af9b client_secret : Optional[str] - 'Client Secret' of Bitly OAuth2 app. For example: + 'Client Secret' of Bitly OAuth2 app. For example: a13e250000000000000000000000000000d73095 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. @@ -1046,7 +1073,7 @@ def update_o_auth2_box( client_id : Optional[str] 'Client ID' of Box OAuth2 app. For example: deglcs00000000000000000000x2og6y client_secret : Optional[str] - 'Client Secret' of Box OAuth2 app. For example: + 'Client Secret' of Box OAuth2 app. For example: OKM1f100000000000000000000eshEif 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. @@ -1089,7 +1116,7 @@ def update_o_auth2_dailymotion( api_key : Optional[str] 'API Key' of Dailymotion OAuth2 app. For example: 07a9000000000000067f api_secret : Optional[str] - 'API Secret' of Dailymotion OAuth2 app. For example: + 'API Secret' of Dailymotion OAuth2 app. For example: a399a90000000000000000000000000000d90639 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. @@ -1132,7 +1159,7 @@ def update_o_auth2_discord( client_id : Optional[str] 'Client ID' of Discord OAuth2 app. For example: 950722000000343754 client_secret : Optional[str] - 'Client Secret' of Discord OAuth2 app. For example: + 'Client Secret' of Discord OAuth2 app. For example: YmPXnM000000000000000000002zFg5D 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. @@ -1175,7 +1202,7 @@ def update_o_auth2_disqus( public_key : Optional[str] 'Public Key, also known as API Key' of Disqus OAuth2 app. For example: cgegH70000000000000000000000000000000000000000000000000000Hr1nYX secret_key : Optional[str] - 'Secret Key, also known as API Secret' of Disqus OAuth2 app. For example: + 'Secret Key, also known as API Secret' of Disqus OAuth2 app. For example: W7Bykj00000000000000000000000000000000000000000000000000003o43w9 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. @@ -1218,7 +1245,7 @@ def update_o_auth2_dropbox( app_key : Optional[str] 'App Key' of Dropbox OAuth2 app. For example: jl000000000009t app_secret : Optional[str] - 'App Secret' of Dropbox OAuth2 app. For example: + 'App Secret' of Dropbox OAuth2 app. For example: g200000000000vw 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. @@ -1261,7 +1288,7 @@ def update_o_auth2_etsy( key_string : Optional[str] 'Keystring' of Etsy OAuth2 app. For example: nsgzxh0000000000008j85a2 shared_secret : Optional[str] - 'Shared Secret' of Etsy OAuth2 app. For example: + 'Shared Secret' of Etsy OAuth2 app. For example: tp000000ru 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. @@ -1304,7 +1331,7 @@ def update_o_auth2_facebook( app_id : Optional[str] 'App ID' of Facebook OAuth2 app. For example: 260600000007694 app_secret : Optional[str] - 'App Secret' of Facebook OAuth2 app. For example: + 'App Secret' of Facebook OAuth2 app. For example: 2d0b2800000000000000000000d38af4 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. @@ -1347,7 +1374,7 @@ def update_o_auth2_figma( client_id : Optional[str] 'Client ID' of Figma OAuth2 app. For example: byay5H0000000000VtiI40 client_secret : Optional[str] - 'Client Secret' of Figma OAuth2 app. For example: + 'Client Secret' of Figma OAuth2 app. For example: yEpOYn0000000000000000004iIsU5 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. @@ -1391,7 +1418,7 @@ def update_o_auth2_fusion_auth( client_id : Optional[str] 'Client ID' of FusionAuth OAuth2 app. For example: b2222c00-0000-0000-0000-000000862097 client_secret : Optional[str] - 'Client Secret' of FusionAuth OAuth2 app. For example: + 'Client Secret' of FusionAuth OAuth2 app. For example: Jx4s0C0000000000000000000000000000000wGqLsc endpoint : Optional[str] Domain of FusionAuth instance. For example: example.fusionauth.io enabled : Optional[bool] @@ -1437,7 +1464,7 @@ def update_o_auth2_git_hub( client_id : Optional[str] 'OAuth2 app Client ID, or App ID' of GitHub OAuth2 app. For example: e4d87900000000540733. Example of wrong value: 370006 client_secret : Optional[str] - 'Client Secret' of GitHub OAuth2 app. For example: + 'Client Secret' of GitHub OAuth2 app. For example: 5e07c00000000000000000000000000000198bcc 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. @@ -1481,7 +1508,7 @@ def update_o_auth2_gitlab( application_id : Optional[str] 'Application ID' of Gitlab OAuth2 app. For example: d41ffe0000000000000000000000000000000000000000000000000000d5e252 secret : Optional[str] - 'Secret' of Gitlab OAuth2 app. For example: + 'Secret' of Gitlab OAuth2 app. For example: gloas-838cfa0000000000000000000000000000000000000000000000000000ecbb38 endpoint : Optional[str] Endpoint URL of self-hosted GitLab instance. For example: https://gitlab.com enabled : Optional[bool] @@ -1517,6 +1544,7 @@ def update_o_auth2_google( self, client_id: Optional[str] = None, client_secret: Optional[str] = None, + prompt: Optional[List[ProjectOAuth2GooglePrompt]] = None, enabled: Optional[bool] = None ) -> OAuth2Google: """ @@ -1527,7 +1555,9 @@ def update_o_auth2_google( client_id : Optional[str] 'Client ID' of Google OAuth2 app. For example: 120000000095-92ifjb00000000000000000000g7ijfb.apps.googleusercontent.com client_secret : Optional[str] - 'Client Secret' of Google OAuth2 app. For example: + 'Client Secret' of Google OAuth2 app. For example: example-google-client-secret + prompt : Optional[List[ProjectOAuth2GooglePrompt]] + Array of Google OAuth2 prompt values. If "none" is included, it must be the only element. "none" means: don't display any authentication or consent screens. Must not be specified with other values. "consent" means: prompt the user for consent. "select_account" means: prompt the user to select an account. 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. @@ -1547,6 +1577,7 @@ def update_o_auth2_google( 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) response = self.client.call('patch', api_path, { @@ -1572,7 +1603,7 @@ def update_o_auth2_keycloak( client_id : Optional[str] 'Client ID' of Keycloak OAuth2 app. For example: appwrite-o0000000st-app client_secret : Optional[str] - 'Client Secret' of Keycloak OAuth2 app. For example: + 'Client Secret' of Keycloak OAuth2 app. For example: jdjrJd00000000000000000000HUsaZO endpoint : Optional[str] Domain of Keycloak instance. For example: keycloak.example.com realm_name : Optional[str] @@ -1621,7 +1652,7 @@ def update_o_auth2_kick( client_id : Optional[str] 'Client ID' of Kick OAuth2 app. For example: 01KQ7C00000000000001MFHS32 client_secret : Optional[str] - 'Client Secret' of Kick OAuth2 app. For example: + 'Client Secret' of Kick OAuth2 app. For example: 34ac5600000000000000000000000000000000000000000000000000e830c8b 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. @@ -1664,7 +1695,7 @@ def update_o_auth2_linkedin( client_id : Optional[str] 'Client ID' of Linkedin OAuth2 app. For example: 770000000000dv primary_client_secret : Optional[str] - 'Primary Client Secret or Secondary Client Secret' of Linkedin OAuth2 app. For example: + 'Primary Client Secret or Secondary Client Secret' of Linkedin OAuth2 app. For example: example-linkedin-client-secret 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. @@ -1708,7 +1739,7 @@ def update_o_auth2_microsoft( application_id : Optional[str] 'Entra ID Application ID, also known as Client ID' of Microsoft OAuth2 app. For example: 00001111-aaaa-2222-bbbb-3333cccc4444 application_secret : Optional[str] - 'Entra ID Application Secret, also known as Client Secret' of Microsoft OAuth2 app. For example: + 'Entra ID Application Secret, also known as Client Secret' of Microsoft OAuth2 app. For example: A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u tenant : Optional[str] Microsoft Entra ID tenant identifier. Use 'common', 'organizations', 'consumers' or a specific tenant ID. For example: common enabled : Optional[bool] @@ -1754,7 +1785,7 @@ def update_o_auth2_notion( oauth_client_id : Optional[str] 'OAuth Client ID' of Notion OAuth2 app. For example: 341d8700-0000-0000-0000-000000446ee3 oauth_client_secret : Optional[str] - 'OAuth Client Secret' of Notion OAuth2 app. For example: + 'OAuth Client Secret' of Notion OAuth2 app. For example: secret_dLUr4b000000000000000000000000000000lFHAa9 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. @@ -1801,7 +1832,7 @@ def update_o_auth2_oidc( client_id : Optional[str] 'Client ID' of Oidc OAuth2 app. For example: qibI2x0000000000000000000000000006L2YFoG client_secret : Optional[str] - 'Client Secret' of Oidc OAuth2 app. For example: + 'Client Secret' of Oidc OAuth2 app. For example: Ah68ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003qpcHV well_known_url : Optional[str] OpenID Connect well-known configuration URL. When provided, authorization, token, and user info endpoints can be discovered automatically. For example: https://myoauth.com/.well-known/openid-configuration authorization_url : Optional[str] @@ -1858,7 +1889,7 @@ def update_o_auth2_okta( client_id : Optional[str] 'Client ID' of Okta OAuth2 app. For example: 0oa00000000000000698 client_secret : Optional[str] - 'Client Secret' of Okta OAuth2 app. For example: + 'Client Secret' of Okta OAuth2 app. For example: Kiq0000000000000000000000000000000000000-00000000000H2L5-3SJ-vRV domain : Optional[str] Okta company domain. Required when enabling the provider. For example: trial-6400025.okta.com. Example of wrong value: trial-6400025-admin.okta.com, or https://trial-6400025.okta.com/ authorization_server_id : Optional[str] @@ -1907,7 +1938,7 @@ def update_o_auth2_paypal( client_id : Optional[str] 'Client ID' of Paypal OAuth2 app. For example: AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB secret_key : Optional[str] - 'Secret Key 1 or Secret Key 2' of Paypal OAuth2 app. For example: + 'Secret Key 1 or Secret Key 2' of Paypal OAuth2 app. For example: EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp 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. @@ -1950,7 +1981,7 @@ def update_o_auth2_paypal_sandbox( client_id : Optional[str] 'Client ID' of PaypalSandbox OAuth2 app. For example: AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB secret_key : Optional[str] - 'Secret Key 1 or Secret Key 2' of PaypalSandbox OAuth2 app. For example: + 'Secret Key 1 or Secret Key 2' of PaypalSandbox OAuth2 app. For example: EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp 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. @@ -1993,7 +2024,7 @@ def update_o_auth2_podio( client_id : Optional[str] 'Client ID' of Podio OAuth2 app. For example: appwrite-o0000000st-app client_secret : Optional[str] - 'Client Secret' of Podio OAuth2 app. For example: + 'Client Secret' of Podio OAuth2 app. For example: Rn247T0000000000000000000000000000000000000000000000000000W2zWTN 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. @@ -2036,7 +2067,7 @@ def update_o_auth2_salesforce( customer_key : Optional[str] 'Consumer Key' of Salesforce OAuth2 app. For example: 3MVG9I0000000000000000000000000000000000000000000000000000000000000000000000000C5Aejq customer_secret : Optional[str] - 'Consumer Secret' of Salesforce OAuth2 app. For example: + 'Consumer Secret' of Salesforce OAuth2 app. For example: 3w000000000000e2 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. @@ -2079,7 +2110,7 @@ def update_o_auth2_slack( client_id : Optional[str] 'Client ID' of Slack OAuth2 app. For example: 23000000089.15000000000023 client_secret : Optional[str] - 'Client Secret' of Slack OAuth2 app. For example: + 'Client Secret' of Slack OAuth2 app. For example: 81656000000000000000000000f3d2fd 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. @@ -2122,7 +2153,7 @@ def update_o_auth2_spotify( client_id : Optional[str] 'Client ID' of Spotify OAuth2 app. For example: 6ec271000000000000000000009beace client_secret : Optional[str] - 'Client Secret' of Spotify OAuth2 app. For example: + 'Client Secret' of Spotify OAuth2 app. For example: db068a000000000000000000008b5b9f 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. @@ -2165,7 +2196,7 @@ def update_o_auth2_stripe( client_id : Optional[str] 'Client ID' of Stripe OAuth2 app. For example: ca_UKibXX0000000000000000000006byvR api_secret_key : Optional[str] - 'API Secret Key' of Stripe OAuth2 app. For example: + 'API Secret Key' of Stripe OAuth2 app. For example: sk_51SfOd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000QGWYfp 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. @@ -2208,7 +2239,7 @@ def update_o_auth2_tradeshift( oauth2_client_id : Optional[str] 'OAuth2 Client ID' of Tradeshift OAuth2 app. For example: appwrite-tes00000.0000000000est-app oauth2_client_secret : Optional[str] - 'OAuth2 Client Secret' of Tradeshift OAuth2 app. For example: + 'OAuth2 Client Secret' of Tradeshift OAuth2 app. For example: 7cb52700-0000-0000-0000-000000ca5b83 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. @@ -2251,7 +2282,7 @@ def update_o_auth2_tradeshift_sandbox( oauth2_client_id : Optional[str] 'OAuth2 Client ID' of Tradeshift Sandbox OAuth2 app. For example: appwrite-tes00000.0000000000est-app oauth2_client_secret : Optional[str] - 'OAuth2 Client Secret' of Tradeshift Sandbox OAuth2 app. For example: + 'OAuth2 Client Secret' of Tradeshift Sandbox OAuth2 app. For example: 7cb52700-0000-0000-0000-000000ca5b83 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. @@ -2294,7 +2325,7 @@ def update_o_auth2_twitch( client_id : Optional[str] 'Client ID' of Twitch OAuth2 app. For example: vvi0in000000000000000000ikmt9p client_secret : Optional[str] - 'Client Secret' of Twitch OAuth2 app. For example: + 'Client Secret' of Twitch OAuth2 app. For example: pmapue000000000000000000zylw3v 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. @@ -2337,7 +2368,7 @@ def update_o_auth2_word_press( client_id : Optional[str] 'Client ID' of WordPress OAuth2 app. For example: 130005 client_secret : Optional[str] - 'Client Secret' of WordPress OAuth2 app. For example: + 'Client Secret' of WordPress OAuth2 app. For example: PlBfJS0000000000000000000000000000000000000000000000000000EdUZJk 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. @@ -2380,7 +2411,7 @@ def update_o_auth2_x( customer_key : Optional[str] 'Customer Key' of X OAuth2 app. For example: slzZV0000000000000NFLaWT secret_key : Optional[str] - 'Secret Key' of X OAuth2 app. For example: + 'Secret Key' of X OAuth2 app. For example: tkEPkp00000000000000000000000000000000000000FTxbI9 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. @@ -2423,7 +2454,7 @@ def update_o_auth2_yahoo( client_id : Optional[str] 'Client ID, also known as Customer Key' of Yahoo OAuth2 app. For example: dj0yJm000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z4PWRm client_secret : Optional[str] - 'Client Secret, also known as Customer Secret' of Yahoo OAuth2 app. For example: + 'Client Secret, also known as Customer Secret' of Yahoo OAuth2 app. For example: cf978f0000000000000000000000000000c5e2e9 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. @@ -2466,7 +2497,7 @@ def update_o_auth2_yandex( client_id : Optional[str] 'Client ID' of Yandex OAuth2 app. For example: 6a8a6a0000000000000000000091483c client_secret : Optional[str] - 'Client Secret' of Yandex OAuth2 app. For example: + 'Client Secret' of Yandex OAuth2 app. For example: bbf98500000000000000000000c75a63 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. @@ -2509,7 +2540,7 @@ def update_o_auth2_zoho( client_id : Optional[str] 'Client ID' of Zoho OAuth2 app. For example: 1000.83C178000000000000000000RPNX0B client_secret : Optional[str] - 'Client Secret' of Zoho OAuth2 app. For example: + 'Client Secret' of Zoho OAuth2 app. For example: fb5cac000000000000000000000000000000a68f6e 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. @@ -2552,7 +2583,7 @@ def update_o_auth2_zoom( client_id : Optional[str] 'Client ID' of Zoom OAuth2 app. For example: QMAC00000000000000w0AQ client_secret : Optional[str] - 'Client Secret' of Zoom OAuth2 app. For example: + 'Client Secret' of Zoom OAuth2 app. For example: GAWsG4000000000000000000007U01ON 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. @@ -2583,14 +2614,14 @@ def update_o_auth2_zoom( def get_o_auth2_provider( self, - provider_id: OAuthProvider + provider_id: ProjectOAuthProviderId ) -> 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]: """ Get a single OAuth2 provider configuration. Credential fields (client secret, p8 file, key/team IDs) are write-only and always returned empty. Parameters ---------- - provider_id : OAuthProvider + provider_id : ProjectOAuthProviderId OAuth2 provider key. For example: github, google, apple. Returns @@ -3432,6 +3463,120 @@ def list_policies( return self._parse_response(response, model=PolicyList) + def update_deny_aliased_email_policy( + self, + enabled: bool + ) -> ProjectModel: + """ + Configures if aliased emails such as subaddresses and emails with suffixes are denied during new users sign-ups and email updates. + + Parameters + ---------- + enabled : bool + Set whether or not to block aliased emails during signup and email updates. + + Returns + ------- + ProjectModel + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project/policies/deny-aliased-email' + api_params = {} + if enabled is None: + raise AppwriteException('Missing required parameter: "enabled"') + + + api_params['enabled'] = self._normalize_value(enabled) + + response = self.client.call('patch', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=ProjectModel) + + + def update_deny_disposable_email_policy( + self, + enabled: bool + ) -> ProjectModel: + """ + Configures if disposable emails from known temporary domains are denied during new users sign-ups and email updates. + + Parameters + ---------- + enabled : bool + Set whether or not to block disposable email addresses during signup and email updates. + + Returns + ------- + ProjectModel + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project/policies/deny-disposable-email' + api_params = {} + if enabled is None: + raise AppwriteException('Missing required parameter: "enabled"') + + + api_params['enabled'] = self._normalize_value(enabled) + + response = self.client.call('patch', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=ProjectModel) + + + def update_deny_free_email_policy( + self, + enabled: bool + ) -> ProjectModel: + """ + Configures if emails from free providers such as Gmail or Yahoo are denied during new users sign-ups and email updates. + + Parameters + ---------- + enabled : bool + Set whether or not to block free email addresses during signup and email updates. + + Returns + ------- + ProjectModel + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/project/policies/deny-free-email' + api_params = {} + if enabled is None: + raise AppwriteException('Missing required parameter: "enabled"') + + + api_params['enabled'] = self._normalize_value(enabled) + + response = self.client.call('patch', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=ProjectModel) + + def update_membership_privacy_policy( self, user_id: Optional[bool] = None, @@ -3787,14 +3932,14 @@ def update_user_limit_policy( def get_policy( self, - policy_id: ProjectPolicy + policy_id: ProjectPolicyId ) -> Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy]: """ Get a policy by its unique ID. This endpoint returns the current configuration for the requested project policy. Parameters ---------- - policy_id : ProjectPolicy + policy_id : ProjectPolicyId Policy ID. Can be one of: password-dictionary, password-history, password-personal-data, session-alert, session-duration, session-invalidation, session-limit, user-limit, membership-privacy. Returns @@ -3853,7 +3998,7 @@ def get_policy( def update_protocol( self, - protocol_id: ProtocolId, + protocol_id: ProjectProtocolId, enabled: bool ) -> ProjectModel: """ @@ -3861,7 +4006,7 @@ def update_protocol( Parameters ---------- - protocol_id : ProtocolId + protocol_id : ProjectProtocolId Protocol name. Can be one of: rest, graphql, websocket enabled : bool Protocol status. @@ -3898,7 +4043,7 @@ def update_protocol( def update_service( self, - service_id: ServiceId, + service_id: ProjectServiceId, enabled: bool ) -> ProjectModel: """ @@ -3906,8 +4051,8 @@ def update_service( Parameters ---------- - service_id : ServiceId - Service name. Can be one of: account, avatars, databases, tablesdb, locale, health, project, storage, teams, users, vcs, sites, functions, proxy, graphql, migrations, messaging + service_id : ProjectServiceId + Service name. Can be one of: account, avatars, databases, tablesdb, locale, health, project, storage, teams, users, vcs, sites, functions, proxy, graphql, migrations, messaging, advisor enabled : bool Service status. @@ -3951,7 +4096,7 @@ def update_smtp( sender_name: Optional[str] = None, reply_to_email: Optional[str] = None, reply_to_name: Optional[str] = None, - secure: Optional[Secure] = None, + secure: Optional[ProjectSMTPSecure] = None, enabled: Optional[bool] = None ) -> ProjectModel: """ @@ -3975,7 +4120,7 @@ def update_smtp( Email used when user replies to the email. reply_to_name : Optional[str] Name used when user replies to the email. - secure : Optional[Secure] + secure : Optional[ProjectSMTPSecure] Configures if communication with SMTP server is encrypted. Allowed values are: tls, ssl. Leave empty for no encryption. enabled : Optional[bool] Enable or disable custom SMTP. Custom SMTP is useful for branding purposes, but also allows use of custom email templates. @@ -4092,8 +4237,8 @@ def list_email_templates( def update_email_template( self, - template_id: EmailTemplateType, - locale: Optional[EmailTemplateLocale] = None, + template_id: ProjectEmailTemplateId, + locale: Optional[ProjectEmailTemplateLocale] = None, subject: Optional[str] = None, message: Optional[str] = None, sender_name: Optional[str] = None, @@ -4106,9 +4251,9 @@ def update_email_template( Parameters ---------- - template_id : EmailTemplateType + template_id : ProjectEmailTemplateId Custom email template type. Can be one of: verification, magicSession, recovery, invitation, mfaChallenge, sessionAlert, otpSession - locale : Optional[EmailTemplateLocale] + locale : Optional[ProjectEmailTemplateLocale] Custom email template locale. If left empty, the fallback locale (en) will be used. subject : Optional[str] Subject of the email template. Can be up to 255 characters. @@ -4159,17 +4304,17 @@ def update_email_template( def get_email_template( self, - template_id: EmailTemplateType, - locale: Optional[EmailTemplateLocale] = None + template_id: ProjectEmailTemplateId, + locale: Optional[ProjectEmailTemplateLocale] = None ) -> EmailTemplate: """ Get a custom email template for the specified locale and type. This endpoint returns the template content, subject, and other configuration details. Parameters ---------- - template_id : EmailTemplateType + template_id : ProjectEmailTemplateId Custom email template type. Can be one of: verification, magicSession, recovery, invitation, mfaChallenge, sessionAlert, otpSession - locale : Optional[EmailTemplateLocale] + locale : Optional[ProjectEmailTemplateLocale] Custom email template locale. If left empty, the fallback locale (en) will be used. Returns diff --git a/appwrite/services/usage.py b/appwrite/services/usage.py new file mode 100644 index 00000000..249bfaf7 --- /dev/null +++ b/appwrite/services/usage.py @@ -0,0 +1,91 @@ +from ..service import Service +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, + queries: Optional[List[str]] = None, + total: Optional[bool] = None + ) -> UsageEventList: + """ + Query usage event metrics from the usage database. Returns individual event rows with full metadata. Pass Query objects as JSON strings to filter, paginate, and order results. Supported query methods: equal, greaterThanEqual, lessThanEqual, orderAsc, orderDesc, limit, offset. Supported filter attributes: metric, path, method, status, resource, resourceId, country, userAgent, time (these match the underlying column names — note that the response surfaces `resource` as `resourceType` and `country` as `countryCode`). When no time filter is supplied the endpoint defaults to the last 7 days. Default `limit(100)` is applied if none is given; user-supplied limits are capped at 500. The `total` field is capped at 5000 to keep counts predictable — pass `total=false` to skip the count entirely. + + Parameters + ---------- + queries : Optional[List[str]] + Array of query strings as JSON. Supported: equal("metric", [...]), equal("path", [...]), equal("method", [...]), equal("status", [...]), equal("resource", [...]), equal("resourceId", [...]), equal("country", [...]), equal("userAgent", [...]), greaterThanEqual("time", "..."), lessThanEqual("time", "..."), orderAsc("time"), orderDesc("time"), limit(N), offset(N). + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + UsageEventList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/usage/events' + api_params = {} + + 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, { + }, api_params) + + return self._parse_response(response, model=UsageEventList) + + + def list_gauges( + self, + queries: Optional[List[str]] = None, + total: Optional[bool] = None + ) -> UsageGaugeList: + """ + Query usage gauge metrics (point-in-time resource snapshots) from the usage database. Returns individual gauge snapshots with metric, value, and timestamp. Pass Query objects as JSON strings to filter, paginate, and order results. Supported query methods: equal, greaterThanEqual, lessThanEqual, orderAsc, orderDesc, limit, offset. Supported filter attributes: metric, time. Use `orderDesc("time"), limit(1)` to fetch the most recent snapshot. When no time filter is supplied the endpoint defaults to the last 7 days. Default `limit(100)` is applied if none is given; user-supplied limits are capped at 500. The `total` field is capped at 5000 to keep counts predictable — pass `total=false` to skip the count entirely. + + Parameters + ---------- + queries : Optional[List[str]] + Array of query strings as JSON. Supported: equal("metric", [...]), greaterThanEqual("time", "..."), lessThanEqual("time", "..."), orderAsc("time"), orderDesc("time"), limit(N), offset(N). + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + UsageGaugeList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/usage/gauges' + api_params = {} + + 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, { + }, api_params) + + return self._parse_response(response, model=UsageGaugeList) + diff --git a/docs/examples/advisor/delete-report.md b/docs/examples/advisor/delete-report.md new file mode 100644 index 00000000..ef50a2f0 --- /dev/null +++ b/docs/examples/advisor/delete-report.md @@ -0,0 +1,15 @@ +```python +from appwrite.client import Client +from appwrite.services.advisor import Advisor + +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 + +advisor = Advisor(client) + +result = advisor.delete_report( + report_id = '' +) +``` diff --git a/docs/examples/advisor/get-insight.md b/docs/examples/advisor/get-insight.md new file mode 100644 index 00000000..16607e04 --- /dev/null +++ b/docs/examples/advisor/get-insight.md @@ -0,0 +1,19 @@ +```python +from appwrite.client import Client +from appwrite.services.advisor import Advisor +from appwrite.models import Insight + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_session('') # The user session to authenticate with + +advisor = Advisor(client) + +result: Insight = advisor.get_insight( + report_id = '', + insight_id = '' +) + +print(result.model_dump()) +``` diff --git a/docs/examples/advisor/get-report.md b/docs/examples/advisor/get-report.md new file mode 100644 index 00000000..60abf552 --- /dev/null +++ b/docs/examples/advisor/get-report.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.advisor import Advisor +from appwrite.models import Report + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_session('') # The user session to authenticate with + +advisor = Advisor(client) + +result: Report = advisor.get_report( + report_id = '' +) + +print(result.model_dump()) +``` diff --git a/docs/examples/advisor/list-insights.md b/docs/examples/advisor/list-insights.md new file mode 100644 index 00000000..1e425fe3 --- /dev/null +++ b/docs/examples/advisor/list-insights.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.advisor import Advisor +from appwrite.models import InsightList + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_session('') # The user session to authenticate with + +advisor = Advisor(client) + +result: InsightList = advisor.list_insights( + report_id = '', + queries = [], # optional + total = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/advisor/list-reports.md b/docs/examples/advisor/list-reports.md new file mode 100644 index 00000000..314464ad --- /dev/null +++ b/docs/examples/advisor/list-reports.md @@ -0,0 +1,19 @@ +```python +from appwrite.client import Client +from appwrite.services.advisor import Advisor +from appwrite.models import ReportList + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_session('') # The user session to authenticate with + +advisor = Advisor(client) + +result: ReportList = advisor.list_reports( + queries = [], # optional + total = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/presences/delete.md b/docs/examples/presences/delete.md new file mode 100644 index 00000000..ca4ba660 --- /dev/null +++ b/docs/examples/presences/delete.md @@ -0,0 +1,15 @@ +```python +from appwrite.client import Client +from appwrite.services.presences import Presences + +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 + +presences = Presences(client) + +result = presences.delete( + presence_id = '' +) +``` diff --git a/docs/examples/presences/get.md b/docs/examples/presences/get.md new file mode 100644 index 00000000..2c57df09 --- /dev/null +++ b/docs/examples/presences/get.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.presences import Presences +from appwrite.models import Presence + +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 + +presences = Presences(client) + +result: Presence = presences.get( + presence_id = '' +) + +print(result.model_dump()) +``` diff --git a/docs/examples/presences/list.md b/docs/examples/presences/list.md new file mode 100644 index 00000000..a0349285 --- /dev/null +++ b/docs/examples/presences/list.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.presences import Presences +from appwrite.models import PresenceList + +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 + +presences = Presences(client) + +result: PresenceList = presences.list( + queries = [], # optional + total = False, # optional + ttl = 0 # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/presences/update-presence.md b/docs/examples/presences/update-presence.md new file mode 100644 index 00000000..ea7a7c58 --- /dev/null +++ b/docs/examples/presences/update-presence.md @@ -0,0 +1,26 @@ +```python +from appwrite.client import Client +from appwrite.services.presences import Presences +from appwrite.models import Presence +from appwrite.permission import Permission +from appwrite.role import Role + +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 + +presences = Presences(client) + +result: Presence = presences.update_presence( + presence_id = '', + user_id = '', + status = '', # optional + expires_at = '2020-10-15T06:38:00.000+00:00', # optional + metadata = {}, # optional + permissions = [Permission.read(Role.any())], # optional + purge = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/presences/upsert.md b/docs/examples/presences/upsert.md new file mode 100644 index 00000000..2750434c --- /dev/null +++ b/docs/examples/presences/upsert.md @@ -0,0 +1,25 @@ +```python +from appwrite.client import Client +from appwrite.services.presences import Presences +from appwrite.models import Presence +from appwrite.permission import Permission +from appwrite.role import Role + +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 + +presences = Presences(client) + +result: Presence = presences.upsert( + presence_id = '', + user_id = '', + status = '', + permissions = [Permission.read(Role.any())], # optional + expires_at = '2020-10-15T06:38:00.000+00:00', # optional + metadata = {} # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/project/create-ephemeral-key.md b/docs/examples/project/create-ephemeral-key.md index 4b51248c..17a48da6 100644 --- a/docs/examples/project/create-ephemeral-key.md +++ b/docs/examples/project/create-ephemeral-key.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import EphemeralKey -from appwrite.enums import Scopes +from appwrite.enums import ProjectKeyScopes client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -12,7 +12,7 @@ client.set_key('') # Your secret API key project = Project(client) result: EphemeralKey = project.create_ephemeral_key( - scopes = [Scopes.PROJECT_READ], + scopes = [ProjectKeyScopes.PROJECT_READ], duration = 600 ) diff --git a/docs/examples/project/create-key.md b/docs/examples/project/create-key.md index bca74d67..a3e040f7 100644 --- a/docs/examples/project/create-key.md +++ b/docs/examples/project/create-key.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import Key -from appwrite.enums import Scopes +from appwrite.enums import ProjectKeyScopes client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -14,7 +14,7 @@ project = Project(client) result: Key = project.create_key( key_id = '', name = '', - scopes = [Scopes.PROJECT_READ], + scopes = [ProjectKeyScopes.PROJECT_READ], expire = '2020-10-15T06:38:00.000+00:00' # optional ) diff --git a/docs/examples/project/get-email-template.md b/docs/examples/project/get-email-template.md index f695b72d..8fedaf74 100644 --- a/docs/examples/project/get-email-template.md +++ b/docs/examples/project/get-email-template.md @@ -2,8 +2,8 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import EmailTemplate -from appwrite.enums import EmailTemplateType -from appwrite.enums import EmailTemplateLocale +from appwrite.enums import ProjectEmailTemplateId +from appwrite.enums import ProjectEmailTemplateLocale client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -13,8 +13,8 @@ client.set_key('') # Your secret API key project = Project(client) result: EmailTemplate = project.get_email_template( - template_id = EmailTemplateType.VERIFICATION, - locale = EmailTemplateLocale.AF # optional + template_id = ProjectEmailTemplateId.VERIFICATION, + locale = ProjectEmailTemplateLocale.AF # optional ) print(result.model_dump()) diff --git a/docs/examples/project/get-o-auth-2-provider.md b/docs/examples/project/get-o-auth-2-provider.md index 486443ea..f13325e0 100644 --- a/docs/examples/project/get-o-auth-2-provider.md +++ b/docs/examples/project/get-o-auth-2-provider.md @@ -42,7 +42,7 @@ from appwrite.models import OAuth2Okta from appwrite.models import OAuth2Kick from appwrite.models import OAuth2Microsoft from typing import Union -from appwrite.enums import OAuthProvider +from appwrite.enums import ProjectOAuthProviderId client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -52,7 +52,7 @@ client.set_key('') # Your secret API key project = Project(client) result: Union[OAuth2Github, OAuth2Discord, OAuth2Figma, OAuth2Dropbox, OAuth2Dailymotion, OAuth2Bitbucket, OAuth2Bitly, OAuth2Box, OAuth2Autodesk, OAuth2Google, OAuth2Zoom, OAuth2Zoho, OAuth2Yandex, OAuth2X, OAuth2WordPress, OAuth2Twitch, OAuth2Stripe, OAuth2Spotify, OAuth2Slack, OAuth2Podio, OAuth2Notion, OAuth2Salesforce, OAuth2Yahoo, OAuth2Linkedin, OAuth2Disqus, OAuth2Amazon, OAuth2Etsy, OAuth2Facebook, OAuth2Tradeshift, OAuth2Paypal, OAuth2Gitlab, OAuth2Authentik, OAuth2Auth0, OAuth2FusionAuth, OAuth2Keycloak, OAuth2Oidc, OAuth2Apple, OAuth2Okta, OAuth2Kick, OAuth2Microsoft] = project.get_o_auth2_provider( - provider_id = OAuthProvider.AMAZON + provider_id = ProjectOAuthProviderId.AMAZON ) print(result.model_dump()) diff --git a/docs/examples/project/get-policy.md b/docs/examples/project/get-policy.md index 7f971d18..e05516f8 100644 --- a/docs/examples/project/get-policy.md +++ b/docs/examples/project/get-policy.md @@ -11,7 +11,7 @@ from appwrite.models import PolicySessionLimit from appwrite.models import PolicyUserLimit from appwrite.models import PolicyMembershipPrivacy from typing import Union -from appwrite.enums import ProjectPolicy +from appwrite.enums import ProjectPolicyId client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -21,7 +21,7 @@ client.set_key('') # Your secret API key project = Project(client) result: Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy] = project.get_policy( - policy_id = ProjectPolicy.PASSWORD_DICTIONARY + policy_id = ProjectPolicyId.PASSWORD_DICTIONARY ) print(result.model_dump()) diff --git a/docs/examples/project/get.md b/docs/examples/project/get.md new file mode 100644 index 00000000..ea0046c7 --- /dev/null +++ b/docs/examples/project/get.md @@ -0,0 +1,16 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import Project as ProjectModel + +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: ProjectModel = project.get() + +print(result.model_dump()) +``` diff --git a/docs/examples/project/update-auth-method.md b/docs/examples/project/update-auth-method.md index a83e0880..d9e4c643 100644 --- a/docs/examples/project/update-auth-method.md +++ b/docs/examples/project/update-auth-method.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import Project as ProjectModel -from appwrite.enums import AuthMethod +from appwrite.enums import ProjectAuthMethodId client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -12,7 +12,7 @@ client.set_key('') # Your secret API key project = Project(client) result: ProjectModel = project.update_auth_method( - method_id = AuthMethod.EMAIL_PASSWORD, + method_id = ProjectAuthMethodId.EMAIL_PASSWORD, enabled = False ) diff --git a/docs/examples/project/update-deny-aliased-email-policy.md b/docs/examples/project/update-deny-aliased-email-policy.md new file mode 100644 index 00000000..02d1f7d4 --- /dev/null +++ b/docs/examples/project/update-deny-aliased-email-policy.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import Project as ProjectModel + +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: ProjectModel = project.update_deny_aliased_email_policy( + enabled = False +) + +print(result.model_dump()) +``` diff --git a/docs/examples/project/update-deny-disposable-email-policy.md b/docs/examples/project/update-deny-disposable-email-policy.md new file mode 100644 index 00000000..2dbeaf5e --- /dev/null +++ b/docs/examples/project/update-deny-disposable-email-policy.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import Project as ProjectModel + +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: ProjectModel = project.update_deny_disposable_email_policy( + enabled = False +) + +print(result.model_dump()) +``` diff --git a/docs/examples/project/update-deny-free-email-policy.md b/docs/examples/project/update-deny-free-email-policy.md new file mode 100644 index 00000000..e9af632b --- /dev/null +++ b/docs/examples/project/update-deny-free-email-policy.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.models import Project as ProjectModel + +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: ProjectModel = project.update_deny_free_email_policy( + enabled = False +) + +print(result.model_dump()) +``` diff --git a/docs/examples/project/update-email-template.md b/docs/examples/project/update-email-template.md index b7e86d0a..d5548fdb 100644 --- a/docs/examples/project/update-email-template.md +++ b/docs/examples/project/update-email-template.md @@ -2,8 +2,8 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import EmailTemplate -from appwrite.enums import EmailTemplateType -from appwrite.enums import EmailTemplateLocale +from appwrite.enums import ProjectEmailTemplateId +from appwrite.enums import ProjectEmailTemplateLocale client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -13,8 +13,8 @@ client.set_key('') # Your secret API key project = Project(client) result: EmailTemplate = project.update_email_template( - template_id = EmailTemplateType.VERIFICATION, - locale = EmailTemplateLocale.AF, # optional + template_id = ProjectEmailTemplateId.VERIFICATION, + locale = ProjectEmailTemplateLocale.AF, # optional subject = '', # optional message = '', # optional sender_name = '', # optional diff --git a/docs/examples/project/update-key.md b/docs/examples/project/update-key.md index 88f6c0a9..e1ecc201 100644 --- a/docs/examples/project/update-key.md +++ b/docs/examples/project/update-key.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import Key -from appwrite.enums import Scopes +from appwrite.enums import ProjectKeyScopes client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -14,7 +14,7 @@ project = Project(client) result: Key = project.update_key( key_id = '', name = '', - scopes = [Scopes.PROJECT_READ], + scopes = [ProjectKeyScopes.PROJECT_READ], expire = '2020-10-15T06:38:00.000+00:00' # optional ) diff --git a/docs/examples/project/update-o-auth-2-google.md b/docs/examples/project/update-o-auth-2-google.md index 865e81f5..b1cc1eca 100644 --- a/docs/examples/project/update-o-auth-2-google.md +++ b/docs/examples/project/update-o-auth-2-google.md @@ -2,6 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import OAuth2Google +from appwrite.enums import ProjectOAuth2GooglePrompt client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -13,6 +14,7 @@ project = Project(client) result: OAuth2Google = project.update_o_auth2_google( client_id = '', # optional client_secret = '', # optional + prompt = [ProjectOAuth2GooglePrompt.NONE], # optional enabled = False # optional ) diff --git a/docs/examples/project/update-protocol.md b/docs/examples/project/update-protocol.md index a8b555d0..db26644d 100644 --- a/docs/examples/project/update-protocol.md +++ b/docs/examples/project/update-protocol.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import Project as ProjectModel -from appwrite.enums import ProtocolId +from appwrite.enums import ProjectProtocolId client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -12,7 +12,7 @@ client.set_key('') # Your secret API key project = Project(client) result: ProjectModel = project.update_protocol( - protocol_id = ProtocolId.REST, + protocol_id = ProjectProtocolId.REST, enabled = False ) diff --git a/docs/examples/project/update-service.md b/docs/examples/project/update-service.md index 66bd6c7d..17c003c0 100644 --- a/docs/examples/project/update-service.md +++ b/docs/examples/project/update-service.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import Project as ProjectModel -from appwrite.enums import ServiceId +from appwrite.enums import ProjectServiceId client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -12,7 +12,7 @@ client.set_key('') # Your secret API key project = Project(client) result: ProjectModel = project.update_service( - service_id = ServiceId.ACCOUNT, + service_id = ProjectServiceId.ACCOUNT, enabled = False ) diff --git a/docs/examples/project/update-smtp.md b/docs/examples/project/update-smtp.md index 481e657d..66428e01 100644 --- a/docs/examples/project/update-smtp.md +++ b/docs/examples/project/update-smtp.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.project import Project from appwrite.models import Project as ProjectModel -from appwrite.enums import Secure +from appwrite.enums import ProjectSMTPSecure client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -20,7 +20,7 @@ result: ProjectModel = project.update_smtp( sender_name = '', # optional reply_to_email = 'email@example.com', # optional reply_to_name = '', # optional - secure = Secure.TLS, # optional + secure = ProjectSMTPSecure.TLS, # optional enabled = False # optional ) diff --git a/docs/examples/usage/list-events.md b/docs/examples/usage/list-events.md new file mode 100644 index 00000000..d3ab1d25 --- /dev/null +++ b/docs/examples/usage/list-events.md @@ -0,0 +1,19 @@ +```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( + queries = [], # optional + total = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/usage/list-gauges.md b/docs/examples/usage/list-gauges.md new file mode 100644 index 00000000..2904b968 --- /dev/null +++ b/docs/examples/usage/list-gauges.md @@ -0,0 +1,19 @@ +```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( + queries = [], # optional + total = False # optional +) + +print(result.model_dump()) +``` diff --git a/pyproject.toml b/pyproject.toml index 30997979..d7611fe5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "appwrite" -version = "18.1.0" +version = "19.0.0" description = "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API" readme = "README.md" requires-python = ">=3.9" diff --git a/setup.py b/setup.py index 7cb7b2fc..5a19c99b 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name = 'appwrite', packages = setuptools.find_packages(), - version = '18.1.0', + version = '19.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/18.1.0.tar.gz', + download_url='https://github.com/appwrite/sdk-for-python/archive/19.0.0.tar.gz', install_requires=[ 'requests', 'pydantic>=2,<3', diff --git a/test/services/test_advisor.py b/test/services/test_advisor.py new file mode 100644 index 00000000..75926cf4 --- /dev/null +++ b/test/services/test_advisor.py @@ -0,0 +1,108 @@ +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.advisor import Advisor + +class AdvisorServiceTest(unittest.TestCase): + + def setUp(self): + self.client = Client() + self.advisor = Advisor(self.client) + + @requests_mock.Mocker() + def test_list_reports(self, m): + data = { + "total": 5.0, + "reports": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.advisor.list_reports( + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_get_report(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "appId": "5e5ea5c16897e", + "type": "lighthouse", + "title": "Lighthouse audit for https:\/\/appwrite.io\/", + "summary": "Performance score 78. 4 opportunities found.", + "targetType": "urls", + "target": "https:\/\/appwrite.io\/", + "categories": [], + "insights": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.advisor.get_report( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_delete_report(self, m): + data = '' + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.advisor.delete_report( + '', + ) + + self.assertEqual(response, data) + + @requests_mock.Mocker() + def test_list_insights(self, m): + data = { + "total": 5.0, + "insights": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.advisor.list_insights( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_get_insight(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "reportId": "5e5ea5c16897e", + "type": "tablesDBIndex", + "severity": "warning", + "status": "active", + "resourceType": "databases", + "resourceId": "main", + "parentResourceType": "tables", + "parentResourceId": "orders", + "title": "Missing index on collection orders", + "summary": "Queries against `orders.status` are scanning the full collection.", + "ctas": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.advisor.get_insight( + '', + '', + ) + + self.assertEqual(response.to_dict(), data) + diff --git a/test/services/test_presences.py b/test/services/test_presences.py new file mode 100644 index 00000000..3665339f --- /dev/null +++ b/test/services/test_presences.py @@ -0,0 +1,101 @@ +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.presences import Presences + +class PresencesServiceTest(unittest.TestCase): + + def setUp(self): + self.client = Client() + self.presences = Presences(self.client) + + @requests_mock.Mocker() + def test_list(self, m): + data = { + "total": 5.0, + "presences": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.presences.list( + ) + + self.assertEqual(response.to_dict(), data) + + @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", + "$permissions": [], + "userId": "674af8f3e12a5f9ac0be", + "source": "HTTP" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.presences.get( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_upsert(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "$permissions": [], + "userId": "674af8f3e12a5f9ac0be", + "source": "HTTP" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.presences.upsert( + '', + '', + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update_presence(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "$permissions": [], + "userId": "674af8f3e12a5f9ac0be", + "source": "HTTP" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.presences.update_presence( + '', + '', + ) + + 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.presences.delete( + '', + ) + + self.assertEqual(response, data) + diff --git a/test/services/test_project.py b/test/services/test_project.py index d83393ec..4c074387 100644 --- a/test/services/test_project.py +++ b/test/services/test_project.py @@ -13,6 +13,54 @@ def setUp(self): self.client = Client() self.project = Project(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": "New Project", + "teamId": "1592981250", + "devKeys": [], + "smtpEnabled": True, + "smtpSenderName": "John Appwrite", + "smtpSenderEmail": "john@appwrite.io", + "smtpReplyToName": "Support Team", + "smtpReplyToEmail": "support@appwrite.io", + "smtpHost": "mail.appwrite.io", + "smtpPort": 25.0, + "smtpUsername": "emailuser", + "smtpPassword": "", + "smtpSecure": "tls", + "pingCount": 1.0, + "pingedAt": "2020-10-15T06:38:00.000+00:00", + "labels": [], + "status": "active", + "authMethods": [], + "services": [], + "protocols": [], + "region": "fra", + "billingLimits": { + "bandwidth": 5.0, + "storage": 150.0, + "users": 200000.0, + "executions": 750000.0, + "GBHours": 100.0, + "imageTransformations": 100.0, + "authPhone": 10.0, + "budgetLimit": 100.0 + }, + "blocks": [], + "consoleAccessedAt": "2020-10-15T06:38:00.000+00:00" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.project.get( + ) + + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_delete(self, m): data = '' @@ -31,37 +79,7 @@ def test_update_auth_method(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -77,33 +95,9 @@ def test_update_auth_method(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -254,37 +248,7 @@ def test_update_labels(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -300,33 +264,9 @@ def test_update_labels(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -449,7 +389,7 @@ def test_update_o_auth2_amazon(self, m): "$id": "github", "enabled": True, "clientId": "amzn1.application-oa2-client.87400c00000000000000000000063d5b2", - "clientSecret": "" + "clientSecret": "79ffe4000000000000000000000000000000000000000000000000000002de55" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -483,7 +423,7 @@ def test_update_o_auth2_auth0(self, m): "$id": "github", "enabled": True, "clientId": "OaOkIA000000000000000000005KLSYq", - "clientSecret": "", + "clientSecret": "zXz0000-00000000000000000000000000000-00000000000000000000PJafnF", "endpoint": "example.us.auth0.com" } headers = {'Content-Type': 'application/json'} @@ -500,7 +440,7 @@ def test_update_o_auth2_authentik(self, m): "$id": "github", "enabled": True, "clientId": "dTKOPa0000000000000000000000000000e7G8hv", - "clientSecret": "", + "clientSecret": "ntQadq000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Hp5WK", "endpoint": "example.authentik.com" } headers = {'Content-Type': 'application/json'} @@ -517,7 +457,7 @@ def test_update_o_auth2_autodesk(self, m): "$id": "github", "enabled": True, "clientId": "5zw90v00000000000000000000kVYXN7", - "clientSecret": "" + "clientSecret": "7I000000000000MW" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -533,7 +473,7 @@ def test_update_o_auth2_bitbucket(self, m): "$id": "github", "enabled": True, "key": "Knt70000000000ByRc", - "secret": "" + "secret": "NMfLZJ00000000000000000000TLQdDx" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -549,7 +489,7 @@ def test_update_o_auth2_bitly(self, m): "$id": "github", "enabled": True, "clientId": "d95151000000000000000000000000000067af9b", - "clientSecret": "" + "clientSecret": "a13e250000000000000000000000000000d73095" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -565,7 +505,7 @@ def test_update_o_auth2_box(self, m): "$id": "github", "enabled": True, "clientId": "deglcs00000000000000000000x2og6y", - "clientSecret": "" + "clientSecret": "OKM1f100000000000000000000eshEif" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -581,7 +521,7 @@ def test_update_o_auth2_dailymotion(self, m): "$id": "github", "enabled": True, "apiKey": "07a9000000000000067f", - "apiSecret": "" + "apiSecret": "a399a90000000000000000000000000000d90639" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -597,7 +537,7 @@ def test_update_o_auth2_discord(self, m): "$id": "github", "enabled": True, "clientId": "950722000000343754", - "clientSecret": "" + "clientSecret": "YmPXnM000000000000000000002zFg5D" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -613,7 +553,7 @@ def test_update_o_auth2_disqus(self, m): "$id": "github", "enabled": True, "publicKey": "cgegH70000000000000000000000000000000000000000000000000000Hr1nYX", - "secretKey": "" + "secretKey": "W7Bykj00000000000000000000000000000000000000000000000000003o43w9" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -629,7 +569,7 @@ def test_update_o_auth2_dropbox(self, m): "$id": "github", "enabled": True, "appKey": "jl000000000009t", - "appSecret": "" + "appSecret": "g200000000000vw" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -645,7 +585,7 @@ def test_update_o_auth2_etsy(self, m): "$id": "github", "enabled": True, "keyString": "nsgzxh0000000000008j85a2", - "sharedSecret": "" + "sharedSecret": "tp000000ru" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -661,7 +601,7 @@ def test_update_o_auth2_facebook(self, m): "$id": "github", "enabled": True, "appId": "260600000007694", - "appSecret": "" + "appSecret": "2d0b2800000000000000000000d38af4" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -677,7 +617,7 @@ def test_update_o_auth2_figma(self, m): "$id": "github", "enabled": True, "clientId": "byay5H0000000000VtiI40", - "clientSecret": "" + "clientSecret": "yEpOYn0000000000000000004iIsU5" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -693,7 +633,7 @@ def test_update_o_auth2_fusion_auth(self, m): "$id": "github", "enabled": True, "clientId": "b2222c00-0000-0000-0000-000000862097", - "clientSecret": "", + "clientSecret": "Jx4s0C0000000000000000000000000000000wGqLsc", "endpoint": "example.fusionauth.io" } headers = {'Content-Type': 'application/json'} @@ -710,7 +650,7 @@ def test_update_o_auth2_git_hub(self, m): "$id": "github", "enabled": True, "clientId": "e4d87900000000540733", - "clientSecret": "" + "clientSecret": "5e07c00000000000000000000000000000198bcc" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -726,7 +666,7 @@ def test_update_o_auth2_gitlab(self, m): "$id": "github", "enabled": True, "applicationId": "d41ffe0000000000000000000000000000000000000000000000000000d5e252", - "secret": "", + "secret": "gloas-838cfa0000000000000000000000000000000000000000000000000000ecbb38", "endpoint": "https:\/\/gitlab.com" } headers = {'Content-Type': 'application/json'} @@ -743,7 +683,8 @@ def test_update_o_auth2_google(self, m): "$id": "github", "enabled": True, "clientId": "120000000095-92ifjb00000000000000000000g7ijfb.apps.googleusercontent.com", - "clientSecret": "" + "clientSecret": "example-google-client-secret", + "prompt": [] } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -759,7 +700,7 @@ def test_update_o_auth2_keycloak(self, m): "$id": "github", "enabled": True, "clientId": "appwrite-o0000000st-app", - "clientSecret": "", + "clientSecret": "jdjrJd00000000000000000000HUsaZO", "endpoint": "keycloak.example.com", "realmName": "appwrite-realm" } @@ -777,7 +718,7 @@ def test_update_o_auth2_kick(self, m): "$id": "github", "enabled": True, "clientId": "01KQ7C00000000000001MFHS32", - "clientSecret": "" + "clientSecret": "34ac5600000000000000000000000000000000000000000000000000e830c8b" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -793,7 +734,7 @@ def test_update_o_auth2_linkedin(self, m): "$id": "github", "enabled": True, "clientId": "770000000000dv", - "primaryClientSecret": "" + "primaryClientSecret": "example-linkedin-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -809,7 +750,7 @@ def test_update_o_auth2_microsoft(self, m): "$id": "github", "enabled": True, "applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444", - "applicationSecret": "", + "applicationSecret": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u", "tenant": "common" } headers = {'Content-Type': 'application/json'} @@ -826,7 +767,7 @@ def test_update_o_auth2_notion(self, m): "$id": "github", "enabled": True, "oauthClientId": "341d8700-0000-0000-0000-000000446ee3", - "oauthClientSecret": "" + "oauthClientSecret": "secret_dLUr4b000000000000000000000000000000lFHAa9" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -842,7 +783,7 @@ def test_update_o_auth2_oidc(self, m): "$id": "github", "enabled": True, "clientId": "qibI2x0000000000000000000000000006L2YFoG", - "clientSecret": "", + "clientSecret": "Ah68ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003qpcHV", "wellKnownURL": "https:\/\/myoauth.com\/.well-known\/openid-configuration", "authorizationURL": "https:\/\/myoauth.com\/oauth2\/authorize", "tokenURL": "https:\/\/myoauth.com\/oauth2\/token", @@ -862,7 +803,7 @@ def test_update_o_auth2_okta(self, m): "$id": "github", "enabled": True, "clientId": "0oa00000000000000698", - "clientSecret": "", + "clientSecret": "Kiq0000000000000000000000000000000000000-00000000000H2L5-3SJ-vRV", "domain": "trial-6400025.okta.com", "authorizationServerId": "aus000000000000000h7z" } @@ -880,7 +821,7 @@ def test_update_o_auth2_paypal(self, m): "$id": "github", "enabled": True, "clientId": "AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB", - "secretKey": "" + "secretKey": "EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -896,7 +837,7 @@ def test_update_o_auth2_paypal_sandbox(self, m): "$id": "github", "enabled": True, "clientId": "AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB", - "secretKey": "" + "secretKey": "EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -912,7 +853,7 @@ def test_update_o_auth2_podio(self, m): "$id": "github", "enabled": True, "clientId": "appwrite-oauth-test-app", - "clientSecret": "" + "clientSecret": "Rn247T0000000000000000000000000000000000000000000000000000W2zWTN" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -928,7 +869,7 @@ def test_update_o_auth2_salesforce(self, m): "$id": "github", "enabled": True, "customerKey": "3MVG9I0000000000000000000000000000000000000000000000000000000000000000000000000C5Aejq", - "customerSecret": "" + "customerSecret": "3w000000000000e2" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -944,7 +885,7 @@ def test_update_o_auth2_slack(self, m): "$id": "github", "enabled": True, "clientId": "23000000089.15000000000023", - "clientSecret": "" + "clientSecret": "81656000000000000000000000f3d2fd" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -960,7 +901,7 @@ def test_update_o_auth2_spotify(self, m): "$id": "github", "enabled": True, "clientId": "6ec271000000000000000000009beace", - "clientSecret": "" + "clientSecret": "db068a000000000000000000008b5b9f" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -976,7 +917,7 @@ def test_update_o_auth2_stripe(self, m): "$id": "github", "enabled": True, "clientId": "ca_UKibXX0000000000000000000006byvR", - "apiSecretKey": "" + "apiSecretKey": "sk_51SfOd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000QGWYfp" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -992,7 +933,7 @@ def test_update_o_auth2_tradeshift(self, m): "$id": "github", "enabled": True, "oauth2ClientId": "appwrite-test-org.appwrite-test-app", - "oauth2ClientSecret": "" + "oauth2ClientSecret": "7cb52700-0000-0000-0000-000000ca5b83" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1008,7 +949,7 @@ def test_update_o_auth2_tradeshift_sandbox(self, m): "$id": "github", "enabled": True, "oauth2ClientId": "appwrite-test-org.appwrite-test-app", - "oauth2ClientSecret": "" + "oauth2ClientSecret": "7cb52700-0000-0000-0000-000000ca5b83" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1024,7 +965,7 @@ def test_update_o_auth2_twitch(self, m): "$id": "github", "enabled": True, "clientId": "vvi0in000000000000000000ikmt9p", - "clientSecret": "" + "clientSecret": "pmapue000000000000000000zylw3v" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1040,7 +981,7 @@ def test_update_o_auth2_word_press(self, m): "$id": "github", "enabled": True, "clientId": "130005", - "clientSecret": "" + "clientSecret": "PlBfJS0000000000000000000000000000000000000000000000000000EdUZJk" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1056,7 +997,7 @@ def test_update_o_auth2_x(self, m): "$id": "github", "enabled": True, "customerKey": "slzZV0000000000000NFLaWT", - "secretKey": "" + "secretKey": "tkEPkp00000000000000000000000000000000000000FTxbI9" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1072,7 +1013,7 @@ def test_update_o_auth2_yahoo(self, m): "$id": "github", "enabled": True, "clientId": "dj0yJm000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z4PWRm", - "clientSecret": "" + "clientSecret": "cf978f0000000000000000000000000000c5e2e9" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1088,7 +1029,7 @@ def test_update_o_auth2_yandex(self, m): "$id": "github", "enabled": True, "clientId": "6a8a6a0000000000000000000091483c", - "clientSecret": "" + "clientSecret": "bbf98500000000000000000000c75a63" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1104,7 +1045,7 @@ def test_update_o_auth2_zoho(self, m): "$id": "github", "enabled": True, "clientId": "1000.83C178000000000000000000RPNX0B", - "clientSecret": "" + "clientSecret": "fb5cac000000000000000000000000000000a68f6e" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1120,7 +1061,7 @@ def test_update_o_auth2_zoom(self, m): "$id": "github", "enabled": True, "clientId": "QMAC00000000000000w0AQ", - "clientSecret": "" + "clientSecret": "GAWsG4000000000000000000007U01ON" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1136,7 +1077,7 @@ def test_get_o_auth2_provider(self, m): "$id": "github", "enabled": True, "clientId": "e4d87900000000540733", - "clientSecret": "" + "clientSecret": "5e07c00000000000000000000000000000198bcc" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1416,6 +1357,153 @@ def test_list_policies(self, m): self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() + def test_update_deny_aliased_email_policy(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "New Project", + "teamId": "1592981250", + "devKeys": [], + "smtpEnabled": True, + "smtpSenderName": "John Appwrite", + "smtpSenderEmail": "john@appwrite.io", + "smtpReplyToName": "Support Team", + "smtpReplyToEmail": "support@appwrite.io", + "smtpHost": "mail.appwrite.io", + "smtpPort": 25.0, + "smtpUsername": "emailuser", + "smtpPassword": "", + "smtpSecure": "tls", + "pingCount": 1.0, + "pingedAt": "2020-10-15T06:38:00.000+00:00", + "labels": [], + "status": "active", + "authMethods": [], + "services": [], + "protocols": [], + "region": "fra", + "billingLimits": { + "bandwidth": 5.0, + "storage": 150.0, + "users": 200000.0, + "executions": 750000.0, + "GBHours": 100.0, + "imageTransformations": 100.0, + "authPhone": 10.0, + "budgetLimit": 100.0 + }, + "blocks": [], + "consoleAccessedAt": "2020-10-15T06:38:00.000+00:00" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.project.update_deny_aliased_email_policy( + True, + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update_deny_disposable_email_policy(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "New Project", + "teamId": "1592981250", + "devKeys": [], + "smtpEnabled": True, + "smtpSenderName": "John Appwrite", + "smtpSenderEmail": "john@appwrite.io", + "smtpReplyToName": "Support Team", + "smtpReplyToEmail": "support@appwrite.io", + "smtpHost": "mail.appwrite.io", + "smtpPort": 25.0, + "smtpUsername": "emailuser", + "smtpPassword": "", + "smtpSecure": "tls", + "pingCount": 1.0, + "pingedAt": "2020-10-15T06:38:00.000+00:00", + "labels": [], + "status": "active", + "authMethods": [], + "services": [], + "protocols": [], + "region": "fra", + "billingLimits": { + "bandwidth": 5.0, + "storage": 150.0, + "users": 200000.0, + "executions": 750000.0, + "GBHours": 100.0, + "imageTransformations": 100.0, + "authPhone": 10.0, + "budgetLimit": 100.0 + }, + "blocks": [], + "consoleAccessedAt": "2020-10-15T06:38:00.000+00:00" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.project.update_deny_disposable_email_policy( + True, + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update_deny_free_email_policy(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "New Project", + "teamId": "1592981250", + "devKeys": [], + "smtpEnabled": True, + "smtpSenderName": "John Appwrite", + "smtpSenderEmail": "john@appwrite.io", + "smtpReplyToName": "Support Team", + "smtpReplyToEmail": "support@appwrite.io", + "smtpHost": "mail.appwrite.io", + "smtpPort": 25.0, + "smtpUsername": "emailuser", + "smtpPassword": "", + "smtpSecure": "tls", + "pingCount": 1.0, + "pingedAt": "2020-10-15T06:38:00.000+00:00", + "labels": [], + "status": "active", + "authMethods": [], + "services": [], + "protocols": [], + "region": "fra", + "billingLimits": { + "bandwidth": 5.0, + "storage": 150.0, + "users": 200000.0, + "executions": 750000.0, + "GBHours": 100.0, + "imageTransformations": 100.0, + "authPhone": 10.0, + "budgetLimit": 100.0 + }, + "blocks": [], + "consoleAccessedAt": "2020-10-15T06:38:00.000+00:00" +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.project.update_deny_free_email_policy( + True, + ) + + self.assertEqual(response.to_dict(), data) + @requests_mock.Mocker() def test_update_membership_privacy_policy(self, m): data = { @@ -1423,37 +1511,7 @@ def test_update_membership_privacy_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -1469,33 +1527,9 @@ def test_update_membership_privacy_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -1525,37 +1559,7 @@ def test_update_password_dictionary_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -1571,33 +1575,9 @@ def test_update_password_dictionary_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -1628,37 +1608,7 @@ def test_update_password_history_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -1674,33 +1624,9 @@ def test_update_password_history_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -1731,37 +1657,7 @@ def test_update_password_personal_data_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -1777,33 +1673,9 @@ def test_update_password_personal_data_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -1834,37 +1706,7 @@ def test_update_session_alert_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -1880,33 +1722,9 @@ def test_update_session_alert_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -1937,37 +1755,7 @@ def test_update_session_duration_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -1983,33 +1771,9 @@ def test_update_session_duration_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -2040,37 +1804,7 @@ def test_update_session_invalidation_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -2086,33 +1820,9 @@ def test_update_session_invalidation_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -2143,37 +1853,7 @@ def test_update_session_limit_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -2189,33 +1869,9 @@ def test_update_session_limit_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -2246,37 +1902,7 @@ def test_update_user_limit_policy(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -2292,33 +1918,9 @@ def test_update_user_limit_policy(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -2364,37 +1966,7 @@ def test_update_protocol(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -2410,33 +1982,9 @@ def test_update_protocol(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -2468,37 +2016,7 @@ def test_update_service(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -2514,33 +2032,9 @@ def test_update_service(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, @@ -2572,37 +2066,7 @@ def test_update_smtp(self, m): "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "New Project", - "description": "This is a new project.", "teamId": "1592981250", - "logo": "5f5c451b403cb", - "url": "5f5c451b403cb", - "legalName": "Company LTD.", - "legalCountry": "US", - "legalState": "New York", - "legalCity": "New York City.", - "legalAddress": "620 Eighth Avenue, New York, NY 10018", - "legalTaxId": "131102020", - "authDuration": 60.0, - "authLimit": 100.0, - "authSessionsLimit": 10.0, - "authPasswordHistory": 5.0, - "authPasswordDictionary": True, - "authPersonalDataCheck": True, - "authDisposableEmails": True, - "authCanonicalEmails": True, - "authFreeEmails": True, - "authMockNumbers": [], - "authSessionAlerts": True, - "authMembershipsUserName": True, - "authMembershipsUserEmail": True, - "authMembershipsMfa": True, - "authMembershipsUserId": True, - "authMembershipsUserPhone": True, - "authInvalidateSessions": True, - "oAuthProviders": [], - "platforms": [], - "webhooks": [], - "keys": [], "devKeys": [], "smtpEnabled": True, "smtpSenderName": "John Appwrite", @@ -2618,33 +2082,9 @@ def test_update_smtp(self, m): "pingedAt": "2020-10-15T06:38:00.000+00:00", "labels": [], "status": "active", - "authEmailPassword": True, - "authUsersAuthMagicURL": True, - "authEmailOtp": True, - "authAnonymous": True, - "authInvites": True, - "authJWT": True, - "authPhone": True, - "serviceStatusForAccount": True, - "serviceStatusForAvatars": True, - "serviceStatusForDatabases": True, - "serviceStatusForTablesdb": True, - "serviceStatusForLocale": True, - "serviceStatusForHealth": True, - "serviceStatusForProject": True, - "serviceStatusForStorage": True, - "serviceStatusForTeams": True, - "serviceStatusForUsers": True, - "serviceStatusForVcs": True, - "serviceStatusForSites": True, - "serviceStatusForFunctions": True, - "serviceStatusForProxy": True, - "serviceStatusForGraphql": True, - "serviceStatusForMigrations": True, - "serviceStatusForMessaging": True, - "protocolStatusForRest": True, - "protocolStatusForGraphql": True, - "protocolStatusForWebsocket": True, + "authMethods": [], + "services": [], + "protocols": [], "region": "fra", "billingLimits": { "bandwidth": 5.0, diff --git a/test/services/test_usage.py b/test/services/test_usage.py new file mode 100644 index 00000000..6f4617dc --- /dev/null +++ b/test/services/test_usage.py @@ -0,0 +1,43 @@ +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 = { + "total": 5.0, + "events": [] +} + 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 = { + "total": 5.0, + "gauges": [] +} + 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 6f5cb7c89d596837c970b65df93265335cbb83af Mon Sep 17 00:00:00 2001 From: root Date: Mon, 18 May 2026 13:37:59 +0000 Subject: [PATCH 2/3] chore: update Python SDK to 19.0.0 --- appwrite/models/document.py | 8 +- appwrite/models/preferences.py | 8 +- appwrite/models/presence.py | 8 +- appwrite/models/row.py | 8 +- appwrite/services/account.py | 30 +++---- appwrite/services/activities.py | 4 +- appwrite/services/advisor.py | 8 +- appwrite/services/avatars.py | 14 +-- appwrite/services/backups.py | 14 +-- appwrite/services/databases.py | 66 +++++++------- appwrite/services/functions.py | 32 +++---- appwrite/services/health.py | 14 +-- appwrite/services/locale.py | 14 +-- appwrite/services/messaging.py | 24 ++--- appwrite/services/presences.py | 4 +- appwrite/services/project.py | 154 ++++++++++++++++---------------- appwrite/services/proxy.py | 8 +- appwrite/services/sites.py | 32 +++---- appwrite/services/storage.py | 14 +-- appwrite/services/tables_db.py | 66 +++++++------- appwrite/services/teams.py | 10 +-- appwrite/services/tokens.py | 4 +- appwrite/services/usage.py | 4 +- appwrite/services/users.py | 34 +++---- appwrite/services/webhooks.py | 4 +- 25 files changed, 301 insertions(+), 285 deletions(-) diff --git a/appwrite/models/document.py b/appwrite/models/document.py index 8cc031b4..dcff339a 100644 --- a/appwrite/models/document.py +++ b/appwrite/models/document.py @@ -37,8 +37,12 @@ class Document(AppwriteModel, Generic[T]): @classmethod def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Document[T]': """Create Document instance with typed data.""" - internal_fields = {k: v for k, v in data.items() if k.startswith('$')} - user_data = {k: v for k, v in data.items() if not k.startswith('$')} + internal_aliases = {'$id', '$sequence', '$collectionId', '$databaseId', '$createdAt', '$updatedAt', '$permissions'} + internal_fields = {k: v for k, v in data.items() if k in internal_aliases} + user_data = {k: v for k, v in data.items() if k not in internal_aliases and k != 'data'} + nested = data.get('data') + if isinstance(nested, dict): + user_data = {**nested, **user_data} instance = cls.model_validate(internal_fields) instance._data = model_type(**user_data) if model_type is not dict else user_data return instance diff --git a/appwrite/models/preferences.py b/appwrite/models/preferences.py index 01f36c35..7f6561d0 100644 --- a/appwrite/models/preferences.py +++ b/appwrite/models/preferences.py @@ -14,8 +14,12 @@ class Preferences(AppwriteModel, Generic[T]): @classmethod def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Preferences[T]': """Create Preferences instance with typed data.""" - internal_fields = {k: v for k, v in data.items() if k.startswith('$')} - user_data = {k: v for k, v in data.items() if not k.startswith('$')} + internal_aliases = {} + internal_fields = {k: v for k, v in data.items() if k in internal_aliases} + user_data = {k: v for k, v in data.items() if k not in internal_aliases and k != 'data'} + nested = data.get('data') + if isinstance(nested, dict): + user_data = {**nested, **user_data} instance = cls.model_validate(internal_fields) instance._data = model_type(**user_data) if model_type is not dict else user_data return instance diff --git a/appwrite/models/presence.py b/appwrite/models/presence.py index 336c63fb..bddda7d9 100644 --- a/appwrite/models/presence.py +++ b/appwrite/models/presence.py @@ -40,8 +40,12 @@ class Presence(AppwriteModel, Generic[T]): @classmethod def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Presence[T]': """Create Presence instance with typed data.""" - internal_fields = {k: v for k, v in data.items() if k.startswith('$')} - user_data = {k: v for k, v in data.items() if not k.startswith('$')} + internal_aliases = {'$id', '$createdAt', '$updatedAt', '$permissions', 'userId', 'status', 'source', 'expiresAt'} + internal_fields = {k: v for k, v in data.items() if k in internal_aliases} + user_data = {k: v for k, v in data.items() if k not in internal_aliases and k != 'metadata'} + nested = data.get('metadata') + if isinstance(nested, dict): + user_data = {**nested, **user_data} instance = cls.model_validate(internal_fields) instance._metadata = model_type(**user_data) if model_type is not dict else user_data return instance diff --git a/appwrite/models/row.py b/appwrite/models/row.py index fca9d70b..8ccc97e4 100644 --- a/appwrite/models/row.py +++ b/appwrite/models/row.py @@ -37,8 +37,12 @@ class Row(AppwriteModel, Generic[T]): @classmethod def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Row[T]': """Create Row instance with typed data.""" - internal_fields = {k: v for k, v in data.items() if k.startswith('$')} - user_data = {k: v for k, v in data.items() if not k.startswith('$')} + internal_aliases = {'$id', '$sequence', '$tableId', '$databaseId', '$createdAt', '$updatedAt', '$permissions'} + internal_fields = {k: v for k, v in data.items() if k in internal_aliases} + user_data = {k: v for k, v in data.items() if k not in internal_aliases and k != 'data'} + nested = data.get('data') + if isinstance(nested, dict): + user_data = {**nested, **user_data} instance = cls.model_validate(internal_fields) instance._data = model_type(**user_data) if model_type is not dict else user_data return instance diff --git a/appwrite/services/account.py b/appwrite/services/account.py index 0e80be8e..f9d21d07 100644 --- a/appwrite/services/account.py +++ b/appwrite/services/account.py @@ -2,21 +2,21 @@ from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.user import User; -from ..models.identity_list import IdentityList; -from ..models.jwt import Jwt; -from ..models.log_list import LogList; -from ..enums.authenticator_type import AuthenticatorType; -from ..models.mfa_type import MfaType; -from ..enums.authentication_factor import AuthenticationFactor; -from ..models.mfa_challenge import MfaChallenge; -from ..models.session import Session; -from ..models.mfa_factors import MfaFactors; -from ..models.mfa_recovery_codes import MfaRecoveryCodes; -from ..models.preferences import Preferences; -from ..models.token import Token; -from ..models.session_list import SessionList; -from ..enums.o_auth_provider import OAuthProvider; +from ..models.user import User +from ..models.identity_list import IdentityList +from ..models.jwt import Jwt +from ..models.log_list import LogList +from ..enums.authenticator_type import AuthenticatorType +from ..models.mfa_type import MfaType +from ..enums.authentication_factor import AuthenticationFactor +from ..models.mfa_challenge import MfaChallenge +from ..models.session import Session +from ..models.mfa_factors import MfaFactors +from ..models.mfa_recovery_codes import MfaRecoveryCodes +from ..models.preferences import Preferences +from ..models.token import Token +from ..models.session_list import SessionList +from ..enums.o_auth_provider import OAuthProvider T = TypeVar('T') diff --git a/appwrite/services/activities.py b/appwrite/services/activities.py index 4c50a8f1..687adb0d 100644 --- a/appwrite/services/activities.py +++ b/appwrite/services/activities.py @@ -2,8 +2,8 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.activity_event_list import ActivityEventList; -from ..models.activity_event import ActivityEvent; +from ..models.activity_event_list import ActivityEventList +from ..models.activity_event import ActivityEvent class Activities(Service): diff --git a/appwrite/services/advisor.py b/appwrite/services/advisor.py index af8d578a..f79345c7 100644 --- a/appwrite/services/advisor.py +++ b/appwrite/services/advisor.py @@ -2,10 +2,10 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.report_list import ReportList; -from ..models.report import Report; -from ..models.insight_list import InsightList; -from ..models.insight import Insight; +from ..models.report_list import ReportList +from ..models.report import Report +from ..models.insight_list import InsightList +from ..models.insight import Insight class Advisor(Service): diff --git a/appwrite/services/avatars.py b/appwrite/services/avatars.py index f437c04c..e21ce057 100644 --- a/appwrite/services/avatars.py +++ b/appwrite/services/avatars.py @@ -2,13 +2,13 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..enums.browser import Browser; -from ..enums.credit_card import CreditCard; -from ..enums.flag import Flag; -from ..enums.theme import Theme; -from ..enums.timezone import Timezone; -from ..enums.browser_permission import BrowserPermission; -from ..enums.image_format import ImageFormat; +from ..enums.browser import Browser +from ..enums.credit_card import CreditCard +from ..enums.flag import Flag +from ..enums.theme import Theme +from ..enums.timezone import Timezone +from ..enums.browser_permission import BrowserPermission +from ..enums.image_format import ImageFormat class Avatars(Service): diff --git a/appwrite/services/backups.py b/appwrite/services/backups.py index ce05f0a7..b3a8b1b9 100644 --- a/appwrite/services/backups.py +++ b/appwrite/services/backups.py @@ -2,13 +2,13 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.backup_archive_list import BackupArchiveList; -from ..enums.backup_services import BackupServices; -from ..models.backup_archive import BackupArchive; -from ..models.backup_policy_list import BackupPolicyList; -from ..models.backup_policy import BackupPolicy; -from ..models.backup_restoration import BackupRestoration; -from ..models.backup_restoration_list import BackupRestorationList; +from ..models.backup_archive_list import BackupArchiveList +from ..enums.backup_services import BackupServices +from ..models.backup_archive import BackupArchive +from ..models.backup_policy_list import BackupPolicyList +from ..models.backup_policy import BackupPolicy +from ..models.backup_restoration import BackupRestoration +from ..models.backup_restoration_list import BackupRestorationList class Backups(Service): diff --git a/appwrite/services/databases.py b/appwrite/services/databases.py index a1a458d3..a239de09 100644 --- a/appwrite/services/databases.py +++ b/appwrite/services/databases.py @@ -2,39 +2,39 @@ from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.database_list import DatabaseList; -from ..models.database import Database; -from ..models.transaction_list import TransactionList; -from ..models.transaction import Transaction; -from ..models.collection_list import CollectionList; -from ..models.collection import Collection; -from ..models.attribute_list import AttributeList; -from ..models.attribute_bigint import AttributeBigint; -from ..models.attribute_boolean import AttributeBoolean; -from ..models.attribute_datetime import AttributeDatetime; -from ..models.attribute_email import AttributeEmail; -from ..models.attribute_enum import AttributeEnum; -from ..models.attribute_float import AttributeFloat; -from ..models.attribute_integer import AttributeInteger; -from ..models.attribute_ip import AttributeIp; -from ..models.attribute_line import AttributeLine; -from ..models.attribute_longtext import AttributeLongtext; -from ..models.attribute_mediumtext import AttributeMediumtext; -from ..models.attribute_point import AttributePoint; -from ..models.attribute_polygon import AttributePolygon; -from ..enums.relationship_type import RelationshipType; -from ..enums.relation_mutate import RelationMutate; -from ..models.attribute_relationship import AttributeRelationship; -from ..models.attribute_string import AttributeString; -from ..models.attribute_text import AttributeText; -from ..models.attribute_url import AttributeUrl; -from ..models.attribute_varchar import AttributeVarchar; -from ..models.document_list import DocumentList; -from ..models.document import Document; -from ..models.index_list import IndexList; -from ..enums.databases_index_type import DatabasesIndexType; -from ..enums.order_by import OrderBy; -from ..models.index import Index; +from ..models.database_list import DatabaseList +from ..models.database import Database +from ..models.transaction_list import TransactionList +from ..models.transaction import Transaction +from ..models.collection_list import CollectionList +from ..models.collection import Collection +from ..models.attribute_list import AttributeList +from ..models.attribute_bigint import AttributeBigint +from ..models.attribute_boolean import AttributeBoolean +from ..models.attribute_datetime import AttributeDatetime +from ..models.attribute_email import AttributeEmail +from ..models.attribute_enum import AttributeEnum +from ..models.attribute_float import AttributeFloat +from ..models.attribute_integer import AttributeInteger +from ..models.attribute_ip import AttributeIp +from ..models.attribute_line import AttributeLine +from ..models.attribute_longtext import AttributeLongtext +from ..models.attribute_mediumtext import AttributeMediumtext +from ..models.attribute_point import AttributePoint +from ..models.attribute_polygon import AttributePolygon +from ..enums.relationship_type import RelationshipType +from ..enums.relation_mutate import RelationMutate +from ..models.attribute_relationship import AttributeRelationship +from ..models.attribute_string import AttributeString +from ..models.attribute_text import AttributeText +from ..models.attribute_url import AttributeUrl +from ..models.attribute_varchar import AttributeVarchar +from ..models.document_list import DocumentList +from ..models.document import Document +from ..models.index_list import IndexList +from ..enums.databases_index_type import DatabasesIndexType +from ..enums.order_by import OrderBy +from ..models.index import Index T = TypeVar('T') diff --git a/appwrite/services/functions.py b/appwrite/services/functions.py index 34f7efee..55cb49f9 100644 --- a/appwrite/services/functions.py +++ b/appwrite/services/functions.py @@ -2,23 +2,23 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.function_list import FunctionList; -from ..enums.runtime import Runtime; -from ..enums.scopes import Scopes; -from ..models.function import Function; -from ..models.runtime_list import RuntimeList; -from ..models.specification_list import SpecificationList; -from ..models.deployment_list import DeploymentList; +from ..models.function_list import FunctionList +from ..enums.runtime import Runtime +from ..enums.scopes import Scopes +from ..models.function import Function +from ..models.runtime_list import RuntimeList +from ..models.specification_list import SpecificationList +from ..models.deployment_list import DeploymentList from ..input_file import InputFile -from ..models.deployment import Deployment; -from ..enums.template_reference_type import TemplateReferenceType; -from ..enums.vcs_reference_type import VCSReferenceType; -from ..enums.deployment_download_type import DeploymentDownloadType; -from ..models.execution_list import ExecutionList; -from ..enums.execution_method import ExecutionMethod; -from ..models.execution import Execution; -from ..models.variable_list import VariableList; -from ..models.variable import Variable; +from ..models.deployment import Deployment +from ..enums.template_reference_type import TemplateReferenceType +from ..enums.vcs_reference_type import VCSReferenceType +from ..enums.deployment_download_type import DeploymentDownloadType +from ..models.execution_list import ExecutionList +from ..enums.execution_method import ExecutionMethod +from ..models.execution import Execution +from ..models.variable_list import VariableList +from ..models.variable import Variable class Functions(Service): diff --git a/appwrite/services/health.py b/appwrite/services/health.py index 7b0eaa6c..9d604b3d 100644 --- a/appwrite/services/health.py +++ b/appwrite/services/health.py @@ -2,13 +2,13 @@ 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.name import Name; -from ..models.health_time import HealthTime; +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.name import Name +from ..models.health_time import HealthTime class Health(Service): diff --git a/appwrite/services/locale.py b/appwrite/services/locale.py index a2573e6b..f097b7dc 100644 --- a/appwrite/services/locale.py +++ b/appwrite/services/locale.py @@ -2,13 +2,13 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.locale import Locale as LocaleModel; -from ..models.locale_code_list import LocaleCodeList; -from ..models.continent_list import ContinentList; -from ..models.country_list import CountryList; -from ..models.phone_list import PhoneList; -from ..models.currency_list import CurrencyList; -from ..models.language_list import LanguageList; +from ..models.locale import Locale as LocaleModel +from ..models.locale_code_list import LocaleCodeList +from ..models.continent_list import ContinentList +from ..models.country_list import CountryList +from ..models.phone_list import PhoneList +from ..models.currency_list import CurrencyList +from ..models.language_list import LanguageList class Locale(Service): diff --git a/appwrite/services/messaging.py b/appwrite/services/messaging.py index 7a297143..50de1eee 100644 --- a/appwrite/services/messaging.py +++ b/appwrite/services/messaging.py @@ -2,18 +2,18 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -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; -from ..enums.smtp_encryption import SmtpEncryption; -from ..models.topic_list import TopicList; -from ..models.topic import Topic; -from ..models.subscriber_list import SubscriberList; -from ..models.subscriber import Subscriber; +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 +from ..enums.smtp_encryption import SmtpEncryption +from ..models.topic_list import TopicList +from ..models.topic import Topic +from ..models.subscriber_list import SubscriberList +from ..models.subscriber import Subscriber class Messaging(Service): diff --git a/appwrite/services/presences.py b/appwrite/services/presences.py index 0566623e..cb57e3b5 100644 --- a/appwrite/services/presences.py +++ b/appwrite/services/presences.py @@ -2,8 +2,8 @@ from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.presence_list import PresenceList; -from ..models.presence import Presence; +from ..models.presence_list import PresenceList +from ..models.presence import Presence T = TypeVar('T') diff --git a/appwrite/services/project.py b/appwrite/services/project.py index 44fed54b..13d43259 100644 --- a/appwrite/services/project.py +++ b/appwrite/services/project.py @@ -2,83 +2,83 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.project import Project as ProjectModel; -from ..enums.project_auth_method_id import ProjectAuthMethodId; -from ..models.key_list import KeyList; -from ..enums.project_key_scopes import ProjectKeyScopes; -from ..models.key import Key; -from ..models.ephemeral_key import EphemeralKey; -from ..models.mock_number_list import MockNumberList; -from ..models.mock_number import MockNumber; -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_auth0 import OAuth2Auth0; -from ..models.o_auth2_authentik import OAuth2Authentik; -from ..models.o_auth2_autodesk import OAuth2Autodesk; -from ..models.o_auth2_bitbucket import OAuth2Bitbucket; -from ..models.o_auth2_bitly import OAuth2Bitly; -from ..models.o_auth2_box import OAuth2Box; -from ..models.o_auth2_dailymotion import OAuth2Dailymotion; -from ..models.o_auth2_discord import OAuth2Discord; -from ..models.o_auth2_disqus import OAuth2Disqus; -from ..models.o_auth2_dropbox import OAuth2Dropbox; -from ..models.o_auth2_etsy import OAuth2Etsy; -from ..models.o_auth2_facebook import OAuth2Facebook; -from ..models.o_auth2_figma import OAuth2Figma; -from ..models.o_auth2_fusion_auth import OAuth2FusionAuth; -from ..models.o_auth2_github import OAuth2Github; -from ..models.o_auth2_gitlab import OAuth2Gitlab; -from ..enums.project_o_auth2_google_prompt import ProjectOAuth2GooglePrompt; -from ..models.o_auth2_google import OAuth2Google; -from ..models.o_auth2_keycloak import OAuth2Keycloak; -from ..models.o_auth2_kick import OAuth2Kick; -from ..models.o_auth2_linkedin import OAuth2Linkedin; -from ..models.o_auth2_microsoft import OAuth2Microsoft; -from ..models.o_auth2_notion import OAuth2Notion; -from ..models.o_auth2_oidc import OAuth2Oidc; -from ..models.o_auth2_okta import OAuth2Okta; -from ..models.o_auth2_paypal import OAuth2Paypal; -from ..models.o_auth2_podio import OAuth2Podio; -from ..models.o_auth2_salesforce import OAuth2Salesforce; -from ..models.o_auth2_slack import OAuth2Slack; -from ..models.o_auth2_spotify import OAuth2Spotify; -from ..models.o_auth2_stripe import OAuth2Stripe; -from ..models.o_auth2_tradeshift import OAuth2Tradeshift; -from ..models.o_auth2_twitch import OAuth2Twitch; -from ..models.o_auth2_word_press import OAuth2WordPress; -from ..models.o_auth2_x import OAuth2X; -from ..models.o_auth2_yahoo import OAuth2Yahoo; -from ..models.o_auth2_yandex import OAuth2Yandex; -from ..models.o_auth2_zoho import OAuth2Zoho; -from ..models.o_auth2_zoom import OAuth2Zoom; -from ..enums.project_o_auth_provider_id import ProjectOAuthProviderId; -from ..models.platform_list import PlatformList; -from ..models.platform_android import PlatformAndroid; -from ..models.platform_apple import PlatformApple; -from ..models.platform_linux import PlatformLinux; -from ..models.platform_web import PlatformWeb; -from ..models.platform_windows import PlatformWindows; -from ..models.policy_list import PolicyList; -from ..enums.project_policy_id import ProjectPolicyId; -from ..models.policy_password_dictionary import PolicyPasswordDictionary; -from ..models.policy_password_history import PolicyPasswordHistory; -from ..models.policy_password_personal_data import PolicyPasswordPersonalData; -from ..models.policy_session_alert import PolicySessionAlert; -from ..models.policy_session_duration import PolicySessionDuration; -from ..models.policy_session_invalidation import PolicySessionInvalidation; -from ..models.policy_session_limit import PolicySessionLimit; -from ..models.policy_user_limit import PolicyUserLimit; -from ..models.policy_membership_privacy import PolicyMembershipPrivacy; -from ..enums.project_protocol_id import ProjectProtocolId; -from ..enums.project_service_id import ProjectServiceId; -from ..enums.project_smtp_secure import ProjectSMTPSecure; -from ..models.email_template_list import EmailTemplateList; -from ..enums.project_email_template_id import ProjectEmailTemplateId; -from ..enums.project_email_template_locale import ProjectEmailTemplateLocale; -from ..models.email_template import EmailTemplate; -from ..models.variable_list import VariableList; -from ..models.variable import Variable; +from ..models.project import Project as ProjectModel +from ..enums.project_auth_method_id import ProjectAuthMethodId +from ..models.key_list import KeyList +from ..enums.project_key_scopes import ProjectKeyScopes +from ..models.key import Key +from ..models.ephemeral_key import EphemeralKey +from ..models.mock_number_list import MockNumberList +from ..models.mock_number import MockNumber +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_auth0 import OAuth2Auth0 +from ..models.o_auth2_authentik import OAuth2Authentik +from ..models.o_auth2_autodesk import OAuth2Autodesk +from ..models.o_auth2_bitbucket import OAuth2Bitbucket +from ..models.o_auth2_bitly import OAuth2Bitly +from ..models.o_auth2_box import OAuth2Box +from ..models.o_auth2_dailymotion import OAuth2Dailymotion +from ..models.o_auth2_discord import OAuth2Discord +from ..models.o_auth2_disqus import OAuth2Disqus +from ..models.o_auth2_dropbox import OAuth2Dropbox +from ..models.o_auth2_etsy import OAuth2Etsy +from ..models.o_auth2_facebook import OAuth2Facebook +from ..models.o_auth2_figma import OAuth2Figma +from ..models.o_auth2_fusion_auth import OAuth2FusionAuth +from ..models.o_auth2_github import OAuth2Github +from ..models.o_auth2_gitlab import OAuth2Gitlab +from ..enums.project_o_auth2_google_prompt import ProjectOAuth2GooglePrompt +from ..models.o_auth2_google import OAuth2Google +from ..models.o_auth2_keycloak import OAuth2Keycloak +from ..models.o_auth2_kick import OAuth2Kick +from ..models.o_auth2_linkedin import OAuth2Linkedin +from ..models.o_auth2_microsoft import OAuth2Microsoft +from ..models.o_auth2_notion import OAuth2Notion +from ..models.o_auth2_oidc import OAuth2Oidc +from ..models.o_auth2_okta import OAuth2Okta +from ..models.o_auth2_paypal import OAuth2Paypal +from ..models.o_auth2_podio import OAuth2Podio +from ..models.o_auth2_salesforce import OAuth2Salesforce +from ..models.o_auth2_slack import OAuth2Slack +from ..models.o_auth2_spotify import OAuth2Spotify +from ..models.o_auth2_stripe import OAuth2Stripe +from ..models.o_auth2_tradeshift import OAuth2Tradeshift +from ..models.o_auth2_twitch import OAuth2Twitch +from ..models.o_auth2_word_press import OAuth2WordPress +from ..models.o_auth2_x import OAuth2X +from ..models.o_auth2_yahoo import OAuth2Yahoo +from ..models.o_auth2_yandex import OAuth2Yandex +from ..models.o_auth2_zoho import OAuth2Zoho +from ..models.o_auth2_zoom import OAuth2Zoom +from ..enums.project_o_auth_provider_id import ProjectOAuthProviderId +from ..models.platform_list import PlatformList +from ..models.platform_android import PlatformAndroid +from ..models.platform_apple import PlatformApple +from ..models.platform_linux import PlatformLinux +from ..models.platform_web import PlatformWeb +from ..models.platform_windows import PlatformWindows +from ..models.policy_list import PolicyList +from ..enums.project_policy_id import ProjectPolicyId +from ..models.policy_password_dictionary import PolicyPasswordDictionary +from ..models.policy_password_history import PolicyPasswordHistory +from ..models.policy_password_personal_data import PolicyPasswordPersonalData +from ..models.policy_session_alert import PolicySessionAlert +from ..models.policy_session_duration import PolicySessionDuration +from ..models.policy_session_invalidation import PolicySessionInvalidation +from ..models.policy_session_limit import PolicySessionLimit +from ..models.policy_user_limit import PolicyUserLimit +from ..models.policy_membership_privacy import PolicyMembershipPrivacy +from ..enums.project_protocol_id import ProjectProtocolId +from ..enums.project_service_id import ProjectServiceId +from ..enums.project_smtp_secure import ProjectSMTPSecure +from ..models.email_template_list import EmailTemplateList +from ..enums.project_email_template_id import ProjectEmailTemplateId +from ..enums.project_email_template_locale import ProjectEmailTemplateLocale +from ..models.email_template import EmailTemplate +from ..models.variable_list import VariableList +from ..models.variable import Variable class Project(Service): diff --git a/appwrite/services/proxy.py b/appwrite/services/proxy.py index fdbb869a..598c294c 100644 --- a/appwrite/services/proxy.py +++ b/appwrite/services/proxy.py @@ -2,10 +2,10 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.proxy_rule_list import ProxyRuleList; -from ..models.proxy_rule import ProxyRule; -from ..enums.status_code import StatusCode; -from ..enums.proxy_resource_type import ProxyResourceType; +from ..models.proxy_rule_list import ProxyRuleList +from ..models.proxy_rule import ProxyRule +from ..enums.status_code import StatusCode +from ..enums.proxy_resource_type import ProxyResourceType class Proxy(Service): diff --git a/appwrite/services/sites.py b/appwrite/services/sites.py index 57ea0377..5f755625 100644 --- a/appwrite/services/sites.py +++ b/appwrite/services/sites.py @@ -2,23 +2,23 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.site_list import SiteList; -from ..enums.framework import Framework; -from ..enums.build_runtime import BuildRuntime; -from ..enums.adapter import Adapter; -from ..models.site import Site; -from ..models.framework_list import FrameworkList; -from ..models.specification_list import SpecificationList; -from ..models.deployment_list import DeploymentList; +from ..models.site_list import SiteList +from ..enums.framework import Framework +from ..enums.build_runtime import BuildRuntime +from ..enums.adapter import Adapter +from ..models.site import Site +from ..models.framework_list import FrameworkList +from ..models.specification_list import SpecificationList +from ..models.deployment_list import DeploymentList from ..input_file import InputFile -from ..models.deployment import Deployment; -from ..enums.template_reference_type import TemplateReferenceType; -from ..enums.vcs_reference_type import VCSReferenceType; -from ..enums.deployment_download_type import DeploymentDownloadType; -from ..models.execution_list import ExecutionList; -from ..models.execution import Execution; -from ..models.variable_list import VariableList; -from ..models.variable import Variable; +from ..models.deployment import Deployment +from ..enums.template_reference_type import TemplateReferenceType +from ..enums.vcs_reference_type import VCSReferenceType +from ..enums.deployment_download_type import DeploymentDownloadType +from ..models.execution_list import ExecutionList +from ..models.execution import Execution +from ..models.variable_list import VariableList +from ..models.variable import Variable class Sites(Service): diff --git a/appwrite/services/storage.py b/appwrite/services/storage.py index 3e6d4683..95efa375 100644 --- a/appwrite/services/storage.py +++ b/appwrite/services/storage.py @@ -2,14 +2,14 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.bucket_list import BucketList; -from ..enums.compression import Compression; -from ..models.bucket import Bucket; -from ..models.file_list import FileList; +from ..models.bucket_list import BucketList +from ..enums.compression import Compression +from ..models.bucket import Bucket +from ..models.file_list import FileList from ..input_file import InputFile -from ..models.file import File; -from ..enums.image_gravity import ImageGravity; -from ..enums.image_format import ImageFormat; +from ..models.file import File +from ..enums.image_gravity import ImageGravity +from ..enums.image_format import ImageFormat class Storage(Service): diff --git a/appwrite/services/tables_db.py b/appwrite/services/tables_db.py index a2be7601..9916c5c2 100644 --- a/appwrite/services/tables_db.py +++ b/appwrite/services/tables_db.py @@ -2,39 +2,39 @@ from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.database_list import DatabaseList; -from ..models.database import Database; -from ..models.transaction_list import TransactionList; -from ..models.transaction import Transaction; -from ..models.table_list import TableList; -from ..models.table import Table; -from ..models.column_list import ColumnList; -from ..models.column_bigint import ColumnBigint; -from ..models.column_boolean import ColumnBoolean; -from ..models.column_datetime import ColumnDatetime; -from ..models.column_email import ColumnEmail; -from ..models.column_enum import ColumnEnum; -from ..models.column_float import ColumnFloat; -from ..models.column_integer import ColumnInteger; -from ..models.column_ip import ColumnIp; -from ..models.column_line import ColumnLine; -from ..models.column_longtext import ColumnLongtext; -from ..models.column_mediumtext import ColumnMediumtext; -from ..models.column_point import ColumnPoint; -from ..models.column_polygon import ColumnPolygon; -from ..enums.relationship_type import RelationshipType; -from ..enums.relation_mutate import RelationMutate; -from ..models.column_relationship import ColumnRelationship; -from ..models.column_string import ColumnString; -from ..models.column_text import ColumnText; -from ..models.column_url import ColumnUrl; -from ..models.column_varchar import ColumnVarchar; -from ..models.column_index_list import ColumnIndexList; -from ..enums.tables_db_index_type import TablesDBIndexType; -from ..enums.order_by import OrderBy; -from ..models.column_index import ColumnIndex; -from ..models.row_list import RowList; -from ..models.row import Row; +from ..models.database_list import DatabaseList +from ..models.database import Database +from ..models.transaction_list import TransactionList +from ..models.transaction import Transaction +from ..models.table_list import TableList +from ..models.table import Table +from ..models.column_list import ColumnList +from ..models.column_bigint import ColumnBigint +from ..models.column_boolean import ColumnBoolean +from ..models.column_datetime import ColumnDatetime +from ..models.column_email import ColumnEmail +from ..models.column_enum import ColumnEnum +from ..models.column_float import ColumnFloat +from ..models.column_integer import ColumnInteger +from ..models.column_ip import ColumnIp +from ..models.column_line import ColumnLine +from ..models.column_longtext import ColumnLongtext +from ..models.column_mediumtext import ColumnMediumtext +from ..models.column_point import ColumnPoint +from ..models.column_polygon import ColumnPolygon +from ..enums.relationship_type import RelationshipType +from ..enums.relation_mutate import RelationMutate +from ..models.column_relationship import ColumnRelationship +from ..models.column_string import ColumnString +from ..models.column_text import ColumnText +from ..models.column_url import ColumnUrl +from ..models.column_varchar import ColumnVarchar +from ..models.column_index_list import ColumnIndexList +from ..enums.tables_db_index_type import TablesDBIndexType +from ..enums.order_by import OrderBy +from ..models.column_index import ColumnIndex +from ..models.row_list import RowList +from ..models.row import Row T = TypeVar('T') diff --git a/appwrite/services/teams.py b/appwrite/services/teams.py index 6557f870..1c90ac65 100644 --- a/appwrite/services/teams.py +++ b/appwrite/services/teams.py @@ -2,11 +2,11 @@ from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.team_list import TeamList; -from ..models.team import Team; -from ..models.membership_list import MembershipList; -from ..models.membership import Membership; -from ..models.preferences import Preferences; +from ..models.team_list import TeamList +from ..models.team import Team +from ..models.membership_list import MembershipList +from ..models.membership import Membership +from ..models.preferences import Preferences T = TypeVar('T') diff --git a/appwrite/services/tokens.py b/appwrite/services/tokens.py index 215e9ccd..198c395d 100644 --- a/appwrite/services/tokens.py +++ b/appwrite/services/tokens.py @@ -2,8 +2,8 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.resource_token_list import ResourceTokenList; -from ..models.resource_token import ResourceToken; +from ..models.resource_token_list import ResourceTokenList +from ..models.resource_token import ResourceToken class Tokens(Service): diff --git a/appwrite/services/usage.py b/appwrite/services/usage.py index 249bfaf7..8ff96911 100644 --- a/appwrite/services/usage.py +++ b/appwrite/services/usage.py @@ -2,8 +2,8 @@ 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; +from ..models.usage_event_list import UsageEventList +from ..models.usage_gauge_list import UsageGaugeList class Usage(Service): diff --git a/appwrite/services/users.py b/appwrite/services/users.py index 62eb4cd3..83224f28 100644 --- a/appwrite/services/users.py +++ b/appwrite/services/users.py @@ -2,23 +2,23 @@ from typing import Any, Dict, List, Optional, Union, Type, TypeVar from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.user_list import UserList; -from ..models.user import User; -from ..models.identity_list import IdentityList; -from ..enums.password_hash import PasswordHash; -from ..models.jwt import Jwt; -from ..models.log_list import LogList; -from ..models.membership_list import MembershipList; -from ..enums.authenticator_type import AuthenticatorType; -from ..models.mfa_factors import MfaFactors; -from ..models.mfa_recovery_codes import MfaRecoveryCodes; -from ..models.preferences import Preferences; -from ..models.session_list import SessionList; -from ..models.session import Session; -from ..models.target_list import TargetList; -from ..enums.messaging_provider_type import MessagingProviderType; -from ..models.target import Target; -from ..models.token import Token; +from ..models.user_list import UserList +from ..models.user import User +from ..models.identity_list import IdentityList +from ..enums.password_hash import PasswordHash +from ..models.jwt import Jwt +from ..models.log_list import LogList +from ..models.membership_list import MembershipList +from ..enums.authenticator_type import AuthenticatorType +from ..models.mfa_factors import MfaFactors +from ..models.mfa_recovery_codes import MfaRecoveryCodes +from ..models.preferences import Preferences +from ..models.session_list import SessionList +from ..models.session import Session +from ..models.target_list import TargetList +from ..enums.messaging_provider_type import MessagingProviderType +from ..models.target import Target +from ..models.token import Token T = TypeVar('T') diff --git a/appwrite/services/webhooks.py b/appwrite/services/webhooks.py index 079c18b3..8c0e9407 100644 --- a/appwrite/services/webhooks.py +++ b/appwrite/services/webhooks.py @@ -2,8 +2,8 @@ from typing import Any, Dict, List, Optional, Union from ..exception import AppwriteException from appwrite.utils.deprecated import deprecated -from ..models.webhook_list import WebhookList; -from ..models.webhook import Webhook; +from ..models.webhook_list import WebhookList +from ..models.webhook import Webhook class Webhooks(Service): From 3550a4608180a11aaedb2854eb943bddbf1e08d3 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 18 May 2026 16:14:26 +0000 Subject: [PATCH 3/3] chore: update Python SDK to 19.0.0 --- appwrite/models/preferences.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/appwrite/models/preferences.py b/appwrite/models/preferences.py index 7f6561d0..ce469590 100644 --- a/appwrite/models/preferences.py +++ b/appwrite/models/preferences.py @@ -14,13 +14,8 @@ class Preferences(AppwriteModel, Generic[T]): @classmethod def with_data(cls, data: Dict[str, Any], model_type: Type[T] = dict) -> 'Preferences[T]': """Create Preferences instance with typed data.""" - internal_aliases = {} - internal_fields = {k: v for k, v in data.items() if k in internal_aliases} - user_data = {k: v for k, v in data.items() if k not in internal_aliases and k != 'data'} - nested = data.get('data') - if isinstance(nested, dict): - user_data = {**nested, **user_data} - instance = cls.model_validate(internal_fields) + user_data = dict(data) + instance = cls.model_validate({}) instance._data = model_type(**user_data) if model_type is not dict else user_data return instance