Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆️ Upgrade openapi generator #202

Open
wants to merge 57 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
15869d0
begin converting to new generator
bisgaard-itis Oct 23, 2024
6df235f
remove invalid import
bisgaard-itis Oct 23, 2024
e6663e6
fix minor bug in tests
bisgaard-itis Oct 24, 2024
456a98b
fix download file method
bisgaard-itis Oct 24, 2024
e7756b1
remove skip if dev version decorator
bisgaard-itis Oct 24, 2024
373089b
update models in wrapper
bisgaard-itis Oct 24, 2024
4bb8a1c
patch JobInputs model
bisgaard-itis Oct 24, 2024
f55455b
make JobOutputs backwards compatible
bisgaard-itis Oct 24, 2024
4351ea5
improve wrapping of JobOutputs
bisgaard-itis Oct 24, 2024
8837472
improve JobInputs constructor
bisgaard-itis Oct 24, 2024
dae27fe
resolve configuration issue
bisgaard-itis Oct 24, 2024
35b66fd
include configuration directly in api
bisgaard-itis Oct 24, 2024
bc3bfe1
update to latest openapi.json
bisgaard-itis Oct 24, 2024
a5985bd
cleanup model location
bisgaard-itis Oct 24, 2024
4039885
start adding metadata test
bisgaard-itis Oct 27, 2024
728c497
expose MetadataValue
bisgaard-itis Oct 27, 2024
7a6ca5f
only missing check that objects coincide
bisgaard-itis Oct 27, 2024
98b53e5
improve wrapper models
bisgaard-itis Oct 28, 2024
f703002
improve jobinputs model
bisgaard-itis Oct 29, 2024
040d1f9
handle metadata and job inputs/outputs in studies api
bisgaard-itis Oct 29, 2024
5d0b7b5
fix several unittests
bisgaard-itis Oct 29, 2024
4257335
improve design of unittests
bisgaard-itis Oct 29, 2024
c38eac2
minor refactoring
bisgaard-itis Oct 29, 2024
8cd2ff3
start creating test for create solver jobs
bisgaard-itis Oct 29, 2024
295c827
add create job test
bisgaard-itis Oct 29, 2024
1ef0fd5
extract models from openapi specs
bisgaard-itis Nov 1, 2024
5b47cc2
add test for joboutputs
bisgaard-itis Nov 1, 2024
da0965f
minor cleanup
bisgaard-itis Nov 1, 2024
3fd8207
remove obsolete tests
bisgaard-itis Nov 1, 2024
99a4a65
fix create job function
bisgaard-itis Nov 1, 2024
9ba877c
use monkeypatch to avoid rouge env vars
bisgaard-itis Nov 1, 2024
a11cab2
redo uneeded change
bisgaard-itis Nov 3, 2024
36f5c1c
improve some signatures in the wrapped client
bisgaard-itis Nov 3, 2024
3e1e831
automate response model creation when mocking
bisgaard-itis Nov 4, 2024
3fc1767
add study api unit tests
bisgaard-itis Nov 4, 2024
bc42b5e
minor corrections
bisgaard-itis Nov 4, 2024
31e62ee
delete old comment @pcrespov
bisgaard-itis Nov 4, 2024
2ceb1ad
fix faker.uuid4 type issue
bisgaard-itis Nov 4, 2024
e76b901
fix
bisgaard-itis Nov 4, 2024
41f0df1
update openapi.json with new model examples
bisgaard-itis Nov 4, 2024
99341ad
make Make recipe more readable @pcrespov
bisgaard-itis Nov 4, 2024
db56108
merge master into 201-experiment-with-upgrading-openapi-generator
bisgaard-itis Nov 5, 2024
f0f31f6
python 3.8 compatible
bisgaard-itis Nov 6, 2024
e0d5f2d
merge master into 201-experiment-with-upgrading-openapi-generator
bisgaard-itis Nov 6, 2024
b9bcdc7
remove Annotated import from typing
bisgaard-itis Nov 6, 2024
ff7c0d5
fix type hinting dict to Dict for py 3.8
bisgaard-itis Nov 6, 2024
6323aaf
more py3.8 compatibility changes
bisgaard-itis Nov 6, 2024
084fa56
more py3.8 compatibility changes
bisgaard-itis Nov 6, 2024
db2d5d2
more py3.8 compatibility changes
bisgaard-itis Nov 6, 2024
866fa8a
more py3.8 compatibility changes
bisgaard-itis Nov 6, 2024
122e912
update openapi.json
bisgaard-itis Nov 8, 2024
002b157
minor fix after openapi.json update
bisgaard-itis Nov 8, 2024
5d37230
test fix for https://github.com/ITISFoundation/osparc-simcore/issues/…
bisgaard-itis Nov 8, 2024
baf7bc1
Merge branch '201-experiment-with-upgrading-openapi-generator' of git…
bisgaard-itis Nov 8, 2024
308dd7f
merge master into 201-experiment-with-upgrading-openapi-generator
bisgaard-itis Nov 18, 2024
4041620
add make target for installing local client for running e2e tests
bisgaard-itis Nov 18, 2024
5fd1600
Merge branch 'master' into 201-experiment-with-upgrading-openapi-gene…
bisgaard-itis Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,079 changes: 1,235 additions & 844 deletions api/openapi.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions clients/python/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ _check_venv_active:

