Flask and FastAPI are popular Python micro-frameworks for building small-scale data science and machine learning-based websites or applications. Even though FastAPI is a relatively new framework, many developers use it in their new projects. In this post, we will first discuss the reason for FastAPI’s popularity, followed by building a simple API using FastAPI in everyone’s favorite Python IDE: PyScripter. Then we will create a GUI in Delphi FMX that consumes this API. So, let’s get started!
Table of Contents
Why is FastAPI Preferred to Make APIs?
FastAPI is a modern API development framework based on the Asynchronous Server Gateway Interface (ASGI) web server Uvicorn. Though it is new, you can also mount Web Server Gateway Interface (WSGI) applications using appropriate middleware. It is currently being used by many companies, among the most notable include Uber, Microsoft, Explosion AI, and others.
FastAPI easily supports concurrency and provides a simple and easy-to-use dependency injection system. Another advantage to consider is built-in data validation.
Most importantly, if we were to name one quality by which FastAPI beats Flask, it’s the excellent performance. FastAPI is known as one of the fastest Python web frameworks. Only Starlette and Uvicorn, which FastAPI is built upon, are faster. The superior performance of FastAPI is made possible by ASGI, enabling it to support concurrency and asynchronous code. This is accomplished by using async def syntax to declare the endpoints.
How Can We Build a Simple Employee Management System with FastAPI?
This tutorial aims to teach you the basics of FastAPI with PythonGUI. So, we will create a REST API in PyScripter that serves as an employee management system.
What Are the Requirements for This FastAPI and Python GUI Tutorial?
You will require an IDE like PyScripter, Python3.9, and its FastAPI (with Uvicorn) as well as the DelphiFMX libraries.
After you have Python set up on your system, you can install FastAPI and Uvicorn using pip:
1 |
pip install fastapi uvicorn |
If you followed the above steps correctly, you will now have a working instance of FastAPI and Uvicorn installed on your PC and are ready to learn how to use them. We will use the FastAPI framework to build our API, while Uvicorn will act as the server that will serve requests based on the API you build.
Similarly, to install DelphiFMX:
1 |
pip install delphifmx |
How to Create a FastAPI Instance?
Now, we will create a simple FastAPI app and run it with a server using Uvicorn.
1 2 3 |
from fastapi import FastAPI app = FastAPI() |
The code above is added to a file named main.py. In this case, the app variable is an instance of the FastAPI class. This will serve as the primary point of contact when developing your API.
This code defines your application but will not run if you call it directly with Python. A server program is required to run it. Uvicorn was already installed in the preceding steps and will be our server. But the question arises: where would all our data be stored, and how would it be managed?
What is User Model and How to Create a Database With Python?
First, import BaseModel
from pydantic and use it to create subclasses that define the schema, or data shapes, that you want to receive.
Next, you will declare your data model as a class inheriting from BaseModel
, with all attributes being standard Python types:
1 2 3 4 5 6 7 8 9 |
from typing import List from pydantic import BaseModel class User(BaseModel): id: int firstName: str lastName: str gender: str role: str |
Note: When a model attribute has a default value, it is not required.
Pydantic handles all data validation under the hood, so you get all the benefits and know you’re in good hands. For example, with pydantic, you can use the same type declarations with str, float, bool,
and many other complex data types.
Now let’s create a database of users using the BaseModel
, and populate it with some initial employees:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
db: List[User] = [ User( id=1, firstName="Alina", lastName="Rahid", gender="F", role="Cashier" ), User( id=2, firstName="Ahmed", lastName="Ali", gender="M", role="Admin" ) ] |
How to Create an Endpoint In Python For Our Employee Management System?
Now, we are making a simple endpoint, "users"
, that allow GET and POST calls so that one can get all the employee records or add an employee to the existing record:
1 2 3 4 5 6 7 8 |
@app.get("/users") def fetchUsers(): return db @app.post("/users") def addUser(user: User): db.append(user) return {"id": user.id} |
This may seem a bit confusing at first, but rest assured, we will explain it in detail below. But another suggestion is to work in PyScripter as it offers the best syntax highlighting, which can help you organize and understand your code better. Furthermore, its integrated debugger can help you fix broken code quickly. So, if you’re a beginner in Python, PyScripter should be part of your starter kit.
How to Use the HTTP GET Method In Python?
The @app.get("/users")
tells FastAPI that the function right below is in charge of handling requests that go to the path /users
using a get operation. This is a path operation decorator or a path operation decorator. If you want to learn more about decorators, read the Python Decorators Primer.
FastAPI will invoke this function whenever it receives a GET request to the specified URL (/users)
.
With this, you can return lists, dictionaries, or single values as strings, integers, etc. Moreover, you can also return pydantic models, which is what we’re doing here.
How to Use the HTTP POST Method In Python?
In a function, you can declare the type of a path parameter using standard Python type hints. Declaring the path parameter’s type will provide editor support within your function, such as error checks and completion.
So, the final code looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
from fastapi import FastAPI from typing import List from pydantic import BaseModel import uvicorn class User(BaseModel): id: int firstName: str lastName: str gender: str role: str app = FastAPI() db: List[User] = [ User( id=1, firstName="Alina", lastName="Rahid", gender="F", role="Cashier" ), User( id=2, firstName="Ahmed", lastName="Ali", gender="M", role="Admin" ) ] @app.get("/users") def fetchUsers(): return db @app.post("/users") def addUser(user: User): db.append(user) return {"id": user.id} |
How to Run the FastAPI Server For Our Python GUI Employee Management System?
Now, you are all set to run your server and interact with the database using the API!
Add the following line to your main.py, and your API will be served via uvicorn on port 8000
:
1 |
uvicorn.run(app, port=8000, host="127.0.0.1") |
Then, normally execute the code in your python file.
The app will, by default, run on the localhost, i.e., http://127.0.0.1:8000
. Overall, the output you get from running the command above shows the URL where your app is being served on your local machine. You can use the parameter reload=True
in uvicorn.run
so that the server will reload automatically when you update your application code.
On a side note, an alternative way to run the server in through the following command in the terminal:
1 |
uvicorn main:app --reload |
How to Make an HTTP GET Request In Python?
To get all the employee information, we will call the fetchUsers
method. For this, you can go to http://127.0.0.1:8000/users
.
How to Make an HTTP POSTRequest In Python?
Adding an employee instance to your existing records is comparatively tricky. But don’t worry; we’ve got you covered. The easiest way to make a POST request would be through the Swagger UI (In some later articles, we may discuss how to build REST clients, so keep a look out!)
What Are Swagger Docs?
When you visit http://127.0.0.1:8000/docs
in your browser, you will see an automatic, interactive API documentation. Here we have an option to make a POST call to the user
endpoint.
Once we execute this request, we will get a response:
Here, we can see that the response is the employee’s id that has just been added, i.e., 3 in this case.
Swagger can also be used to make the GET request for the same endpoint. So let’s go ahead and execute it to check whether our records have been updated with the third employee.
And it worked!
How to Create a REST Client in Python?
The HTTP protocol sends a client request to the web server, retrieving specific data and information if the transaction is legitimate. You could examine the server’s answer using many methods in the python request package.
Firstly, import the requests module to your code top. Then, for a GET request, we have to use the requests module get method to fetch all the data on the google server in a text form.
1 2 3 4 5 6 7 8 |
import requests BASE = "http://127.0.0.1:8000/" response = requests.get(BASE + "users") response = response.json() print(response) |
A similar approach can be taken for making a POST request and getting the corresponding API response. Overall, one tip that cannot be emphasized enough is to use PyScripter for all your Python development. FastAPI and PyScripter produce a strong combination that will allow you to build APIs efficiently and can help boost your salary.
Why is PyScripter the Best IDE for Using FastAPI?
PyScripter began as a simple integrated development environment (IDE) to supplement the excellent Python for Delphi (P4D) components by providing a reliable scripting solution for Delphi applications. It has a more modern UI and is faster than some other IDEs because it is written in a compiled language. It also has numerous features that make it an excellent Python development environment.
This fantastic IDE aims to create a Python IDE that can compete with traditional Windows-based IDEs for other languages. PyScripter is a fantastic program. With many features, it is lightweight, versatile, and extendable. Furthermore, compared to other text editors and general-purpose IDEs, it is significantly faster and more responsive because it was built from scratch with Windows in mind, making it a perfect match for Python GUI programming and application.
How Can We Build a Python GUI That Consumes This API?
Let’s take our work a step further and use the amazing Python4Delphi’s DelphiFMX library to build a simple GUI that makes GET and POST requests to the API we have just created.
What is DelphiFMX?
DelphiFMX is a Python module that is natively compiled and powered by the Python4Delphi library. It is freely redistributable and provides Python developers access to the FireMonkey GUI framework for GUI development in Windows, macOS, Linux, and Android.
Embarcadero Delphi’s FireMonkey is a graphical user interface framework for native cross-platform application development that uses hardware-accelerated rendering using the GPU via DirectX or OpenGL. In addition, it has a robust styling system, is user-extensible, and does not require Delphi or any previous knowledge of Object Pascal.
How to Create a Simple Python GUI Application?
The code below creates a simple DelphiFMX application, a window (with name “Hello Delphi FMX”), and simply gives a greeting:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from delphifmx import * Application.Initialize() Application.Title = "Hello Delphi FMX" Application.MainForm = Form(Application) Application.MainForm.SetProps(Caption = "Hello World") msg = Label(Application.MainForm) msg.SetProps(Parent = Application.MainForm, Text = "Hello Python from Delphi FMX", Position = Position(PointF(20, 20)), Width = 200) Application.MainForm.Show() Application.Run() # This is the main loop Application.MainForm.Destroy() |
This code is taken from the GitHub repository of Python DelphiFMX. Several other sample codes in this repository will help you, master Python GUIs.
How to Enhance This Python GUI For Our Use Case?
Our code will be using two libraries:
1 2 |
import requests from delphifmx import * |
It is better to save your base URL (where the API is being served) as a global variable, BASE
:
1 |
BASE = "http://127.0.0.1:8000/" |
Now, we will define a class EmployeeManager that will define our main form:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
class EmployeeManager(Form): def __init__(self, owner): “““ Initialization function, that initializes the form window and assigns different attributes to different parts of the form.””” # Initializing the main Wwindow and setting its name as “Employee Management” self.SetProps(Caption = "Employee Management", OnShow = self.__form_show, OnClose = self.__form_close) # Creating a Label called fName that will display the String “First Name: ” next to our input box. self.fName = Label(self) self.fName.SetProps(Parent = self, Text = "First Name: ", Position = Position(PointF(20, 20))) # Creating a Label called lName that will display the String “Last Name: ” next to our input box. self.lName = Label(self) self.lName.SetProps(Parent = self, Text = "Last Name: ", Position = Position(PointF(20, 45))) # Creating a Label called gender that will display the String “Gender: ” next to our input box. self.gender = Label(self) self.gender.SetProps(Parent = self, Text = "Gender: ", Position = Position(PointF(20, 70))) # Creating a Label called role that will display the String “Role: ” next to our input box. self.role = Label(self) self.role.SetProps(Parent = self, Text = "Role: ", Position = Position(PointF(20, 95))) # Creating a Label called id that will display the String “ID: ” next to our input box. self.id = Label(self) self.id.SetProps(Parent = self, Text = "ID: ", Position = Position(PointF(20, 120))) # Creating a TextBox named editFName that will allow us to add the First Name of our employees to the form. self.editFName = Edit(self) self.editFName.SetProps(Parent = self, Position = Position(PointF(80,20)), Height = 15) # Creating a TextBox named editLName that will allow us to add the Last Name of our employees to the form. self.editLName = Edit(self) self.editLName.SetProps(Parent = self, Position = Position(PointF(80,45)), Height = 15) # Creating a TextBox named editGender that will allow us to add the gender of our employees to the form. self.editGender = Edit(self) self.editGender.SetProps(Parent = self, Position = Position(PointF(80,70)), Height = 15) # Creating a TextBox named editRole that will allow us to add the Role of our employees to the form. self.editRole = Edit(self) self.editRole.SetProps(Parent = self, Position = Position(PointF(80,95)), Height = 15) # Creating a TextBox named editId that will allow us to add the id of our employees to the form. self.editId = Edit(self) self.editId.SetProps(Parent = self, Position = Position(PointF(80,120)), Height = 15) # Creating a Button named addEmployee that, when clicked, adds the entries in the textboxes to the database. The Button also displays some text specified in the “Text” parameter. self.addEmployee = Button(self) self.addEmployee.SetProps(Parent = self, Text = "Add Employee", Position = Position(PointF(250, 115)), Width = 90, OnClick = self.__button_click_add) # Creating a Button named “view” that, when clicked, displays all of the employees in our Database. It also displays some text specified in the “Text” parameter. self.view = Button(self) self.view.SetProps(Parent = self, Text = "View Employees", Position = Position(PointF(350, 115)), Width = 100, OnClick = self.__button_click_view) # Creating a ListBox named “list” that displays all of the employees in our Database. self.list = ListBox(self) self.list.SetProps(Parent = self, Position = Position(PointF(20, 140)), Width = 450, Height = 150) def __form_show(self, sender): “““This function initializes the dimensions of the form, and helps us show the form.””” self.SetProps(Width = 500, Height = 350) def __form_close(self, sender, action): “““ Function helps close the form by defining an action.””” action = "caFree" def __button_click_add(self, sender): “““ This Function, parses over all the text boxes on the form, creates JSON named “myobj,” send the JSON to the database, and finally adds it to our list object.””” # Initializing a JSON with all the employee details from the form. myobj = {"id":int(self.editId.text), "firstName":self.editFName.text,"lastName":self.editLName.text,"gender":self.editGender.text,"role":self.editRole.text} # Posting the JSON using FASTApi to our Database. x = requests.post(BASE+"users", json = myobj) # Adding the new Employee to our Database. self.list.items.add(x.text) self.list.items.add("Your Entry was successfully added!") # Resetting the text boxes as empty. self.editFName.text = self.editLName.text = self.editGender.text = self.editRole.text = self.editId.text = "" def __button_click_view(self, sender): “““ This function, when called, uses a FASTApi GET request to get a lists all the employees in the organization. It then displays said employees to the list box for display.””” # Getting all the employees from the database. response = requests.get(BASE + "users") # Storing the Employees into a JSON response = response.json() # Iterating over all the employees and adding them to the list box for display. self.list.items.text = "" for employee in response: self.list.items.add(employee) |
Here, we are creating a simple form with five labels, First Name, Last Name, Gender, Role, and ID, using the Label method of delphifmx. Then we create editable text boxes corresponding to each of these five labels using Edit method. Next, we define two buttons, “Add Employee” and “View Employees” that call the __button_click_add and __button_click_view methods of our class, respectively, when clicked.
The __button_click_view method uses requests to make GET requests while the __button_click_view method uses the library to make POST requests. Responses to both these requests are printed for the user in the ListBox object names list.
Lastly, we will define our main method that initializes the form defined earlier:
1 2 3 4 5 6 7 |
def main(): Application.Initialize() Application.Title = "Employee Management Using Delphi FMX" Application.MainForm = EmployeeManager(Application) Application.MainForm.Show() Application.Run() Application.MainForm.Destroy() |
Adding the following lines will initiate the app whenever this Python code file is run:
1 2 |
if __name__ == '__main__': main() |
Running the code will give us this GUI:
Note, your server must be running via Uvicorn for the GUI to be completely functional. Now, let’s see everything we have done in action!
Clicking the “View Employees”
button will show the two initial employees in the list box of the GUI. Now let’s add an employee via the GUI.
We should even be able to add a new employee. Below, we can see that the POST response (id of the added employee) is visible in the list box.
Let’s go ahead and even confirm that the employee records are updated. We will click the “View Employees”
button to make the GET request.
Congratulations on successfully reaching the end of this tutorial!
What Have We Learned From This Python GUI and FastAPI Tutorial?
In this tutorial, we learned a great deal about FastAPI and how you can use it to create your first production-ready API. We also looked at some best coding practices while providing the best developer experience possible with a great PythonGUI.
You learned how to receive JSON data in your API requests using pydantic and API best practices like validation and documentation while building APIs with FastAPI.
Designing a user interface does not have to be difficult. Pip packages provide access to a variety of Python tools. DelphiFMX is a powerful tool with numerous capabilities and customization options. Because of its inherent support for hardware acceleration, it is highly recommended for Windows developers. If you want to dive deeper into Python GUI’s offerings, you can download Python GUI’s getting started e-book.
Moreover, the true potential of these modules can only be availed through PyScipter. Why don’t you follow this tutorial right now in PyScripter? If you already have, then you’re ready to create your own highly performant APIs using your favorite IDE
What Are Some FAQs Relating to FastAPI and PythonGUI?
What is DelphiFMX?
Delphi’s FireMonkey framework is Embarcadero’s Python module for developing graphical user interfaces (GUIs) for Windows, macOS, Linux, and Android.
This GUI framework is primarily used to develop GUIs for native cross-platform application development. For hardware-accelerated rendering, it uses the GPU via DirectX or OpenGL. In addition, it has a robust styling system and is user-extensible.
What is DelphiVCL?
The Visual Component Library (VCL) is a key part of Delphi’s state-of-the-art user interface support. It contains most native Windows controls and controls with additional features and functionality.
What is FastAPI?
FastAPI is a modern, high-performance web framework for building APIs with Python based on standard type hints.
Which IDE should I use for Python Scripting?
Several IDEs exist for Python coding, including IDLE, Sublime Text, VS Code, PyCharm, and Atom. But as of yet, PyScripter seems to be the best Python IDE in the business and is loved by all Python developers.