yuval9313 / FastApi-RESTful

Quicker way to develop FastApi
MIT License
180 stars 25 forks source link

dependency injection with command line arguments #173

Closed dineshbvadhia closed 1 year ago

dineshbvadhia commented 1 year ago

What is the correct way to perform dependency injection with command line arguments - see the example code below?

# crown.py

from fastapi_restful.cbv import cbv
from fastapi_restful.inferring_router import InferringRouter

def consort(a, b, c):
    return prince: dict = do_stuff(a, b, c)

app = FastAPI()
router = InferringRouter()  # Step 1: Create a router

@cbv(router)                # Step 2: Create and decorate a class to hold the endpoints
class King:
    # Step 3: Add dependencies as class attributes
    prince: dict = Depends(consort)

    @router.get("/")
    async def item(self):
        # Step 4: Use `self.<dependency_name>` to access shared dependencies
        return self.prince.banquet()

    @router.get("/jewel")
    async def jewel(self):
        # Step 4: Use `self.<dependency_name>` to access shared dependencies
        return self.prince.get_jewel()

if __name__ == "__main__":
    a, b, c = arg_parse()   # parse command line arguments

    prince = consort(a, b, c)
    service = King(prince)                # This is not right but what is the correct construction?
    app.include_router(service.router)

    import uvicorn
    uvicorn.run('crown:app', host="127.0.0.1", port=8000, log_level="debug", reload=True)

Secondly, I keep getting the error:

 File "C:\Users\dines\AppData\Local\Programs\Python\Python310\lib\site-packages\fastapi_restful\cbv.py", line 151, in _update_cbv_route_endpoint_signature
    old_first_parameter = old_parameters[0]
IndexError: list index out of range

What does this mean?

yuval9313 commented 1 year ago

I'm lost, I do not understand what you are trying to do

dineshbvadhia commented 1 year ago

Fair enough. Let's start again. The 3 command line arguments, a, b, c, are passed into the module. The args are for the dependency Consort. How do you connect the dependency Consort to the class King?

import sys
from fastapi import FastAPI, APIRouter, Depends
from fastapi_restful.cbv import cbv
from fastapi_restful.inferring_router import InferringRouter

class Consort:
    def __init__(self, a, b, c):
        self.d = a + b + c

app = FastAPI()
router = InferringRouter()  # Step 1: Create a router

@cbv(router)                # Step 2: Create and decorate a class to hold the endpoints
class King:
    # Step 3: Add dependencies as class attributes
    consort: Consort = Depends(Consort)

    @router.get("/star")
    async def star(self):
        # Step 4: Use `self.<dependency_name>` to access shared dependencies
        return do_star(self)

def do_star(self):
    print(self.consort.d)
    return

app.include_router(router)

if __name__ == "__main__":
    params: list[int] = sys.argv[2].split()     # simulate parsing of command line arguments
    a: int = params[0]
    b: int = params[1]
    c: int = params[2]

    import uvicorn
    uvicorn.run('crown:app', host="127.0.0.1", port=8000, log_level="debug", reload=True)
dineshbvadhia commented 1 year ago

Use the fastapi startup/shutdown events to capture the command line arguments. Then, do the startup stuff including those using the command line arguments.