Skip to content

feat: Python SDK update for version 20.0.0#147

Merged
ArnabChatterjee20k merged 2 commits into
mainfrom
dev
Jun 1, 2026
Merged

feat: Python SDK update for version 20.0.0#147
ArnabChatterjee20k merged 2 commits into
mainfrom
dev

Conversation

@ArnabChatterjee20k
Copy link
Copy Markdown
Member

@ArnabChatterjee20k ArnabChatterjee20k commented Jun 1, 2026

This PR contains updates to the Python SDK for version 20.0.0.

@ArnabChatterjee20k ArnabChatterjee20k changed the title feat: Python SDK update for version 20.0.0 feat: python SDK update for version 20.0.0 Jun 1, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 1, 2026

Greptile Summary

This PR updates the Python SDK to align with Appwrite v20.0.0, introducing a new Organization service and several breaking changes documented in the PR description.

  • New Organization service providing full CRUD for organization-level API keys (/organization/keys) and projects (/organization/projects), backed by new ProjectList, KeyList models and OrganizationKeyScopes / Region enums.
  • Breaking renames: ScopesProjectKeyScopes, ThemeBrowserTheme, NameHealthQueueName; update_presenceupdate in Presences; StatusCode members drop numeric suffixes (e.g. MOVED_PERMANENTLY_301MOVEDPERMANENTLY); ActivityEvent user-fields renamed to actor-fields.
  • New policy models (PolicyDenyAliasedEmail, PolicyDenyDisposableEmail, PolicyDenyFreeEmail) integrated into PolicyList and the get_policy discriminator chain in project.py.

Confidence Score: 5/5

Safe to merge; all functional changes align with the documented v20.0.0 API surface and breaking changes are explicitly called out in the PR description.

The new Organization service, enum renames, model field additions, and policy discriminator extensions are all consistent with the rest of the codebase's patterns. No new logic bugs were introduced beyond what was already flagged in previous review rounds. The only findings here are unused imports left over from the Generic/PrivateAttr refactoring in the Presence models and presences service.

No files require special attention beyond the three unused-import suggestions in appwrite/models/presence.py, appwrite/models/presence_list.py, and appwrite/services/presences.py.

Important Files Changed

Filename Overview
appwrite/services/organization.py New Organization service with list/create/get/update/delete for keys and projects; expire is sent unconditionally (null = unlimited by design for PUT semantics).
appwrite/services/presences.py Renamed update_presence to update (breaking change, major version); removed Generic type parameter from all methods; deprecated import is now unused.
appwrite/encoders/value_class_encoder.py Correctly renamed Theme→BrowserTheme, Name→HealthQueueName, Scopes→ProjectKeyScopes; added OrganizationKeyScopes and Region handlers.
appwrite/models/presence.py Removed Generic[T] and the typed with_data factory; metadata is now a plain Optional[Dict[str, Any]] field; PrivateAttr import is now unused.
appwrite/enums/status_code.py Breaking rename: numeric suffixes dropped (e.g., MOVED_PERMANENTLY_301 → MOVEDPERMANENTLY); documented as a breaking change for v20.0.0.
appwrite/services/project.py Added three new PolicyDeny* model imports and extended get_policy discriminator chain to handle deny-aliased-email, deny-disposable-email, and deny-free-email IDs.
appwrite/models/activity_event.py Breaking field rename: userType/userId/userEmail/userName → actorType/actorId/actorEmail/actorName to align with v20 API response shape.
appwrite/models/function.py Added required fields providerbranches and providerpaths (List[Any]) for new branch/path deployment filter feature.

Reviews (2): Last reviewed commit: "chore: merge main and resolve version co..." | Re-trigger Greptile

Comment on lines +435 to +436
api_params['providerBranches'] = self._normalize_value(provider_branches)
api_params['providerPaths'] = self._normalize_value(provider_paths)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unconditional None parameters silently clear VCS config on update

provider_branches and provider_paths are always added to api_params without a None guard, so any call to update() that omits these arguments will send None to the API. This differs from the create method, which correctly wraps these with if provider_branches is not None: guards (lines ~199–204). A PUT request sending None for both fields will erase any previously configured branch-filter and path-filter rules without the caller realising it.

Suggested change
api_params['providerBranches'] = self._normalize_value(provider_branches)
api_params['providerPaths'] = self._normalize_value(provider_paths)
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)

Comment on lines +450 to +451
api_params['providerBranches'] = self._normalize_value(provider_branches)
api_params['providerPaths'] = self._normalize_value(provider_paths)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Same unconditional None issue in sites update()

provider_branches and provider_paths are added to api_params unconditionally in the update method, mirroring the same bug found in functions.py update. Any call to sites.update() that omits these parameters will send None to the API, potentially clearing existing branch/path filter configurations. The create method (lines ~206–209) correctly guards them with if ... is not None: checks.

Suggested change
api_params['providerBranches'] = self._normalize_value(provider_branches)
api_params['providerPaths'] = self._normalize_value(provider_paths)
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)

Comment thread appwrite/client.py
Comment on lines +311 to +314
with ThreadPoolExecutor(max_workers=8) as executor:
futures = [executor.submit(upload_remaining_chunk, chunk) for chunk in chunks[1:]]
for future in as_completed(futures):
future.result()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Parallel chunk upload: no cancellation on partial failure

Chunks 1..N are dispatched concurrently via ThreadPoolExecutor(max_workers=8). If any chunk raises (network error, server 5xx), its future.result() re-raises but the executor continues running all other already-submitted futures — there is no cancellation. The caller receives the exception only after all in-flight chunks have completed, wasting bandwidth and leaving the upload in an ambiguous state.

@ArnabChatterjee20k ArnabChatterjee20k changed the title feat: python SDK update for version 20.0.0 feat: Python SDK update for version 20.0.0 Jun 1, 2026
@ArnabChatterjee20k ArnabChatterjee20k merged commit 4c9c1ca into main Jun 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants