FastAPI (30) - Classes as Dependencies class dependency injection

FastAPI (30) - Classes as Dependencies class dependency injection

 

Dependency function returns dict

The return value type of dependency function in the previous dependency injection article is dict

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: Little pineapple test notes
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/24 1:08 PM
# file: 25_dependency.py
"""
from typing import Optional, Dict, Any
# 2. Import dependencies
from fastapi import Depends, FastAPI

import uvicorn

app = FastAPI()


# 1. Write dependencies
async def common_parameters(q: Optional[str] = None,
                            skip: int = 0,
                            limit: int = 100):
  # Return to dict
    return {"q": q, "skip": skip, "limit": limit}


# 3. Write the path operation function, and the parameters are declared as dependencies
@app.get("/items")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons


if __name__ == "__main__":
    uvicorn.run(app="25_dependency:app", host="127.0.0.1", port=8080, reload=True, debug=True)

The dependency function returns a dict, and then the path operation function's parameter commons gets a dict, but the IDE does not support more code intelligent prompts because the types of keys and values cannot be known

 

Soul question: what is a dependency?

  • The chestnut above is to declare functions as dependencies, but this is not the only way to declare dependencies (although it will be more common)
  • The key point should be that dependencies are callable
  • In Python, callable is an object that can be called like a function

Callable tutorial in typing

Object oriented__ call__ () tutorial

 

Look at the source code of dependencies()

The first parameter dependency type is Callable and must be a Callable object

 

Class as a dependency

Is a class a callable object?

from typing import Callable


class Cat:
    def __init__(self, name: str):
        self.name = name


# Determine whether the class object is a callable object
print(isinstance(Cat, Callable))


# Output results
True

So classes can be declared as dependencies!

 

Actual code

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: Little pineapple test notes
# blog:  https://www.cnblogs.com/poloyy/
# Time: 7:58 pm on September 24, 2021
# file: 26_class_dependency.py
"""

from typing import Optional, Dict, Any
# 2. Import dependencies
from fastapi import Depends, FastAPI

import uvicorn

app = FastAPI()

# Simulation database
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


# 1. Class as a dependency
class CommonQueryParams:
    # Still three parameters
    def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit


# 2. Declare dependencies ()
@app.get("/items")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
    response = {}
    # Simulate reading data from the database
    items = fake_items_db[commons.skip: commons.skip + commons.limit]
    response.update({"items": items, "q": commons.q})
    return response


if __name__ == "__main__":
    uvicorn.run(app="26_class_dependency:app", host="127.0.0.1", port=8080, reload=True, debug=True)

 

a key

  • When making a request, you need to__ init__ () to pass parameters
  • The request data is passed to the initialization method of the class (_init_)
  • The value type received by the commons parameter is CommonQueryParams

 

Request result for correct parameter transmission

 

View Swagger API documentation

 

Three ways to write classes as dependencies

commons: CommonQueryParams = Depends()
commons: CommonQueryParams = Depends(CommonQueryParams)
commons = Depends(CommonQueryParams)
  • Standard writing is the second
  • But the first one is recommended. It is the abbreviation of the second one
  • The third type is not recommended because the parameter does not specify a type, and the IDE will not have code intelligent prompt

 

commons: CommonQueryParams = Depends()

  • This is the shortcut to Commons: commonqueryparams = dependencies (commonqueryparams)
  • If the dependency is a class, it is recommended to write it in this way, because the FastAPI will automatically call the dependency class to create an instance object of the class itself

 

Dependent class__ init__ Method has no arguments

class NoInitClass:
    def __str__(self):
        return "hhh,Rewritten str method"


@app.get("/items2")
async def read_items(
        # Use the first recommended way to declare dependencies
        commons: NoInitClass = Depends()
):
    return {"result": str(commons)}

 

View Swagger API documentation

 

Request result

 

Dependent class__ int__ Method has parameters of type Dict and List

from typing import List, Dict, Any, Optional
from fastapi import Depends
from fastapi.encoders import jsonable_encoder


# Dependent class
class DictListClass:
    def __init__(self,
                 *,
                 name: str,
                 address: Optional[List[str]] = None,
                 info: Optional[Dict[str, Any]] = None,
                 ext: Optional[List[Dict[str, Any]]] = None
                 ):
        self.name = name
        self.address = address
        self.info = info
        self.ext = ext

    # Example method
    def test(self):
        self.info.update({"test_func": "Key value pair added by calling method"})


@app.get("/items3")
async def read_items(
        # Use the first recommended way to declare dependencies
        commons: DictListClass = Depends()
):
    # Print it and see what commons are
    print(commons, type(commons))

    # Call instance method
    commons.test()

    commons = jsonable_encoder(commons)
    # What are the converted commons after printing
    print(commons, type(commons))
    return {"commons": commons}

 

View Swagger API documentation

 

Request result for correct parameter transmission

 

After the request, view the console output

<26_class_dependency.DictListClass object at 0x10d20ff40> <class '26_class_dependency.DictListClass'>
{'name': 'Little pineapple', 'address': ['Guangzhou', 'Shenzhen'], 'info': {'age': 24, 'test_func': 'Key value pair added by calling method'}, 'ext': [{'sex': 'girl'}, {'phone': 135012121212}]} <class 'dict'>
  • You can see that before the conversion, commons is an instance object of the "DictListClass" class
  • jsonable_ The converted commons of the encoder is a dict (jsonable_encoder is really powerful)

 

Code prompt after declaring dependencies with {Commons: dictlistclass = dependencies()

Not only is the code elegant and concise, but there are still IDE code tips

 

Keywords: FastAPI

Added by kel on Wed, 05 Jan 2022 13:52:01 +0200