.PHONY: install-dev
install-dev: _check_venv_active .install-dev-reqs python-client ## installs osparc_client and osparc in edit mode
uv pip install -e artifacts/client
uv pip install -e .
# for some reason this command refuses to run with uv. Looks related to https://github.com/astral-sh/uv/issues/1661
pip install -e artifacts/client -e .
bisgaard-itis marked this conversation as resolved.
Show resolved Hide resolved
uv pip list

.PHONY: install-unit-test
Expand Down
1 change: 0 additions & 1 deletion clients/python/requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
-r ../../../requirements.txt
-r unit-test.txt
-r e2e-test.txt
pylint
6 changes: 2 additions & 4 deletions clients/python/src/osparc/_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
from typing import Optional

from osparc_client.api_client import ApiClient as _ApiClient
from osparc_client import Configuration
from ._configuration import Configuration
from pydantic import ValidationError

from ._settings import ConfigurationEnvVars


Expand All @@ -16,7 +15,6 @@ def __init__(
header_name=None,
header_value=None,
cookie=None,
pool_threads=1,
):
if configuration is None:
try:
Expand All @@ -36,4 +34,4 @@ def __init__(
"osparc.Configuration object explicitly"
) from exc

super().__init__(configuration, header_name, header_value, cookie, pool_threads)
super().__init__(configuration, header_name, header_value, cookie)
9 changes: 7 additions & 2 deletions clients/python/src/osparc/_api_files_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
import string
from pathlib import Path
from typing import Any, Iterator, List, Optional, Tuple, Union
from tempfile import NamedTemporaryFile

import httpx
from httpx import Response
from osparc_client.api.files_api import FilesApi as _FilesApi
from osparc_client import Filesize as _Filesize
from tqdm.asyncio import tqdm
from tqdm.contrib.logging import logging_redirect_tqdm

