Skip to content

Commit

Permalink
Merge branch 'master' into issue-222
Browse files Browse the repository at this point in the history
  • Loading branch information
koxudaxi authored Aug 10, 2023
2 parents 9ce49c0 + 28f8af2 commit 365a118
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 29 deletions.
13 changes: 12 additions & 1 deletion fastapi_code_generator/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ def get_argument_list(self, snake_case: bool, path: List[str]) -> List[Argument]
for argument in arguments:
if positional_argument and argument.required and argument.default is None:
argument.default = UsefulStr('...')
positional_argument = argument.required
positional_argument = argument.required or argument.default is not None

return arguments

Expand Down Expand Up @@ -379,6 +379,17 @@ def parse_request_body(
Import.from_full_path('starlette.requests.Request')
)
elif media_type == 'application/octet-stream':
arguments.append(
Argument(
name='request', # type: ignore
type_hint='Request', # type: ignore
required=True,
)
)
self.imports_for_fastapi.append(
Import.from_full_path("fastapi.Request")
)
elif media_type == 'multipart/form-data':
arguments.append(
Argument(
name='file', # type: ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from typing import List, Optional, Union

from fastapi import FastAPI, Path, Query
from fastapi import FastAPI, Path, Query, UploadFile
from starlette.requests import Request

from .models import (
Expand Down Expand Up @@ -36,6 +36,11 @@ def post_bar(request: Request) -> None:
pass


@app.post('/convert', response_model=bytes)
def convert(format: Optional[str] = 'pdf', file: UploadFile = ...) -> bytes:
pass


@app.get('/foo', response_model=str, tags=['foo'])
def get_foo(foo: Optional[str] = None) -> str:
pass
Expand Down
49 changes: 49 additions & 0 deletions tests/data/expected/openapi/default_template/upload/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# generated by fastapi-codegen:
# filename: upload.yaml
# timestamp: 2020-06-19T00:00:00+00:00

from __future__ import annotations

from typing import Union

from fastapi import FastAPI, Request, UploadFile

from .models import Error

app = FastAPI(
version='1.0.0',
title='Swagger Petstore',
license={'name': 'MIT'},
description='API definiton for testing file upload',
servers=[{'url': 'http://petstore.swagger.io/v1'}],
)


@app.post(
'/pets/{id}/image/form-data',
response_model=None,
responses={'default': {'model': Error}},
tags=['pets'],
)
def upload_pet_image_with_form_data(
id: str, file: UploadFile = ...
) -> Union[None, Error]:
"""
Upload image with Form-Data for a pet
"""
pass


@app.post(
'/pets/{id}/image/octet-stream',
response_model=None,
responses={'default': {'model': Error}},
tags=['pets'],
)
def upload_pet_image_with_octet_stream(
id: str, request: Request = ...
) -> Union[None, Error]:
"""
Upload image with octet-stream for a pet
"""
pass
12 changes: 12 additions & 0 deletions tests/data/expected/openapi/default_template/upload/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# generated by fastapi-codegen:
# filename: upload.yaml
# timestamp: 2020-06-19T00:00:00+00:00

from __future__ import annotations

from pydantic import BaseModel


class Error(BaseModel):
code: int
message: str
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from typing import List, Optional, Union

from fastapi import FastAPI, Path, Query, UploadFile
from fastapi import FastAPI, Path, Query, Request

from .models import Error, Pet, PetForm

Expand Down Expand Up @@ -106,7 +106,7 @@ def put_pets_pet_id(
tags=['pets'],
)
def upload_pet_image(
pet_id: str = Path(..., alias='petId'), file: UploadFile = ...
pet_id: str = Path(..., alias='petId'), request: Request = ...
) -> Union[None, str]:
"""
Upload image for a pet
Expand Down
23 changes: 23 additions & 0 deletions tests/data/openapi/default_template/body_and_parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,29 @@ paths:
schema:
$ref: '#/components/schemas/Pet'
required: true
/convert:
post:
operationId: convert
parameters:
- in: query
name: format
schema:
type: string
default: pdf
requestBody:
required: true
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
"200":
content:
application/octet-stream:
schema:
type: string
format: binary
components:
parameters:
MyParam:
Expand Down
79 changes: 79 additions & 0 deletions tests/data/openapi/default_template/upload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
description: API definiton for testing file upload

servers:
- url: http://petstore.swagger.io/v1
paths:
/pets/{id}/image/octet-stream:
post:
summary: Upload image with octet-stream for a pet
operationId: uploadPetImageWithOctetStream
tags:
- pets
parameters:
- name: id
in: path
required: true
description: The id of the pet
schema:
type: string
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
'201':
description: empty response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{id}/image/form-data:
post:
summary: Upload image with Form-Data for a pet
operationId: uploadPetImageWithFormData
tags:
- pets
parameters:
- name: id
in: path
required: true
description: The id of the pet
schema:
type: string
requestBody:
content:
multipart/form-data:
schema:
type: string
format: binary
responses:
'201':
description: empty response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
58 changes: 33 additions & 25 deletions tests/test_generate.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import shutil
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import call
Expand Down Expand Up @@ -152,28 +153,35 @@ def test_generate_using_routers(oas_file):
)
@freeze_time("2023-04-11")
def test_generate_modify_specific_routers(oas_file):
test_dir = EXPECTED_DIR / 'openapi/modify_specific_routers/modified'
output_dir = Path(test_dir) / oas_file.stem
Path(output_dir / "routers").mkdir(parents=True, exist_ok=True)
generate_code(
input_name=oas_file.name,
input_text=oas_file.read_text(),
output_dir=output_dir,
template_dir=BUILTIN_MODULAR_TEMPLATE_DIR,
generate_routers=True,
specify_tags=SPECIFIC_TAGS,
)
expected_dir = (
EXPECTED_DIR / 'openapi/modify_specific_routers/expected' / oas_file.stem
)
output_files = sorted(list(output_dir.glob('*')))
expected_files = sorted(list(expected_dir.glob('*')))
assert [f.name for f in output_files] == [f.name for f in expected_files]
for output_file, expected_file in zip(output_files, expected_files):
if output_file.is_dir() and expected_file.is_dir():
output_inners = sorted(list((output_dir / output_file).glob('*')))
expected_inners = sorted(list((expected_dir / expected_file).glob('*')))
for output_inner, expected_inner in zip(output_inners, expected_inners):
assert output_inner.read_text() == expected_inner.read_text()
else:
assert output_file.read_text() == expected_file.read_text()
with TemporaryDirectory() as tmp_dir:
output_dir = Path(tmp_dir) / (oas_file.stem + '_modify_specific_routers')
# modified contains generated source files. Some of them will be regenerated in this test.
modified_dir = (
EXPECTED_DIR
/ 'openapi/modify_specific_routers/modified/using_routers_example'
)
shutil.copytree(modified_dir, output_dir)

Path(output_dir / "routers").mkdir(parents=True, exist_ok=True)
generate_code(
input_name=oas_file.name,
input_text=oas_file.read_text(),
output_dir=output_dir,
template_dir=BUILTIN_MODULAR_TEMPLATE_DIR,
generate_routers=True,
specify_tags=SPECIFIC_TAGS,
)
expected_dir = (
EXPECTED_DIR / 'openapi/modify_specific_routers/expected' / oas_file.stem
)
output_files = sorted(list(output_dir.glob('*')))
expected_files = sorted(list(expected_dir.glob('*')))
assert [f.name for f in output_files] == [f.name for f in expected_files]
for output_file, expected_file in zip(output_files, expected_files):
if output_file.is_dir() and expected_file.is_dir():
output_inners = sorted(list((output_dir / output_file).glob('*')))
expected_inners = sorted(list((expected_dir / expected_file).glob('*')))
for output_inner, expected_inner in zip(output_inners, expected_inners):
assert output_inner.read_text() == expected_inner.read_text()
else:
assert output_file.read_text() == expected_file.read_text()

0 comments on commit 365a118

Please sign in to comment.