2
2
from openapi_spec_validator import validate_spec
3
3
import yaml
4
4
5
- def generate_openapi_spec ():
5
+ def get_operation_summary (method ):
6
+ return {
7
+ 'GET' : 'Retrieve all records from' ,
8
+ 'POST' : 'Create a new record in' ,
9
+ 'PUT' : 'Update a record in' ,
10
+ 'DELETE' : 'Delete a record from' ,
11
+ 'PATCH' : 'Partially update a record in' ,
12
+ 'TRACE' : 'Trace a request to'
13
+ }.get (method , 'Perform operation on' )
14
+
15
+ def add_paging_parameters (operation_obj ):
16
+ operation_obj ["parameters" ] = [
17
+ {
18
+ "name" : "page" ,
19
+ "in" : "query" ,
20
+ "description" : "Page number to retrieve" ,
21
+ "required" : False ,
22
+ "schema" : {
23
+ "type" : "integer" ,
24
+ "default" : 1
25
+ }
26
+ },
27
+ {
28
+ "name" : "per_page" ,
29
+ "in" : "query" ,
30
+ "description" : "Number of records per page" ,
31
+ "required" : False ,
32
+ "schema" : {
33
+ "type" : "integer" ,
34
+ "default" : 10
35
+ }
36
+ }
37
+ ]
38
+
39
+ def add_operation_to_path (path_item , method , rule_str , primary_key_type ):
40
+ operation = get_operation_summary (method )
41
+ table_name = rule_str .split ('/' )[1 ]
42
+ operation_obj = {
43
+ "summary" : f"{ operation } the { table_name } table" ,
44
+ "responses" : {
45
+ "200" : {
46
+ "description" : "OK"
47
+ }
48
+ }
49
+ }
50
+ if method == 'GET' :
51
+ if '<id>' in rule_str :
52
+ operation_obj ["parameters" ] = [
53
+ {
54
+ "name" : "id" ,
55
+ "in" : "path" ,
56
+ "description" : "The ID of the record to retrieve" ,
57
+ "required" : True ,
58
+ "schema" : {
59
+ "type" : primary_key_type ,
60
+ }
61
+ }
62
+ ]
63
+ else :
64
+ add_paging_parameters (operation_obj )
65
+ path_item [method .lower ()] = operation_obj
66
+
67
+ def sqlite_type_to_openapi_type (sqlite_type ):
68
+ """
69
+ Convert SQLite data types to OpenAPI data types.
70
+ """
71
+ sqlite_type = sqlite_type .upper ()
72
+ if sqlite_type in ["INT" , "INTEGER" , "TINYINT" , "SMALLINT" , "MEDIUMINT" , "BIGINT" , "UNSIGNED BIG INT" , "INT2" , "INT8" ]:
73
+ return "integer"
74
+ elif sqlite_type in ["REAL" , "DOUBLE" , "DOUBLE PRECISION" , "FLOAT" ]:
75
+ return "number"
76
+ elif sqlite_type in ["TEXT" , "CHARACTER" , "VARCHAR" , "VARYING CHARACTER" , "NCHAR" , "NATIVE CHARACTER" , "NVARCHAR" , "CLOB" ]:
77
+ return "string"
78
+ elif sqlite_type in ["BLOB" ]:
79
+ return "string" , "byte"
80
+ elif sqlite_type in ["BOOLEAN" ]:
81
+ return "boolean"
82
+ elif sqlite_type in ["DATE" , "DATETIME" ]:
83
+ return "string" , "date-time"
84
+ else :
85
+ return "string"
86
+
87
+ def generate_openapi_spec (db ):
6
88
# Basic OpenAPI spec
7
89
spec = {
8
90
"openapi" : "3.0.0" ,
@@ -28,33 +110,16 @@ def generate_openapi_spec():
28
110
# Add an operation object for each method
29
111
for method in rule .methods :
30
112
if method in ['GET' , 'POST' , 'PUT' , 'DELETE' ]:
31
- operation = {
32
- 'GET' : 'Retrieve all records from' ,
33
- 'POST' : 'Create a new record in' ,
34
- 'PUT' : 'Update a record in' ,
35
- 'DELETE' : 'Delete a record from' ,
36
- 'PATCH' : 'Partially update a record in' ,
37
- 'TRACE' : 'Trace a request to'
38
- }.get (method , 'Perform operation on' )
39
-
40
113
table_name = str (rule ).split ('/' )[1 ]
41
-
42
- path_item [method .lower ()] = {
43
- "summary" : f"{ operation } the { table_name } table" ,
44
- "responses" : {
45
- "200" : {
46
- "description" : "OK"
47
- }
48
- }
49
- }
114
+ _ , primary_key_type = db .get_primary_key (table_name )
115
+ add_operation_to_path (path_item , method , str (rule ), sqlite_type_to_openapi_type (primary_key_type ))
50
116
51
117
# Validate the spec
52
118
validate_spec (spec )
53
119
54
120
# Return the spec as a dictionary
55
121
return spec
56
122
57
- def get_openapi_spec ():
58
- spec = generate_openapi_spec ()
123
+ def get_openapi_spec (db ):
124
+ spec = generate_openapi_spec (db )
59
125
return yaml .dump (spec )
60
-
0 commit comments