Expand Down Expand Up @@ -71,7 +73,10 @@ def download_file(
raise RuntimeError(
f"destination_folder: {destination_folder} must be a directory"
)
downloaded_file: Path = Path(super().download_file(file_id, **kwargs))
with NamedTemporaryFile(delete=False) as tmp_file:
downloaded_file = Path(tmp_file.name)
data = super().download_file(file_id, **kwargs)
downloaded_file.write_bytes(data)
if destination_folder is not None:
dest_file: Path = destination_folder / downloaded_file.name
while dest_file.is_file():
Expand Down Expand Up @@ -115,7 +120,7 @@ async def upload_file_async(
return file_result
client_file: ClientFile = ClientFile(
filename=file.name,
filesize=file.stat().st_size,
filesize=_Filesize(file.stat().st_size),
sha256_checksum=checksum,
)
client_upload_schema: ClientFileUploadData = super().get_upload_links(
Expand Down
18 changes: 16 additions & 2 deletions clients/python/src/osparc/_api_solvers_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import httpx
from osparc_client.api.solvers_api import SolversApi as _SolversApi
from .models import JobInputs, OnePageSolverPort, SolverPort
from .models import JobInputs, OnePageSolverPort, SolverPort, JobOutputs

from ._api_client import ApiClient
from ._settings import ParentProjectInfo
Expand All @@ -15,8 +15,9 @@
dev_feature,
dev_features_enabled,
)

import warnings
from tempfile import NamedTemporaryFile
from pathlib import Path


class SolversApi(_SolversApi):
Expand Down Expand Up @@ -102,3 +103,16 @@ def create_job(
):
kwargs = {**kwargs, **ParentProjectInfo().model_dump(exclude_none=True)}
return super().create_job(solver_key, version, job_inputs, **kwargs)

def get_job_output_logfile(self, *args, **kwargs):
data = super().get_job_output_logfile(*args, **kwargs)
with NamedTemporaryFile(delete=False) as tmp_file:
log_file = Path(tmp_file.name)
log_file.write_bytes(data)
return log_file

def get_job_outputs(self, *args, **kwargs) -> JobOutputs:
_osparc_client_outputs = super().get_job_outputs(*args, **kwargs)
_outputs = JobOutputs.from_osparc_client_job_outputs(_osparc_client_outputs)
assert _outputs is not None
return _outputs
45 changes: 45 additions & 0 deletions clients/python/src/osparc/_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from osparc_client import Configuration as _Configuration
from typing import Set
from urllib3 import Retry


class Configuration(_Configuration):
def __init__(
self,
host="https://api.osparc.io",
api_key=None,
api_key_prefix=None,
username=None,
password=None,
*,
retry_max_count: int = 4,
retry_methods: Set[str] = {
"DELETE",
"GET",
"HEAD",
"OPTIONS",
"PUT",
"TRACE",
"POST",
"PATCH",
"CONNECT",
},
retry_status_codes: Set[int] = {429, 503, 504},
retry_backoff_factor=4.0,
):
retries = Retry(
total=retry_max_count,
backoff_factor=retry_backoff_factor,
status_forcelist=retry_status_codes,
allowed_methods=retry_methods,
respect_retry_after_header=True,
raise_on_status=True,
)
super().__init__(
host=host,
api_key=api_key,
api_key_prefix=api_key_prefix,
username=username,
password=password,
retries=retries,
)
48 changes: 48 additions & 0 deletions clients/python/src/osparc/_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from osparc_client import ValuesValue
from osparc_client import JobInputs as _JobInputs
from osparc_client import JobOutputs as _JobOutputs
from typing import Dict, Any
from pydantic import BaseModel, StrictStr, Field


def _values_dict(v: Dict[str, Any]) -> Dict[str, ValuesValue | None]:
result = {}
for k, v in v.items():
if v is not None:
result[k] = ValuesValue(v)
else:
result[k] = v
return result


class JobInputs(_JobInputs):
def __init__(self, *args, **kwargs):
if len(args) == 1 and len(kwargs) == 0:
input = args[0]
assert isinstance(input, dict)
super().__init__(values=_values_dict(input))
return
if len(args) == 0 and len(kwargs) == 1:
values = kwargs.get("values")
if values is None:
raise RuntimeError("When passing a single kwarg it must be 'values'")
super().__init__(values=_values_dict(values))
return
else:
super().__init__(*args, **kwargs)


class JobOutputs(BaseModel):
job_id: StrictStr = Field(description="Job that produced this output")
results: Dict[str, Any]

@classmethod
def from_osparc_client_job_outputs(cls, outputs: _JobOutputs) -> "JobOutputs":
_results = {}
for k, v in outputs.results.items():
if isinstance(v, ValuesValue):
_results[k] = v.actual_instance
else:
_results[k] = v

return cls(job_id=outputs.job_id, results=_results)
2 changes: 1 addition & 1 deletion clients/python/src/osparc/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# NOTE: this is an interface. Keep it clean!


from osparc_client.configuration import Configuration as Configuration
from ._configuration import Configuration as Configuration
from ._api_client import ApiClient as ApiClient


Expand Down
8 changes: 3 additions & 5 deletions clients/python/src/osparc/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
from osparc_client.models.body_complete_multipart_upload_v0_files_file_id_complete_post import (
BodyCompleteMultipartUploadV0FilesFileIdCompletePost as BodyCompleteMultipartUploadV0FilesFileIdCompletePost,
)
from osparc_client.models.body_upload_file_v0_files_content_put import (
BodyUploadFileV0FilesContentPut as BodyUploadFileV0FilesContentPut,
)
from osparc_client.models.client_file import ClientFile as ClientFile
from osparc_client.models.client_file_upload_data import (
ClientFileUploadData as ClientFileUploadData,
Expand All @@ -31,13 +28,12 @@
HTTPValidationError as HTTPValidationError,
)
from osparc_client.models.job import Job as Job
from osparc_client.models.job_inputs import JobInputs as JobInputs
from osparc_client.models.job_logs_map import JobLogsMap as JobLogsMap
from osparc_client.models.job_metadata import JobMetadata as JobMetadata
from osparc_client.models.job_metadata_update import (
JobMetadataUpdate as JobMetadataUpdate,
)
from osparc_client.models.job_outputs import JobOutputs as JobOutputs
from osparc_client.models.values_value import ValuesValue as ValuesValue
from osparc_client.models.job_status import JobStatus as JobStatus
from osparc_client.models.links import Links as Links
from osparc_client.models.log_link import LogLink as LogLink
Expand Down Expand Up @@ -75,6 +71,8 @@
)
from osparc_client.models.wallet_status import WalletStatus as WalletStatus

from ._models import JobInputs as JobInputs
from ._models import JobOutputs as JobOutputs

# renames
TaskStates = _RunningState
14 changes: 0 additions & 14 deletions clients/python/test/e2e/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,6 @@ def repo_version() -> Version:
return Version(version_file.read_text())


def skip_if_no_dev_features(test):
if (
Version(osparc.__version__) < repo_version()
or not osparc_dev_features_enabled()
):
return pytest.mark.skip(
(
f"{osparc.__version__=}<{str(repo_version)} "
f"or {osparc_dev_features_enabled()=}"
)
)(test)
return test


def skip_if_osparc_version(
*,
at_least: Optional[Version] = None,
Expand Down
2 changes: 1 addition & 1 deletion clients/python/test/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def pytest_configure(config):

@pytest.fixture
def api_client() -> Iterable[osparc.ApiClient]:
if Version(osparc.__version__) >= Version("8.0.0"):
if Version(osparc.__version__) >= Version("0.8.0"):
with osparc.ApiClient() as api_client:
yield api_client
else:
Expand Down
3 changes: 0 additions & 3 deletions clients/python/test/e2e/test_files_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import osparc
import pytest
from _utils import skip_if_no_dev_features
from conftest import _KB


Expand All @@ -25,7 +24,6 @@ def _hash_file(file: Path) -> str:
return sha256.hexdigest()


@skip_if_no_dev_features
def test_upload_file(tmp_file: Path, api_client: osparc.ApiClient) -> None:
"""Test that we can upload a file via the multipart upload"""
tmp_path: Path = tmp_file.parent
Expand All @@ -43,7 +41,6 @@ def test_upload_file(tmp_file: Path, api_client: osparc.ApiClient) -> None:
files_api.delete_file(uploaded_file1.id)


@skip_if_no_dev_features
@pytest.mark.parametrize("use_checksum", [True, False])
@pytest.mark.parametrize("use_id", [True, False])
def test_search_files(
Expand Down
3 changes: 1 addition & 2 deletions clients/python/test/e2e/test_solvers_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
import json

import osparc
from _utils import skip_if_no_dev_features, skip_if_osparc_version
from _utils import skip_if_osparc_version
from httpx import AsyncClient
from packaging.version import Version

DEFAULT_TIMEOUT_SECONDS = 10 * 60 # 10 min


@skip_if_no_dev_features
def test_jobs(api_client: osparc.ApiClient, sleeper: osparc.Solver):
"""Test the jobs method

Expand Down
bisgaard-itis marked this conversation as resolved.
Show resolved Hide resolved

This file was deleted.

4 changes: 2 additions & 2 deletions scripts/common.Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ APP_NAME := $(notdir $(CURDIR))

# Specify which openapi generator should be used to generate the clients in this repo
# Build from modified fork https://github.com/ITISFoundation/openapi-generator/tree/openapi-generator-v4.2.3
bisgaard-itis marked this conversation as resolved.
Show resolved Hide resolved
OPENAPI_GENERATOR_NAME := itisfoundation/openapi-generator-cli-openapi-generator-v4.2.3
OPENAPI_GENERATOR_TAG := v0
OPENAPI_GENERATOR_NAME := openapitools/openapi-generator-cli
OPENAPI_GENERATOR_TAG := latest
OPENAPI_GENERATOR_IMAGE := $(OPENAPI_GENERATOR_NAME):$(OPENAPI_GENERATOR_TAG)

# openapi specification
Expand Down
Loading