然後 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
沒有留言:
張貼留言