openapi-parser 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openapi_parser-0.3.0/LICENSE +25 -0
- openapi_parser-0.3.0/PKG-INFO +129 -0
- openapi_parser-0.3.0/README.md +71 -0
- openapi_parser-0.3.0/pyproject.toml +3 -0
- openapi_parser-0.3.0/requirements.txt +11 -0
- openapi_parser-0.3.0/setup.cfg +4 -0
- openapi_parser-0.3.0/setup.py +29 -0
- openapi_parser-0.3.0/src/openapi_parser/__init__.py +26 -0
- openapi_parser-0.3.0/src/openapi_parser/__main__.py +5 -0
- openapi_parser-0.3.0/src/openapi_parser/cli.py +103 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/__init__.py +40 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/abstract_writer.py +154 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/attribute_writer.py +75 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/class_writer.py +125 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/client_writer.py +296 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/description_writer.py +110 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/exporting_features/__init__.py +1 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/exporting_features/client.py +37 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/exporting_features/utils.py +4 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/footer_writer.py +63 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/header_writer.py +55 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/inspect_writer.py +127 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/method_writer.py +245 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/model_writer.py +99 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/pacakge_init_writer.py +129 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/package_writer.py +174 -0
- openapi_parser-0.3.0/src/openapi_parser/exporter/utils_writer.py +78 -0
- openapi_parser-0.3.0/src/openapi_parser/model.py +359 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/__init__.py +30 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/date_formats.py +65 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/errors.py +77 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/filters.py +308 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/inheritance_support.py +166 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/loader.py +547 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/model_impl.py +543 -0
- openapi_parser-0.3.0/src/openapi_parser/parser/path.py +116 -0
- openapi_parser-0.3.0/src/openapi_parser/util/__init__.py +1 -0
- openapi_parser-0.3.0/src/openapi_parser/util/_backports.py +21 -0
- openapi_parser-0.3.0/src/openapi_parser/util/naming_conventions.py +57 -0
- openapi_parser-0.3.0/src/openapi_parser/util/typing_proxy.py +257 -0
- openapi_parser-0.3.0/src/openapi_parser/util/utils.py +95 -0
- openapi_parser-0.3.0/src/openapi_parser.egg-info/PKG-INFO +129 -0
- openapi_parser-0.3.0/src/openapi_parser.egg-info/SOURCES.txt +43 -0
- openapi_parser-0.3.0/src/openapi_parser.egg-info/dependency_links.txt +1 -0
- openapi_parser-0.3.0/src/openapi_parser.egg-info/requires.txt +25 -0
- openapi_parser-0.3.0/src/openapi_parser.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-2026, Peter Zaitcev
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openapi-parser
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: OpenAPI 3.0 specs parser and client/server generator
|
|
5
|
+
Home-page: https://gitlab.com/Hares-Lab/libraries/openapi-parser
|
|
6
|
+
Author: Peter Zaitcev / USSX Hares
|
|
7
|
+
Maintainer: Peter Zaitcev / USSX Hares
|
|
8
|
+
License: BSD 2-Clause License
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Natural Language :: English
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.7
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: PyYAML~=6.0.1
|
|
30
|
+
Requires-Dist: functional-python~=0.4.0
|
|
31
|
+
Requires-Dist: http-server-base~=2.0.10
|
|
32
|
+
Requires-Dist: license~=0.1a3
|
|
33
|
+
Requires-Dist: stringcase~=1.2.0
|
|
34
|
+
Requires-Dist: tornado~=6.2; python_version <= "3.8"
|
|
35
|
+
Requires-Dist: tornado~=6.5; python_version >= "3.9"
|
|
36
|
+
Requires-Dist: backports.cached-property~=1.0.2; python_version < "3.8"
|
|
37
|
+
Requires-Dist: singledispatchmethod~=1.0; python_version < "3.8"
|
|
38
|
+
Provides-Extra: test
|
|
39
|
+
Requires-Dist: wheel; extra == "test"
|
|
40
|
+
Requires-Dist: lxml; extra == "test"
|
|
41
|
+
Requires-Dist: unittest-xml-reporting; extra == "test"
|
|
42
|
+
Provides-Extra: all
|
|
43
|
+
Requires-Dist: wheel; extra == "all"
|
|
44
|
+
Requires-Dist: lxml; extra == "all"
|
|
45
|
+
Requires-Dist: unittest-xml-reporting; extra == "all"
|
|
46
|
+
Dynamic: author
|
|
47
|
+
Dynamic: classifier
|
|
48
|
+
Dynamic: description
|
|
49
|
+
Dynamic: description-content-type
|
|
50
|
+
Dynamic: home-page
|
|
51
|
+
Dynamic: license
|
|
52
|
+
Dynamic: license-file
|
|
53
|
+
Dynamic: maintainer
|
|
54
|
+
Dynamic: provides-extra
|
|
55
|
+
Dynamic: requires-dist
|
|
56
|
+
Dynamic: requires-python
|
|
57
|
+
Dynamic: summary
|
|
58
|
+
|
|
59
|
+
# OpenAPI 3.0 Parser
|
|
60
|
+
This package provides functionality to analyze [OpenAPI 3.0 Specification] files
|
|
61
|
+
and build clients and servers from that specification.
|
|
62
|
+
|
|
63
|
+
For more details, please refer the [Project Documentation]
|
|
64
|
+
|
|
65
|
+
### Example Usage
|
|
66
|
+
From the command line:
|
|
67
|
+
```bash
|
|
68
|
+
$ python -m openapi_parser data/petstore.yaml
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
From the Python:
|
|
72
|
+
```python
|
|
73
|
+
from openapi_parser.exporter import PackageWriter
|
|
74
|
+
from openapi_parser.parser.loader import OpenApiParser
|
|
75
|
+
|
|
76
|
+
def main():
|
|
77
|
+
parser = OpenApiParser.open('data/petstore.yaml')
|
|
78
|
+
parser.load_all()
|
|
79
|
+
|
|
80
|
+
package_writer = PackageWriter(parser)
|
|
81
|
+
package_writer.write_package()
|
|
82
|
+
|
|
83
|
+
return 0
|
|
84
|
+
|
|
85
|
+
if (__name__ == '__main__'):
|
|
86
|
+
exit_code = main()
|
|
87
|
+
exit(exit_code)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### TODOs:
|
|
91
|
+
- [x] Model generator:
|
|
92
|
+
- [x] Core functionality
|
|
93
|
+
- [x] Class inheritance support
|
|
94
|
+
- [x] Enums support
|
|
95
|
+
- [ ] Required properties in combination with `readOnly`/`writeOnly`
|
|
96
|
+
- [x] Discriminator property support
|
|
97
|
+
- [ ] Cyclic refs resolution
|
|
98
|
+
- [ ] Support of `additionalProperties` inside class
|
|
99
|
+
- [x] Client generator
|
|
100
|
+
- [x] Core functionality
|
|
101
|
+
- [x] Smart body encoding
|
|
102
|
+
- [x] Smart response decoding
|
|
103
|
+
- [ ] `style`-encoding
|
|
104
|
+
- [ ] `schema` and `content` inside parameters conflict support
|
|
105
|
+
- [x] Enums for parameters support
|
|
106
|
+
- [ ] Cookies parameters support
|
|
107
|
+
- [x] Methods descriptions
|
|
108
|
+
- [ ] Authorization support
|
|
109
|
+
- [x] Metadata extractor
|
|
110
|
+
- [x] Version
|
|
111
|
+
- [x] Licence
|
|
112
|
+
- [x] Description
|
|
113
|
+
- [x] Servers
|
|
114
|
+
- [x] Security definitions
|
|
115
|
+
- [ ] Server generator
|
|
116
|
+
- [ ] Test coverage
|
|
117
|
+
- [ ] Documentation
|
|
118
|
+
- [x] Command-line interface
|
|
119
|
+
- [x] Basic CLI support
|
|
120
|
+
- [ ] Extended CLI support
|
|
121
|
+
|
|
122
|
+
### See Also:
|
|
123
|
+
- [Project Documentation]
|
|
124
|
+
- [OpenAPI 3.0 Specification]
|
|
125
|
+
- [JSON Schema Standard]
|
|
126
|
+
|
|
127
|
+
[Project Documentation]: https://hares-lab.gitlab.io/openapi-parser
|
|
128
|
+
[OpenAPI 3.0 Specification]: https://swagger.io/specification
|
|
129
|
+
[JSON Schema Standard]: https://tools.ietf.org/html/draft-wright-json-schema-validation-00
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# OpenAPI 3.0 Parser
|
|
2
|
+
This package provides functionality to analyze [OpenAPI 3.0 Specification] files
|
|
3
|
+
and build clients and servers from that specification.
|
|
4
|
+
|
|
5
|
+
For more details, please refer the [Project Documentation]
|
|
6
|
+
|
|
7
|
+
### Example Usage
|
|
8
|
+
From the command line:
|
|
9
|
+
```bash
|
|
10
|
+
$ python -m openapi_parser data/petstore.yaml
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
From the Python:
|
|
14
|
+
```python
|
|
15
|
+
from openapi_parser.exporter import PackageWriter
|
|
16
|
+
from openapi_parser.parser.loader import OpenApiParser
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
parser = OpenApiParser.open('data/petstore.yaml')
|
|
20
|
+
parser.load_all()
|
|
21
|
+
|
|
22
|
+
package_writer = PackageWriter(parser)
|
|
23
|
+
package_writer.write_package()
|
|
24
|
+
|
|
25
|
+
return 0
|
|
26
|
+
|
|
27
|
+
if (__name__ == '__main__'):
|
|
28
|
+
exit_code = main()
|
|
29
|
+
exit(exit_code)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### TODOs:
|
|
33
|
+
- [x] Model generator:
|
|
34
|
+
- [x] Core functionality
|
|
35
|
+
- [x] Class inheritance support
|
|
36
|
+
- [x] Enums support
|
|
37
|
+
- [ ] Required properties in combination with `readOnly`/`writeOnly`
|
|
38
|
+
- [x] Discriminator property support
|
|
39
|
+
- [ ] Cyclic refs resolution
|
|
40
|
+
- [ ] Support of `additionalProperties` inside class
|
|
41
|
+
- [x] Client generator
|
|
42
|
+
- [x] Core functionality
|
|
43
|
+
- [x] Smart body encoding
|
|
44
|
+
- [x] Smart response decoding
|
|
45
|
+
- [ ] `style`-encoding
|
|
46
|
+
- [ ] `schema` and `content` inside parameters conflict support
|
|
47
|
+
- [x] Enums for parameters support
|
|
48
|
+
- [ ] Cookies parameters support
|
|
49
|
+
- [x] Methods descriptions
|
|
50
|
+
- [ ] Authorization support
|
|
51
|
+
- [x] Metadata extractor
|
|
52
|
+
- [x] Version
|
|
53
|
+
- [x] Licence
|
|
54
|
+
- [x] Description
|
|
55
|
+
- [x] Servers
|
|
56
|
+
- [x] Security definitions
|
|
57
|
+
- [ ] Server generator
|
|
58
|
+
- [ ] Test coverage
|
|
59
|
+
- [ ] Documentation
|
|
60
|
+
- [x] Command-line interface
|
|
61
|
+
- [x] Basic CLI support
|
|
62
|
+
- [ ] Extended CLI support
|
|
63
|
+
|
|
64
|
+
### See Also:
|
|
65
|
+
- [Project Documentation]
|
|
66
|
+
- [OpenAPI 3.0 Specification]
|
|
67
|
+
- [JSON Schema Standard]
|
|
68
|
+
|
|
69
|
+
[Project Documentation]: https://hares-lab.gitlab.io/openapi-parser
|
|
70
|
+
[OpenAPI 3.0 Specification]: https://swagger.io/specification
|
|
71
|
+
[JSON Schema Standard]: https://tools.ietf.org/html/draft-wright-json-schema-validation-00
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
PyYAML ~= 6.0.1
|
|
2
|
+
functional-python ~= 0.4.0
|
|
3
|
+
http-server-base ~= 2.0.10
|
|
4
|
+
license ~= 0.1a3
|
|
5
|
+
stringcase ~= 1.2.0
|
|
6
|
+
tornado ~= 6.2 ; python_version <= "3.8"
|
|
7
|
+
tornado ~= 6.5 ; python_version >= "3.9"
|
|
8
|
+
|
|
9
|
+
# Backports
|
|
10
|
+
backports.cached-property ~= 1.0.2 ; python_version < "3.8"
|
|
11
|
+
singledispatchmethod ~= 1.0 ; python_version < "3.8"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from extended_setup import ExtendedSetupManager
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
ExtendedSetupManager('openapi-parser').setup \
|
|
5
|
+
(
|
|
6
|
+
license = "BSD 2-Clause License",
|
|
7
|
+
short_description = "OpenAPI 3.0 specs parser and client/server generator",
|
|
8
|
+
min_python_version = '3.7',
|
|
9
|
+
classifiers =
|
|
10
|
+
[
|
|
11
|
+
'Development Status :: 2 - Pre-Alpha',
|
|
12
|
+
'Intended Audience :: Developers',
|
|
13
|
+
'Natural Language :: English',
|
|
14
|
+
'Operating System :: OS Independent',
|
|
15
|
+
'Programming Language :: Python :: 3.7',
|
|
16
|
+
'Programming Language :: Python :: 3.8',
|
|
17
|
+
'Programming Language :: Python :: 3.9',
|
|
18
|
+
'Programming Language :: Python :: 3.10',
|
|
19
|
+
'Programming Language :: Python :: 3.11',
|
|
20
|
+
'Programming Language :: Python :: 3.12',
|
|
21
|
+
'Programming Language :: Python :: 3.13',
|
|
22
|
+
'Programming Language :: Python :: 3.14',
|
|
23
|
+
'Topic :: Software Development :: Code Generators',
|
|
24
|
+
'Topic :: Software Development :: Libraries',
|
|
25
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
26
|
+
'Topic :: Utilities',
|
|
27
|
+
'Typing :: Typed',
|
|
28
|
+
]
|
|
29
|
+
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. include:: ../../README.md
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from collections import namedtuple
|
|
6
|
+
|
|
7
|
+
__title__ = 'openapi-parser'
|
|
8
|
+
__author__ = 'Peter Zaitcev / USSX Hares'
|
|
9
|
+
__license__ = 'BSD 2-clause'
|
|
10
|
+
__copyright__ = 'Copyright 2020-2026 Peter Zaitcev'
|
|
11
|
+
__version__ = '0.3.0'
|
|
12
|
+
|
|
13
|
+
VersionInfo = namedtuple('VersionInfo', 'major minor micro releaselevel serial')
|
|
14
|
+
version_info = VersionInfo(*__version__.split('.'), releaselevel='alpha', serial=0)
|
|
15
|
+
|
|
16
|
+
__all__ = \
|
|
17
|
+
[
|
|
18
|
+
'version_info',
|
|
19
|
+
'__title__',
|
|
20
|
+
'__author__',
|
|
21
|
+
'__license__',
|
|
22
|
+
'__copyright__',
|
|
23
|
+
'__version__',
|
|
24
|
+
]
|
|
25
|
+
__pdoc__ = { }
|
|
26
|
+
__pdoc_extras__ = [ ]
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from logging import getLogger, StreamHandler
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
from .__init__ import __version__, __title__
|
|
6
|
+
from .exporter import PackageWriter
|
|
7
|
+
from .model import HavingId
|
|
8
|
+
from .parser.loader import *
|
|
9
|
+
from .util.utils import list_pop_any
|
|
10
|
+
|
|
11
|
+
JUSTIFICATION_SIZE = 140
|
|
12
|
+
def get_logger(verbose: bool = False):
|
|
13
|
+
logger = getLogger('openapi-parser')
|
|
14
|
+
handler = StreamHandler(sys.stdout)
|
|
15
|
+
logger.addHandler(handler)
|
|
16
|
+
if (verbose):
|
|
17
|
+
handler.setLevel('DEBUG')
|
|
18
|
+
logger.setLevel('DEBUG')
|
|
19
|
+
else:
|
|
20
|
+
handler.setLevel('INFO')
|
|
21
|
+
logger.setLevel('INFO')
|
|
22
|
+
|
|
23
|
+
return logger
|
|
24
|
+
|
|
25
|
+
def run(schema_file: str, *writer_args, verbose: bool = False, dry_run: bool = False, clean: bool = True) -> int:
|
|
26
|
+
logger = get_logger(verbose=verbose)
|
|
27
|
+
|
|
28
|
+
parser = OpenApiParser.open(schema_file)
|
|
29
|
+
parser.load_all()
|
|
30
|
+
|
|
31
|
+
for path, mdl in parser.loaded_objects.items():
|
|
32
|
+
msg = ('# ' + type(mdl).__name__ + (f" '{mdl.id}'" if isinstance(mdl, HavingId) else '')).ljust(JUSTIFICATION_SIZE, ' ') + f" -- '{path}'"
|
|
33
|
+
logger.debug(msg)
|
|
34
|
+
logger.debug('# ' + '=' * JUSTIFICATION_SIZE)
|
|
35
|
+
logger.debug('')
|
|
36
|
+
|
|
37
|
+
package_writer = PackageWriter(parser, *writer_args, dry_run=dry_run)
|
|
38
|
+
package_writer.write_package(clean=clean)
|
|
39
|
+
return 0
|
|
40
|
+
|
|
41
|
+
def header_line() -> str:
|
|
42
|
+
return f"Python OpenAPI Parser Command-Line Interface v{__version__}"
|
|
43
|
+
def version_line() -> str:
|
|
44
|
+
return f"{__title__} {__version__}"
|
|
45
|
+
def usage_line() -> str:
|
|
46
|
+
return 'python -m openapi_parser SCHEMA [DESTINATION] [PACKAGE_NAME]'
|
|
47
|
+
def usage_options() -> List[str]:
|
|
48
|
+
return \
|
|
49
|
+
[
|
|
50
|
+
"-v, --verbose | Enables extra verbosity",
|
|
51
|
+
"--dry-run | Performs dry run (does not create any files)",
|
|
52
|
+
"--no-cleanup | Does not perform cleanup before running",
|
|
53
|
+
"-h, --help -? | Print this message and exit",
|
|
54
|
+
"-V, --version | Print version and exit",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
def cli(args: Optional[List[str]] = None) -> int:
|
|
58
|
+
if (args is None):
|
|
59
|
+
args = sys.argv[1:]
|
|
60
|
+
|
|
61
|
+
if (len(args) < 1):
|
|
62
|
+
print(header_line(), file=sys.stderr)
|
|
63
|
+
print(f"Not enough arguments, usage: {usage_line()}", file=sys.stderr)
|
|
64
|
+
return 1
|
|
65
|
+
|
|
66
|
+
help = bool(list_pop_any(args, '-h', '--help', '-?'))
|
|
67
|
+
if (help):
|
|
68
|
+
print(header_line())
|
|
69
|
+
print(f"Usage: {usage_line()}")
|
|
70
|
+
print()
|
|
71
|
+
print("Options:")
|
|
72
|
+
for opt in usage_options():
|
|
73
|
+
print(' '*4 + opt)
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
version = bool(list_pop_any(args, '-V', '--version'))
|
|
77
|
+
if (version):
|
|
78
|
+
print(version_line())
|
|
79
|
+
return 0
|
|
80
|
+
|
|
81
|
+
verbose = bool(list_pop_any(args, '-v', '--verbose'))
|
|
82
|
+
dry_run = bool(list_pop_any(args, '--dry-run'))
|
|
83
|
+
clean = not bool(list_pop_any(args, '--no-cleanup'))
|
|
84
|
+
schema_file = args.pop(0)
|
|
85
|
+
|
|
86
|
+
return run(schema_file, *args, verbose=verbose, dry_run=dry_run, clean=clean)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
__all__ = \
|
|
90
|
+
[
|
|
91
|
+
'cli',
|
|
92
|
+
'run',
|
|
93
|
+
'get_logger',
|
|
94
|
+
'usage_options',
|
|
95
|
+
'version_line',
|
|
96
|
+
'header_line',
|
|
97
|
+
'usage_line',
|
|
98
|
+
'JUSTIFICATION_SIZE',
|
|
99
|
+
]
|
|
100
|
+
__pdoc_extras__ = \
|
|
101
|
+
[
|
|
102
|
+
'JUSTIFICATION_SIZE',
|
|
103
|
+
]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from .abstract_writer import *
|
|
2
|
+
from .attribute_writer import *
|
|
3
|
+
from .class_writer import *
|
|
4
|
+
from .client_writer import *
|
|
5
|
+
from .description_writer import *
|
|
6
|
+
from .footer_writer import *
|
|
7
|
+
from .header_writer import *
|
|
8
|
+
from .inspect_writer import *
|
|
9
|
+
from .method_writer import *
|
|
10
|
+
from .model_writer import *
|
|
11
|
+
from .package_writer import *
|
|
12
|
+
from .utils_writer import *
|
|
13
|
+
|
|
14
|
+
__all__ = [ ]
|
|
15
|
+
|
|
16
|
+
_submodules = \
|
|
17
|
+
[
|
|
18
|
+
abstract_writer,
|
|
19
|
+
attribute_writer,
|
|
20
|
+
class_writer,
|
|
21
|
+
client_writer,
|
|
22
|
+
description_writer,
|
|
23
|
+
footer_writer,
|
|
24
|
+
header_writer,
|
|
25
|
+
inspect_writer,
|
|
26
|
+
method_writer,
|
|
27
|
+
model_writer,
|
|
28
|
+
package_writer,
|
|
29
|
+
utils_writer,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
__pdoc__ = { }
|
|
33
|
+
for _submodule in _submodules:
|
|
34
|
+
_submodule_name = _submodule.__name__.partition(f'{__name__}.')[-1]
|
|
35
|
+
__all__.extend(_submodule.__all__)
|
|
36
|
+
__pdoc__[_submodule_name] = True
|
|
37
|
+
_submodule.__pdoc__ = getattr(_submodule, '__pdoc__', dict())
|
|
38
|
+
_extras = getattr(_submodule, '__pdoc_extras__', list())
|
|
39
|
+
for _element in _submodule.__all__:
|
|
40
|
+
__pdoc__[_element] = _element in _extras
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import keyword
|
|
4
|
+
import re
|
|
5
|
+
from abc import ABC
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from functools import wraps, partial
|
|
8
|
+
from logging import Logger, getLogger
|
|
9
|
+
from typing import *
|
|
10
|
+
|
|
11
|
+
from openapi_parser.model import Model, Filter
|
|
12
|
+
from openapi_parser.util._backports import singledispatchmethod
|
|
13
|
+
from openapi_parser.util.naming_conventions import *
|
|
14
|
+
from openapi_parser.util.typing_proxy import ref_name_pretty, class_name_pretty, GenericProxy, ref_name_logger
|
|
15
|
+
from openapi_parser.util.utils import StrIO
|
|
16
|
+
|
|
17
|
+
W = TypeVar('W', bound='Writer')
|
|
18
|
+
class Writer(ABC):
|
|
19
|
+
JUSTIFICATION_SIZE = 80
|
|
20
|
+
INDENT_SIZE = 4
|
|
21
|
+
INDENT_SYMBOL = ' '
|
|
22
|
+
TRIPLE_QUOT = '"""'
|
|
23
|
+
TRIPLE_BACKQUOT = '```'
|
|
24
|
+
NEWLINE = '\n'
|
|
25
|
+
|
|
26
|
+
_indent_level: int
|
|
27
|
+
logger: Logger
|
|
28
|
+
def __init__(self, *args, **kwargs):
|
|
29
|
+
self._indent_level = 0
|
|
30
|
+
self.logger = getLogger(ref_name_logger(type(self)))
|
|
31
|
+
super().__init__(*args, **kwargs)
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def indent_level(self) -> int:
|
|
35
|
+
return self._indent_level
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def indent_marker(self) -> str:
|
|
39
|
+
return self.INDENT_SYMBOL * self.INDENT_SIZE
|
|
40
|
+
|
|
41
|
+
def indent(self, increment: int = 1) -> 'Indenting[W]':
|
|
42
|
+
return Indenting(self, increment)
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def class_name_pretty(cls, ref: Union[str, Type, GenericProxy, Model, Filter]) -> str:
|
|
46
|
+
if (isinstance(ref, str)):
|
|
47
|
+
return class_name(ref)
|
|
48
|
+
else:
|
|
49
|
+
return class_name_pretty(ref)
|
|
50
|
+
@classmethod
|
|
51
|
+
def package_name_pretty(cls, name: str) -> str:
|
|
52
|
+
return package_name(name)
|
|
53
|
+
@classmethod
|
|
54
|
+
def enum_entry_name_pretty(cls, name: str) -> str:
|
|
55
|
+
return enum_entry_name(name)
|
|
56
|
+
@classmethod
|
|
57
|
+
def field_name_pretty(cls, name: str) -> str:
|
|
58
|
+
return field_name(name)
|
|
59
|
+
@classmethod
|
|
60
|
+
def method_name_pretty(cls, name: str) -> str:
|
|
61
|
+
return method_name(name)
|
|
62
|
+
@classmethod
|
|
63
|
+
def const_name_pretty(cls, name: str) -> str:
|
|
64
|
+
return const_name(name)
|
|
65
|
+
@classmethod
|
|
66
|
+
def ref_name_pretty(cls, ref: Union[object, str], full: bool = False) -> str:
|
|
67
|
+
if (isinstance(ref, str)):
|
|
68
|
+
return ref
|
|
69
|
+
else:
|
|
70
|
+
return ref_name_pretty(ref, full=full)
|
|
71
|
+
@classmethod
|
|
72
|
+
def object_valid_name_filter(cls, name: str) -> str:
|
|
73
|
+
if (not re.fullmatch(r'\w+', name)):
|
|
74
|
+
name = re.sub(r'[\W_]+', '_', name).strip('_')
|
|
75
|
+
if (not name):
|
|
76
|
+
name += '_'
|
|
77
|
+
if (name[0].isdigit()):
|
|
78
|
+
name = 'OBJECT_' + name
|
|
79
|
+
if (name in keyword.kwlist):
|
|
80
|
+
name += '_'
|
|
81
|
+
|
|
82
|
+
return name
|
|
83
|
+
@classmethod
|
|
84
|
+
def constructor(cls, prefix: str, *args, suffix: str = '', sep: str = '=', brackets: Tuple[str, str] = ('(', ')'), **kwargs) -> str:
|
|
85
|
+
return prefix + brackets[0] + ', '.join(list(args) + [ f'{k}{sep}{v}' for k, v in kwargs.items() ]) + brackets[1] + suffix
|
|
86
|
+
@classmethod
|
|
87
|
+
def dict_constructor(cls, **kwargs) -> str:
|
|
88
|
+
return cls.constructor('', sep=': ', brackets=('{', '}'), **{ repr(k): v for k, v in kwargs.items() })
|
|
89
|
+
def multiline_constructor(self, prefix: str, *args, suffix: str = '', sep: str = ' = ', brackets: Tuple[str, str] = ('(', ')'), **kwargs) -> Iterator[str]:
|
|
90
|
+
yield f'{prefix} \\'
|
|
91
|
+
yield brackets[0]
|
|
92
|
+
with self.indent():
|
|
93
|
+
for x in args:
|
|
94
|
+
yield f'{x},'
|
|
95
|
+
for k, v in kwargs.items():
|
|
96
|
+
yield f'{k}{sep}{v},'
|
|
97
|
+
yield brackets[1] + suffix
|
|
98
|
+
def smart_constructor(self, prefix: str, *args, suffix: str = '', **kwargs) -> Iterator[str]:
|
|
99
|
+
inline = self.constructor(prefix, *args, suffix=suffix, **kwargs)
|
|
100
|
+
if (len(inline) < 160):
|
|
101
|
+
yield inline
|
|
102
|
+
else:
|
|
103
|
+
yield from self.multiline_constructor(prefix, *args, suffix=suffix, **kwargs)
|
|
104
|
+
|
|
105
|
+
@singledispatchmethod
|
|
106
|
+
def join_line(self, indent_level: int, line_text: str) -> str:
|
|
107
|
+
return self.indent_marker * indent_level + line_text
|
|
108
|
+
@join_line.register
|
|
109
|
+
def _(self, tup: tuple) -> str:
|
|
110
|
+
return self.join_line(*tup)
|
|
111
|
+
|
|
112
|
+
def write_line(self, file: StrIO, line: str):
|
|
113
|
+
file.write(line)
|
|
114
|
+
file.write(self.NEWLINE)
|
|
115
|
+
|
|
116
|
+
# noinspection PyProtectedMember
|
|
117
|
+
@dataclass
|
|
118
|
+
class Indenting(ContextManager, Generic[W]):
|
|
119
|
+
writer: W
|
|
120
|
+
increment: int = 1
|
|
121
|
+
|
|
122
|
+
def __enter__(self):
|
|
123
|
+
self.writer._indent_level += self.increment
|
|
124
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
125
|
+
self.writer._indent_level -= self.increment
|
|
126
|
+
|
|
127
|
+
def yielder(dumper_func: Callable[[W], Iterator[Optional[str]]]) -> Callable[[W], Iterator[Tuple[int, str]]]:
|
|
128
|
+
@wraps(dumper_func)
|
|
129
|
+
def wrapper(self: Writer, *args, **kwargs):
|
|
130
|
+
# noinspection PyArgumentList
|
|
131
|
+
return map(lambda line: (self.indent_level, line or ''), dumper_func(self, *args, **kwargs))
|
|
132
|
+
return wrapper
|
|
133
|
+
|
|
134
|
+
def writer(yielder_func: Callable[[W], Iterator[Tuple[int, str]]]) -> Callable[[W], Optional[Iterator[str]]]:
|
|
135
|
+
@wraps(yielder_func)
|
|
136
|
+
def wrapper(self: Writer, *args, file: StrIO | None = None, **kwargs):
|
|
137
|
+
# noinspection PyArgumentList
|
|
138
|
+
stream = map(self.join_line, yielder_func(self, *args, **kwargs))
|
|
139
|
+
if (file is not None):
|
|
140
|
+
list(map(partial(self.write_line, file), stream))
|
|
141
|
+
else:
|
|
142
|
+
return stream
|
|
143
|
+
|
|
144
|
+
return wrapper
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
__all__ = \
|
|
148
|
+
[
|
|
149
|
+
'Indenting',
|
|
150
|
+
'Writer',
|
|
151
|
+
|
|
152
|
+
'writer',
|
|
153
|
+
'yielder',
|
|
154
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
from functional import OptionNone, Some, Option
|
|
5
|
+
|
|
6
|
+
from openapi_parser.model import ModelSchema
|
|
7
|
+
from openapi_parser.util.typing_proxy import GenericProxy
|
|
8
|
+
from .abstract_writer import Writer
|
|
9
|
+
|
|
10
|
+
class AttributeWriter(Writer, ABC):
|
|
11
|
+
def parse_attribute(self, name: str, prop: Optional[ModelSchema], *, is_required: bool = True) -> Tuple[str, Option[str], Option[str], Option[str]]:
|
|
12
|
+
field_name_pretty = self.field_name_pretty(name)
|
|
13
|
+
actual_name = self.object_valid_name_filter(field_name_pretty)
|
|
14
|
+
|
|
15
|
+
if (prop is None):
|
|
16
|
+
f_type = Some('Optional[Any]') if (not is_required) else OptionNone
|
|
17
|
+
f_value = Some('None') if (not is_required) else OptionNone
|
|
18
|
+
f_default = Some('None') if (not is_required) else OptionNone
|
|
19
|
+
|
|
20
|
+
else:
|
|
21
|
+
if (prop.cls == Any):
|
|
22
|
+
f_type = OptionNone
|
|
23
|
+
else:
|
|
24
|
+
f_type = Some(self.class_name_pretty(prop.cls)) if isinstance(prop, ModelSchema) else OptionNone
|
|
25
|
+
f_default = prop.default
|
|
26
|
+
|
|
27
|
+
# for enum in find_filters(prop.filter, ModelEnumData):
|
|
28
|
+
# f_type = Some(self.object_valid_name_filter(self.class_name_pretty(enum)))
|
|
29
|
+
|
|
30
|
+
if (not is_required):
|
|
31
|
+
f_type = f_type.map('Optional[{}]'.format)
|
|
32
|
+
f_default = f_default or (Some(None) if (not is_required) else OptionNone)
|
|
33
|
+
|
|
34
|
+
f_value = f_default.map('{!r}'.format)
|
|
35
|
+
|
|
36
|
+
return actual_name, f_type, f_value, f_default
|
|
37
|
+
|
|
38
|
+
def join_attribute(self, actual_name: str, f_type: Option[str], f_value: Option[str]) -> str:
|
|
39
|
+
return actual_name + f_type.map(': {}'.format).get_or_else('') + f_value.map(' = {}'.format).get_or_else('')
|
|
40
|
+
|
|
41
|
+
def extract_generic_coder(self, generic: GenericProxy, coder_type: str) -> Optional[str]:
|
|
42
|
+
parsed = generic.deep_coder(coder_type)
|
|
43
|
+
if (parsed is None):
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
return 'lambda x: ' + self._extract_generic_coder('x', *parsed)
|
|
47
|
+
|
|
48
|
+
def _extract_generic_coder(self, super_var: str, gen: GenericProxy, params: Dict[str, Optional[Union[Tuple, Callable, str, None]]]) -> str:
|
|
49
|
+
items = list()
|
|
50
|
+
for var, coder in params.items():
|
|
51
|
+
if (coder is None):
|
|
52
|
+
coder = var
|
|
53
|
+
elif (isinstance(coder, tuple)):
|
|
54
|
+
coder = Option(self._extract_generic_coder(var, *coder)).map(lambda x: x + f'({var})').get_or_else(var)
|
|
55
|
+
else:
|
|
56
|
+
coder = self.ref_name_pretty(coder)
|
|
57
|
+
|
|
58
|
+
items.append(coder)
|
|
59
|
+
|
|
60
|
+
return gen.constructor(f"{gen.item_constructor(tuple(items))} for {', '.join(params.keys())} in {gen.iterator(super_var)}")
|
|
61
|
+
|
|
62
|
+
def extract_coder(self, prop: ModelSchema, coder_type: str) -> Optional[str]:
|
|
63
|
+
coder = getattr(prop.filter, coder_type)
|
|
64
|
+
if (coder is not None):
|
|
65
|
+
return self.ref_name_pretty(coder)
|
|
66
|
+
elif (isinstance(prop.cls, GenericProxy)):
|
|
67
|
+
return self.extract_generic_coder(prop.cls, coder_type)
|
|
68
|
+
else:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
__all__ = \
|
|
73
|
+
[
|
|
74
|
+
'AttributeWriter',
|
|
75
|
+
]
|