diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a7e67d9..0d5ba813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,18 @@ # Change Log -## 19.1.0 - -* Added `DENO_1_21`, `DENO_1_24`, and `DENO_1_35` runtime options -* Added `sizeactual` field to `File` model for compressed file size -* Updated `BillingLimits` model fields to be optional -* Updated `Project` model `billinglimits` field to be optional -* Updated authentication examples in advisor documentation +## 20.0.0 + +* Breaking: Removed `githubImagine` and `googleImagine` from `ProjectOAuthProviderId` +* Breaking: Removed `deno-1.21`, `deno-1.24`, and `deno-1.35` from `Runtime` and `BuildRuntime` +* Breaking: Dropped numeric suffixes from `StatusCode` redirect members +* Added: `Organization` service for managing projects and API keys +* Added: `PolicyDenyAliasedEmail`, `PolicyDenyDisposableEmail`, and `PolicyDenyFreeEmail` policy models +* Added: `deny-aliased-email`, `deny-disposable-email`, and `deny-free-email` to `ProjectPolicyId` +* Added: `BrowserTheme`, `HealthQueueName`, `OrganizationKeyScopes`, and `Region` enums +* Added: `dart-3.12` and `flutter-3.44` runtimes +* Added: `ProjectList` model and new attributes on `Function`, `Site`, and `UsageGauge` +* Updated: `functions`, `sites`, `usage`, `health`, and `avatars` services +* Updated: Renamed `updatePresence` to `update` in the `presences` service ## 19.0.0 diff --git a/appwrite/client.py b/appwrite/client.py index 5c3cdef8..e0a6ab25 100644 --- a/appwrite/client.py +++ b/appwrite/client.py @@ -17,11 +17,11 @@ def __init__(self): self._endpoint = 'https://cloud.appwrite.io/v1' self._global_headers = { 'content-type': '', - 'user-agent' : f'AppwritePythonSDK/19.2.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})', + 'user-agent' : f'AppwritePythonSDK/20.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': '19.2.0', + 'x-sdk-version': '20.0.0', 'X-Appwrite-Response-Format' : '1.9.5', } diff --git a/appwrite/encoders/value_class_encoder.py b/appwrite/encoders/value_class_encoder.py index b894901d..5a4914b1 100644 --- a/appwrite/encoders/value_class_encoder.py +++ b/appwrite/encoders/value_class_encoder.py @@ -6,7 +6,7 @@ from ..enums.browser import Browser from ..enums.credit_card import CreditCard from ..enums.flag import Flag -from ..enums.theme import Theme +from ..enums.browser_theme import BrowserTheme from ..enums.timezone import Timezone from ..enums.browser_permission import BrowserPermission from ..enums.image_format import ImageFormat @@ -16,16 +16,17 @@ from ..enums.databases_index_type import DatabasesIndexType from ..enums.order_by import OrderBy from ..enums.runtime import Runtime -from ..enums.scopes import Scopes +from ..enums.project_key_scopes import ProjectKeyScopes from ..enums.template_reference_type import TemplateReferenceType from ..enums.vcs_reference_type import VCSReferenceType from ..enums.deployment_download_type import DeploymentDownloadType from ..enums.execution_method import ExecutionMethod -from ..enums.name import Name +from ..enums.health_queue_name import HealthQueueName from ..enums.message_priority import MessagePriority from ..enums.smtp_encryption import SmtpEncryption +from ..enums.organization_key_scopes import OrganizationKeyScopes +from ..enums.region import Region from ..enums.project_auth_method_id import ProjectAuthMethodId -from ..enums.project_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 @@ -82,7 +83,7 @@ def default(self, o): if isinstance(o, Flag): return o.value - if isinstance(o, Theme): + if isinstance(o, BrowserTheme): return o.value if isinstance(o, Timezone): @@ -112,7 +113,7 @@ def default(self, o): if isinstance(o, Runtime): return o.value - if isinstance(o, Scopes): + if isinstance(o, ProjectKeyScopes): return o.value if isinstance(o, TemplateReferenceType): @@ -127,7 +128,7 @@ def default(self, o): if isinstance(o, ExecutionMethod): return o.value - if isinstance(o, Name): + if isinstance(o, HealthQueueName): return o.value if isinstance(o, MessagePriority): @@ -136,10 +137,13 @@ def default(self, o): if isinstance(o, SmtpEncryption): return o.value - if isinstance(o, ProjectAuthMethodId): + if isinstance(o, OrganizationKeyScopes): return o.value - if isinstance(o, ProjectKeyScopes): + if isinstance(o, Region): + return o.value + + if isinstance(o, ProjectAuthMethodId): return o.value if isinstance(o, ProjectOAuth2GooglePrompt): diff --git a/appwrite/enums/backup_services.py b/appwrite/enums/backup_services.py index 20b99791..9c53935b 100644 --- a/appwrite/enums/backup_services.py +++ b/appwrite/enums/backup_services.py @@ -5,5 +5,6 @@ class BackupServices(Enum): TABLESDB = "tablesdb" DOCUMENTSDB = "documentsdb" VECTORSDB = "vectorsdb" + DEDICATEDDATABASES = "dedicatedDatabases" FUNCTIONS = "functions" STORAGE = "storage" diff --git a/appwrite/enums/theme.py b/appwrite/enums/browser_theme.py similarity index 70% rename from appwrite/enums/theme.py rename to appwrite/enums/browser_theme.py index cd30f8bd..5d9ba62f 100644 --- a/appwrite/enums/theme.py +++ b/appwrite/enums/browser_theme.py @@ -1,5 +1,5 @@ from enum import Enum -class Theme(Enum): +class BrowserTheme(Enum): LIGHT = "light" DARK = "dark" diff --git a/appwrite/enums/build_runtime.py b/appwrite/enums/build_runtime.py index 18fa29dc..7b1c6dc1 100644 --- a/appwrite/enums/build_runtime.py +++ b/appwrite/enums/build_runtime.py @@ -32,9 +32,6 @@ class BuildRuntime(Enum): PYTHON_ML_3_11 = "python-ml-3.11" PYTHON_ML_3_12 = "python-ml-3.12" PYTHON_ML_3_13 = "python-ml-3.13" - DENO_1_21 = "deno-1.21" - DENO_1_24 = "deno-1.24" - DENO_1_35 = "deno-1.35" DENO_1_40 = "deno-1.40" DENO_1_46 = "deno-1.46" DENO_2_0 = "deno-2.0" @@ -53,6 +50,7 @@ class BuildRuntime(Enum): DART_3_9 = "dart-3.9" DART_3_10 = "dart-3.10" DART_3_11 = "dart-3.11" + DART_3_12 = "dart-3.12" DOTNET_6_0 = "dotnet-6.0" DOTNET_7_0 = "dotnet-7.0" DOTNET_8_0 = "dotnet-8.0" @@ -93,3 +91,4 @@ class BuildRuntime(Enum): FLUTTER_3_35 = "flutter-3.35" FLUTTER_3_38 = "flutter-3.38" FLUTTER_3_41 = "flutter-3.41" + FLUTTER_3_44 = "flutter-3.44" diff --git a/appwrite/enums/name.py b/appwrite/enums/health_queue_name.py similarity index 94% rename from appwrite/enums/name.py rename to appwrite/enums/health_queue_name.py index 7af7da78..a04ab15f 100644 --- a/appwrite/enums/name.py +++ b/appwrite/enums/health_queue_name.py @@ -1,6 +1,6 @@ from enum import Enum -class Name(Enum): +class HealthQueueName(Enum): V1_DATABASE = "v1-database" V1_DELETES = "v1-deletes" V1_AUDITS = "v1-audits" diff --git a/appwrite/enums/organization_key_scopes.py b/appwrite/enums/organization_key_scopes.py new file mode 100644 index 00000000..aa788f1a --- /dev/null +++ b/appwrite/enums/organization_key_scopes.py @@ -0,0 +1,13 @@ +from enum import Enum + +class OrganizationKeyScopes(Enum): + PROJECTS_READ = "projects.read" + PROJECTS_WRITE = "projects.write" + DEVKEYS_READ = "devKeys.read" + DEVKEYS_WRITE = "devKeys.write" + ORGANIZATION_KEYS_READ = "organization.keys.read" + ORGANIZATION_KEYS_WRITE = "organization.keys.write" + DOMAINS_READ = "domains.read" + DOMAINS_WRITE = "domains.write" + KEYS_READ = "keys.read" + KEYS_WRITE = "keys.write" diff --git a/appwrite/enums/project_o_auth_provider_id.py b/appwrite/enums/project_o_auth_provider_id.py index b22ea44c..71ba1213 100644 --- a/appwrite/enums/project_o_auth_provider_id.py +++ b/appwrite/enums/project_o_auth_provider_id.py @@ -44,5 +44,3 @@ class ProjectOAuthProviderId(Enum): YANDEX = "yandex" ZOHO = "zoho" ZOOM = "zoom" - GITHUBIMAGINE = "githubImagine" - GOOGLEIMAGINE = "googleImagine" diff --git a/appwrite/enums/project_policy_id.py b/appwrite/enums/project_policy_id.py index 7c7a0c50..1b347dab 100644 --- a/appwrite/enums/project_policy_id.py +++ b/appwrite/enums/project_policy_id.py @@ -10,3 +10,6 @@ class ProjectPolicyId(Enum): SESSION_LIMIT = "session-limit" USER_LIMIT = "user-limit" MEMBERSHIP_PRIVACY = "membership-privacy" + DENY_ALIASED_EMAIL = "deny-aliased-email" + DENY_DISPOSABLE_EMAIL = "deny-disposable-email" + DENY_FREE_EMAIL = "deny-free-email" diff --git a/appwrite/enums/region.py b/appwrite/enums/region.py new file mode 100644 index 00000000..dd8c47c5 --- /dev/null +++ b/appwrite/enums/region.py @@ -0,0 +1,9 @@ +from enum import Enum + +class Region(Enum): + FRA = "fra" + NYC = "nyc" + SYD = "syd" + SFO = "sfo" + SGP = "sgp" + TOR = "tor" diff --git a/appwrite/enums/runtime.py b/appwrite/enums/runtime.py index 7a2ac6f7..74e3a279 100644 --- a/appwrite/enums/runtime.py +++ b/appwrite/enums/runtime.py @@ -32,9 +32,6 @@ class Runtime(Enum): PYTHON_ML_3_11 = "python-ml-3.11" PYTHON_ML_3_12 = "python-ml-3.12" PYTHON_ML_3_13 = "python-ml-3.13" - DENO_1_21 = "deno-1.21" - DENO_1_24 = "deno-1.24" - DENO_1_35 = "deno-1.35" DENO_1_40 = "deno-1.40" DENO_1_46 = "deno-1.46" DENO_2_0 = "deno-2.0" @@ -53,6 +50,7 @@ class Runtime(Enum): DART_3_9 = "dart-3.9" DART_3_10 = "dart-3.10" DART_3_11 = "dart-3.11" + DART_3_12 = "dart-3.12" DOTNET_6_0 = "dotnet-6.0" DOTNET_7_0 = "dotnet-7.0" DOTNET_8_0 = "dotnet-8.0" @@ -93,3 +91,4 @@ class Runtime(Enum): FLUTTER_3_35 = "flutter-3.35" FLUTTER_3_38 = "flutter-3.38" FLUTTER_3_41 = "flutter-3.41" + FLUTTER_3_44 = "flutter-3.44" diff --git a/appwrite/enums/scopes.py b/appwrite/enums/scopes.py deleted file mode 100644 index d3784f33..00000000 --- a/appwrite/enums/scopes.py +++ /dev/null @@ -1,97 +0,0 @@ -from enum import Enum - -class Scopes(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/status_code.py b/appwrite/enums/status_code.py index 4eb00ec0..e6f7e49e 100644 --- a/appwrite/enums/status_code.py +++ b/appwrite/enums/status_code.py @@ -1,7 +1,7 @@ from enum import Enum class StatusCode(Enum): - MOVED_PERMANENTLY_301 = "301" - FOUND_302 = "302" - TEMPORARY_REDIRECT_307 = "307" - PERMANENT_REDIRECT_308 = "308" + MOVEDPERMANENTLY = "301" + FOUND = "302" + TEMPORARYREDIRECT = "307" + PERMANENTREDIRECT = "308" diff --git a/appwrite/models/__init__.py b/appwrite/models/__init__.py index 734b280e..550ec73d 100644 --- a/appwrite/models/__init__.py +++ b/appwrite/models/__init__.py @@ -22,6 +22,7 @@ from .runtime_list import RuntimeList from .deployment_list import DeploymentList from .execution_list import ExecutionList +from .project_list import ProjectList from .webhook_list import WebhookList from .key_list import KeyList from .country_list import CountryList @@ -217,15 +218,18 @@ from .billing_limits import BillingLimits from .block import Block from .backup_policy import BackupPolicy +from .policy_deny_aliased_email import PolicyDenyAliasedEmail +from .policy_deny_disposable_email import PolicyDenyDisposableEmail +from .policy_deny_free_email import PolicyDenyFreeEmail from .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 from .backup_restoration_list import BackupRestorationList +from .usage_event_list import UsageEventList +from .usage_gauge_list import UsageGaugeList __all__ = [ 'AppwriteModel', @@ -252,6 +256,7 @@ 'RuntimeList', 'DeploymentList', 'ExecutionList', + 'ProjectList', 'WebhookList', 'KeyList', 'CountryList', @@ -447,13 +452,16 @@ 'BillingLimits', 'Block', 'BackupPolicy', + 'PolicyDenyAliasedEmail', + 'PolicyDenyDisposableEmail', + 'PolicyDenyFreeEmail', 'BackupRestoration', 'UsageEvent', - 'UsageEventList', 'UsageGauge', - 'UsageGaugeList', 'ActivityEventList', 'BackupArchiveList', 'BackupPolicyList', 'BackupRestorationList', + 'UsageEventList', + 'UsageGaugeList', ] diff --git a/appwrite/models/activity_event.py b/appwrite/models/activity_event.py index 1d4daf64..c3146494 100644 --- a/appwrite/models/activity_event.py +++ b/appwrite/models/activity_event.py @@ -11,14 +11,14 @@ class ActivityEvent(AppwriteModel): ---------- id : str Event ID. - usertype : str - User type. - userid : str - User ID. - useremail : str - User Email. - username : str - User Name. + actortype : str + Actor type. + actorid : str + Actor ID. + actoremail : str + Actor Email. + actorname : str + Actor Name. resourceparent : str Resource parent. resourcetype : str @@ -75,10 +75,10 @@ class ActivityEvent(AppwriteModel): Country name. """ id: str = Field(..., alias='$id') - usertype: str = Field(..., alias='userType') - userid: str = Field(..., alias='userId') - useremail: str = Field(..., alias='userEmail') - username: str = Field(..., alias='userName') + actortype: str = Field(..., alias='actorType') + actorid: str = Field(..., alias='actorId') + actoremail: str = Field(..., alias='actorEmail') + actorname: str = Field(..., alias='actorName') resourceparent: str = Field(..., alias='resourceParent') resourcetype: str = Field(..., alias='resourceType') resourceid: str = Field(..., alias='resourceId') diff --git a/appwrite/models/billing_limits.py b/appwrite/models/billing_limits.py index c7c5b747..4f9ee620 100644 --- a/appwrite/models/billing_limits.py +++ b/appwrite/models/billing_limits.py @@ -5,7 +5,7 @@ class BillingLimits(AppwriteModel): """ - BillingLimits + Limits Attributes ---------- diff --git a/appwrite/models/function.py b/appwrite/models/function.py index b7f5a208..6e3dd16a 100644 --- a/appwrite/models/function.py +++ b/appwrite/models/function.py @@ -66,6 +66,10 @@ class Function(AppwriteModel): Path to function in VCS (Version Control System) repository providersilentmode : bool Is VCS (Version Control System) connection is in silent mode? When in silence mode, no comments will be posted on the repository pull or merge requests + providerbranches : List[Any] + List of branch name patterns that trigger automatic deployments. Supports glob wildcards. Empty list deploys on all branches. + providerpaths : List[Any] + List of file path patterns that trigger automatic deployments. Supports glob wildcards. Empty list deploys on all file changes. buildspecification : str Machine specification for deployment builds. runtimespecification : str @@ -99,5 +103,7 @@ class Function(AppwriteModel): providerbranch: str = Field(..., alias='providerBranch') providerrootdirectory: str = Field(..., alias='providerRootDirectory') providersilentmode: bool = Field(..., alias='providerSilentMode') + providerbranches: List[Any] = Field(..., alias='providerBranches') + providerpaths: List[Any] = Field(..., alias='providerPaths') buildspecification: str = Field(..., alias='buildSpecification') runtimespecification: str = Field(..., alias='runtimeSpecification') diff --git a/appwrite/models/policy_deny_aliased_email.py b/appwrite/models/policy_deny_aliased_email.py new file mode 100644 index 00000000..765fab82 --- /dev/null +++ b/appwrite/models/policy_deny_aliased_email.py @@ -0,0 +1,18 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class PolicyDenyAliasedEmail(AppwriteModel): + """ + Policy Deny Aliased Email + + Attributes + ---------- + id : str + Policy ID. + enabled : bool + Whether the deny aliased email policy is enabled. + """ + id: str = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/policy_deny_disposable_email.py b/appwrite/models/policy_deny_disposable_email.py new file mode 100644 index 00000000..458018c0 --- /dev/null +++ b/appwrite/models/policy_deny_disposable_email.py @@ -0,0 +1,18 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class PolicyDenyDisposableEmail(AppwriteModel): + """ + Policy Deny Disposable Email + + Attributes + ---------- + id : str + Policy ID. + enabled : bool + Whether the deny disposable email policy is enabled. + """ + id: str = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/policy_deny_free_email.py b/appwrite/models/policy_deny_free_email.py new file mode 100644 index 00000000..6e1672a7 --- /dev/null +++ b/appwrite/models/policy_deny_free_email.py @@ -0,0 +1,18 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel + +class PolicyDenyFreeEmail(AppwriteModel): + """ + Policy Deny Free Email + + Attributes + ---------- + id : str + Policy ID. + enabled : bool + Whether the deny free email policy is enabled. + """ + id: str = Field(..., alias='$id') + enabled: bool = Field(..., alias='enabled') diff --git a/appwrite/models/policy_list.py b/appwrite/models/policy_list.py index bed74bcb..ab5149b3 100644 --- a/appwrite/models/policy_list.py +++ b/appwrite/models/policy_list.py @@ -11,6 +11,9 @@ from .policy_session_limit import PolicySessionLimit from .policy_user_limit import PolicyUserLimit from .policy_membership_privacy import PolicyMembershipPrivacy +from .policy_deny_aliased_email import PolicyDenyAliasedEmail +from .policy_deny_disposable_email import PolicyDenyDisposableEmail +from .policy_deny_free_email import PolicyDenyFreeEmail class PolicyList(AppwriteModel): """ @@ -20,8 +23,8 @@ class PolicyList(AppwriteModel): ---------- total : float Total number of policies in the given project. - policies : List[Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy]] + policies : List[Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy, PolicyDenyAliasedEmail, PolicyDenyDisposableEmail, PolicyDenyFreeEmail]] List of policies. """ total: float = Field(..., alias='total') - policies: List[Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy]] = Field(..., alias='policies') + policies: List[Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy, PolicyDenyAliasedEmail, PolicyDenyDisposableEmail, PolicyDenyFreeEmail]] = Field(..., alias='policies') diff --git a/appwrite/models/presence.py b/appwrite/models/presence.py index bddda7d9..d4afedb1 100644 --- a/appwrite/models/presence.py +++ b/appwrite/models/presence.py @@ -1,11 +1,9 @@ -from typing import Any, Dict, List, Optional, Union, cast, Generic, TypeVar, Type +from typing import Any, Dict, List, Optional, Union, cast from pydantic import Field, PrivateAttr from .base_model import AppwriteModel -T = TypeVar('T') - -class Presence(AppwriteModel, Generic[T]): +class Presence(AppwriteModel): """ Presence @@ -27,6 +25,8 @@ class Presence(AppwriteModel, Generic[T]): Presence source. expiresat : Optional[str] Presence expiry date in ISO 8601 format. + metadata : Optional[Dict[str, Any]] + Presence metadata. """ id: str = Field(..., alias='$id') createdat: str = Field(..., alias='$createdAt') @@ -36,37 +36,4 @@ class Presence(AppwriteModel, Generic[T]): 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_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 - - _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 + metadata: Optional[Dict[str, Any]] = Field(default=None, alias='metadata') diff --git a/appwrite/models/presence_list.py b/appwrite/models/presence_list.py index 516db718..2d37c0e4 100644 --- a/appwrite/models/presence_list.py +++ b/appwrite/models/presence_list.py @@ -1,12 +1,10 @@ -from typing import Any, Dict, List, Optional, Union, cast, Generic, TypeVar, Type +from typing import Any, Dict, List, Optional, Union, cast from pydantic import Field, PrivateAttr from .base_model import AppwriteModel from .presence import Presence -T = TypeVar('T') - -class PresenceList(AppwriteModel, Generic[T]): +class PresenceList(AppwriteModel): """ Presences List @@ -14,19 +12,8 @@ class PresenceList(AppwriteModel, Generic[T]): ---------- total : float Total number of presences that matched your query. - presences : List[Presence[T]] + presences : List[Presence] 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 + presences: List[Presence] = Field(..., alias='presences') diff --git a/appwrite/models/project_list.py b/appwrite/models/project_list.py new file mode 100644 index 00000000..c41de6f6 --- /dev/null +++ b/appwrite/models/project_list.py @@ -0,0 +1,19 @@ +from typing import Any, Dict, List, Optional, Union, cast +from pydantic import Field, PrivateAttr + +from .base_model import AppwriteModel +from .project import Project + +class ProjectList(AppwriteModel): + """ + Projects List + + Attributes + ---------- + total : float + Total number of projects that matched your query. + projects : List[Project] + List of projects. + """ + total: float = Field(..., alias='total') + projects: List[Project] = Field(..., alias='projects') diff --git a/appwrite/models/site.py b/appwrite/models/site.py index 4874c046..a4ecfef9 100644 --- a/appwrite/models/site.py +++ b/appwrite/models/site.py @@ -64,6 +64,10 @@ class Site(AppwriteModel): Path to site in VCS (Version Control System) repository providersilentmode : bool Is VCS (Version Control System) connection is in silent mode? When in silence mode, no comments will be posted on the repository pull or merge requests + providerbranches : List[Any] + List of branch name patterns that trigger automatic deployments. Supports glob wildcards. Empty list deploys on all branches. + providerpaths : List[Any] + List of file path patterns that trigger automatic deployments. Supports glob wildcards. Empty list deploys on all file changes. buildspecification : str Machine specification for deployment builds. runtimespecification : str @@ -102,6 +106,8 @@ class Site(AppwriteModel): providerbranch: str = Field(..., alias='providerBranch') providerrootdirectory: str = Field(..., alias='providerRootDirectory') providersilentmode: bool = Field(..., alias='providerSilentMode') + providerbranches: List[Any] = Field(..., alias='providerBranches') + providerpaths: List[Any] = Field(..., alias='providerPaths') buildspecification: str = Field(..., alias='buildSpecification') runtimespecification: str = Field(..., alias='runtimeSpecification') buildruntime: str = Field(..., alias='buildRuntime') diff --git a/appwrite/models/usage_gauge.py b/appwrite/models/usage_gauge.py index 3808eccc..dd56e10e 100644 --- a/appwrite/models/usage_gauge.py +++ b/appwrite/models/usage_gauge.py @@ -15,7 +15,13 @@ class UsageGauge(AppwriteModel): The current snapshot value. time : str The snapshot timestamp. + resourcetype : str + The resource type. + resourceid : str + The resource ID. """ metric: str = Field(..., alias='metric') value: float = Field(..., alias='value') time: str = Field(..., alias='time') + resourcetype: str = Field(..., alias='resourceType') + resourceid: str = Field(..., alias='resourceId') diff --git a/appwrite/services/avatars.py b/appwrite/services/avatars.py index e21ce057..393fd629 100644 --- a/appwrite/services/avatars.py +++ b/appwrite/services/avatars.py @@ -5,7 +5,7 @@ from ..enums.browser import Browser from ..enums.credit_card import CreditCard from ..enums.flag import Flag -from ..enums.theme import Theme +from ..enums.browser_theme import BrowserTheme from ..enums.timezone import Timezone from ..enums.browser_permission import BrowserPermission from ..enums.image_format import ImageFormat @@ -384,7 +384,7 @@ def get_screenshot( viewport_width: Optional[float] = None, viewport_height: Optional[float] = None, scale: Optional[float] = None, - theme: Optional[Theme] = None, + theme: Optional[BrowserTheme] = None, user_agent: Optional[str] = None, fullpage: Optional[bool] = None, locale: Optional[str] = None, @@ -419,7 +419,7 @@ def get_screenshot( Browser viewport height. Pass an integer between 1 to 1080. Defaults to 720. scale : Optional[float] Browser scale factor. Pass a number between 0.1 to 3. Defaults to 1. - theme : Optional[Theme] + theme : Optional[BrowserTheme] Browser theme. Pass "light" or "dark". Defaults to "light". user_agent : Optional[str] Custom user agent string. Defaults to browser default. diff --git a/appwrite/services/functions.py b/appwrite/services/functions.py index 55cb49f9..3a400990 100644 --- a/appwrite/services/functions.py +++ b/appwrite/services/functions.py @@ -4,7 +4,7 @@ from appwrite.utils.deprecated import deprecated from ..models.function_list import FunctionList from ..enums.runtime import Runtime -from ..enums.scopes import Scopes +from ..enums.project_key_scopes import ProjectKeyScopes from ..models.function import Function from ..models.runtime_list import RuntimeList from ..models.specification_list import SpecificationList @@ -83,12 +83,14 @@ def create( logging: Optional[bool] = None, entrypoint: Optional[str] = None, commands: Optional[str] = None, - scopes: Optional[List[Scopes]] = None, + scopes: Optional[List[ProjectKeyScopes]] = None, installation_id: Optional[str] = None, provider_repository_id: Optional[str] = None, provider_branch: Optional[str] = None, provider_silent_mode: Optional[bool] = None, provider_root_directory: Optional[str] = None, + provider_branches: Optional[List[str]] = None, + provider_paths: Optional[List[str]] = None, build_specification: Optional[str] = None, runtime_specification: Optional[str] = None, deployment_retention: Optional[float] = None @@ -120,7 +122,7 @@ def create( Entrypoint File. This path is relative to the "providerRootDirectory". commands : Optional[str] Build Commands. - scopes : Optional[List[Scopes]] + scopes : Optional[List[ProjectKeyScopes]] List of scopes allowed for API key auto-generated for every execution. Maximum of 100 scopes are allowed. installation_id : Optional[str] Appwrite Installation ID for VCS (Version Control System) deployment. @@ -132,6 +134,10 @@ def create( Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests. provider_root_directory : Optional[str] Path to function code in the linked repo. + provider_branches : Optional[List[str]] + List of branch name patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all branches. + provider_paths : Optional[List[str]] + List of file path patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all file changes. build_specification : Optional[str] Build specification for the function deployments. runtime_specification : Optional[str] @@ -193,6 +199,10 @@ def create( api_params['providerSilentMode'] = self._normalize_value(provider_silent_mode) if provider_root_directory is not None: api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) + if provider_branches is not None: + api_params['providerBranches'] = self._normalize_value(provider_branches) + if provider_paths is not None: + api_params['providerPaths'] = self._normalize_value(provider_paths) if build_specification is not None: api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: @@ -309,12 +319,14 @@ def update( logging: Optional[bool] = None, entrypoint: Optional[str] = None, commands: Optional[str] = None, - scopes: Optional[List[Scopes]] = None, + scopes: Optional[List[ProjectKeyScopes]] = None, installation_id: Optional[str] = None, provider_repository_id: Optional[str] = None, provider_branch: Optional[str] = None, provider_silent_mode: Optional[bool] = None, provider_root_directory: Optional[str] = None, + provider_branches: Optional[List[str]] = None, + provider_paths: Optional[List[str]] = None, build_specification: Optional[str] = None, runtime_specification: Optional[str] = None, deployment_retention: Optional[float] = None @@ -346,7 +358,7 @@ def update( Entrypoint File. This path is relative to the "providerRootDirectory". commands : Optional[str] Build Commands. - scopes : Optional[List[Scopes]] + scopes : Optional[List[ProjectKeyScopes]] List of scopes allowed for API Key auto-generated for every execution. Maximum of 100 scopes are allowed. installation_id : Optional[str] Appwrite Installation ID for VCS (Version Controle System) deployment. @@ -358,6 +370,10 @@ def update( Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests. provider_root_directory : Optional[str] Path to function code in the linked repo. + provider_branches : Optional[List[str]] + List of branch name patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all branches. + provider_paths : Optional[List[str]] + List of file path patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all file changes. build_specification : Optional[str] Build specification for the function deployments. runtime_specification : Optional[str] @@ -416,6 +432,8 @@ def update( api_params['providerSilentMode'] = self._normalize_value(provider_silent_mode) if provider_root_directory is not None: api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) + api_params['providerBranches'] = self._normalize_value(provider_branches) + api_params['providerPaths'] = self._normalize_value(provider_paths) if build_specification is not None: api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: diff --git a/appwrite/services/health.py b/appwrite/services/health.py index 9d604b3d..c8f2c8f4 100644 --- a/appwrite/services/health.py +++ b/appwrite/services/health.py @@ -7,7 +7,7 @@ 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 ..enums.health_queue_name import HealthQueueName from ..models.health_time import HealthTime class Health(Service): @@ -404,7 +404,7 @@ def get_queue_deletes( def get_failed_jobs( self, - name: Name, + name: HealthQueueName, threshold: Optional[float] = None ) -> HealthQueue: """ @@ -413,7 +413,7 @@ def get_failed_jobs( Parameters ---------- - name : Name + name : HealthQueueName The name of the queue threshold : Optional[float] Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000. diff --git a/appwrite/services/organization.py b/appwrite/services/organization.py new file mode 100644 index 00000000..7f5c3759 --- /dev/null +++ b/appwrite/services/organization.py @@ -0,0 +1,457 @@ +from ..service import Service +from typing import Any, Dict, List, Optional, Union +from ..exception import AppwriteException +from appwrite.utils.deprecated import deprecated +from ..models.key_list import KeyList +from ..enums.organization_key_scopes import OrganizationKeyScopes +from ..models.key import Key +from ..models.project_list import ProjectList +from ..enums.region import Region +from ..models.project import Project + +class Organization(Service): + + def __init__(self, client) -> None: + super(Organization, self).__init__(client) + + def list_keys( + self, + queries: Optional[List[str]] = None, + total: Optional[bool] = None + ) -> KeyList: + """ + Get a list of all API keys from the current organization. + + Parameters + ---------- + queries : Optional[List[str]] + Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: expire, accessedAt, name, scopes + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + KeyList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/keys' + 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=KeyList) + + + def create_key( + self, + key_id: str, + name: str, + scopes: List[OrganizationKeyScopes], + expire: Optional[str] = None + ) -> Key: + """ + Create a new organization API key. + + Parameters + ---------- + key_id : str + 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[OrganizationKeyScopes] + 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. + + Returns + ------- + Key + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/keys' + api_params = {} + if key_id is None: + raise AppwriteException('Missing required parameter: "key_id"') + + if name is None: + raise AppwriteException('Missing required parameter: "name"') + + if scopes is None: + raise AppwriteException('Missing required parameter: "scopes"') + + + api_params['keyId'] = self._normalize_value(key_id) + api_params['name'] = self._normalize_value(name) + api_params['scopes'] = self._normalize_value(scopes) + api_params['expire'] = self._normalize_value(expire) + + response = self.client.call('post', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=Key) + + + def get_key( + self, + key_id: str + ) -> Key: + """ + Get a key by its unique ID. This endpoint returns details about a specific API key in your organization including its scopes. + + Parameters + ---------- + key_id : str + Key unique ID. + + Returns + ------- + Key + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/keys/{keyId}' + api_params = {} + if key_id is None: + raise AppwriteException('Missing required parameter: "key_id"') + + api_path = api_path.replace('{keyId}', str(self._normalize_value(key_id))) + + + response = self.client.call('get', api_path, { + }, api_params) + + return self._parse_response(response, model=Key) + + + def update_key( + self, + key_id: str, + name: str, + scopes: List[OrganizationKeyScopes], + expire: Optional[str] = None + ) -> Key: + """ + Update a key by its unique ID. Use this endpoint to update the name, scopes, or expiration time of an API key. + + Parameters + ---------- + key_id : str + Key unique ID. + name : str + Key name. Max length: 128 chars. + scopes : List[OrganizationKeyScopes] + 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. + + Returns + ------- + Key + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/keys/{keyId}' + api_params = {} + if key_id is None: + raise AppwriteException('Missing required parameter: "key_id"') + + if name is None: + raise AppwriteException('Missing required parameter: "name"') + + if scopes is None: + raise AppwriteException('Missing required parameter: "scopes"') + + api_path = api_path.replace('{keyId}', str(self._normalize_value(key_id))) + + api_params['name'] = self._normalize_value(name) + api_params['scopes'] = self._normalize_value(scopes) + api_params['expire'] = self._normalize_value(expire) + + response = self.client.call('put', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=Key) + + + def delete_key( + self, + key_id: str + ) -> Dict[str, Any]: + """ + Delete a key by its unique ID. Once deleted, the key can no longer be used to authenticate API calls. + + Parameters + ---------- + key_id : str + Key unique ID. + + Returns + ------- + Dict[str, Any] + API response as a dictionary + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/keys/{keyId}' + api_params = {} + if key_id is None: + raise AppwriteException('Missing required parameter: "key_id"') + + api_path = api_path.replace('{keyId}', str(self._normalize_value(key_id))) + + + response = self.client.call('delete', api_path, { + 'content-type': 'application/json', + }, api_params) + + return response + + + def list_projects( + self, + queries: Optional[List[str]] = None, + search: Optional[str] = None, + total: Optional[bool] = None + ) -> ProjectList: + """ + Get a list of all projects. 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: name, teamId, labels, search + search : Optional[str] + Search term to filter your list results. Max length: 256 chars. + total : Optional[bool] + When set to false, the total count returned will be 0 and will not be calculated. + + Returns + ------- + ProjectList + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/projects' + api_params = {} + + if queries is not None: + api_params['queries'] = self._normalize_value(queries) + if search is not None: + api_params['search'] = self._normalize_value(search) + if total is not None: + api_params['total'] = self._normalize_value(total) + + response = self.client.call('get', api_path, { + }, api_params) + + return self._parse_response(response, model=ProjectList) + + + def create_project( + self, + project_id: str, + name: str, + region: Optional[Region] = None + ) -> Project: + """ + Create a new project. + + Parameters + ---------- + project_id : str + Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, and hyphen. Can't start with a special char. Max length is 36 chars. + name : str + Project name. Max length: 128 chars. + region : Optional[Region] + Project Region. + + Returns + ------- + Project + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/projects' + api_params = {} + if project_id is None: + raise AppwriteException('Missing required parameter: "project_id"') + + if name is None: + raise AppwriteException('Missing required parameter: "name"') + + + api_params['projectId'] = self._normalize_value(project_id) + api_params['name'] = self._normalize_value(name) + if region is not None: + api_params['region'] = self._normalize_value(region) + + response = self.client.call('post', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=Project) + + + def get_project( + self, + project_id: str + ) -> Project: + """ + Get a project. + + Parameters + ---------- + project_id : str + Project unique ID. + + Returns + ------- + Project + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/projects/{projectId}' + api_params = {} + if project_id is None: + raise AppwriteException('Missing required parameter: "project_id"') + + api_path = api_path.replace('{projectId}', str(self._normalize_value(project_id))) + + + response = self.client.call('get', api_path, { + }, api_params) + + return self._parse_response(response, model=Project) + + + def update_project( + self, + project_id: str, + name: str + ) -> Project: + """ + Update a project by its unique ID. + + Parameters + ---------- + project_id : str + Project unique ID. + name : str + Project name. Max length: 128 chars. + + Returns + ------- + Project + API response as a typed Pydantic model + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/projects/{projectId}' + api_params = {} + if project_id is None: + raise AppwriteException('Missing required parameter: "project_id"') + + if name is None: + raise AppwriteException('Missing required parameter: "name"') + + api_path = api_path.replace('{projectId}', str(self._normalize_value(project_id))) + + api_params['name'] = self._normalize_value(name) + + response = self.client.call('patch', api_path, { + 'content-type': 'application/json', + }, api_params) + + return self._parse_response(response, model=Project) + + + def delete_project( + self, + project_id: str + ) -> Dict[str, Any]: + """ + Delete a project by its unique ID. + + Parameters + ---------- + project_id : str + Project unique ID. + + Returns + ------- + Dict[str, Any] + API response as a dictionary + + Raises + ------ + AppwriteException + If API request fails + """ + + api_path = '/organization/projects/{projectId}' + api_params = {} + if project_id is None: + raise AppwriteException('Missing required parameter: "project_id"') + + api_path = api_path.replace('{projectId}', str(self._normalize_value(project_id))) + + + response = self.client.call('delete', api_path, { + 'content-type': 'application/json', + }, api_params) + + return response + diff --git a/appwrite/services/presences.py b/appwrite/services/presences.py index cb57e3b5..883d0be3 100644 --- a/appwrite/services/presences.py +++ b/appwrite/services/presences.py @@ -1,12 +1,10 @@ from ..service import Service -from typing import Any, Dict, List, Optional, Union, Type, TypeVar +from typing import Any, Dict, List, Optional, Union 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: @@ -16,9 +14,8 @@ def list( self, queries: Optional[List[str]] = None, total: Optional[bool] = None, - ttl: Optional[float] = None, - model_type: Type[T] = dict - ) -> PresenceList[T]: + ttl: Optional[float] = None + ) -> PresenceList: """ List presence logs. Expired entries are filtered out automatically. @@ -32,12 +29,9 @@ def list( 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] + PresenceList API response as a typed Pydantic model Raises @@ -59,14 +53,13 @@ def list( response = self.client.call('get', api_path, { }, api_params) - return PresenceList.with_data(response, model_type) + return self._parse_response(response, model=PresenceList) def get( self, - presence_id: str, - model_type: Type[T] = dict - ) -> Presence[T]: + presence_id: str + ) -> Presence: """ Get a presence log by its unique ID. Entries whose `expiresAt` is in the past are treated as not found. @@ -76,12 +69,9 @@ def get( 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] + Presence API response as a typed Pydantic model Raises @@ -101,7 +91,7 @@ def get( response = self.client.call('get', api_path, { }, api_params) - return Presence.with_data(response, model_type) + return self._parse_response(response, model=Presence) def upsert( @@ -111,9 +101,8 @@ def upsert( 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]: + metadata: Optional[Dict[str, Any]] = None + ) -> Presence: """ Create or update a presence log by its user ID. @@ -133,12 +122,9 @@ def upsert( 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] + Presence API response as a typed Pydantic model Raises @@ -173,10 +159,10 @@ def upsert( 'content-type': 'application/json', }, api_params) - return Presence.with_data(response, model_type) + return self._parse_response(response, model=Presence) - def update_presence( + def update( self, presence_id: str, user_id: str, @@ -184,9 +170,8 @@ def update_presence( 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]: + purge: Optional[bool] = None + ) -> Presence: """ Update a presence log by its unique ID. Using the patch method you can pass only specific fields that will get updated. @@ -208,12 +193,9 @@ def update_presence( 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] + Presence API response as a typed Pydantic model Raises @@ -248,7 +230,7 @@ def update_presence( 'content-type': 'application/json', }, api_params) - return Presence.with_data(response, model_type) + return self._parse_response(response, model=Presence) def delete( diff --git a/appwrite/services/project.py b/appwrite/services/project.py index 13d43259..1201226f 100644 --- a/appwrite/services/project.py +++ b/appwrite/services/project.py @@ -70,6 +70,9 @@ from ..models.policy_session_limit import PolicySessionLimit from ..models.policy_user_limit import PolicyUserLimit from ..models.policy_membership_privacy import PolicyMembershipPrivacy +from ..models.policy_deny_aliased_email import PolicyDenyAliasedEmail +from ..models.policy_deny_disposable_email import PolicyDenyDisposableEmail +from ..models.policy_deny_free_email import PolicyDenyFreeEmail from ..enums.project_protocol_id import ProjectProtocolId from ..enums.project_service_id import ProjectServiceId from ..enums.project_smtp_secure import ProjectSMTPSecure @@ -756,7 +759,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: 79ffe4000000000000000000000000000000000000000000000000000002de55 + 'Client Secret' of Amazon OAuth2 app. For example: your-oauth2-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. @@ -851,7 +854,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: zXz0000-00000000000000000000000000000-00000000000000000000PJafnF + 'Client Secret' of Auth0 OAuth2 app. For example: your-oauth2-client-secret endpoint : Optional[str] Domain of Auth0 instance. For example: example.us.auth0.com enabled : Optional[bool] @@ -898,7 +901,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: ntQadq000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Hp5WK + 'Client Secret' of Authentik OAuth2 app. For example: your-oauth2-client-secret endpoint : Optional[str] Domain of Authentik instance. For example: example.authentik.com enabled : Optional[bool] @@ -944,7 +947,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: 7I000000000000MW + 'Client Secret' of Autodesk OAuth2 app. For example: your-oauth2-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. @@ -987,7 +990,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: NMfLZJ00000000000000000000TLQdDx + 'Secret' of Bitbucket OAuth2 app. For example: your-oauth2-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. @@ -1030,7 +1033,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: a13e250000000000000000000000000000d73095 + 'Client Secret' of Bitly OAuth2 app. For example: your-oauth2-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. @@ -1073,7 +1076,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: OKM1f100000000000000000000eshEif + 'Client Secret' of Box OAuth2 app. For example: your-oauth2-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. @@ -1116,7 +1119,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: a399a90000000000000000000000000000d90639 + 'API Secret' of Dailymotion OAuth2 app. For example: your-oauth2-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. @@ -1159,7 +1162,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: YmPXnM000000000000000000002zFg5D + 'Client Secret' of Discord OAuth2 app. For example: your-oauth2-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. @@ -1202,7 +1205,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: W7Bykj00000000000000000000000000000000000000000000000000003o43w9 + 'Secret Key, also known as API Secret' of Disqus OAuth2 app. For example: your-oauth2-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. @@ -1245,7 +1248,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: g200000000000vw + 'App Secret' of Dropbox OAuth2 app. For example: your-oauth2-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. @@ -1288,7 +1291,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: tp000000ru + 'Shared Secret' of Etsy OAuth2 app. For example: your-oauth2-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. @@ -1331,7 +1334,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: 2d0b2800000000000000000000d38af4 + 'App Secret' of Facebook OAuth2 app. For example: your-oauth2-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. @@ -1374,7 +1377,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: yEpOYn0000000000000000004iIsU5 + 'Client Secret' of Figma OAuth2 app. For example: your-oauth2-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. @@ -1418,7 +1421,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: Jx4s0C0000000000000000000000000000000wGqLsc + 'Client Secret' of FusionAuth OAuth2 app. For example: your-oauth2-client-secret endpoint : Optional[str] Domain of FusionAuth instance. For example: example.fusionauth.io enabled : Optional[bool] @@ -1464,7 +1467,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: 5e07c00000000000000000000000000000198bcc + 'Client Secret' of GitHub OAuth2 app. For example: your-oauth2-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. @@ -1508,7 +1511,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: gloas-838cfa0000000000000000000000000000000000000000000000000000ecbb38 + 'Secret' of Gitlab OAuth2 app. For example: your-oauth2-client-secret endpoint : Optional[str] Endpoint URL of self-hosted GitLab instance. For example: https://gitlab.com enabled : Optional[bool] @@ -1555,7 +1558,7 @@ 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: example-google-client-secret + 'Client Secret' of Google OAuth2 app. For example: your-oauth2-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] @@ -1603,7 +1606,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: jdjrJd00000000000000000000HUsaZO + 'Client Secret' of Keycloak OAuth2 app. For example: your-oauth2-client-secret endpoint : Optional[str] Domain of Keycloak instance. For example: keycloak.example.com realm_name : Optional[str] @@ -1652,7 +1655,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: 34ac5600000000000000000000000000000000000000000000000000e830c8b + 'Client Secret' of Kick OAuth2 app. For example: your-oauth2-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. @@ -1695,7 +1698,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: example-linkedin-client-secret + 'Primary Client Secret or Secondary Client Secret' of Linkedin OAuth2 app. For example: your-oauth2-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. @@ -1739,7 +1742,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: A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u + 'Entra ID Application Secret, also known as Client Secret' of Microsoft OAuth2 app. For example: your-oauth2-client-secret tenant : Optional[str] Microsoft Entra ID tenant identifier. Use 'common', 'organizations', 'consumers' or a specific tenant ID. For example: common enabled : Optional[bool] @@ -1785,7 +1788,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: secret_dLUr4b000000000000000000000000000000lFHAa9 + 'OAuth Client Secret' of Notion OAuth2 app. For example: your-oauth2-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. @@ -1832,7 +1835,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: Ah68ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003qpcHV + 'Client Secret' of Oidc OAuth2 app. For example: your-oauth2-client-secret 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] @@ -1889,7 +1892,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: Kiq0000000000000000000000000000000000000-00000000000H2L5-3SJ-vRV + 'Client Secret' of Okta OAuth2 app. For example: your-oauth2-client-secret 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] @@ -1938,7 +1941,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: EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp + 'Secret Key 1 or Secret Key 2' of Paypal OAuth2 app. For example: your-oauth2-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. @@ -1981,7 +1984,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: EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp + 'Secret Key 1 or Secret Key 2' of PaypalSandbox OAuth2 app. For example: your-oauth2-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. @@ -2024,7 +2027,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: Rn247T0000000000000000000000000000000000000000000000000000W2zWTN + 'Client Secret' of Podio OAuth2 app. For example: your-oauth2-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. @@ -2067,7 +2070,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: 3w000000000000e2 + 'Consumer Secret' of Salesforce OAuth2 app. For example: your-oauth2-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. @@ -2110,7 +2113,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: 81656000000000000000000000f3d2fd + 'Client Secret' of Slack OAuth2 app. For example: your-oauth2-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. @@ -2153,7 +2156,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: db068a000000000000000000008b5b9f + 'Client Secret' of Spotify OAuth2 app. For example: your-oauth2-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. @@ -2196,7 +2199,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: sk_51SfOd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000QGWYfp + 'API Secret Key' of Stripe OAuth2 app. For example: your-oauth2-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. @@ -2239,7 +2242,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: 7cb52700-0000-0000-0000-000000ca5b83 + 'OAuth2 Client Secret' of Tradeshift OAuth2 app. For example: your-oauth2-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. @@ -2282,7 +2285,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: 7cb52700-0000-0000-0000-000000ca5b83 + 'OAuth2 Client Secret' of Tradeshift Sandbox OAuth2 app. For example: your-oauth2-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. @@ -2325,7 +2328,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: pmapue000000000000000000zylw3v + 'Client Secret' of Twitch OAuth2 app. For example: your-oauth2-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. @@ -2368,7 +2371,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: PlBfJS0000000000000000000000000000000000000000000000000000EdUZJk + 'Client Secret' of WordPress OAuth2 app. For example: your-oauth2-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. @@ -2411,7 +2414,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: tkEPkp00000000000000000000000000000000000000FTxbI9 + 'Secret Key' of X OAuth2 app. For example: your-oauth2-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. @@ -2454,7 +2457,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: cf978f0000000000000000000000000000c5e2e9 + 'Client Secret, also known as Customer Secret' of Yahoo OAuth2 app. For example: your-oauth2-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. @@ -2497,7 +2500,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: bbf98500000000000000000000c75a63 + 'Client Secret' of Yandex OAuth2 app. For example: your-oauth2-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. @@ -2540,7 +2543,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: fb5cac000000000000000000000000000000a68f6e + 'Client Secret' of Zoho OAuth2 app. For example: your-oauth2-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. @@ -2583,7 +2586,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: GAWsG4000000000000000000007U01ON + 'Client Secret' of Zoom OAuth2 app. For example: your-oauth2-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. @@ -3933,18 +3936,18 @@ def update_user_limit_policy( def get_policy( self, policy_id: ProjectPolicyId - ) -> Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy]: + ) -> Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy, PolicyDenyAliasedEmail, PolicyDenyDisposableEmail, PolicyDenyFreeEmail]: """ Get a policy by its unique ID. This endpoint returns the current configuration for the requested project policy. Parameters ---------- 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. + 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, deny-aliased-email, deny-disposable-email, deny-free-email. Returns ------- - Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy] + Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy, PolicyDenyAliasedEmail, PolicyDenyDisposableEmail, PolicyDenyFreeEmail] API response as one of the typed response models Raises @@ -3993,6 +3996,15 @@ def get_policy( if response.get('$id') == 'membership-privacy': return self._parse_response(response, model=PolicyMembershipPrivacy) + if response.get('$id') == 'deny-aliased-email': + return self._parse_response(response, model=PolicyDenyAliasedEmail) + + if response.get('$id') == 'deny-disposable-email': + return self._parse_response(response, model=PolicyDenyDisposableEmail) + + if response.get('$id') == 'deny-free-email': + return self._parse_response(response, model=PolicyDenyFreeEmail) + raise AppwriteException('Unable to match response to any known model') @@ -4109,17 +4121,17 @@ def update_smtp( port : Optional[float] SMTP server port username : Optional[str] - SMTP server username. Leave empty for no authorization. + SMTP server username. Pass an empty string to clear a previously set value. password : Optional[str] - SMTP server password. Leave empty for no authorization. This property is stored securely and cannot be read in future (write-only). + SMTP server password. Pass an empty string to clear a previously set value. This property is stored securely and cannot be read in future (write-only). sender_email : Optional[str] - Email address shown in inbox as the sender of the email. + Email address shown in inbox as the sender of the email. Pass an empty string to clear a previously set value. sender_name : Optional[str] - Name shown in inbox as the sender of the email. + Name shown in inbox as the sender of the email. Pass an empty string to clear a previously set value. reply_to_email : Optional[str] - Email used when user replies to the email. + Email used when user replies to the email. Pass an empty string to clear a previously set value. reply_to_name : Optional[str] - Name used when user replies to the email. + Name used when user replies to the email. Pass an empty string to clear a previously set value. secure : Optional[ProjectSMTPSecure] Configures if communication with SMTP server is encrypted. Allowed values are: tls, ssl. Leave empty for no encryption. enabled : Optional[bool] @@ -4262,9 +4274,9 @@ def update_email_template( sender_name : Optional[str] Name of the email sender. sender_email : Optional[str] - Email of the sender. + Email of the sender. Pass an empty string to clear a previously set value. reply_to_email : Optional[str] - Reply to email. + Reply to email. Pass an empty string to clear a previously set value. reply_to_name : Optional[str] Reply to name. diff --git a/appwrite/services/sites.py b/appwrite/services/sites.py index 5f755625..17eacc79 100644 --- a/appwrite/services/sites.py +++ b/appwrite/services/sites.py @@ -90,6 +90,8 @@ def create( provider_branch: Optional[str] = None, provider_silent_mode: Optional[bool] = None, provider_root_directory: Optional[str] = None, + provider_branches: Optional[List[str]] = None, + provider_paths: Optional[List[str]] = None, build_specification: Optional[str] = None, runtime_specification: Optional[str] = None, deployment_retention: Optional[float] = None @@ -135,6 +137,10 @@ def create( Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests. provider_root_directory : Optional[str] Path to site code in the linked repo. + provider_branches : Optional[List[str]] + List of branch name patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all branches. + provider_paths : Optional[List[str]] + List of file path patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all file changes. build_specification : Optional[str] Build specification for the site deployments. runtime_specification : Optional[str] @@ -200,6 +206,10 @@ def create( api_params['providerSilentMode'] = self._normalize_value(provider_silent_mode) if provider_root_directory is not None: api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) + if provider_branches is not None: + api_params['providerBranches'] = self._normalize_value(provider_branches) + if provider_paths is not None: + api_params['providerPaths'] = self._normalize_value(provider_paths) if build_specification is not None: api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: @@ -323,6 +333,8 @@ def update( provider_branch: Optional[str] = None, provider_silent_mode: Optional[bool] = None, provider_root_directory: Optional[str] = None, + provider_branches: Optional[List[str]] = None, + provider_paths: Optional[List[str]] = None, build_specification: Optional[str] = None, runtime_specification: Optional[str] = None, deployment_retention: Optional[float] = None @@ -368,6 +380,10 @@ def update( Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests. provider_root_directory : Optional[str] Path to site code in the linked repo. + provider_branches : Optional[List[str]] + List of branch name patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all branches. + provider_paths : Optional[List[str]] + List of file path patterns to trigger automatic deployments. Supports wildcards. Leave empty to deploy on all file changes. build_specification : Optional[str] Build specification for the site deployments. runtime_specification : Optional[str] @@ -431,6 +447,8 @@ def update( api_params['providerSilentMode'] = self._normalize_value(provider_silent_mode) if provider_root_directory is not None: api_params['providerRootDirectory'] = self._normalize_value(provider_root_directory) + api_params['providerBranches'] = self._normalize_value(provider_branches) + api_params['providerPaths'] = self._normalize_value(provider_paths) if build_specification is not None: api_params['buildSpecification'] = self._normalize_value(build_specification) if runtime_specification is not None: diff --git a/appwrite/services/usage.py b/appwrite/services/usage.py index 8ff96911..3f3eb308 100644 --- a/appwrite/services/usage.py +++ b/appwrite/services/usage.py @@ -56,7 +56,7 @@ def list_gauges( 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. + Query usage gauge metrics (point-in-time resource snapshots) from the usage database. Returns individual gauge snapshots with metric, value, timestamp, resourceType, and resourceId. 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 ---------- diff --git a/docs/examples/avatars/get-screenshot.md b/docs/examples/avatars/get-screenshot.md index 60803279..cf7f9a6b 100644 --- a/docs/examples/avatars/get-screenshot.md +++ b/docs/examples/avatars/get-screenshot.md @@ -1,7 +1,7 @@ ```python from appwrite.client import Client from appwrite.services.avatars import Avatars -from appwrite.enums import Theme +from appwrite.enums import BrowserTheme from appwrite.enums import Timezone from appwrite.enums import BrowserPermission from appwrite.enums import ImageFormat @@ -22,11 +22,11 @@ result: bytes = avatars.get_screenshot( viewport_width = 1920, # optional viewport_height = 1080, # optional scale = 2, # optional - theme = Theme.DARK, # optional + theme = BrowserTheme.DARK, # optional user_agent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', # optional fullpage = True, # optional locale = 'en-US', # optional - timezone = Timezone.AMERICA_NEW_YORK, # optional + timezone = Timezone.AFRICA_ABIDJAN, # optional latitude = 37.7749, # optional longitude = -122.4194, # optional accuracy = 100, # optional diff --git a/docs/examples/functions/create.md b/docs/examples/functions/create.md index fdded0ed..1c6c3854 100644 --- a/docs/examples/functions/create.md +++ b/docs/examples/functions/create.md @@ -3,7 +3,7 @@ from appwrite.client import Client from appwrite.services.functions import Functions from appwrite.models import Function from appwrite.enums import Runtime -from appwrite.enums import Scopes +from appwrite.enums import ProjectKeyScopes client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -24,12 +24,14 @@ result: Function = functions.create( logging = False, # optional entrypoint = '', # optional commands = '', # optional - scopes = [Scopes.PROJECT_READ], # optional + scopes = [ProjectKeyScopes.PROJECT_READ], # optional installation_id = '', # optional provider_repository_id = '', # optional provider_branch = '', # optional provider_silent_mode = False, # optional provider_root_directory = '', # optional + provider_branches = [], # optional + provider_paths = [], # optional build_specification = '', # optional runtime_specification = '', # optional deployment_retention = 0 # optional diff --git a/docs/examples/functions/update.md b/docs/examples/functions/update.md index ab634e5e..c7b1393a 100644 --- a/docs/examples/functions/update.md +++ b/docs/examples/functions/update.md @@ -3,7 +3,7 @@ from appwrite.client import Client from appwrite.services.functions import Functions from appwrite.models import Function from appwrite.enums import Runtime -from appwrite.enums import Scopes +from appwrite.enums import ProjectKeyScopes client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -24,12 +24,14 @@ result: Function = functions.update( logging = False, # optional entrypoint = '', # optional commands = '', # optional - scopes = [Scopes.PROJECT_READ], # optional + scopes = [ProjectKeyScopes.PROJECT_READ], # optional installation_id = '', # optional provider_repository_id = '', # optional provider_branch = '', # optional provider_silent_mode = False, # optional provider_root_directory = '', # optional + provider_branches = [], # optional + provider_paths = [], # optional build_specification = '', # optional runtime_specification = '', # optional deployment_retention = 0 # optional diff --git a/docs/examples/health/get-failed-jobs.md b/docs/examples/health/get-failed-jobs.md index 9815c246..da08c619 100644 --- a/docs/examples/health/get-failed-jobs.md +++ b/docs/examples/health/get-failed-jobs.md @@ -2,7 +2,7 @@ from appwrite.client import Client from appwrite.services.health import Health from appwrite.models import HealthQueue -from appwrite.enums import Name +from appwrite.enums import HealthQueueName client = Client() client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint @@ -12,7 +12,7 @@ client.set_key('') # Your secret API key health = Health(client) result: HealthQueue = health.get_failed_jobs( - name = Name.V1_DATABASE, + name = HealthQueueName.V1_DATABASE, threshold = None # optional ) diff --git a/docs/examples/organization/create-key.md b/docs/examples/organization/create-key.md new file mode 100644 index 00000000..14fee9a7 --- /dev/null +++ b/docs/examples/organization/create-key.md @@ -0,0 +1,22 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Key +from appwrite.enums import OrganizationKeyScopes + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: Key = organization.create_key( + key_id = '', + name = '', + scopes = [OrganizationKeyScopes.PROJECTS_READ], + expire = '2020-10-15T06:38:00.000+00:00' # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/create-project.md b/docs/examples/organization/create-project.md new file mode 100644 index 00000000..61e03e46 --- /dev/null +++ b/docs/examples/organization/create-project.md @@ -0,0 +1,21 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Project +from appwrite.enums import Region + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: Project = organization.create_project( + project_id = '', + name = '', + region = Region.FRA # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/delete-key.md b/docs/examples/organization/delete-key.md new file mode 100644 index 00000000..6e48d845 --- /dev/null +++ b/docs/examples/organization/delete-key.md @@ -0,0 +1,15 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result = organization.delete_key( + key_id = '' +) +``` diff --git a/docs/examples/organization/delete-project.md b/docs/examples/organization/delete-project.md new file mode 100644 index 00000000..024c03e8 --- /dev/null +++ b/docs/examples/organization/delete-project.md @@ -0,0 +1,15 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result = organization.delete_project( + project_id = '' +) +``` diff --git a/docs/examples/organization/get-key.md b/docs/examples/organization/get-key.md new file mode 100644 index 00000000..d60f1190 --- /dev/null +++ b/docs/examples/organization/get-key.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Key + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: Key = organization.get_key( + key_id = '' +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/get-project.md b/docs/examples/organization/get-project.md new file mode 100644 index 00000000..f0d74fd1 --- /dev/null +++ b/docs/examples/organization/get-project.md @@ -0,0 +1,18 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: Project = organization.get_project( + project_id = '' +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/list-keys.md b/docs/examples/organization/list-keys.md new file mode 100644 index 00000000..41634a0e --- /dev/null +++ b/docs/examples/organization/list-keys.md @@ -0,0 +1,19 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import KeyList + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: KeyList = organization.list_keys( + queries = [], # optional + total = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/list-projects.md b/docs/examples/organization/list-projects.md new file mode 100644 index 00000000..42b902ea --- /dev/null +++ b/docs/examples/organization/list-projects.md @@ -0,0 +1,20 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import ProjectList + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: ProjectList = organization.list_projects( + queries = [], # optional + search = '', # optional + total = False # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/update-key.md b/docs/examples/organization/update-key.md new file mode 100644 index 00000000..2c32078b --- /dev/null +++ b/docs/examples/organization/update-key.md @@ -0,0 +1,22 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Key +from appwrite.enums import OrganizationKeyScopes + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: Key = organization.update_key( + key_id = '', + name = '', + scopes = [OrganizationKeyScopes.PROJECTS_READ], + expire = '2020-10-15T06:38:00.000+00:00' # optional +) + +print(result.model_dump()) +``` diff --git a/docs/examples/organization/update-project.md b/docs/examples/organization/update-project.md new file mode 100644 index 00000000..c14fd0cc --- /dev/null +++ b/docs/examples/organization/update-project.md @@ -0,0 +1,19 @@ +```python +from appwrite.client import Client +from appwrite.services.organization import Organization +from appwrite.models import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +organization = Organization(client) + +result: Project = organization.update_project( + project_id = '', + name = '' +) + +print(result.model_dump()) +``` diff --git a/docs/examples/presences/update-presence.md b/docs/examples/presences/update.md similarity index 94% rename from docs/examples/presences/update-presence.md rename to docs/examples/presences/update.md index ea7a7c58..fd3a9ef0 100644 --- a/docs/examples/presences/update-presence.md +++ b/docs/examples/presences/update.md @@ -12,7 +12,7 @@ client.set_key('') # Your secret API key presences = Presences(client) -result: Presence = presences.update_presence( +result: Presence = presences.update( presence_id = '', user_id = '', status = '', # optional diff --git a/docs/examples/project/get-policy.md b/docs/examples/project/get-policy.md index e05516f8..4ab04c3c 100644 --- a/docs/examples/project/get-policy.md +++ b/docs/examples/project/get-policy.md @@ -10,6 +10,9 @@ from appwrite.models import PolicySessionInvalidation from appwrite.models import PolicySessionLimit from appwrite.models import PolicyUserLimit from appwrite.models import PolicyMembershipPrivacy +from appwrite.models import PolicyDenyAliasedEmail +from appwrite.models import PolicyDenyDisposableEmail +from appwrite.models import PolicyDenyFreeEmail from typing import Union from appwrite.enums import ProjectPolicyId @@ -20,7 +23,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( +result: Union[PolicyPasswordDictionary, PolicyPasswordHistory, PolicyPasswordPersonalData, PolicySessionAlert, PolicySessionDuration, PolicySessionInvalidation, PolicySessionLimit, PolicyUserLimit, PolicyMembershipPrivacy, PolicyDenyAliasedEmail, PolicyDenyDisposableEmail, PolicyDenyFreeEmail] = project.get_policy( policy_id = ProjectPolicyId.PASSWORD_DICTIONARY ) diff --git a/docs/examples/proxy/create-redirect-rule.md b/docs/examples/proxy/create-redirect-rule.md index 4da7b6c9..6014fbed 100644 --- a/docs/examples/proxy/create-redirect-rule.md +++ b/docs/examples/proxy/create-redirect-rule.md @@ -15,7 +15,7 @@ proxy = Proxy(client) result: ProxyRule = proxy.create_redirect_rule( domain = '', url = 'https://example.com', - status_code = StatusCode.MOVED_PERMANENTLY_301, + status_code = StatusCode.MOVEDPERMANENTLY, resource_id = '', resource_type = ProxyResourceType.SITE ) diff --git a/docs/examples/sites/create.md b/docs/examples/sites/create.md index 9fa508a1..684cd054 100644 --- a/docs/examples/sites/create.md +++ b/docs/examples/sites/create.md @@ -32,6 +32,8 @@ result: Site = sites.create( provider_branch = '', # optional provider_silent_mode = False, # optional provider_root_directory = '', # optional + provider_branches = [], # optional + provider_paths = [], # optional build_specification = '', # optional runtime_specification = '', # optional deployment_retention = 0 # optional diff --git a/docs/examples/sites/update.md b/docs/examples/sites/update.md index 3ce49756..2c917b9f 100644 --- a/docs/examples/sites/update.md +++ b/docs/examples/sites/update.md @@ -32,6 +32,8 @@ result: Site = sites.update( provider_branch = '', # optional provider_silent_mode = False, # optional provider_root_directory = '', # optional + provider_branches = [], # optional + provider_paths = [], # optional build_specification = '', # optional runtime_specification = '', # optional deployment_retention = 0 # optional diff --git a/pyproject.toml b/pyproject.toml index acda430a..7e61f375 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "appwrite" -version = "19.2.0" +version = "20.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 b9f2f734..71980fb1 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name = 'appwrite', packages = setuptools.find_packages(), - version = '19.2.0', + version = '20.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/19.2.0.tar.gz', + download_url='https://github.com/appwrite/sdk-for-python/archive/20.0.0.tar.gz', install_requires=[ 'requests', 'pydantic>=2,<3', diff --git a/test/services/test_activities.py b/test/services/test_activities.py index 2ab995d7..a96b831f 100644 --- a/test/services/test_activities.py +++ b/test/services/test_activities.py @@ -31,10 +31,10 @@ def test_list_events(self, m): def test_get_event(self, m): data = { "$id": "5e5ea5c16897e", - "userType": "user", - "userId": "610fc2f985ee0", - "userEmail": "john@appwrite.io", - "userName": "John Doe", + "actorType": "user", + "actorId": "610fc2f985ee0", + "actorEmail": "john@appwrite.io", + "actorName": "John Doe", "resourceParent": "database\/ID", "resourceType": "collection", "resourceId": "610fc2f985ee0", diff --git a/test/services/test_functions.py b/test/services/test_functions.py index 04fc26cb..411d41e1 100644 --- a/test/services/test_functions.py +++ b/test/services/test_functions.py @@ -58,6 +58,8 @@ def test_create(self, m): "providerBranch": "main", "providerRootDirectory": "functions\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb" } @@ -131,6 +133,8 @@ def test_get(self, m): "providerBranch": "main", "providerRootDirectory": "functions\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb" } @@ -174,6 +178,8 @@ def test_update(self, m): "providerBranch": "main", "providerRootDirectory": "functions\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb" } @@ -230,6 +236,8 @@ def test_update_function_deployment(self, m): "providerBranch": "main", "providerRootDirectory": "functions\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb" } diff --git a/test/services/test_organization.py b/test/services/test_organization.py new file mode 100644 index 00000000..71bdc4b0 --- /dev/null +++ b/test/services/test_organization.py @@ -0,0 +1,256 @@ +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.organization import Organization + +class OrganizationServiceTest(unittest.TestCase): + + def setUp(self): + self.client = Client() + self.organization = Organization(self.client) + + @requests_mock.Mocker() + def test_list_keys(self, m): + data = { + "total": 5.0, + "keys": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.list_keys( + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_create_key(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "My API Key", + "expire": "2020-10-15T06:38:00.000+00:00", + "scopes": [], + "secret": "919c2d18fb5d4...a2ae413da83346ad2", + "accessedAt": "2020-10-15T06:38:00.000+00:00", + "sdks": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.create_key( + '', + '', + [], + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_get_key(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "My API Key", + "expire": "2020-10-15T06:38:00.000+00:00", + "scopes": [], + "secret": "919c2d18fb5d4...a2ae413da83346ad2", + "accessedAt": "2020-10-15T06:38:00.000+00:00", + "sdks": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.get_key( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update_key(self, m): + data = { + "$id": "5e5ea5c16897e", + "$createdAt": "2020-10-15T06:38:00.000+00:00", + "$updatedAt": "2020-10-15T06:38:00.000+00:00", + "name": "My API Key", + "expire": "2020-10-15T06:38:00.000+00:00", + "scopes": [], + "secret": "919c2d18fb5d4...a2ae413da83346ad2", + "accessedAt": "2020-10-15T06:38:00.000+00:00", + "sdks": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.update_key( + '', + '', + [], + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_delete_key(self, m): + data = '' + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.delete_key( + '', + ) + + self.assertEqual(response, data) + + @requests_mock.Mocker() + def test_list_projects(self, m): + data = { + "total": 5.0, + "projects": [] +} + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.list_projects( + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_create_project(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", + "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.organization.create_project( + '', + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_get_project(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", + "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.organization.get_project( + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_update_project(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", + "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.organization.update_project( + '', + '', + ) + + self.assertEqual(response.to_dict(), data) + + @requests_mock.Mocker() + def test_delete_project(self, m): + data = '' + headers = {'Content-Type': 'application/json'} + m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) + + response = self.organization.delete_project( + '', + ) + + self.assertEqual(response, data) + diff --git a/test/services/test_presences.py b/test/services/test_presences.py index 3665339f..c5b3189a 100644 --- a/test/services/test_presences.py +++ b/test/services/test_presences.py @@ -68,7 +68,7 @@ def test_upsert(self, m): self.assertEqual(response.to_dict(), data) @requests_mock.Mocker() - def test_update_presence(self, m): + def test_update(self, m): data = { "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", @@ -80,7 +80,7 @@ def test_update_presence(self, m): headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) - response = self.presences.update_presence( + response = self.presences.update( '', '', ) diff --git a/test/services/test_project.py b/test/services/test_project.py index 24162713..1dadabfa 100644 --- a/test/services/test_project.py +++ b/test/services/test_project.py @@ -359,7 +359,7 @@ def test_update_o_auth2_amazon(self, m): "$id": "github", "enabled": True, "clientId": "amzn1.application-oa2-client.87400c00000000000000000000063d5b2", - "clientSecret": "79ffe4000000000000000000000000000000000000000000000000000002de55" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -393,7 +393,7 @@ def test_update_o_auth2_auth0(self, m): "$id": "github", "enabled": True, "clientId": "OaOkIA000000000000000000005KLSYq", - "clientSecret": "zXz0000-00000000000000000000000000000-00000000000000000000PJafnF", + "clientSecret": "your-oauth2-client-secret", "endpoint": "example.us.auth0.com" } headers = {'Content-Type': 'application/json'} @@ -410,7 +410,7 @@ def test_update_o_auth2_authentik(self, m): "$id": "github", "enabled": True, "clientId": "dTKOPa0000000000000000000000000000e7G8hv", - "clientSecret": "ntQadq000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Hp5WK", + "clientSecret": "your-oauth2-client-secret", "endpoint": "example.authentik.com" } headers = {'Content-Type': 'application/json'} @@ -427,7 +427,7 @@ def test_update_o_auth2_autodesk(self, m): "$id": "github", "enabled": True, "clientId": "5zw90v00000000000000000000kVYXN7", - "clientSecret": "7I000000000000MW" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -443,7 +443,7 @@ def test_update_o_auth2_bitbucket(self, m): "$id": "github", "enabled": True, "key": "Knt70000000000ByRc", - "secret": "NMfLZJ00000000000000000000TLQdDx" + "secret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -459,7 +459,7 @@ def test_update_o_auth2_bitly(self, m): "$id": "github", "enabled": True, "clientId": "d95151000000000000000000000000000067af9b", - "clientSecret": "a13e250000000000000000000000000000d73095" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -475,7 +475,7 @@ def test_update_o_auth2_box(self, m): "$id": "github", "enabled": True, "clientId": "deglcs00000000000000000000x2og6y", - "clientSecret": "OKM1f100000000000000000000eshEif" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -491,7 +491,7 @@ def test_update_o_auth2_dailymotion(self, m): "$id": "github", "enabled": True, "apiKey": "07a9000000000000067f", - "apiSecret": "a399a90000000000000000000000000000d90639" + "apiSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -507,7 +507,7 @@ def test_update_o_auth2_discord(self, m): "$id": "github", "enabled": True, "clientId": "950722000000343754", - "clientSecret": "YmPXnM000000000000000000002zFg5D" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -523,7 +523,7 @@ def test_update_o_auth2_disqus(self, m): "$id": "github", "enabled": True, "publicKey": "cgegH70000000000000000000000000000000000000000000000000000Hr1nYX", - "secretKey": "W7Bykj00000000000000000000000000000000000000000000000000003o43w9" + "secretKey": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -539,7 +539,7 @@ def test_update_o_auth2_dropbox(self, m): "$id": "github", "enabled": True, "appKey": "jl000000000009t", - "appSecret": "g200000000000vw" + "appSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -555,7 +555,7 @@ def test_update_o_auth2_etsy(self, m): "$id": "github", "enabled": True, "keyString": "nsgzxh0000000000008j85a2", - "sharedSecret": "tp000000ru" + "sharedSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -571,7 +571,7 @@ def test_update_o_auth2_facebook(self, m): "$id": "github", "enabled": True, "appId": "260600000007694", - "appSecret": "2d0b2800000000000000000000d38af4" + "appSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -587,7 +587,7 @@ def test_update_o_auth2_figma(self, m): "$id": "github", "enabled": True, "clientId": "byay5H0000000000VtiI40", - "clientSecret": "yEpOYn0000000000000000004iIsU5" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -603,7 +603,7 @@ def test_update_o_auth2_fusion_auth(self, m): "$id": "github", "enabled": True, "clientId": "b2222c00-0000-0000-0000-000000862097", - "clientSecret": "Jx4s0C0000000000000000000000000000000wGqLsc", + "clientSecret": "your-oauth2-client-secret", "endpoint": "example.fusionauth.io" } headers = {'Content-Type': 'application/json'} @@ -620,7 +620,7 @@ def test_update_o_auth2_git_hub(self, m): "$id": "github", "enabled": True, "clientId": "e4d87900000000540733", - "clientSecret": "5e07c00000000000000000000000000000198bcc" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -636,7 +636,7 @@ def test_update_o_auth2_gitlab(self, m): "$id": "github", "enabled": True, "applicationId": "d41ffe0000000000000000000000000000000000000000000000000000d5e252", - "secret": "gloas-838cfa0000000000000000000000000000000000000000000000000000ecbb38", + "secret": "your-oauth2-client-secret", "endpoint": "https:\/\/gitlab.com" } headers = {'Content-Type': 'application/json'} @@ -653,7 +653,7 @@ def test_update_o_auth2_google(self, m): "$id": "github", "enabled": True, "clientId": "120000000095-92ifjb00000000000000000000g7ijfb.apps.googleusercontent.com", - "clientSecret": "example-google-client-secret", + "clientSecret": "your-oauth2-client-secret", "prompt": [] } headers = {'Content-Type': 'application/json'} @@ -670,7 +670,7 @@ def test_update_o_auth2_keycloak(self, m): "$id": "github", "enabled": True, "clientId": "appwrite-o0000000st-app", - "clientSecret": "jdjrJd00000000000000000000HUsaZO", + "clientSecret": "your-oauth2-client-secret", "endpoint": "keycloak.example.com", "realmName": "appwrite-realm" } @@ -688,7 +688,7 @@ def test_update_o_auth2_kick(self, m): "$id": "github", "enabled": True, "clientId": "01KQ7C00000000000001MFHS32", - "clientSecret": "34ac5600000000000000000000000000000000000000000000000000e830c8b" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -704,7 +704,7 @@ def test_update_o_auth2_linkedin(self, m): "$id": "github", "enabled": True, "clientId": "770000000000dv", - "primaryClientSecret": "example-linkedin-client-secret" + "primaryClientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -720,7 +720,7 @@ def test_update_o_auth2_microsoft(self, m): "$id": "github", "enabled": True, "applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444", - "applicationSecret": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u", + "applicationSecret": "your-oauth2-client-secret", "tenant": "common" } headers = {'Content-Type': 'application/json'} @@ -737,7 +737,7 @@ def test_update_o_auth2_notion(self, m): "$id": "github", "enabled": True, "oauthClientId": "341d8700-0000-0000-0000-000000446ee3", - "oauthClientSecret": "secret_dLUr4b000000000000000000000000000000lFHAa9" + "oauthClientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -753,7 +753,7 @@ def test_update_o_auth2_oidc(self, m): "$id": "github", "enabled": True, "clientId": "qibI2x0000000000000000000000000006L2YFoG", - "clientSecret": "Ah68ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003qpcHV", + "clientSecret": "your-oauth2-client-secret", "wellKnownURL": "https:\/\/myoauth.com\/.well-known\/openid-configuration", "authorizationURL": "https:\/\/myoauth.com\/oauth2\/authorize", "tokenURL": "https:\/\/myoauth.com\/oauth2\/token", @@ -773,7 +773,7 @@ def test_update_o_auth2_okta(self, m): "$id": "github", "enabled": True, "clientId": "0oa00000000000000698", - "clientSecret": "Kiq0000000000000000000000000000000000000-00000000000H2L5-3SJ-vRV", + "clientSecret": "your-oauth2-client-secret", "domain": "trial-6400025.okta.com", "authorizationServerId": "aus000000000000000h7z" } @@ -791,7 +791,7 @@ def test_update_o_auth2_paypal(self, m): "$id": "github", "enabled": True, "clientId": "AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB", - "secretKey": "EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp" + "secretKey": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -807,7 +807,7 @@ def test_update_o_auth2_paypal_sandbox(self, m): "$id": "github", "enabled": True, "clientId": "AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB", - "secretKey": "EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp" + "secretKey": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -823,7 +823,7 @@ def test_update_o_auth2_podio(self, m): "$id": "github", "enabled": True, "clientId": "appwrite-oauth-test-app", - "clientSecret": "Rn247T0000000000000000000000000000000000000000000000000000W2zWTN" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -839,7 +839,7 @@ def test_update_o_auth2_salesforce(self, m): "$id": "github", "enabled": True, "customerKey": "3MVG9I0000000000000000000000000000000000000000000000000000000000000000000000000C5Aejq", - "customerSecret": "3w000000000000e2" + "customerSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -855,7 +855,7 @@ def test_update_o_auth2_slack(self, m): "$id": "github", "enabled": True, "clientId": "23000000089.15000000000023", - "clientSecret": "81656000000000000000000000f3d2fd" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -871,7 +871,7 @@ def test_update_o_auth2_spotify(self, m): "$id": "github", "enabled": True, "clientId": "6ec271000000000000000000009beace", - "clientSecret": "db068a000000000000000000008b5b9f" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -887,7 +887,7 @@ def test_update_o_auth2_stripe(self, m): "$id": "github", "enabled": True, "clientId": "ca_UKibXX0000000000000000000006byvR", - "apiSecretKey": "sk_51SfOd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000QGWYfp" + "apiSecretKey": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -903,7 +903,7 @@ def test_update_o_auth2_tradeshift(self, m): "$id": "github", "enabled": True, "oauth2ClientId": "appwrite-test-org.appwrite-test-app", - "oauth2ClientSecret": "7cb52700-0000-0000-0000-000000ca5b83" + "oauth2ClientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -919,7 +919,7 @@ def test_update_o_auth2_tradeshift_sandbox(self, m): "$id": "github", "enabled": True, "oauth2ClientId": "appwrite-test-org.appwrite-test-app", - "oauth2ClientSecret": "7cb52700-0000-0000-0000-000000ca5b83" + "oauth2ClientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -935,7 +935,7 @@ def test_update_o_auth2_twitch(self, m): "$id": "github", "enabled": True, "clientId": "vvi0in000000000000000000ikmt9p", - "clientSecret": "pmapue000000000000000000zylw3v" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -951,7 +951,7 @@ def test_update_o_auth2_word_press(self, m): "$id": "github", "enabled": True, "clientId": "130005", - "clientSecret": "PlBfJS0000000000000000000000000000000000000000000000000000EdUZJk" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -967,7 +967,7 @@ def test_update_o_auth2_x(self, m): "$id": "github", "enabled": True, "customerKey": "slzZV0000000000000NFLaWT", - "secretKey": "tkEPkp00000000000000000000000000000000000000FTxbI9" + "secretKey": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -983,7 +983,7 @@ def test_update_o_auth2_yahoo(self, m): "$id": "github", "enabled": True, "clientId": "dj0yJm000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z4PWRm", - "clientSecret": "cf978f0000000000000000000000000000c5e2e9" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -999,7 +999,7 @@ def test_update_o_auth2_yandex(self, m): "$id": "github", "enabled": True, "clientId": "6a8a6a0000000000000000000091483c", - "clientSecret": "bbf98500000000000000000000c75a63" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1015,7 +1015,7 @@ def test_update_o_auth2_zoho(self, m): "$id": "github", "enabled": True, "clientId": "1000.83C178000000000000000000RPNX0B", - "clientSecret": "fb5cac000000000000000000000000000000a68f6e" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1031,7 +1031,7 @@ def test_update_o_auth2_zoom(self, m): "$id": "github", "enabled": True, "clientId": "QMAC00000000000000w0AQ", - "clientSecret": "GAWsG4000000000000000000007U01ON" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) @@ -1047,7 +1047,7 @@ def test_get_o_auth2_provider(self, m): "$id": "github", "enabled": True, "clientId": "e4d87900000000540733", - "clientSecret": "5e07c00000000000000000000000000000198bcc" + "clientSecret": "your-oauth2-client-secret" } headers = {'Content-Type': 'application/json'} m.request(requests_mock.ANY, requests_mock.ANY, text=json.dumps(data), headers=headers) diff --git a/test/services/test_sites.py b/test/services/test_sites.py index 4f83b6f2..e514bfc3 100644 --- a/test/services/test_sites.py +++ b/test/services/test_sites.py @@ -57,6 +57,8 @@ def test_create(self, m): "providerBranch": "main", "providerRootDirectory": "sites\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb", "buildRuntime": "node-22", @@ -133,6 +135,8 @@ def test_get(self, m): "providerBranch": "main", "providerRootDirectory": "sites\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb", "buildRuntime": "node-22", @@ -178,6 +182,8 @@ def test_update(self, m): "providerBranch": "main", "providerRootDirectory": "sites\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb", "buildRuntime": "node-22", @@ -237,6 +243,8 @@ def test_update_site_deployment(self, m): "providerBranch": "main", "providerRootDirectory": "sites\/helloWorld", "providerSilentMode": True, + "providerBranches": [], + "providerPaths": [], "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb", "buildRuntime": "node-22",