一. 首先你要启动你的swagger.json或者openapi.json
二. 然后你需要启动openapi生成代码的容器(如:python、javascript、php、golang...)我这里是python
docker run -d -p 8090:8080 --name openapi_generator openapitools/openapi-generator-online:latest-release
三. 调用容器生成代码
import logging import os import pathlib import shutil import tempfile import zipfile import requests logging.basicConfig() logging.getLogger().setLevel(logging.DEBUG) L = logging.getLogger("generate_openapi_client") L.setLevel(logging.DEBUG) def generate_client(package_name: str, spec_url: str, install_dir: str, openapi_gen_url: str, project_name: str = None): if project_name is None: project_name = package_name L.debug(f"Requesting OpenAPI client generation for python {package_name=}") response = requests.post( f"{openapi_gen_url}/api/gen/clients/python", json={ "openAPIUrl": spec_url, "options": { "packageName": package_name, "projectName": project_name, "generateSourceCodeOnly": "true", }, "spec": {}, }, ) response.raise_for_status() data = response.json() L.debug(data) download_link = data["link"] L.debug(f"Downloading generated client {download_link=}") response = requests.get(download_link) response.raise_for_status() with tempfile.TemporaryDirectory() as tmpdirname: L.debug(f"created temporary directory {tmpdirname=}") tmpdirname = pathlib.Path(tmpdirname) extract_file = tmpdirname / "client.zip" extract_dir = tmpdirname / "client" with open(extract_file, "wb") as f: f.write(response.content) with zipfile.ZipFile(extract_file, "r") as zip_ref: zip_ref.extractall(extract_dir) os.makedirs(install_dir, exist_ok=True) root_package_name = package_name.split(".")[0] source_dir = extract_dir / "python-client" / root_package_name # source_dir = extract_dir / 'python-client' L.debug(f"Moving source to target dir {source_dir=} {install_dir=}") shutil.copytree(source_dir, pathlib.Path(install_dir) / root_package_name, dirs_exist_ok=True) if __name__ == "__main__": PACKAGE_PATH = os.environ.get("PACKAGE_PATH", ".") L.debug(f"{PACKAGE_PATH=}") generate_client( os.environ.get("PACKAGE_NAME", "openapi_client"), os.environ.get("OPENAPI_SPEC_URL", "http://host.docker.internal:8000/openapi.json"), openapi_gen_url=os.environ.get("OPENAPI_DOCKER_URL", "http://localhost:8090"), install_dir=PACKAGE_PATH, ) """ { "packageName": { "opt": "packageName", "description": "python package name (convention: snake_case).", "type": "string", "optValue": null, "default": "openapi_client", "enum": null }, "projectName": { "opt": "projectName", "description": "python project name in setup.py (e.g. petstore-api).", "type": "string", "optValue": null, "default": null, "enum": null }, "packageVersion": { "opt": "packageVersion", "description": "python package version.", "type": "string", "optValue": null, "default": "1.0.0", "enum": null }, "packageUrl": { "opt": "packageUrl", "description": "python package URL.", "type": "string", "optValue": null, "default": null, "enum": null }, "hideGenerationTimestamp": { "opt": "hideGenerationTimestamp", "description": "Hides the generation timestamp when files are generated.", "type": "string", "optValue": null, "default": "true", "enum": null }, "generateSourceCodeOnly": { "opt": "generateSourceCodeOnly", "description": "Specifies that only a library source code is to be generated.", "type": "string", "optValue": null, "default": "false", "enum": null }, "recursionLimit": { "opt": "recursionLimit", "description": "Set the recursion limit. If not set, use the system default value.", "type": "string", "optValue": null, "default": null, "enum": null }, "mapNumberTo": { "opt": "mapNumberTo", "description": "Map number to Union[StrictFloat, StrictInt], StrictStr or float.", "type": "string", "optValue": null, "default": "Union[StrictFloat, StrictInt]", "enum": null }, "datetimeFormat": { "opt": "datetimeFormat", "description": "datetime format for query parameters", "type": "string", "optValue": null, "default": "%Y-%m-%dT%H:%M:%S%z", "enum": null }, "dateFormat": { "opt": "dateFormat", "description": "date format for query parameters", "type": "string", "optValue": null, "default": "%Y-%m-%d", "enum": null }, "useOneOfDiscriminatorLookup": { "opt": "useOneOfDiscriminatorLookup", "description": "Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped.", "type": "string", "optValue": null, "default": "false", "enum": null }, "library": { "opt": "library", "description": "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3", "type": "string", "optValue": null, "default": "urllib3", "enum": null }, "disallowAdditionalPropertiesIfNotPresent": { "opt": "disallowAdditionalPropertiesIfNotPresent", "description": "If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.", "type": "boolean", "optValue": null, "default": "true", "enum": { "false": "The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.", "true": "Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default." } } } http://localhost:8090/api/gen/clients/python { "openAPIUrl": "https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml", "options": { "packageName": "sf_pickup_client", "projectName": "sf_pickup_client", "generateSourceCodeOnly": "true", }, "spec": {} } { "code": "58276864-f444-4a4a-a93f-ee251e517fb6", "link": "http://localhost:8090/api/gen/download/58276864-f444-4a4a-a93f-ee251e517fb6" } """
四. 代码生成成功,会有一个DefaultAPI的class,你的所有api都在这里可以操作。
1 from enum import Enum 2 3 import pytest 4 5 from openapi_client import configuration 6 from openapi_client.api.default_api import DefaultApi 7 from openapi_client.api_client import ApiClient 8 from openapi_client.exceptions import ServiceException 9 from openapi_client.models.operation import Operation 10 from openapi_client.models.operation_response import OperationResponse 11 from openapi_client.models.operation_type import OperationType 12 13 14 @pytest.fixture(scope="module") 15 def default_api(): 16 config = configuration.Configuration(host="http://localhost:8000") 17 with ApiClient(config) as client: 18 yield DefaultApi(client) 19 20 21 def test_hello_world(default_api: DefaultApi): 22 assert default_api.root() == {"message": "Hello World"} 23 24 25 def test_hello_pytest(default_api: DefaultApi): 26 assert default_api.say_hello(name="pytest") == {"message": "Hello pytest"} 27 28 29 def test_operation_add(default_api: DefaultApi): 30 op = Operation(a=1, b=2, type=OperationType.ADD) 31 assert default_api.operation(op) == OperationResponse(result=3) 32 33 34 def test_operation_sub(default_api: DefaultApi): 35 op = Operation(a=1, b=2, type=OperationType.SUB) 36 assert default_api.operation(op) == OperationResponse(result=-1) 37 38 39 def test_operation_mul(default_api: DefaultApi): 40 op = Operation(a=1, b=2, type=OperationType.MUL) 41 assert default_api.operation(op) == OperationResponse(result=2) 42 43 44 def test_operation_div(default_api: DefaultApi): 45 op = Operation(a=1, b=2, type=OperationType.DIV) 46 assert default_api.operation(op) == OperationResponse(result=0.5) 47 48 49 def test_operation_div_by_zero(default_api: DefaultApi): 50 with pytest.raises(ServiceException): 51 op = Operation(a=1, b=0, type=OperationType.DIV) 52 default_api.operation(op) 53 54 55 def test_operation_type(): 56 assert OperationType.ADD == "add" 57 assert OperationType.SUB == "sub" 58 assert OperationType.MUL == "mul" 59 assert OperationType.DIV == "div" 60 assert issubclass(OperationType, str) 61 assert issubclass(OperationType, Enum)
标签:null,default,client,api,OpenAPI,openapi,Swagger,type From: https://www.cnblogs.com/watermeloncode/p/18188891