Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[flake8]
max-line-length = 88
max-complexity = 10
exclude =
.git,
__pycache__,
docs/source/conf.py,
old,
build,
dist
src/gunicorn_conf.py
src/catalog/migration.py
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Run Tests

on: [push, pull_request]
on: [ pull_request ]

jobs:
build:
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Lint
on: [ pull_request ]

jobs:
lint:
strategy:
fail-fast: false
matrix:
python-version: [ 3.9 ]
os: [ ubuntu-18.04 ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: flake8 install
run: pip3 install flake8
- name: lint
run: flake8 fastapi_router_controller/
12 changes: 12 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
repos:
- repo: https://github.com/psf/black
rev: 21.5b1
hooks:
- id: black
args: [
"fastapi_router_controller"
]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.0.0
hooks:
- id: flake8
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ExampleController:
self.x = x

@controller.route.get(
"/some_aoi", summary="A sample description", response_model=Foo
"/some_api", summary="A sample description", response_model=Foo
)
def sample_api(self):
print(self.x.bar) # -> amazing_variable
Expand Down
6 changes: 3 additions & 3 deletions example/sample_app/app.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from fastapi import FastAPI
from fastapi.testclient import TestClient
from fastapi_router_controller import ControllersTags
from controller.sample_controller import SampleController
from controller.sample_controller_2 import AnotherSampleController

app = FastAPI(
title='A sample application using fastapi_router_controller',
title="A sample application using fastapi_router_controller",
version="0.1.0",
openapi_tags=ControllersTags)
openapi_tags=ControllersTags,
)

app.include_router(SampleController.router())
app.include_router(AnotherSampleController.router())
58 changes: 38 additions & 20 deletions example/sample_app/controller/sample_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,61 @@
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field

router = APIRouter(prefix='/sample_controller')
router = APIRouter(prefix="/sample_controller")

controller = Controller(
router,
openapi_tag={
"name": "sample_controller",
},
)

controller = Controller(router, openapi_tag={
'name': 'sample_controller',
})

class SampleObject(BaseModel):
id: str = Field(..., description='sample id')
id: str = Field(..., description="sample id")

def to_json(self):
return {'id': self.id}
return {"id": self.id}


class Foo():
class Foo:
def create_foo(_, item):
print('Created Foo', str(item))
print("Created Foo", str(item))


def get_foo():
return Foo()

# With the "resource" decorator define the controller Class linked to the Controller router arguments

# With the "resource" decorator define the controller Class
# linked to the Controller router arguments
@controller.resource()
class SampleController():
class SampleController:
def __init__(self, foo: Foo = Depends(get_foo)):
self.foo = foo

@controller.route.get(
'/',
tags=['sample_controller'],
summary='return a sample object')
def sample_get_request(self, id: str = Query(..., title="itemId", description="The id of the sample object")):
return JSONResponse(status_code=status.HTTP_200_OK, content=SampleObject(**{'id': id}).to_json())
"/", tags=["sample_controller"], summary="return a sample object"
)
def sample_get_request(
self,
id: str = Query(..., title="itemId", description="The id of the sample object"),
):
return JSONResponse(
status_code=status.HTTP_200_OK, content=SampleObject(**{"id": id}).to_json()
)

@controller.route.post(
'/',
tags=['sample_controller'],
summary='create another sample object',
status_code=201)
def sample_post_request(self, simple_object: SampleObject = Body({}, title="SampleObject", description="A sample object model")):
"/",
tags=["sample_controller"],
summary="create another sample object",
status_code=201,
)
def sample_post_request(
self,
simple_object: SampleObject = Body(
{}, title="SampleObject", description="A sample object model"
),
):
self.foo.create_foo(simple_object)
return JSONResponse(status_code=status.HTTP_201_CREATED, content={})
46 changes: 30 additions & 16 deletions example/sample_app/controller/sample_controller_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,43 @@
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field

router = APIRouter(prefix='/sample_controller_2')
router = APIRouter(prefix="/sample_controller_2")

controller = Controller(
router,
openapi_tag={
"name": "sample_controller_2",
},
)

controller = Controller(router, openapi_tag={
'name': 'sample_controller_2',
})

class SampleObject(BaseModel):
id: str = Field(..., description='sample id')
id: str = Field(..., description="sample id")


# With the "resource" decorator define the controller Class linked to the Controller router arguments
# With the "resource" decorator define the controller Class
# linked to the Controller router arguments
@controller.resource()
class AnotherSampleController():
class AnotherSampleController:
@controller.route.get(
'/',
tags=['sample_controller_2'],
summary='return another sample object')
def sample_get_request(_, id: str = Query(..., title="itemId", description="The id of the sample object")):
"/", tags=["sample_controller_2"], summary="return another sample object"
)
def sample_get_request(
_,
id: str = Query(..., title="itemId", description="The id of the sample object"),
):
return JSONResponse(status_code=status.HTTP_200_OK, content=SampleObject(id))

