Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .generation/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Patched version of openapi-generator-cli with python3 support

FROM docker.io/openapitools/openapi-generator-cli:v7.0.1
FROM docker.io/openapitools/openapi-generator-cli:v7.11.0

RUN apt-get update && apt-get install -y python3
2 changes: 1 addition & 1 deletion .generation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ From the root of the repository run:
To fetch the OpenAPI spec from the backend, run:

```bash
cargo run --features pro
cargo run
wget http://localhost:3030/api/api-docs/openapi.json -O - \
| python -m json.tool --indent 2 > .generation/input/openapi.json
```
Expand Down
4 changes: 2 additions & 2 deletions .generation/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ githubUrl = https://github.com/geo-engine/openapi-client

[python]
name = geoengine_openapi_client
version = 0.0.20
version = 0.0.21

[typescript]
name = @geoengine/openapi-client
version = 0.0.20
version = 0.0.21

4 changes: 4 additions & 0 deletions .generation/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ def fetch_spec(*, ge_backend_tag: str) -> None:
# "-p", "3030:8080",
f"quay.io/geoengine/geoengine:{ge_backend_tag}",
],
env={
'GEOENGINE__POSTGRES__CLEAR_DATABASE_ON_START': 'true',
'PATH': os.environ['PATH'],
},
)

for _ in range(180): # <3 minutes
Expand Down
131 changes: 79 additions & 52 deletions .generation/post-process/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,23 @@

import sys
from pathlib import Path
from typing import Generator, List
from typing import List, Literal, Callable, Generator
from textwrap import dedent, indent
from util import pairwise, modify_file, version
from util import modify_file, version

INDENT = ' '
HALF_INDENT = ' '

def api_client_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the api_client.py file.'''
for (prev_line, line) in pairwise(file_contents):
for line in file_contents:
dedented_line = dedent(line)
dedented_prev_line = dedent(prev_line)

if dedented_line.startswith('self.user_agent = '):
line = indent(dedent(f'''\
self.user_agent = 'geoengine/openapi-client/python/{version('python')}'
'''), 2 * INDENT)

elif dedented_prev_line.startswith('response_data.data = response_data.data') \
and dedented_line.startswith('else:'):
line = indent(dedent('''\
elif response_data.data is not None:
# Note: fixed handling of empty responses
'''), 2 * INDENT + HALF_INDENT)

elif dedented_line.startswith('if not async_req:'):
line = indent(dedent('''\
# Note: remove query string in path part for ogc endpoints
resource_path = resource_path.partition("?")[0]
'''), 2 * INDENT) + '\n' + line

yield line

def exceptions_py(file_contents: List[str]) -> Generator[str, None, None]:
Expand All @@ -53,29 +39,6 @@ def exceptions_py(file_contents: List[str]) -> Generator[str, None, None]:

yield line

def palette_colorizer_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the palette_colorizer.py file.'''
for line in file_contents:
if dedent(line).startswith('# override the default output'):
line = indent(dedent('''\
# Note: fixed wrong handling of colors field
return _dict
'''), 2 * INDENT) + '\n' + line

yield line

def raster_dataset_from_workflow_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the raster_dataset_from_workflow.py file.'''
for line in file_contents:
if dedent(line).startswith('exclude_none=True)'):
line = indent(dedent('''\
exclude_none=True,
# Note: remove as_cog when set to default
exclude_defaults=True)
'''), 6 * INDENT + HALF_INDENT)

yield line

def task_status_with_id_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the task_status_with_id.py file.'''
for line in file_contents:
Expand All @@ -98,10 +61,10 @@ def task_status_with_id_py(file_contents: List[str]) -> Generator[str, None, Non
if getattr(self.actual_instance, "error", None) is None and "error" in self.actual_instance.__fields_set__:
'''), 2 * INDENT)

elif dedented_line.startswith('_obj = TaskStatusWithId.parse_obj({'):
elif dedented_line.startswith('_obj = cls.model_validate({'):
line = indent(dedent('''\
# Note: fixed handling of actual_instance
_obj = TaskStatusWithId.parse_obj({
_obj = cls.model_validate({
"actual_instance": TaskStatus.from_dict(obj).actual_instance,
"task_id": obj.get("taskId")
})
Expand All @@ -110,19 +73,83 @@ def task_status_with_id_py(file_contents: List[str]) -> Generator[str, None, Non

yield line

EARLY_RETURN_EMPTY_HTTP_RESPONSE = indent(dedent('''\
# Note: fixed handling of empty responses
if response_data.data is None:
return None
'''), 2 * INDENT)

def tasks_api_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the tasks_api.py file.'''
state: Literal[None, 'abort_handler'] = None
for line in file_contents:
dedented_line = dedent(line)
if state is None and dedented_line.startswith('def abort_handler('):
state = 'abort_handler'

elif state == 'abort_handler' and \
dedented_line.startswith('return self.api_client.response_deserialize('):
line = EARLY_RETURN_EMPTY_HTTP_RESPONSE + '\n' + line
state = None

yield line

def layers_api_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the tasks_api.py file.'''
state: Literal[
None,
'add_early_return_empty_http_response',
] = None
for line in file_contents:
dedented_line = dedent(line)
if state is None and (
dedented_line.startswith('def add_existing_layer_to_collection(')
or
dedented_line.startswith('def add_existing_collection_to_collection(')
or
dedented_line.startswith('def remove_collection_from_collection(')
or
dedented_line.startswith('def remove_layer_from_collection(')
or
dedented_line.startswith('def remove_collection(')
):
state = 'add_early_return_empty_http_response'

elif state == 'add_early_return_empty_http_response' and \
dedented_line.startswith('return self.api_client.response_deserialize('):
line = EARLY_RETURN_EMPTY_HTTP_RESPONSE + '\n' + line
state = None

yield line

def ogc_xyz_api_py(ogc_api: Literal['wfs', 'wms']) -> Callable[[List[str]], Generator[str, None, None]]:
def ogc_wfs_api_py(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the ogc_wfs_api.py file.'''
for line in file_contents:
dedented_line = dedent(line)
if dedented_line.startswith(f"resource_path='/{ogc_api}/{{workflow}}?request="):
line = indent(dedent(f'''\
# Note: remove query string in path part for ogc endpoints
resource_path='/{ogc_api}/{{workflow}}',
'''), 3 * INDENT)

yield line
return ogc_wfs_api_py

input_file = Path(sys.argv[1])

if input_file.name == 'api_client.py':
modify_file(input_file, api_client_py)
elif input_file.name == 'exceptions.py':
modify_file(input_file, exceptions_py)
elif input_file.name == 'palette_colorizer.py':
modify_file(input_file, palette_colorizer_py)
elif input_file.name == 'raster_dataset_from_workflow.py':
modify_file(input_file, raster_dataset_from_workflow_py)
elif input_file.name == 'task_status_with_id.py':
modify_file(input_file, task_status_with_id_py)
file_modifications = {
'api_client.py': api_client_py,
'exceptions.py': exceptions_py,
'layers_api.py': layers_api_py,
'ogcwfs_api.py': ogc_xyz_api_py('wfs'),
'ogcwms_api.py': ogc_xyz_api_py('wms'),
'task_status_with_id.py': task_status_with_id_py,
'tasks_api.py': tasks_api_py,
}

if modifier_function := file_modifications.get(input_file.name):
modify_file(input_file, modifier_function)
else:
pass # leave file untouched

Expand Down
56 changes: 10 additions & 46 deletions .generation/post-process/typescript.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,13 @@ def runtime_ts(file_contents: List[str]) -> Generator[str, None, None]:

yield line

# fixes due to https://github.com/OpenAPITools/openapi-generator/issues/14831
def project_update_token_ts(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the ProjectUpdateToken.ts file.'''
for line in file_contents:

if line.startswith('export function ProjectUpdateTokenToJSON'):
line = dedent('''\
export function instanceOfProjectUpdateToken(value: any): boolean {
return value === ProjectUpdateToken.None || value === ProjectUpdateToken.Delete;
}
''') + '\n' + line

yield line

# fixes due to https://github.com/OpenAPITools/openapi-generator/issues/14831
def plot_update_ts(file_contents: List[str]) -> Generator[str, None, None]:
'''Modify the PlotUpdate.ts file.'''
for line in file_contents:
dedented_line = dedent(line)

if dedented_line.startswith('return { ...PlotFromJSONTyped(json, true)'):
line = indent(dedent('''\
if (json === ProjectUpdateToken.None) {
return ProjectUpdateToken.None;
} else if (json === ProjectUpdateToken.Delete) {
return ProjectUpdateToken.Delete;
} else {
return { ...PlotFromJSONTyped(json, true) };
}
'''), INDENT)
elif dedented_line.startswith('if (instanceOfPlot(value))'):
if dedented_line.startswith('if (instanceOfPlot(value))'):
line = indent(dedent('''\
if (typeof value === 'object' && instanceOfPlot(value)) {
'''), INDENT)
Expand All @@ -69,17 +45,7 @@ def layer_update_ts(file_contents: List[str]) -> Generator[str, None, None]:
for line in file_contents:
dedented_line = dedent(line)

if dedented_line.startswith('return { ...ProjectLayerFromJSONTyped(json, true)'):
line = indent(dedent('''\
if (json === ProjectUpdateToken.None) {
return ProjectUpdateToken.None;
} else if (json === ProjectUpdateToken.Delete) {
return ProjectUpdateToken.Delete;
} else {
return { ...ProjectLayerFromJSONTyped(json, true) };
}
'''), INDENT)
elif dedented_line.startswith('if (instanceOfProjectLayer(value))'):
if dedented_line.startswith('if (instanceOfProjectLayer(value))'):
line = indent(dedent('''\
if (typeof value === 'object' && instanceOfProjectLayer(value)) {
'''), INDENT)
Expand All @@ -104,16 +70,14 @@ def task_status_with_id_ts(file_contents: List[str]) -> Generator[str, None, Non

input_file = Path(sys.argv[1])

if input_file.name == 'runtime.ts':
modify_file(input_file, runtime_ts)
if input_file.name == 'ProjectUpdateToken.ts':
modify_file(input_file, project_update_token_ts)
elif input_file.name == 'PlotUpdate.ts':
modify_file(input_file, plot_update_ts)
elif input_file.name == 'LayerUpdate.ts':
modify_file(input_file, layer_update_ts)
elif input_file.name == 'TaskStatusWithId.ts':
modify_file(input_file, task_status_with_id_ts)
file_modifications = {
'LayerUpdate.ts': layer_update_ts,
'PlotUpdate.ts': plot_update_ts,
'runtime.ts': runtime_ts,
'TaskStatusWithId.ts': task_status_with_id_ts,
}
if modifier_function := file_modifications.get(input_file.name):
modify_file(input_file, modifier_function)
else:
pass # leave file untouched

Expand Down
17 changes: 5 additions & 12 deletions python/.github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
pip install -r requirements.txt
pip install -r test-requirements.txt
- name: Test with pytest
run: |
pytest
pytest --cov={{packageName}}
6 changes: 3 additions & 3 deletions python/.gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stages:
- pip install -r test-requirements.txt
- pytest --cov=geoengine_openapi_client

pytest-3.7:
extends: .pytest
image: python:3.7-alpine
pytest-3.8:
extends: .pytest
image: python:3.8-alpine
Expand All @@ -29,3 +26,6 @@ pytest-3.10:
pytest-3.11:
extends: .pytest
image: python:3.11-alpine
pytest-3.12:
extends: .pytest
image: python:3.12-alpine
3 changes: 3 additions & 0 deletions python/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ docs/GetLegendGraphicRequest.md
docs/GetMapExceptionFormat.md
docs/GetMapFormat.md
docs/GetMapRequest.md
docs/InlineObject.md
docs/InternalDataId.md
docs/Layer.md
docs/LayerCollection.md
Expand Down Expand Up @@ -330,6 +331,7 @@ geoengine_openapi_client/models/get_legend_graphic_request.py
geoengine_openapi_client/models/get_map_exception_format.py
geoengine_openapi_client/models/get_map_format.py
geoengine_openapi_client/models/get_map_request.py
geoengine_openapi_client/models/inline_object.py
geoengine_openapi_client/models/internal_data_id.py
geoengine_openapi_client/models/layer.py
geoengine_openapi_client/models/layer_collection.py
Expand Down Expand Up @@ -565,6 +567,7 @@ test/test_get_legend_graphic_request.py
test/test_get_map_exception_format.py
test/test_get_map_format.py
test/test_get_map_request.py
test/test_inline_object.py
test/test_internal_data_id.py
test/test_layer.py
test/test_layer_collection.py
Expand Down
2 changes: 1 addition & 1 deletion python/.openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.0.1
7.11.0
4 changes: 2 additions & 2 deletions python/.travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# ref: https://docs.travis-ci.com/user/languages/python
language: python
python:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
# uncomment the following if needed
#- "3.11-dev" # 3.11 development branch
#- "3.12-dev" # 3.12 development branch
#- "nightly" # nightly build
# command to install dependencies
install:
Expand Down
Loading