Building a basic API service

A good practice is to start with something simple, where we don't risk having issues in our codeso we can test the framework, first. Let's start with a simple hello world application.

Let's dive in and start with a simple hello world-style application that will return the predefined values, with no computations at all:

  1. First, we will need to import the library and initialize the main application object:
from fastapi import FastAPI
app = FastAPI()
  1. Next, let's define our toy database:
db = {'noise': 24,
'broken hydrant': 2}
  1. We now define the function that will be executed for each URL request and return the value:
def complaints(complaint_type: str, hour:int) -> dict:
return {"complaint_type": complaint_type, "hour": hour, "q": db.get(complaint_type, None)}

Note that we use type annotations for the arguments. With FastAPI, this is importantthose type hints are used for validation and in the autogenerated documentation.

  1. Lastly, we need to register our function as an endpoint for the application, using a decorator:
@app.get("/complaints/{complaint_type}")
def complaints(complaint_type: str, hour:int) -> dict:
return {"complaint_type": complaint_type, "hour": hour, "q": db.get(complaint_type, None)}

Note that we specify the type of the request via the app.get method (similar to the methods of the requests library) and encode one variable, complaint_type, as part of the URL, like an f-string. The framework will take care of the rest.

  1. Now, we can run the server locally:
uvicorn hello_world:app --reload

By doing so, we trigger uvicorn and ASGI server to run, serving app from the hello_world.py file, locally.

  1. Once the application is ready, uvicorn will print a line pointing to the correct IP address, similar to this one:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Now, this link itself won't do anythingthere is no app served on the root directly.

  1. To test our application, we need to specify a resourceadd the path we used in our decorator, and specify the complaint type, as in the following example:
http://127.0.0.1:8000/complaints/noise?hour=12
>>> {"complaint_type":"noise","hour":12, "q":24}
  1. Let's check that the application is indeed livewrite something clearly wrong as a complaint type, don't pass a value, and see what happens:
http://127.0.0.1:8000/complaints/wrong
>>> {"detail":[{"loc":["query","hour"],"msg":"field required","type":"value_error.missing"}]}

http://127.0.0.1:8000/complaints/wrong?hour=2
>>> {"complaint_type":"wrong","hour":2,"q":null}

Let's now discuss what happens under the hood. In our function, we declared two arguments: complaint_type and hour, each with a specified typing. The former is defined within the route we provide; the latter is not specified there knowing that, FastAPI assumes it will be provided as a parameter. Furthermore, everything in the URL is a string; as FastAPI knows what to expect from the type annotation, it will attempt to parse our values appropriatelynote that, in the response, an hour is an integer, and it is not wrapped in quotes.

When we pass an incorrect URL, the first thing that triggered is that there is no hour parameter; therefore, FastAPI raises a scheme validation issue; once an hour is passed, the request is considered successful (except there is no value, of course), as FastAPI does not know which values are acceptable for complaint_type (and hour, for that matter). So, what happens next?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.55.75