@controller.route.post(
'/',
tags=['sample_controller_2'],
summary='create a sample object',
status_code=201)
def sample_post_request(_, simple_object: SampleObject = Body(None, title="SampleObject", description="A sample object model")):
"/",
tags=["sample_controller_2"],
summary="create a sample object",
status_code=201,
)
def sample_post_request(
_,
simple_object: SampleObject = Body(
None, title="SampleObject", description="A sample object model"
),
):
return JSONResponse(status_code=status.HTTP_201_CREATED, content={})
8 changes: 5 additions & 3 deletions example/sample_app_with_auto_import/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
from fastapi_router_controller import Controller, ControllersTags

# just import the main package to load all the controllers in
import controller
import controller # noqa

app = FastAPI(
title='A sample application using fastapi_router_controller with controller auto import',
title="A sample application using fastapi_router_controller"
+ "with controller auto import",
version="0.1.0",
# all of the router openapi_tags are collected in ControllerTags object
openapi_tags=ControllersTags)
openapi_tags=ControllersTags,
)

for router in Controller.routers():
app.include_router(router)
2 changes: 1 addition & 1 deletion example/sample_app_with_auto_import/controller/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
this_dir = os.path.dirname(__file__)

# load all the module inside the given path
ControllerLoader.load(this_dir, __package__)
ControllerLoader.load(this_dir, __package__)
50 changes: 33 additions & 17 deletions example/sample_app_with_auto_import/controller/sample_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,50 @@

from libs.sample_parent_controller import SampleParentController

router = APIRouter(prefix='/sample_extended_controller')
router = APIRouter(prefix="/sample_extended_controller")

controller = Controller(
router,
openapi_tag={
"name": "sample_extended_controller",
},
)

controller = Controller(router, openapi_tag={
'name': 'sample_extended_controller',
})

class SampleObject(BaseModel):
id: str = Field(..., description='sample id')
id: str = Field(..., description="sample id")

def to_json(self):
return {'id': self.id}
return {"id": self.id}


# With the "use" decorator the lib save the Controller Class to load it automatically
@controller.use()
# With the "resource" decorator define the controller Class linked to the Controller router arguments
# With the "resource" decorator define the controller Class
# linked to the Controller router arguments
@controller.resource()
class SampleController(SampleParentController):
@controller.route.get(
'/',
tags=['sample_extended_controller'],
summary='return a sample object')
def sample_get_request(self, id: str = Query(..., title="itemId", description="The id of the sample object")):
return JSONResponse(status_code=status.HTTP_200_OK, content=SampleObject(**{'id': id}).to_json())
"/", tags=["sample_extended_controller"], summary="return a sample object"
)
def sample_get_request(
self,
id: str = Query(..., title="itemId", description="The id of the sample object"),
):
return JSONResponse(
status_code=status.HTTP_200_OK, content=SampleObject(**{"id": id}).to_json()
)

@controller.route.post(
'/',
tags=['sample_extended_controller'],
summary='create another sample object',
status_code=201)
def sample_post_request(self, simple_object: SampleObject = Body(None, title="SampleObject", description="A sample object model")):
"/",
tags=["sample_extended_controller"],
summary="create another sample object",
status_code=201,
)
def sample_post_request(
self,
simple_object: SampleObject = Body(
None, title="SampleObject", description="A sample object model"
),
):
return JSONResponse(status_code=status.HTTP_201_CREATED, content={})
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@

controller = Controller(router)


# This is a Sample Controller that can be exteded by another to inherit its routes
@controller.resource()
class SampleParentController():
class SampleParentController:
@controller.route.get(
'/parent_api',
summary='A sample API from the extended class, it will inherit the basepat of the child router')
"/parent_api",
summary="A sample API from the extended class,"
+ "it will inherit the basepat of the child router",
)
def sample_parent_api(_):
return JSONResponse(status_code=status.HTTP_200_OK, content={ 'message': 'I\'m the parent'})
return JSONResponse(
status_code=status.HTTP_200_OK, content={"message": "I'm the parent"}
)
6 changes: 5 additions & 1 deletion fastapi_router_controller/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

from fastapi_router_controller.lib.controller import Controller as Controller
from fastapi_router_controller.lib.controller import OPEN_API_TAGS as ControllersTags
from fastapi_router_controller.lib.controller_loader import ControllerLoader as ControllerLoader
from fastapi_router_controller.lib.controller_loader import (
ControllerLoader as ControllerLoader,
)

__all__ = ["Controller", "ControllersTags", "ControllerLoader"]
Loading