Skip to content

Commit 4c9ae3c

Browse files
committed
improve path handling and references handling
1 parent 398f4b3 commit 4c9ae3c

File tree

2 files changed

+39
-30
lines changed

2 files changed

+39
-30
lines changed

src/serverless_openapi_generator/openapi_generator.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ def _resolve_file_references(self, value):
3535
abs_path = os.path.join(self.serverless_dir, file_path)
3636
try:
3737
with open(abs_path, 'r') as f:
38-
return yaml.safe_load(f)
39-
except (IOError, yaml.YAMLError) as e:
38+
if file_path.endswith('.json'):
39+
return json.load(f)
40+
else:
41+
return yaml.safe_load(f)
42+
except (IOError, yaml.YAMLError, json.JSONDecodeError) as e:
4043
print(f"Warning: Could not read or parse file reference {abs_path}: {e}")
4144
return value
4245
return value
@@ -128,13 +131,18 @@ def create_paths(self):
128131
continue
129132

130133
# Handle path parameters
134+
if path.startswith('/'):
135+
path = path[1:]
136+
131137
if documentation.get('pathParams'):
132138
for param in documentation.get('pathParams'):
133139
path = path.replace(f"{{{param['name']}}}", "") # Remove if already there
134140
path_params_str = "/".join([f"{{{p['name']}}}" for p in documentation.get('pathParams')])
135-
full_path = f"/{path}/{path_params_str}".replace('//','/')
141+
full_path = f"/{path}/{path_params_str}"
136142
else:
137143
full_path = f"/{path}"
144+
145+
full_path = full_path.replace('//', '/')
138146

139147

140148
if full_path not in paths:

src/serverless_openapi_generator/schema_handler.py

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import uuid
33
import os
44
import re
5+
import yaml
56
from referencing import Registry, Resource
67
from referencing.jsonschema import DRAFT4
78
import requests
@@ -13,31 +14,49 @@ def __init__(self, serverless_config, open_api_spec, serverless_dir='.'):
1314
self.serverless_dir = serverless_dir
1415
self.models = self._standardize_models()
1516

17+
def _resolve_file_references(self, value):
18+
if isinstance(value, dict):
19+
return {k: self._resolve_file_references(v) for k, v in value.items()}
20+
elif isinstance(value, list):
21+
return [self._resolve_file_references(item) for item in value]
22+
elif isinstance(value, str):
23+
match = re.match(r'\${file\((.*)\)}', value)
24+
if match:
25+
file_path = match.group(1).strip()
26+
abs_path = os.path.join(self.serverless_dir, file_path)
27+
try:
28+
with open(abs_path, 'r') as f:
29+
if file_path.endswith('.json'):
30+
return json.load(f)
31+
else:
32+
return yaml.safe_load(f)
33+
except (IOError, yaml.YAMLError, json.JSONDecodeError) as e:
34+
print(f"Warning: Could not read or parse file reference {abs_path}: {e}")
35+
return value
36+
return value
37+
1638
def _standardize_models(self):
17-
documentation = self.serverless_config.get('custom', {})
18-
if not documentation:
19-
service_config = self.serverless_config.get('service', {})
20-
if isinstance(service_config, dict):
21-
documentation = service_config.get('custom', {}).get('documentation', {})
22-
else:
23-
documentation = {}
39+
documentation = self.serverless_config.get('custom', {}).get('documentation', {})
2440

2541
standardized_models = []
2642
model_sources = []
2743
if 'models' in documentation:
28-
models_config = documentation['models']
44+
models_config = self._resolve_file_references(documentation['models'])
2945
if isinstance(models_config, list):
3046
model_sources.extend(models_config)
3147
elif isinstance(models_config, dict):
3248
for name, definition in models_config.items():
3349
model_sources.append({'name': name, **definition})
3450

3551
if 'modelsList' in documentation:
36-
model_sources.extend(documentation['modelsList'])
52+
model_sources.extend(self._resolve_file_references(documentation['modelsList']))
3753

3854
for model in model_sources:
3955
if not isinstance(model, dict) or 'name' not in model:
4056
continue
57+
58+
model = self._resolve_file_references(model)
59+
4160
std_model = {
4261
'name': model.get('name'),
4362
'description': model.get('description', ''),
@@ -68,24 +87,6 @@ def create_schema(self, name, schema_definition):
6887
self.open_api['components']['schemas'][name] = final_schema
6988
return f"#/components/schemas/{name}"
7089

71-
def _resolve_file_references(self, value):
72-
if isinstance(value, dict):
73-
return {k: self._resolve_file_references(v) for k, v in value.items()}
74-
elif isinstance(value, list):
75-
return [self._resolve_file_references(item) for item in value]
76-
elif isinstance(value, str):
77-
match = re.match(r'\${file\((.*)\)}', value)
78-
if match:
79-
file_path = match.group(1).strip()
80-
abs_path = os.path.join(self.serverless_dir, file_path)
81-
try:
82-
with open(abs_path, 'r') as f:
83-
return json.load(f)
84-
except (IOError, json.JSONDecodeError) as e:
85-
print(f"Warning: Could not read or parse file reference {abs_path}: {e}")
86-
return value
87-
return value
88-
8990
def _resolve_schema_references(self, schema):
9091
schema = self._resolve_file_references(schema)
9192
if not isinstance(schema, dict):

0 commit comments

Comments
 (0)