Skip to content

Commit

Permalink
Merge pull request #1045 from appwrite/add-python-types
Browse files Browse the repository at this point in the history
chore: add python types
  • Loading branch information
christyjacob4 authored Mar 10, 2025
2 parents 6a10a65 + ce3ab1b commit f0ee4cc
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 107 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ jobs:
Node20,
PHP80,
PHP83,
Python38,
Python39,
Python310,
Python311,
Python312,
Ruby27,
Ruby30,
Ruby31,
Expand Down
187 changes: 97 additions & 90 deletions composer.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions example.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ function getSSLPage($url) {

$sdk
->setName('NAME')
->setVersion('7.2.0')
->setDescription('Repo description goes here')
->setShortDescription('Repo short description goes here')
->setURL('https://example.com')
Expand Down
33 changes: 23 additions & 10 deletions src/SDK/Language/Python.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,26 @@ public function getTypeName(array $parameter, array $spec = []): string
if (!empty($parameter['enumValues'])) {
return \ucfirst($parameter['name']);
}
return match ($parameter['type'] ?? '') {
self::TYPE_FILE => 'InputFile',
self::TYPE_NUMBER,
self::TYPE_INTEGER => 'float',
self::TYPE_BOOLEAN => 'bool',
self::TYPE_STRING => 'str',
self::TYPE_ARRAY => 'list',
self::TYPE_OBJECT => 'dict',
default => $parameter['type'],
};
switch ($parameter['type'] ?? '') {
case self::TYPE_FILE:
return 'InputFile';
case self::TYPE_NUMBER:
case self::TYPE_INTEGER:
return 'float';
case self::TYPE_BOOLEAN:
return 'bool';
case self::TYPE_STRING:
return 'str';
case self::TYPE_ARRAY:
if (!empty(($parameter['array'] ?? [])['type']) && !\is_array($parameter['array']['type'])) {
return 'list[' . $this->getTypeName($parameter['array']) . ']';
}
return 'list[str]';
case self::TYPE_OBJECT:
return 'dict';
default:
return $parameter['type'];
}
}

/**
Expand Down Expand Up @@ -360,6 +370,9 @@ public function getFilters(): array
new TwigFilter('caseEnumKey', function (string $value) {
return $this->toUpperSnakeCase($value);
}),
new TwigFilter('getPropertyType', function ($value, $method = []) {
return $this->getTypeName($value, $method);
}),
];
}
}
2 changes: 1 addition & 1 deletion templates/python/.github/workflows/publish.yml.twig
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.8'
python-version: '3.9'

- name: Build package
run: |
Expand Down
2 changes: 1 addition & 1 deletion templates/python/package/client.py.twig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Client:
self._endpoint = '{{spec.endpoint}}'
self._global_headers = {
'content-type': '',
'user-agent' : '{{spec.title | caseUcfirst}}{{ language.name | caseUcfirst }}SDK/{{ sdk.version }} (${os.uname().sysname}; ${os.uname().version}; ${os.uname().machine})',
'user-agent' : f'{{spec.title | caseUcfirst}}{{ language.name | caseUcfirst }}SDK/{{ sdk.version }} ({os.uname().sysname}; {os.uname().version}; {os.uname().machine})',
'x-sdk-name': '{{ sdk.name }}',
'x-sdk-platform': '{{ sdk.platform }}',
'x-sdk-language': '{{ language.name | caseLower }}',
Expand Down
23 changes: 22 additions & 1 deletion templates/python/package/services/service.py.twig
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
from ..service import Service
from ..exception import AppwriteException
{% set added = [] %}
{% for method in service.methods %}
{% for parameter in method.parameters.all %}
{% if parameter.type == 'file' and parameter.type not in added %}
from ..input_file import InputFile
{% set added = added|merge(['InputFile']) %}
{% endif %}
{% if parameter.enumValues is not empty%}
{% if parameter.enumName is not empty %}
{% set name = parameter.enumName %}
{% else %}
{% set name = parameter.name %}
{% endif %}
{% if name not in added %}
from ..enums.{{ name | caseSnake }} import {{ name | caseUcfirst }};
{% set added = added|merge([name]) %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}

class {{ service.name | caseUcfirst }}(Service):

def __init__(self, client):
super({{ service.name | caseUcfirst }}, self).__init__(client)
{% for method in service.methods %}

def {{ method.name | caseSnake }}(self{% if method.parameters.all|length > 0 %}, {% endif %}{% for parameter in method.parameters.all %}{{ parameter.name | escapeKeyword | caseSnake }}{% if not parameter.required %} = None{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% if 'multipart/form-data' in method.consumes %}, on_progress = None{% endif %}):
def {{ method.name | caseSnake }}(self{% if method.parameters.all|length > 0 %}, {% endif %}{% for parameter in method.parameters.all %}{{ parameter.name | escapeKeyword | caseSnake }}: {{ parameter | getPropertyType(method) | raw }}{% if not parameter.required %} = None{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% if 'multipart/form-data' in method.consumes %}, on_progress = None{% endif %}):
"""{{method.title}}"""

api_path = '{{ method.path }}'
{{ include('python/base/params.twig') }}
Expand Down
6 changes: 3 additions & 3 deletions tests/Python38Test.php → tests/Python311Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Tests;

class Python38Test extends Base
class Python311Test extends Base
{
protected string $sdkName = 'python';
protected string $sdkPlatform = 'server';
Expand All @@ -14,10 +14,10 @@ class Python38Test extends Base
protected array $build = [
'cp tests/languages/python/tests.py tests/sdks/python/test.py',
'echo "" > tests/sdks/python/__init__.py',
'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor python:3.8-alpine pip install -r tests/sdks/python/requirements.txt --upgrade',
'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor python:3.11-alpine pip install -r tests/sdks/python/requirements.txt --upgrade',
];
protected string $command =
'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.8-alpine python tests/sdks/python/test.py';
'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.11-alpine python tests/sdks/python/test.py';

protected array $expectedOutput = [
...Base::FOO_RESPONSES,
Expand Down
34 changes: 34 additions & 0 deletions tests/Python312Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Tests;

class Python312Test extends Base
{
protected string $sdkName = 'python';
protected string $sdkPlatform = 'server';
protected string $sdkLanguage = 'python';
protected string $version = '0.0.1';

protected string $language = 'python';
protected string $class = 'Appwrite\SDK\Language\Python';
protected array $build = [
'cp tests/languages/python/tests.py tests/sdks/python/test.py',
'echo "" > tests/sdks/python/__init__.py',
'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor python:3.12-alpine pip install -r tests/sdks/python/requirements.txt --upgrade',
];
protected string $command =
'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.12-alpine python tests/sdks/python/test.py';

protected array $expectedOutput = [
...Base::FOO_RESPONSES,
...Base::BAR_RESPONSES,
...Base::GENERAL_RESPONSES,
...Base::UPLOAD_RESPONSES,
...Base::ENUM_RESPONSES,
...Base::EXCEPTION_RESPONSES,
...Base::OAUTH_RESPONSES,
...Base::QUERY_HELPER_RESPONSES,
...Base::PERMISSION_HELPER_RESPONSES,
...Base::ID_HELPER_RESPONSES
];
}

0 comments on commit f0ee4cc

Please sign in to comment.