Skip to content

Commit 247e120

Browse files
committed
make adjustments so the python SDK can be generated
1 parent 701a5b2 commit 247e120

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+4272
-2
lines changed

scripts/generate-sdk/generate-sdk.sh

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ ROOT_DIR=$(git rev-parse --show-toplevel)
1515
GENERATOR_PATH="${ROOT_DIR}/scripts/bin"
1616
LANGUAGE_GENERATORS_FOLDER_PATH="${ROOT_DIR}/scripts/generate-sdk/languages/"
1717
# Renovate: datasource=github-tags depName=OpenAPITools/openapi-generator versioning=semver
18-
GENERATOR_VERSION="v6.6.0"
19-
GENERATOR_VERSION_NUMBER="${GENERATOR_VERSION:1}"
2018

2119
# Check parameters and set defaults if not provided
2220
if [[ -z ${GIT_HOST} ]]; then
@@ -46,6 +44,21 @@ if [ ! -d ${ROOT_DIR}/oas ]; then
4644
echo "\"oas\" folder not found in root. Please add it manually or run \"make download-oas\"."
4745
exit 1
4846
fi
47+
# Choose generator version depending on the language
48+
# Renovate: datasource=github-tags depName=OpenAPITools/openapi-generator versioning=semver
49+
case "${LANGUAGE}" in
50+
go)
51+
GENERATOR_VERSION="v6.6.0" # There are issues with GO SDK generation in version v7
52+
;;
53+
python)
54+
GENERATOR_VERSION="v7.7.0"
55+
;;
56+
*)
57+
echo "SDK language not supported."
58+
exit 1
59+
;;
60+
esac
61+
GENERATOR_VERSION_NUMBER="${GENERATOR_VERSION:1}"
4962

