In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Today, I will talk to you about the working principle and usage of the dependency injection system in python fastapi, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.
There is a powerful and easy-to-understand system in fastapi: dependency injection system
one
What is dependency injection?
Dependency injection first means that our code can declare some items in the program that it must rely on: we call it dependencies, that is, dependencies. Then, in practice, fastapi will provide all the required dependencies to your code, called injection dependencies.
A simple explanation: originally accept a variety of parameters to construct an object, now accept only one parameter this parameter is already instantiated object, the object's "dependency" is injected and decoupled from the way it is constructed. The "control" operation of constructing it is also given to a third party.
1.1
List the applicable scenarios of dependency injection:
1. Business logic reuse
two。 Shared database connection
3. Security mechanism, authority verification, role management, etc.
All the above usage scenarios can improve the code reuse rate and reduce code duplication with the help of dependency injection.
two
Dependency injection implementation scheme
Before looking at the specific implementation of dependency injection, let's take a look at the whole data flow in terms of process. When a new request comes, the actual invocation process is as follows:
1. Call the dependency function (pass the appropriate parameters)
two。 Get the return result of the dependent project function
3. Pass the return result to the corresponding parameter in the routing function
4. Traffic flow data processing in routing function
5. The acquired data is returned to the client / front end.
2.1
Function-level dependency
#-*-encoding: utf-8-*-from fastapi import Depends, FastAPIapp = FastAPI () async def common_paras (request_source: str = None, page: int = 0, limit: int = 100): return {"request_source": request_source, "page": page "limit": limit} @ app.get ("/ items/info") async def read_items_info (commons: dict = Depends (common_paras): return commons@app.get ("/ users/info") async def read_users_info (commons: dict = Depends (common_paras)): return commons
2.2
Class-level dependency
#-*-encoding: utf-8-*-from fastapi import Depends, FastAPIapp = FastAPI () fake_items_db = [{"user_name": "HaiShiNiu"}, {"user_name": "WangXiaoXiao"}, {"user_name": "ZhongCen"}] class CommonQueryParams: def _ init__ (self, request_source: str = None, page: int = 0 Limit: int = 100): self.request_source = request_source self.page = page self.limit = limit@app.get ("/ items/info") async def read_items (commons: CommonQueryParams = Depends (CommonQueryParams)): response = {} if commons.request_source: response.update ({"Q": commons.q}) items = fake_items_ DB [commons.page: commons.page + commons.limit] Response.update ({"items": items}) return response
2.3
Recursive dependency
#-*-encoding: utf-8-*-from fastapi import Cookie, Depends, FastAPIapp = FastAPI () def query_extractor (Q11: str, Q12: str): return Q11 + q12def query_or_cookie_extractor (Q2: str = Depends (query_extractor) Last_query: str = Cookie (None): if not Q2: return last_query return q2@app.get ("/ items/") async def read_query (query_or_default: str = Depends (query_or_cookie_extractor)): return {"q_or_cookie": query_or_default}
Note: some scenarios require multiple calls to dependencies.
If a dependency is declared multiple times in the same path operation, for example, multiple dependencies have a common child dependency, then fastapi calls the dependency only once per request by default. Instead of calling the dependency multiple times in the same request, fastapi caches the return value of the dependency and passes it to the desired dependency. In some scenarios, we don't need to cache the return value of this dependency, but we need to call it multiple times, so we can use the parameter use_cache=False to disable the dependency caching.
Async def needy_dependency (fresh_value: str = Depends (get_value, use_cache=False): return {"fresh_value": fresh_value}
2.4
Manipulate decorator dependencies based on path
In some cases, we do not need the return value of the dependency, but we still need the dependency to be executed. In this case, we can manipulate a list of dependencies through the path manipulation decorator. The path operation decorator receives an optional parameter, dependencies, whose content is a list of Depends ().
#-*-encoding: utf-8-*-from fastapi import Depends, FastAPI, Header, HTTPExceptionapp = FastAPI () async def verify_token (x_token: str = Header (...): if x_token! = "token": raise HTTPException (status_code=400, detail= "X-Token header invalid") async def verify_key (x_key: str = Header (...): if x_key! = "key": raise HTTPException (status_code=400) Detail= "X-Key header invalid") return x_key@app.get ("/ items/info", dependencies= [Depends (verify_token), Depends (verify_key)]) async def read_items_info (): return [{"function_name": "Foo"}, {"function_name": "Bar"}]
These dependencies execute the same as normal dependencies, but their return values, if any, are not passed to the path operation function. We can reuse declared dependencies, regardless of whether they have a return value or not, without affecting the execution of the dependency.
2.5
With yield functional dependencies
Fastapi supports dependencies to do some extra work after the request ends. To do this, we need to replace return with yield, and then add some extra work later. Let's take an example: create a database link and then close the link after the request ends. Of course, there are many solutions to deal with this case, and this time we will implement it based on the dependencies that use the yield function.
#-*-encoding: utf-8-*-async def get_db_info (): "get database connection information" # create link db = DBSession () try: yield db # Database uses finally: db.close () # close database link
To be brief: the value db after yield db is injected into path operations or other dependencies. The code behind the yield db is not executed until the response is submitted. Use try statements to catch possible exceptions. To ensure that the exit logic is executed regardless of whether an exception occurs or not, we execute the exit logic in the finally statement here. Note, however, that if you try to throw HTTPException after yield, it won't work. The exit code after yield is executed after the exception handler, so the exception cannot be caught.
2.6
Parameterized dependency
The dependencies we used earlier are fixed functions or classes, but sometimes we want to set different parameters in the dependencies without declaring different functions or classes. At this point, you can use a callable class instance to implement this function. Note: the class itself is callable, and its instance needs to implement a specific class method to be callable: call
In a word, call:call is a dark magic method of Python. The core function is that logic in call can be triggered directly through object instances, which is widely used in Tornado source code.
#-*-encoding: utf-8-*-from fastapi import Depends, FastAPIapp = FastAPI () class FixedContentQueryCheck (object): def _ init__ (self, fixed_content: str): self.fixed_content = fixed_content def _ call__ (self Q: str = ""): if Q: return self.fixed_content in q return Falsechecker = FixedContentQueryCheck ("bar") @ app.get ("/ query-checker/") async def read_query_check (fixed_content_included: bool = Depends (checker)): return {"fixed_content_in_query": fixed_content_included}
We systematically sort out the various ways to implement dependency injection for everyone to use in the production environment.
After reading the above, do you have any further understanding of how the dependency injection system works and how to use it in python fastapi? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.