1
+ #! /bin/bash
2
+
3
+ set -e
4
+
5
+ SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
6
+ PROJECT_ROOT=" ${SCRIPT_DIR} /.."
7
+ DEFAULT_OPENAPI_FILE=" ${SCRIPT_DIR} /openapi.json"
8
+ DEFAULT_PACKAGE_NAME=" permify"
9
+ DEFAULT_CLIENT_NAME=" PermifyClient"
10
+
11
+ usage () {
12
+ echo " Usage: $0 [OPTIONS]"
13
+ echo " "
14
+ echo " Generate Python SDK from OpenAPI specification and update project directories"
15
+ echo " "
16
+ echo " Options:"
17
+ echo " -i, --input FILE OpenAPI JSON file (default: ${DEFAULT_OPENAPI_FILE} )"
18
+ echo " -p, --package NAME Python package name (default: ${DEFAULT_PACKAGE_NAME} )"
19
+ echo " -c, --client NAME Client class name (default: ${DEFAULT_CLIENT_NAME} )"
20
+ echo " -h, --help Show this help message"
21
+ echo " "
22
+ echo " This script will update the following:"
23
+ echo " - ../permify (generated Python package)"
24
+ echo " - ../docs (API documentation)"
25
+ echo " - ../test (generated tests)"
26
+ echo " - ../setup.py (package metadata and dependencies)"
27
+ echo " - ../pyproject.toml (package metadata and dependencies)"
28
+ echo " "
29
+ echo " Examples:"
30
+ echo " $0 # Use defaults"
31
+ echo " $0 -i swagger.json # Custom input file"
32
+ echo " $0 -p custom_package # Custom package name"
33
+ }
34
+
35
+ OPENAPI_FILE=" ${DEFAULT_OPENAPI_FILE} "
36
+ PACKAGE_NAME=" ${DEFAULT_PACKAGE_NAME} "
37
+ CLIENT_NAME=" ${DEFAULT_CLIENT_NAME} "
38
+
39
+ while [[ $# -gt 0 ]]; do
40
+ case $1 in
41
+ -i|--input)
42
+ OPENAPI_FILE=" $2 "
43
+ shift 2
44
+ ;;
45
+ -p|--package)
46
+ PACKAGE_NAME=" $2 "
47
+ shift 2
48
+ ;;
49
+ -c|--client)
50
+ CLIENT_NAME=" $2 "
51
+ shift 2
52
+ ;;
53
+ -h|--help)
54
+ usage
55
+ exit 0
56
+ ;;
57
+ * )
58
+ echo " Unknown option: $1 "
59
+ usage
60
+ exit 1
61
+ ;;
62
+ esac
63
+ done
64
+
65
+ if [[ ! -f " ${OPENAPI_FILE} " ]]; then
66
+ echo " Error: OpenAPI file '${OPENAPI_FILE} ' not found"
67
+ exit 1
68
+ fi
69
+
70
+ # Check if Java is available
71
+ if ! command -v java & > /dev/null; then
72
+ echo " Error: Java is required but not installed"
73
+ exit 1
74
+ fi
75
+
76
+ TEMP_OUTPUT_DIR=$( mktemp -d)
77
+ trap ' rm -rf "${TEMP_OUTPUT_DIR}"' EXIT
78
+
79
+ OPENAPI_ABSOLUTE_PATH=$( realpath " ${OPENAPI_FILE} " )
80
+
81
+ OPENAPI_VERSION=$( grep -o ' "version": *"[^"]*"' " ${OPENAPI_FILE} " | cut -d ' "' -f 4)
82
+ if [[ -z " ${OPENAPI_VERSION} " ]]; then
83
+ echo " Error: Could not extract version from OpenAPI file"
84
+ exit 1
85
+ fi
86
+
87
+ echo " Generating Python SDK..."
88
+ echo " OpenAPI file: ${OPENAPI_ABSOLUTE_PATH} "
89
+ echo " OpenAPI version: ${OPENAPI_VERSION} "
90
+ echo " Package name: ${PACKAGE_NAME} "
91
+ echo " Client name: ${CLIENT_NAME} "
92
+ echo " Temp directory: ${TEMP_OUTPUT_DIR} "
93
+ echo " "
94
+
95
+ # Download OpenAPI Generator CLI JAR if not present
96
+ GENERATOR_JAR=" ${SCRIPT_DIR} /openapi-generator-cli.jar"
97
+ if [[ ! -f " ${GENERATOR_JAR} " ]]; then
98
+ echo " Downloading OpenAPI Generator CLI..."
99
+ curl -L -o " ${GENERATOR_JAR} " https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.2.0/openapi-generator-cli-7.2.0.jar
100
+ fi
101
+
102
+ # Generate SDK using OpenAPI Generator CLI
103
+ java -jar " ${GENERATOR_JAR} " generate \
104
+ -i " ${OPENAPI_ABSOLUTE_PATH} " \
105
+ -g python \
106
+ -o " ${TEMP_OUTPUT_DIR} " \
107
+ --package-name=" ${PACKAGE_NAME} " \
108
+ --additional-properties=packageName=" ${PACKAGE_NAME} " \
109
+ --additional-properties=clientPackage=" ${PACKAGE_NAME} " \
110
+ --additional-properties=projectName=" ${PACKAGE_NAME} " \
111
+ --additional-properties=packageUrl=" https://github.com/Permify/permify-python" \
112
+ --additional-properties=packageVersion=" ${OPENAPI_VERSION} " \
113
+ --additional-properties=packageDescription=" " " Permify is an open source authorization service for creating fine-grained and scalable authorization systems." " " \
114
+ --additional-properties=library=urllib3 \
115
+ --additional-properties=hideGenerationTimestamp=true \
116
+ --additional-properties=generateSourceCodeOnly=false \
117
+ --additional-properties=licenseName=" Apache-2.0" \
118
+ --skip-validate-spec
119
+
120
+ if [[ $? -ne 0 ]]; then
121
+ echo " "
122
+ echo " ❌ Failed to generate Python SDK"
123
+ exit 1
124
+ fi
125
+
126
+ echo " Updating project directories..."
127
+
128
+ # Update the main package directory
129
+ PACKAGE_DIR=" ${PROJECT_ROOT} /${PACKAGE_NAME} "
130
+ if [[ -d " ${TEMP_OUTPUT_DIR} /${PACKAGE_NAME} " ]]; then
131
+ echo " Updating ${PACKAGE_DIR} "
132
+ # Backup any custom files that shouldn't be overwritten
133
+ if [[ -f " ${PACKAGE_DIR} /py.typed" ]]; then
134
+ cp " ${PACKAGE_DIR} /py.typed" " ${TEMP_OUTPUT_DIR} /${PACKAGE_NAME} /py.typed"
135
+ fi
136
+
137
+ rm -rf " ${PACKAGE_DIR} "
138
+ cp -r " ${TEMP_OUTPUT_DIR} /${PACKAGE_NAME} " " ${PACKAGE_DIR} "
139
+ fi
140
+
141
+ # Update documentation
142
+ DOCS_DIR=" ${PROJECT_ROOT} /docs"
143
+ if [[ -d " ${TEMP_OUTPUT_DIR} /docs" ]]; then
144
+ echo " Updating ${DOCS_DIR} "
145
+ rm -rf " ${DOCS_DIR} " /* .md
146
+ mkdir -p " ${DOCS_DIR} "
147
+ cp " ${TEMP_OUTPUT_DIR} /docs/" * .md " ${DOCS_DIR} /"
148
+ fi
149
+
150
+ # Update tests
151
+ TEST_DIR=" ${PROJECT_ROOT} /test"
152
+ if [[ -d " ${TEMP_OUTPUT_DIR} /test" ]]; then
153
+ echo " Updating ${TEST_DIR} "
154
+ rm -rf " ${TEST_DIR} "
155
+ mkdir -p " ${TEST_DIR} "
156
+ cp -r " ${TEMP_OUTPUT_DIR} /test/" * " ${TEST_DIR} /"
157
+ fi
158
+
159
+ # Function to update setup.py with repository information
160
+ update_setup_py () {
161
+ local generated_setup=" ${TEMP_OUTPUT_DIR} /setup.py"
162
+ local target_setup=" ${PROJECT_ROOT} /setup.py"
163
+
164
+ if [[ ! -f " ${generated_setup} " ]]; then
165
+ echo " ⚠️ Warning: Generated setup.py not found, skipping update"
166
+ return
167
+ fi
168
+
169
+ echo " Updating setup.py"
170
+
171
+ # Create a backup
172
+ if [[ -f " ${target_setup} " ]]; then
173
+ cp " ${target_setup} " " ${target_setup} .bak"
174
+ fi
175
+
176
+ # Directly copy the generated setup.py without any modifications
177
+ cp " ${generated_setup} " " ${target_setup} "
178
+
179
+ echo " ✅ Updated setup.py"
180
+ }
181
+
182
+ # Function to update pyproject.toml
183
+ update_pyproject_toml () {
184
+ local target_pyproject=" ${PROJECT_ROOT} /pyproject.toml"
185
+
186
+ if [[ ! -f " ${target_pyproject} " ]]; then
187
+ echo " ⚠️ Warning: pyproject.toml not found, skipping update"
188
+ return
189
+ fi
190
+
191
+ echo " Updating pyproject.toml version"
192
+
193
+ # Strip 'v' prefix from version if present
194
+ VERSION_WITHOUT_V=" ${OPENAPI_VERSION# v} "
195
+
196
+ # Update version in pyproject.toml
197
+ if [[ " $OSTYPE " == " darwin" * ]]; then
198
+ sed -i ' ' " s/^version = \" [^\" ]*\" /version = \" ${VERSION_WITHOUT_V} \" /" " ${target_pyproject} "
199
+ else
200
+ sed -i " s/^version = \" [^\" ]*\" /version = \" ${VERSION_WITHOUT_V} \" /" " ${target_pyproject} "
201
+ fi
202
+
203
+ echo " ✅ Updated pyproject.toml version to ${VERSION_WITHOUT_V} "
204
+ }
205
+
206
+ # Function to extract and update requirements
207
+ update_requirements () {
208
+ local generated_requirements=" ${TEMP_OUTPUT_DIR} /requirements.txt"
209
+ local target_requirements=" ${PROJECT_ROOT} /requirements.txt"
210
+
211
+ if [[ -f " ${generated_requirements} " ]] && [[ -f " ${target_requirements} " ]]; then
212
+ echo " Updating requirements.txt"
213
+
214
+ # Create backup
215
+ cp " ${target_requirements} " " ${target_requirements} .bak"
216
+
217
+ # Extract non-dev requirements from generated file
218
+ grep -v " pytest\|tox\|flake8" " ${generated_requirements} " > " ${target_requirements} " || true
219
+
220
+ echo " ✅ Updated requirements.txt"
221
+ fi
222
+ }
223
+
224
+ # Update package files
225
+ update_setup_py
226
+ update_pyproject_toml
227
+ update_requirements
228
+
229
+ echo " "
230
+ echo " ✅ Python SDK updated successfully!"
231
+ echo " 📁 Updated directories:"
232
+ echo " - ${PACKAGE_DIR} "
233
+ echo " - ${DOCS_DIR} "
234
+ echo " - ${TEST_DIR} "
235
+ echo " 📝 Updated version to ${VERSION_WITHOUT_V} "
236
+ echo " 🔗 Updated package configuration in:"
237
+ echo " - setup.py"
238
+ echo " - pyproject.toml"
239
+ echo " - requirements.txt"
0 commit comments