5063
# Download OpenAPI generator if not already downloaded
5164
jar_path="${GENERATOR_PATH}/openapi-generator-cli.jar"
@@ -67,6 +80,13 @@ go)
6780
# Usage: generate_go_sdk GENERATOR_PATH GIT_HOST GIT_USER_ID [GIT_REPO_ID] [SDK_REPO_URL]
6881
generate_go_sdk ${jar_path} ${GIT_HOST} ${GIT_USER_ID} ${GIT_REPO_ID} ${SDK_REPO_URL}
6982
;;
83+
python)
84+
echo -e "\nGenerating the Python SDK...\n"
85+
86+
source ${LANGUAGE_GENERATORS_FOLDER_PATH}/${LANGUAGE}.sh
87+
# Usage: generate_python_sdk GENERATOR_PATH GIT_HOST GIT_USER_ID [GIT_REPO_ID] [SDK_REPO_URL]
88+
generate_python_sdk ${jar_path} ${GIT_HOST} ${GIT_USER_ID} ${GIT_REPO_ID} ${SDK_REPO_URL}
89+
;;
7090
*)
7191
echo "SDK language not supported."
7292
exit 1
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/bin/bash
2+
# This script clones the SDK repo and updates it with the generated API modules
3+
# Pre-requisites: Java, goimports, Go
4+
set -eo pipefail
5+
6+
ROOT_DIR=$(git rev-parse --show-toplevel)
7+
SDK_REPO_LOCAL_PATH="${ROOT_DIR}/python-sdk-repo-updated"
8+
9+
OAS_REPO=https://github.com/stackitcloud/stackit-api-specifications
10+
11+
SERVICES_FOLDER="${SDK_REPO_LOCAL_PATH}/services"
12+
13+
GENERATOR_LOG_LEVEL="error" # Must be a Java log level (error, warn, info...)
14+
15+
generate_python_sdk() {
16+
# Required parameters
17+
local GENERATOR_JAR_PATH=$1
18+
local GIT_HOST=$2
19+
local GIT_USER_ID=$3
20+
21+
# Optional parameters
22+
local GIT_REPO_ID=$4
23+
local SDK_REPO_URL=$5
24+
25+
# Check required parameters
26+
if [[ -z ${GIT_HOST} ]]; then
27+
echo "GIT_HOST not specified."
28+
exit 1
29+
fi
30+
31+
if [[ -z ${GIT_USER_ID} ]]; then
32+
echo "GIT_USER_ID id not specified."
33+
exit 1
34+
fi
35+
36+
# Check optional parameters and set defaults if not provided
37+
if [[ -z ${GIT_REPO_ID} ]]; then
38+
echo "GIT_REPO_ID not specified, default will be used."
39+
GIT_REPO_ID="stackit-sdk-python"
40+
fi
41+
42+
if [[ -z ${SDK_REPO_URL} ]]; then
43+
echo "SDK_REPO_URL not specified, default will be used."
44+
SDK_REPO_URL="https://github.com/stackitcloud/stackit-sdk-python.git"
45+
fi
46+
47+
# Prepare folders
48+
if [[ ! -d $SERVICES_FOLDER ]]; then
49+
mkdir -p "$SERVICES_FOLDER"
50+
fi
51+
52+
# Clone SDK repo
53+
if [ -d ${SDK_REPO_LOCAL_PATH} ]; then
54+
echo "Old SDK repo clone was found, it will be removed."
55+
rm -rf ${SDK_REPO_LOCAL_PATH}
56+
fi
57+
git clone --quiet ${SDK_REPO_URL} ${SDK_REPO_LOCAL_PATH}
58+
59+
# Install SDK project tools
60+
cd ${ROOT_DIR}
61+
make project-tools
62+
63+
# Backup of the current state of the SDK services dir (services/)
64+
sdk_services_backup_dir=$(mktemp -d)
65+
if [[ ! ${sdk_services_backup_dir} || -d {sdk_services_backup_dir} ]]; then
66+
echo "Unable to create temporary directory"
67+
exit 1
68+
fi
69+
cleanup() {
70+
rm -rf ${sdk_services_backup_dir}
71+
}
72+
cp -a "${SERVICES_FOLDER}/." ${sdk_services_backup_dir}
73+
74+
# Cleanup after we are done
75+
trap cleanup EXIT
76+
77+
# Remove old contents of services dir (services/)
78+
rm -rf ${SERVICES_FOLDER}
79+
80+
# Generate SDK for each service
81+
for service_json in ${ROOT_DIR}/oas/*.json; do
82+
service="${service_json##*/}"
83+
service="${service%.json}"
84+
85+
# Remove invalid characters to ensure a valid Go pkg name
86+
service="${service//-/}" # remove dashes
87+
service="${service// /}" # remove empty spaces
88+
service="${service//_/}" # remove underscores
89+
service=$(echo "${service}" | tr '[:upper:]' '[:lower:]') # convert upper case letters to lower case
90+
service=$(echo "${service}" | tr -d -c '[:alnum:]') # remove non-alphanumeric characters
91+
92+
echo "Generating \"${service}\" service..."
93+
cd ${ROOT_DIR}
94+
95+
mkdir -p "${SERVICES_FOLDER}/${service}/"
96+
cp "${ROOT_DIR}/scripts/generate-sdk/.openapi-generator-ignore" "${SERVICES_FOLDER}/${service}/"
97+
98+
# Run the generator
99+
java -Dlog.level=${GENERATOR_LOG_LEVEL} -jar ${jar_path} generate \
100+
--generator-name python \
101+
--input-spec "${service_json}" \
102+
--output "${SERVICES_FOLDER}/${service}" \
103+
--package-name "stackit.${service}" \
104+
--template-dir "${ROOT_DIR}/templates/python/" \
105+
--git-host ${GIT_HOST} \
106+
--git-user-id ${GIT_USER_ID} \
107+
--git-repo-id ${GIT_REPO_ID} \
108+
--global-property apis,models,modelTests=false,modelDocs=false,apiDocs=false,apiTests=false,supportingFiles \
109+
--additional-properties=pythonPackageName="stackit-${service},removeEnumValuePrefix=false" >/dev/null
110+
##--enable-post-process-file \
111+
112+
# Remove unnecessary files
113+
rm "${SERVICES_FOLDER}/${service}/.openapi-generator-ignore"
114+
rm -r "${SERVICES_FOLDER}/${service}/.openapi-generator/"
115+
rm "${SERVICES_FOLDER}/${service}/stackit/__init__.py"
116+
117+
# If the service has a wait package files, move them inside the service folder
118+
if [ -d ${sdk_services_backup_dir}/${service}/wait ]; then
119+
echo "Found ${service} \"wait\" package"
120+
cp -r ${sdk_services_backup_dir}/${service}/wait ${SERVICES_FOLDER}/${service}/wait
121+
fi
122+
123+
# If the service has a CHANGELOG file, move it inside the service folder
124+
if [ -f ${sdk_services_backup_dir}/${service}/CHANGELOG.md ]; then
125+
echo "Found ${service} \"CHANGELOG\" file"
126+
cp -r ${sdk_services_backup_dir}/${service}/CHANGELOG.md ${SERVICES_FOLDER}/${service}/CHANGELOG.md
127+
fi
128+
129+
# If the service has a LICENSE file, move it inside the service folder
130+
if [ -f ${sdk_services_backup_dir}/${service}/LICENSE.md ]; then
131+
echo "Found ${service} \"LICENSE\" file"
132+
cp -r ${sdk_services_backup_dir}/${service}/LICENSE.md ${SERVICES_FOLDER}/${service}/LICENSE.md
133+
fi
134+
135+
# If the service has a NOTICE file, move it inside the service folder
136+
if [ -f ${sdk_services_backup_dir}/${service}/NOTICE.txt ]; then
137+
echo "Found ${service} \"NOTICE\" file"
138+
cp -r ${sdk_services_backup_dir}/${service}/NOTICE.txt ${SERVICES_FOLDER}/${service}/NOTICE.txt
139+
fi
140+
141+
cd ${SERVICES_FOLDER}/${service}
142+
# Run formatter
143+
isort .
144+
autoimport --ignore-init-modules .
145+
black .
146+
147+
done
148+
}

