然後 swagger 就做了 codegen,依據openapi 的描述文件產生 restful server 的 code。
依照 server site 使用的語言和 package,產生不同的code。
swagger 官方的 codegen 是用 java 寫的,很不方便(實際用起來就是麻煩,要裝舊版 jdk 跟 maven)。
有人用 python 寫了for python 的 codegen,支援一些python web server framework。
這篇就是用 flask 為例子。
用 "-tlp, --templates" 可以指定產出 flask/tornado/falcon 的 code,default 是 flask。
也就說:
- 依照openapi 寫 api.json/xml/yml
- 用 swagger_py_codegen 依照剛剛的 api.XXX 產生 flask 的 code
- 用 python 來 run 剛剛產生的 code
依照這說明,啟動 flask restful serve
因為要 python3 (python 2.17 pip install 好,run swagger-py-codegen 會出現 No module named abc 的 error),所以用 conda
conda create -n flaskenv python=3.6conda repo 有 flask,沒有 swagger-py-codegen。
要用 pip install,所以用 conda install pip (因為 python version 和 host 不一樣)。
再用
pip install swagger-py-codegen然後抄上面 ref的 api.json:
{ "swagger": "2.0", "info": { "version": "1.0.0", "title": "Simple API", "description": "A simple API to learn how to write OpenAPI Specification" }, "schemes": [ "https" ], "host": "simple.api", "basePath": "/openapi101", "paths": { "/persons": { "get": { "summary": "Gets some persons", "description": "Returns a list containing all persons.", "responses": { "200": { "description": "A list of Person", "schema": { "type": "array", "items": { "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "username": { "type": "string" } } } } } } } } } }就可以generate flask code:
swagger-py-codegen --swagger-doc api.json example-app接著安裝 requirement.txt 需要的module
然後用 python run __init__.py 就可以用 browser 測試:
http://localhost:5000/openapi101/persons因為 code gen 的 code 都是空的,所以內容只有 '[]',可以修改 person.py 的 get(self) 的 return 內容,
就會反應在 browser 上。
codegen 有做 return value 的查核,不符合 api.json 的就會被濾掉。
如果不要濾掉,就要 bypass normalize():
diff --git a/example-app/example_app/openapi101/schemas.py b/example-app/example_app/openapi101/schemas.py index 86571b5..7ca6cbd 100644 --- a/example-app/example_app/openapi101/schemas.py +++ b/example-app/example_app/openapi101/schemas.py @@ -226,4 +226,4 @@ def normalize(schema, data, required_defaults=None, resolver=None): return funcs[type_](schema, data) - return _normalize(schema, data), errors + return data, errors
normailze( ) 會依照 api.json 內容,針對 return 內容 filter,只把符合的項目留下來。
上面的例子,只會產生 rest4 server,不會產生 swagger 的 操作頁面。
要加上--ui 才會。
加上 --spec 的話,會出現 Error:
File "/usr/lib/python3.6/json/encoder.py", line 180, in default o.__class__.__name__) TypeError: Object of type 'date' is not JSON serializable這個要修改swagger_py_codegen 的 code 才行,參考這一篇修改code, build, install。
除此之外,用 python 3.6.9(10,11,13) 都 OK.(update: 20221219 有些3.6都不行了)
使用 3.7.13 也可以。
不過, 在同一個環境 pip install flask 的話, 會出現 Error:
Installing collected packages: zipp, typing-extensions, importlib-metadata, Werkzeug, itsdangerous, click, flask Attempting uninstall: click Found existing installation: click 6.7 Uninstalling click-6.7: Successfully uninstalled click-6.7 ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. swagger-py-codegen 0.4.0 requires click<7, but you have click 8.1.3 which is incompatible. Successfully installed Werkzeug-2.1.2 click-8.1.3 flask-2.1.2 importlib-metadata-4.11.4 itsdangerous-2.1.2 typing-extensions-4.2.0 zipp-3.8.0這樣install flask 完,run swagger_py_codegen 會出現 error 在 click
File "/home/charles-chang/miniconda3/envs/swagger37/lib/python3.7/site-packages/click/core.py", line 760, in invoke return __callback(*args, **kwargs) TypeError: generate() got an unexpected keyword argument 'spec'所以...
swagger-py-codegen 跟 flask 不能同時 install 在同一個 env 中。因為要求的 click 版本不一樣。
如果在 python 2.7 下 run swagger_py_codegen ,會出現 Error:
File "/home/charles-chang/.local/lib/python2.7/site-packages/dpath/util.py", line 1, in <module> from collections.abc import MutableMapping ImportError: No module named abc
2022/12/19 更新:
這時候,用 conda create new env python=3.6 的話,pip install swagger_py_codegen 後,run codegen 已經會出錯了:
Traceback (most recent call last): File "/home/charles-chang/miniconda3/envs/swagger3.6/bin/swagger_py_codegen", line 5, in用 python 3.7 就沒問題。from swagger_py_codegen import generate File "/home/charles-chang/miniconda3/envs/swagger3.6/lib/python3.6/site-packages/swagger_py_codegen/__init__.py", line 4, in from .command import generate # noqa File "/home/charles-chang/miniconda3/envs/swagger3.6/lib/python3.6/site-packages/swagger_py_codegen/command.py", line 18, in from swagger_spec_validator import SwaggerValidationError File "/home/charles-chang/miniconda3/envs/swagger3.6/lib/python3.6/site-packages/swagger_spec_validator/__init__.py", line 1, in from swagger_spec_validator.common import SwaggerValidationError File "/home/charles-chang/miniconda3/envs/swagger3.6/lib/python3.6/site-packages/swagger_spec_validator/common.py", line 1 from __future__ import annotations ^ SyntaxError: future feature annotations is not defined
另外列出 python3.7 pip install swagger_py_codegen 後的 package version:
# packages in environment at /home/charles-chang/miniconda3/envs/swagger3.7: # # Name Version Build Channel _libgcc_mutex 0.1 main _openmp_mutex 5.1 1_gnu ca-certificates 2022.10.11 h06a4308_0 certifi 2022.9.24 py37h06a4308_0 click 6.7 pypi_0 pypi dpath 2.1.3 pypi_0 pypi jinja2 3.1.2 pypi_0 pypi json-spec 0.10.1 pypi_0 pypi jsonschema 2.6.0 pypi_0 pypi ld_impl_linux-64 2.38 h1181459_1 libffi 3.4.2 h6a678d5_6 libgcc-ng 11.2.0 h1234567_1 libgomp 11.2.0 h1234567_1 libstdcxx-ng 11.2.0 h1234567_1 markupsafe 2.1.1 pypi_0 pypi ncurses 6.3 h5eee18b_3 openssl 1.1.1s h7f8727e_0 pip 22.3.1 py37h06a4308_0 python 3.7.15 h7a1cb2a_1 pyyaml 4.2b1 pypi_0 pypi readline 8.2 h5eee18b_0 setuptools 65.5.0 py37h06a4308_0 six 1.16.0 pypi_0 pypi sqlite 3.40.0 h5082296_0 swagger-py-codegen 0.4.0 pypi_0 pypi swagger-spec-validator 3.0.3 pypi_0 pypi tk 8.6.12 h1ccaba5_0 typing-extensions 4.4.0 pypi_0 pypi wheel 0.37.1 pyhd3eb1b0_0 xz 5.2.8 h5eee18b_0 zlib 1.2.13 h5eee18b_0
沒有留言:
張貼留言