Getting Started¶
Let’s walk you through a simple example step by step.
In this guide, we will:
create a Jeroboam app
register a view function
add some view argument configuration to it for inbound data validation
add a response_model to the endpoint for outbound data validation
register the OpenAPI blueprint to get a look at the generated documentation
Create a Jeroboam App¶
Let’s start with creating the application object.
1from flask_jeroboam import Jeroboam
2
3
4app = Jeroboam("Jeroboam Getting Started App")
5app.init_app()
6
7
8if __name__ == "__main__":
9 app.run(host="localhost", port=5000)
As you can see, there is nothing special about the app creation on line 4. The Jeroboam class from flask_jeroboam subclasses flask’s Flask application object, and you can use it as a drop-in replacement of the former.
1from flask_jeroboam import Jeroboam
2
3
4app = Jeroboam("Jeroboam Getting Started App")
5app.init_app()
6
7
8if __name__ == "__main__":
9 app.run(host="localhost", port=5000)
On line 5, we are calling the init_app method of the app instance. You should call this method after loading the configuration to your app: it will register OpenAPI blueprints and generic error handlers. You can always opt-out of these with appropriate configuration values (see here).
1from flask_jeroboam import Jeroboam
2
3
4app = Jeroboam("Jeroboam Getting Started App")
5app.init_app()
6
7
8if __name__ == "__main__":
9 app.run(host="localhost", port=5000)
Finally, lines 8 and 9 are a convenient way to start the app by running the file directly.
Note
The application factory pattern is usually a good practice [1] and should be followed when you start an actual project.
Register a view function¶
Registering a view function means binding a python function to an URL. Whenever a request sent to your server matches the rule you defined, the registered function, called a view function, will be run.
You can register a view function in several ways in Flask. The preferred way to do it in Flask_Jeroboam is to use method decorators, like on line 8 in the example below:
1from flask_jeroboam import Jeroboam
2
3
4app = Jeroboam("Jeroboam Getting Started App")
5app.init_app()
6
7
8@app.get("/health")
9def get_health():
10 return {"status": "Ok"}
11
12if __name__ == "__main__":
13 app.run(host="localhost", port=5000)
Here we are telling the app instance that when it receives an incoming GET Request to the URL /health
, it should call the get_health
function and return the result to the client. Let’s try it. Run your file and start poking.
$ curl http://localhost:5000/health
{"status": "ok"}
Note
Although you can register view functions directly on the app instance, any project beyond the size of a classical tutorial will benefit from using the modularity of Blueprints [2], and you will find yourself using blueprints more than your app instance. The good news is that you register view functions on blueprints as you do on the app instance.
Adding View Arguments¶
Let’s try something more interesting. So far, our Jeroboam application behaves like a regular Flask application.
Let’s register a view function that takes parameters. On line 13, you will find the method decorator we saw in the previous section. But on line 14, the view function takes two parameters with type hints and default values. It then returns them without modifying them.
1from flask_jeroboam import Jeroboam
2
3
4app = Jeroboam("Jeroboam Getting Started App")
5app.init_app()
6
7
8@app.get("/health")
9def get_health():
10 return {"status": "Ok"}
11
12
13@app.get("/query_string_arguments")
14def get_query_string_arguments(page: int = 1, per_page: int = 10):
15 return {"page": page, "per_page": per_page}
16
17
18if __name__ == "__main__":
19 app.run(host="localhost", port=5000)
This view function ‘s only purpose is to help us inspecting the values the function actually receives when it is called and this is precisely what we will do.
$ curl 'http://localhost:5000/query_string_arguments'
{"page":1,"per_page":10}
So far, so good. The result was predictable. The function received the default values for the parameters. Let’s try something else.
$ curl 'http://localhost:5000/query_string_arguments?page=2&per_page=50'
{"page":2,"per_page":50}
Let’s take a closer look at the url we’re hitting: /query_string_arguments?page=2&per_page=50
. The part after the ?
is called a query string. It is a way to pass parameters through a URL. page=2&per_page=50
translates to two parameters, page
and per_page
with respective values of 2
and 50
. Luckily that’s exactly what our view function is expecting. Flask-Jeroboam will parse the query string, validate the values (check they can be cast as int) and inject them into the view function.
The previous example showed us the parsing and injecting part. Let’s take a look at its validation capabilities by passing a page value that can’t be cast to an int. We will add the -w 'Status Code: %{http_code}\n'
option to our curl command to print the status code of the response.
$ curl -w 'Status Code: %{http_code}\n' 'http://localhost:5000/query_string_arguments?page=not_a_int&per_page=50'
{"detail":[{"loc":["query","page"],"msg":"value is not a valid integer","type":"type_error.integer"}]}
Status Code: 400
Here, we got a 400 Bad Request response, with details about the error, telling us that the value of the page
argument located in the query
(“loc”:[“query”,”page”]) is not a valid integer (“msg”:”value is not a valid integer”).
Note
By default, the arguments of a GET
view function are expected to get their values from the query string. It is their location
. You can explicitly set the location of the arguments by using argument functions as default values (Exemple: page: int = Query(1)
). Possible location for parameters include Path
, Query
, Header
and Cookie
. For request bodies, you can set locations to Body
, Form
and File
. Body
is the default location for POST
and PUT
requests.
You will find more information about this mechanics here.
Now that we have covered the basics of inbound handling, let’s look at the outbound parsing and validation. This is done by adding a response_model
to our decorator.
Response Models¶
We start by defining a Pydantic BaseModel for our response. This model will be used to validate the outbound data of our view function. We first import BaseModel and Field from pydantic on line 1 and 2. On line 11-14, we define a subclass of pydnatic’s BaseModel named Item
with three fields: name
, price
and count
. The name
field is a string, the price
field is a float and the count
field is an int with a default value of 1.
1from pydantic import BaseModel
2from pydantic import Field
3
4from flask_jeroboam import Jeroboam
5
6
7app = Jeroboam("Jeroboam Getting Started App")
8app.init_app()
9
10
11class Item(BaseModel):
12 name: str
13 price: float
14 count: int = Field(1)
15
16
17@app.get("/item", response_model=Item)
18def get_an_item():
19 return {"name": "Bottle", "price": 5}
20
21
22if __name__ == "__main__":
23 app.run(host="localhost", port=5000)
We then pass the Item
model as the response_model
argument of the @app.get
decorator on line 17. Our view function’s purpose is to demonstrate that our return value will be processed through the Item
model and not simply returning the {"name": "Bottle", "price": 5}
dictionnary, casting the price into a float, and adding a default value of 1 to the count field.
1from pydantic import BaseModel
2from pydantic import Field
3
4from flask_jeroboam import Jeroboam
5
6
7app = Jeroboam("Jeroboam Getting Started App")
8app.init_app()
9
10
11class Item(BaseModel):
12 name: str
13 price: float
14 count: int = Field(1)
15
16
17@app.get("/item", response_model=Item)
18def get_an_item():
19 return {"name": "Bottle", "price": 5}
20
21
22if __name__ == "__main__":
23 app.run(host="localhost", port=5000)
Let’s try it out.
$ curl 'http://localhost:5000/item'
{"name": "Bottle", "price": 5.0, "count": 1}%
What happened is that the return value of the view function has been fed to the Item
model. The price have been casted as a float, and the missing key-value of count has been added with its default value. The values have been validated and finally serialized into a JSON string.
Finally, to wrap up this first tour of Flask-Jeroboam, let’s take a look at the OpenAPI-complaint documentation our app was able to produce.
OpenAPI Documentation¶
When you visit http://localhost:5000/docs in your browser you should see the OpenAPI documentation for your API. It will look something like this:

Wrapping Up¶
In this page, we covered the three main features of Flask-Jeroboam:
Inbound data parsing and validation based on view function signatures
Outbound data validation and serialization based on response models
OpenAPI auto-documentation
To go further¶
If you want to learn more, you can check out our in-depth features tour.
We also mentioned:
Complete example code for this page can be found here. Examples are tested in this file.