templates/python/README.mustache

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# {{{projectName}}}
2+
{{#appDescriptionWithNewLines}}
3+
{{{.}}}
4+
{{/appDescriptionWithNewLines}}
5+
6+
This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
7+
8+
- API version: {{appVersion}}
9+
- Package version: {{packageVersion}}
10+
{{^hideGenerationTimestamp}}
11+
- Build date: {{generatedDate}}
12+
{{/hideGenerationTimestamp}}
13+
- Generator version: {{generatorVersion}}
14+
- Build package: {{generatorClass}}
15+
{{#infoUrl}}
16+
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
17+
{{/infoUrl}}
18+
19+
## Requirements.
20+
21+
Python {{{generatorLanguageVersion}}}
22+
23+
## Installation & Usage
24+
### pip install
25+
26+
If the python package is hosted on a repository, you can install directly using:
27+
28+
```sh
29+
pip install git+https://{{gitHost}}/{{{gitUserId}}}/{{{gitRepoId}}}.git
30+
```
31+
(you may need to run `pip` with root permission: `sudo pip install git+https://{{gitHost}}/{{{gitUserId}}}/{{{gitRepoId}}}.git`)
32+
33+
Then import the package:
34+
```python
35+
import {{{packageName}}}
36+
```
37+
38+
### Setuptools
39+
40+
Install via [Setuptools](http://pypi.python.org/pypi/setuptools).
41+
42+
```sh
43+
python setup.py install --user
44+
```
45+
(or `sudo python setup.py install` to install the package for all users)
46+
47+
Then import the package:
48+
```python
49+
import {{{packageName}}}
50+
```
51+
52+
### Tests
53+
54+
Execute `pytest` to run the tests.
55+
56+
## Getting Started
57+
58+
Please follow the [installation procedure](#installation--usage) and then run the following:
59+
60+
{{> common_README }}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# {{{projectName}}}
2+
{{#appDescription}}
3+
{{{.}}}
4+
{{/appDescription}}
5+
6+
The `{{packageName}}` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
7+
8+
- API version: {{appVersion}}
9+
- Package version: {{packageVersion}}
10+
{{^hideGenerationTimestamp}}
11+
- Build date: {{generatedDate}}
12+
{{/hideGenerationTimestamp}}
13+
- Generator version: {{generatorVersion}}
14+
- Build package: {{generatorClass}}
15+
{{#infoUrl}}
16+
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
17+
{{/infoUrl}}
18+
19+
## Requirements.
20+
21+
Python {{{generatorLanguageVersion}}}
22+
23+
## Installation & Usage
24+
25+
This python library package is generated without supporting files like setup.py or requirements files
26+
27+
To be able to use it, you will need these dependencies in your own package that uses this library:
28+
29+
* urllib3 >= 1.25.3
30+
* python-dateutil
31+
{{#asyncio}}
32+
* aiohttp
33+
{{/asyncio}}
34+
{{#tornado}}
35+
* tornado>=4.2,<5
36+
{{/tornado}}
37+
* pydantic
38+
39+
## Getting Started
40+
41+
In your own code, to use this library to connect and interact with {{{projectName}}},
42+
you can run the following:
43+
44+
{{> common_README }}

templates/python/__init__.mustache

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# flake8: noqa
2+
3+
# import apis into api package
4+
{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classFilename}} import {{classname}}
5+
{{/apis}}{{/apiInfo}}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# coding: utf-8
2+
3+
# flake8: noqa
4+
{{>partial_header}}
5+
6+
# import models into model package
7+
{{#models}}
8+
{{#model}}
9+
from {{modelPackage}}.{{classFilename}} import {{classname}}
10+
{{/model}}
11+
{{/models}}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# coding: utf-8
2+
3+
# flake8: noqa
4+
5+
{{>partial_header}}
6+
7+
__version__ = "{{packageVersion}}"
8+
9+
# import apis into sdk package
10+
{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classFilename}} import {{classname}}
11+
{{/apis}}{{/apiInfo}}
12+
# import ApiClient
13+
from {{packageName}}.api_response import ApiResponse
14+
from {{packageName}}.api_client import ApiClient
15+
from {{packageName}}.configuration import HostConfiguration
16+
from {{packageName}}.exceptions import OpenApiException
17+
from {{packageName}}.exceptions import ApiTypeError
18+
from {{packageName}}.exceptions import ApiValueError
19+
from {{packageName}}.exceptions import ApiKeyError
20+
from {{packageName}}.exceptions import ApiAttributeError
21+
from {{packageName}}.exceptions import ApiException
22+
{{#hasHttpSignatureMethods}}
23+
from {{packageName}}.signing import HttpSigningConfiguration
24+
{{/hasHttpSignatureMethods}}
25+
26+
# import models into sdk package
27+
{{#models}}
28+
{{#model}}
29+
from {{modelPackage}}.{{classFilename}} import {{classname}}
30+
{{/model}}
31+
{{/models}}
32+
{{#recursionLimit}}
33+
34+
__import__('sys').setrecursionlimit({{{.}}})
35+
{{/recursionLimit}}

0 commit comments

Comments
 (0)