Skip to content

Commit e1667f6

Browse files
authored
Merge pull request #324 from ytoml/disable-timestamp
Add `--disable-timestamp`
2 parents a774314 + 95867a7 commit e1667f6

File tree

5 files changed

+229
-4
lines changed

5 files changed

+229
-4
lines changed

fastapi_code_generator/__main__.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def main(
4646
custom_visitors: Optional[List[Path]] = typer.Option(
4747
None, "--custom-visitor", "-c"
4848
),
49+
disable_timestamp: bool = typer.Option(False, "--disable-timestamp"),
4950
) -> None:
5051
input_name: str = input_file.name
5152
input_text: str = input_file.read()
@@ -61,6 +62,7 @@ def main(
6162
template_dir,
6263
model_path,
6364
enum_field_as_literal,
65+
disable_timestamp=disable_timestamp,
6466
)
6567
return generate_code(
6668
input_name,
@@ -69,6 +71,7 @@ def main(
6971
template_dir,
7072
model_path,
7173
custom_visitors=custom_visitors,
74+
disable_timestamp=disable_timestamp,
7275
)
7376

7477

@@ -90,6 +93,7 @@ def generate_code(
9093
model_path: Optional[Path] = None,
9194
enum_field_as_literal: Optional[str] = None,
9295
custom_visitors: Optional[List[Path]] = [],
96+
disable_timestamp: bool = False,
9397
) -> None:
9498
if not model_path:
9599
model_path = MODEL_PATH
@@ -148,8 +152,9 @@ def generate_code(
148152
timestamp = datetime.now(timezone.utc).replace(microsecond=0).isoformat()
149153
header = f"""\
150154
# generated by fastapi-codegen:
151-
# filename: {Path(input_name).name}
152-
# timestamp: {timestamp}"""
155+
# filename: {Path(input_name).name}"""
156+
if not disable_timestamp:
157+
header += f"\n# timestamp: {timestamp}"
153158

154159
for path, code in results.items():
155160
with output_dir.joinpath(path.with_suffix(".py")).open("wt") as file:
@@ -160,8 +165,8 @@ def generate_code(
160165
header = f'''\
161166
# generated by fastapi-codegen:
162167
# filename: {{filename}}'''
163-
# if not disable_timestamp:
164-
header += f'\n# timestamp: {timestamp}'
168+
if not disable_timestamp:
169+
header += f'\n# timestamp: {timestamp}'
165170

166171
for path, body_and_filename in modules.items():
167172
body, filename = body_and_filename
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# generated by fastapi-codegen:
2+
# filename: simple.yaml
3+
4+
from __future__ import annotations
5+
6+
from typing import Optional, Union
7+
8+
from fastapi import FastAPI, Path
9+
10+
from .models import Error, Pets
11+
12+
app = FastAPI(
13+
version='1.0.0',
14+
title='Swagger Petstore',
15+
license={'name': 'MIT'},
16+
description='This description is for testing\nmulti-line\ndescription\n',
17+
servers=[{'url': 'http://petstore.swagger.io/v1'}],
18+
)
19+
20+
21+
@app.get(
22+
'/pets', response_model=Pets, responses={'default': {'model': Error}}, tags=['pets']
23+
)
24+
def list_pets(limit: Optional[int] = None) -> Union[Pets, Error]:
25+
"""
26+
List all pets
27+
"""
28+
pass
29+
30+
31+
@app.post(
32+
'/pets', response_model=None, responses={'default': {'model': Error}}, tags=['pets']
33+
)
34+
def create_pets() -> Union[None, Error]:
35+
"""
36+
Create a pet
37+
"""
38+
pass
39+
40+
41+
@app.get(
42+
'/pets/{pet_id}',
43+
response_model=Pets,
44+
responses={'default': {'model': Error}},
45+
tags=['pets'],
46+
)
47+
def show_pet_by_id(pet_id: str = Path(..., alias='petId')) -> Union[Pets, Error]:
48+
"""
49+
Info for a specific pet
50+
"""
51+
pass
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# generated by fastapi-codegen:
2+
# filename: simple.yaml
3+
4+
from __future__ import annotations
5+
6+
from typing import List, Optional
7+
8+
from pydantic import BaseModel, Field
9+
10+
11+
class Pet(BaseModel):
12+
id: int
13+
name: str
14+
tag: Optional[str] = None
15+
16+
17+
class Pets(BaseModel):
18+
__root__: List[Pet] = Field(..., description='list of pet')
19+
20+
21+
class Error(BaseModel):
22+
code: int
23+
message: str
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
openapi: "3.0.0"
2+
info:
3+
version: 1.0.0
4+
title: Swagger Petstore
5+
license:
6+
name: MIT
7+
description: |
8+
This description is for testing
9+
multi-line
10+
description
11+
12+
servers:
13+
- url: http://petstore.swagger.io/v1
14+
paths:
15+
/pets:
16+
get:
17+
summary: List all pets
18+
operationId: listPets
19+
tags:
20+
- pets
21+
parameters:
22+
- name: limit
23+
in: query
24+
description: How many items to return at one time (max 100)
25+
required: false
26+
schema:
27+
type: integer
28+
format: int32
29+
responses:
30+
"200":
31+
description: A paged array of pets
32+
headers:
33+
x-next:
34+
description: A link to the next page of responses
35+
schema:
36+
type: string
37+
content:
38+
application/json:
39+
schema:
40+
$ref: "#/components/schemas/Pets"
41+
default:
42+
description: unexpected error
43+
content:
44+
application/json:
45+
schema:
46+
$ref: "#/components/schemas/Error"
47+
x-amazon-apigateway-integration:
48+
uri:
49+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
50+
passthroughBehavior: when_no_templates
51+
httpMethod: POST
52+
type: aws_proxy
53+
post:
54+
summary: Create a pet
55+
operationId: createPets
56+
tags:
57+
- pets
58+
responses:
59+
"201":
60+
description: Null response
61+
default:
62+
description: unexpected error
63+
content:
64+
application/json:
65+
schema:
66+
$ref: "#/components/schemas/Error"
67+
/pets/{petId}:
68+
get:
69+
summary: Info for a specific pet
70+
operationId: showPetById
71+
tags:
72+
- pets
73+
parameters:
74+
- name: petId
75+
in: path
76+
required: true
77+
description: The id of the pet to retrieve
78+
schema:
79+
type: string
80+
responses:
81+
"200":
82+
description: Expected response to a valid request
83+
content:
84+
application/json:
85+
schema:
86+
$ref: "#/components/schemas/Pets"
87+
default:
88+
description: unexpected error
89+
content:
90+
application/json:
91+
schema:
92+
$ref: "#/components/schemas/Error"
93+
components:
94+
schemas:
95+
Pet:
96+
required:
97+
- id
98+
- name
99+
properties:
100+
id:
101+
type: integer
102+
format: int64
103+
name:
104+
type: string
105+
tag:
106+
type: string
107+
Pets:
108+
type: array
109+
description: list of pet
110+
items:
111+
$ref: "#/components/schemas/Pet"
112+
Error:
113+
required:
114+
- code
115+
- message
116+
properties:
117+
code:
118+
type: integer
119+
format: int32
120+
message:
121+
type: string

tests/test_generate.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
OPEN_API_DEFAULT_TEMPLATE_DIR_NAME = Path('openapi') / 'default_template'
1111
OPEN_API_SECURITY_TEMPLATE_DIR_NAME = Path('openapi') / 'custom_template_security'
1212
OPEN_API_REMOTE_REF_DIR_NAME = Path('openapi') / 'remote_ref'
13+
OPEN_API_DISABLE_TIMESTAMP_DIR_NAME = Path('openapi') / 'disable_timestamp'
1314

1415
DATA_DIR = Path(__file__).parent / 'data'
1516

@@ -86,3 +87,27 @@ def test_generate_remote_ref(mocker):
8687
assert [f.name for f in output_files] == [f.name for f in expected_files]
8788
for output_file, expected_file in zip(output_files, expected_files):
8889
assert output_file.read_text() == expected_file.read_text()
90+
91+
92+
@pytest.mark.parametrize(
93+
"oas_file", (DATA_DIR / OPEN_API_DISABLE_TIMESTAMP_DIR_NAME).glob("*.yaml")
94+
)
95+
@freeze_time("2020-06-19")
96+
def test_disable_timestamp(oas_file):
97+
with TemporaryDirectory() as tmp_dir:
98+
output_dir = Path(tmp_dir) / oas_file.stem
99+
generate_code(
100+
input_name=oas_file.name,
101+
input_text=oas_file.read_text(),
102+
output_dir=output_dir,
103+
template_dir=None,
104+
disable_timestamp=True,
105+
)
106+
expected_dir = (
107+
EXPECTED_DIR / OPEN_API_DISABLE_TIMESTAMP_DIR_NAME / oas_file.stem
108+
)
109+
output_files = sorted(list(output_dir.glob('*')))
110+
expected_files = sorted(list(expected_dir.glob('*')))
111+
assert [f.name for f in output_files] == [f.name for f in expected_files]
112+
for output_file, expected_file in zip(output_files, expected_files):
113+
assert output_file.read_text() == expected_file.read_text()

0 commit comments

Comments
 (0)