Giter VIP home page Giter VIP logo

fastapi-router-controller's Introduction

๐Ÿ‘จโ€๐Ÿ’ป Pasquale Carmine Carbone (@KiraPC)

Software Engineer with a strong passion for the technology since I was a child.

I like design and develop solutions using common patterns and best practices, finding the better way.

There's almost always a better way.

while(true) {
  doBetter()
}

My Github stats

KiraPC's GitHub Stats

fastapi-router-controller's People

Contributors

delijati avatar hirano-satoshi avatar kirapc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fastapi-router-controller's Issues

Supporting Multi-Parent

First Thank you for the amazing work! the lib is very handy!

I am trying to implement a controller with multiple parents. I found out that the routes in the second parent are not included. Is there a reason behind disabling that?

I need to allow multi-parent to be able to define two sets of routes with different dependencies, then create a class view that combine them and include some extra abstract methods. Later this view will be inherited and implemented.

router = APIRouter()
controller = Controller(router)


def d1(d):
  return d


@controller.resource()
class ParentA():

  def __init__(self, x = Depends(d1)):
    self.x =x

  @controller.router.get('/parent_a_test')
  def get(self):
    print('in parent A')


router2 = APIRouter()
controller2 = Controller(router2)


@controller2.resource()
class ParentB(abc.ABC):

  @controller2.router.get('/parent_b_test')
  def get(self):
      print('in parent B')

  @abc.abstractmethod
  def get_abstract(self):
      pass


router3 = APIRouter()
controller3 = Controller(router3)


@controller3.resource()
class AbstractView(ParentA, ParentB, abc.ABC):

  @controller3.router.get('/get_view')
  def get(self):
    print('abstract view')



router4 = APIRouter(tags=['child'], prefix='/child')
controller4 = Controller(router4)

@controller4.resource()
class ImplChild(AbstractView):

  @controller4.router.get('/Child_test')
   def get_abstract(self):
      print('get_abstract Implemnetation')

Depends does not work

If i add Depends to the class it does not resolve. See print(self.x.create())

import unittest

from pydantic import BaseModel
from fastapi_router_controller import Controller, ControllersTags
from fastapi import APIRouter, Depends, FastAPI, Query, status
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient

router = APIRouter()

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


class SampleObject(BaseModel):
    id: str


def get_x():
    class Foo:
        def create(self):
            return "XXX"

    return Foo()


# With the "resource" decorator define the controller Class linked to the Controller router arguments
@controller.resource()
class SampleController:
    x = Depends(get_x)

    @controller.route.get(
        "/", tags=["sample_controller"], summary="return a sample object",
        response_model=SampleObject
    )
    def sample_get_request(
        self,
        id: str = Query(..., title="itemId", description="The id of the sample object"),
    ):
        print(self.x.create())
        return SampleObject(id=id)


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

    sample_controller = SampleController()

    app.include_router(sample_controller.router())
    return app


class TestRoutes(unittest.TestCase):
    def setUp(self):
        app = create_app()
        self.client = TestClient(app)

    def test_root(self):
        response = self.client.get("/?id=12")
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), {"id": "12"})


if __name__ == "__main__":
    unittest.main()
    # import uvicorn
    # uvicorn.run(create_app(), host="0.0.0.0", port=9090)

Decorator on the endpoint

It would be good if we can add a decorator to the endpoint something like this :

@controller.route.get("/{id}", status_code=status.HTTP_200_OK, response_model=UserModelSchemaRes)
    @authenticated(Depends(oauth2_scheme))
    def get_user(self, id: int):
        """Get One User By id."""

but the controller parser bug with the following :

Traceback (most recent call last):
  File "/Users/aaaa/.pyenv/versions/3.9.10/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
  File "/Users/aaaa/.pyenv/versions/3.9.10/lib/python3.9/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
    target(sockets=sockets)
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/uvicorn/server.py", line 60, in run
    return asyncio.run(self.serve(sockets=sockets))
  File "/Users/aaaa/.pyenv/versions/3.9.10/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "uvloop/loop.pyx", line 1501, in uvloop.loop.Loop.run_until_complete
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/uvicorn/server.py", line 67, in serve
    config.load()
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/uvicorn/config.py", line 479, in load
    self.loaded_app = import_from_string(self.app)
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/uvicorn/importer.py", line 21, in import_from_string
    module = importlib.import_module(module_str)
  File "/Users/aaaa/.pyenv/versions/3.9.10/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/Volumes/fs/code/project./web/app.py", line 12, in <module>
    from web.apps.auth.app import auth_app
  File "/Volumes/fs/code/project./web/apps/auth/app.py", line 6, in <module>
    auth_app = create_app(controllers)
  File "/Volumes/fs/code/project./web/app_factory.py", line 19, in create_app
    app.include_router(controller.router())
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/fastapi_router_controller/lib/controller.py", line 98, in <lambda>
    cls.router = lambda: Controller.__parse_controller_router(cls)
  File "/Users/aaa/pypoetry/virtualenvs/api-q8MsJZi5-py3.9/lib/python3.9/site-packages/fastapi_router_controller/lib/controller.py", line 148, in __parse_controller_router
    signature_parameters[0] = signature_parameters[0].replace(
  File "/Users/aaaa/.pyenv/versions/3.9.10/lib/python3.9/inspect.py", line 2580, in replace
    return type(self)(name, kind, default=default, annotation=annotation)
  File "/Users/aaaa/.pyenv/versions/3.9.10/lib/python3.9/inspect.py", line 2507, in __init__
    raise ValueError(msg)
ValueError: variadic positional parameters cannot have default values

Setup.py has no version

In the setup.py the version needs to be set hard

version=os.environ.get('RELEASE_VERSION'),
won't work. pip or setuptools are also checking locally the version, but this obviously won't work as env variable RELEASE_VERSION is not set (and also should not be). A simple sed and writing the number is sufficient.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.