Leveraging FastAPI for Building Secure and High-Performance Banking APIs
Explore the importance of FastAPI for developing banking APIs and how it can empower financial institutions to deliver efficient and secure services to their customers.
In today's fast-paced digital world, the banking industry relies heavily on robust and secure APIs to deliver seamless services to customers. FastAPI, a modern web framework for building APIs with Python, has gained significant popularity due to its exceptional performance, scalability, and ease of development. In this blog post, we will explore the importance of FastAPI for developing banking APIs and how it can empower financial institutions to deliver efficient and secure services to their customers also discuss the implementation of automated test cases using the BDD framework.
1. Unmatched Performance: FastAPI is built on top of Starlette, a high-performance asynchronous framework. It leverages Python's asynchronous capabilities to handle multiple requests concurrently, resulting in blazing-fast response times. For banking APIs that require quick response times, FastAPI ensures that transactions, queries, and account information can be retrieved swiftly, providing customers with an excellent user experience.
2. Type Safety and Documentation: FastAPI's strong typing system, powered by Pydantic, allows developers to define clear data models and request/response schemas. This type of safety ensures that the data passed to and from the API is accurate and consistent. Additionally, FastAPI generates interactive and automatically documented APIs based on the defined models, making it easier for developers and other stakeholders to understand and consume the API.
3. Security and Authentication: Banking APIs handle sensitive customer data, and security is of utmost importance. FastAPI provides built-in security features such as OAuth2 authentication, token validation, and request validation, enabling developers to implement robust security measures to protect customer information. Furthermore, FastAPI seamlessly integrates with other security frameworks and tools, allowing the implementation of various authentication and authorization mechanisms, including two-factor authentication and encryption, to meet the stringent security requirements of the banking industry.
4. Scalability and Extensibility: FastAPI's asynchronous architecture enables horizontal scaling, allowing banking APIs to handle a large volume of concurrent requests. Financial institutions can easily scale their API infrastructure based on user demand without sacrificing performance. Additionally, FastAPI's modular design and compatibility with other Python libraries provide developers with the flexibility to extend functionality by integrating with existing banking systems, databases, or third-party services.
5. Automated Testing and Debugging: FastAPI
encourages and facilitates automated testing with tools like pytest
and pytest-bdd
. These
testing frameworks enable developers to write comprehensive tests, ensuring the
correctness and stability of the API. FastAPI's integration with the Swagger UI
and ReDoc documentation tools further simplifies testing and debugging by
providing an interactive interface to explore and validate API endpoints.
Here's an example of a parameterized FastAPI code that creates a banking REST API to connect to a SQL Server database, extract account summary and user details, and return the JSON response. The parameter values are passed using a separate configuration file. Let's go step by step.
First, create a configuration file named config.ini
with
the following content:
[SQLServer]
server = your_server_name
database = your_database_name
username = your_username
password = your_password
driver = {ODBC Driver 17 for SQL Server}
Next, install the required dependencies by running pip
install fastapi pydantic pyodbc python-dotenv
.
from fastapi import FastAPI
from pydantic import BaseModel
import pyodbc
from dotenv import load_dotenv
import os
# Load configuration from the .env file
load_dotenv(".env")
# Define the FastAPI app
app = FastAPI()
# Read configuration from the environment variables or use default values
server = os.getenv("SERVER", "your_server_name")
database = os.getenv("DATABASE", "your_database_name")
username = os.getenv("USERNAME", "your_username")
password = os.getenv("PASSWORD", "your_password")
driver = os.getenv("DRIVER", "{ODBC Driver 17 for SQL Server}")
# Establish a database connection
conn = pyodbc.connect(f"DRIVER={driver};SERVER={server};DATABASE={database};UID={username};PWD={password}")
# Account model
class AccountSummary(BaseModel):
account_number: str
balance: float
# User model
class User(BaseModel):
user_id: int
name: str
email: str
# Route to retrieve account summary
@app.get("/account/{account_number}")
def get_account_summary(account_number: str):
cursor = conn.cursor()
# Execute the SQL query
cursor.execute(f"SELECT account_number, balance FROM accounts WHERE account_number = '{account_number}'")
# Fetch the result
row = cursor.fetchone()
# Check if the account exists
if row is None:
return {"error": "Account not found"}
# Create an instance of the AccountSummary model
account_summary = AccountSummary(account_number=row.account_number, balance=row.balance)
return account_summary
# Route to retrieve user details
@app.get("/user/{user_id}")
def get_user(user_id: int):
cursor = conn.cursor()
# Execute the SQL query
cursor.execute(f"SELECT user_id, name, email FROM users WHERE user_id = {user_id}")
# Fetch the result
row = cursor.fetchone()
# Check if the user exists
if row is None:
return {"error": "User not found"}
# Create an instance of the User model
user = User(user_id=row.user_id, name=row.name, email=row.email)
return user
# Run the FastAPI app
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
Explanation
1. Import the
necessary dependencies: FastAPI
, BaseModel
from pydantic
, pyodbc
, load_dotenv
from dotenv
, and os
.
2. Load the
configuration from the config.ini
file
using load_dotenv(".env")
.
3. Create an
instance of the FastAPI
class.
4. Read the
configuration values from the environment variables or use default values
specified in the code. The os.getenv()
function.
5. Establish a database connection using the configuration values obtained from the environment variables or default values.
6. Define
the AccountSummary
model using BaseModel
to
represent the account summary with account_number
and balance
attributes.
7. Define
the User
model using BaseModel
to
represent user details with user_id
, name
, and email
attributes.
8. Create a
route /account/{account_number}
using
the @app.get
decorator to handle GET
requests and retrieve the account summary for a given account number.
9. Inside the
route function get_account_summary
, establish
a database cursor to execute SQL queries.
10. Execute the SQL query to retrieve the account summary for the provided account number.
11. Fetch the first row of the result using cursor.fetchone()
.
12. Check if the account exists by verifying if the fetched row
is None
. If it is, return an error message indicating
that the account was not found.
13. If the account exists, create an instance of the AccountSummary
model
with the fetched account_number
and balance
.
14. Return the account summary as JSON.
15. Create a route /user/{user_id}
using
the @app.get
decorator to handle GET
requests and retrieve the user details for a given user ID.
16. Inside the route function get_user
, establish
a database cursor to execute SQL queries.
17. Execute the SQL query to retrieve the user details for the provided user ID.
18. Fetch the first row of the result using cursor.fetchone()
.
19. Check if the user exists by verifying if the fetched row
is None
. If it is, return an error message indicating
that the user was not found.
20. If the user exists, create an instance of the User
model
with the fetched user_id
, name
, and email
.
21. Return the user details as JSON.
22. Finally, run the FastAPI app using uvicorn
server.
Make sure to install the required dependencies by running pip
install fastapi pydantic pyodbc python-dotenv
before
running the code. Additionally, create the config.ini
file
with the correct values for the SQL Server connection. You can customize the
configuration values by modifying the config.ini
file
or setting environment variables with the same names.
Automated Behavior-Driven Development (BDD) Test Cases
To create automated Behavior-Driven Development (BDD)
test cases for the banking API, you can use a testing framework like pytest
along
with libraries such as requests
and pytest-bdd
. Here's an
example of how you can structure and write BDD test cases for the API:
1. Install the
required dependencies by running pip install pytest requests
pytest-bdd
.
2. Create a new directory for your test suite and navigate to it.
3. Create a new
file called test_banking_api.feature
and
add the following content:
Feature: Banking API
Scenario: Retrieve account summary
Given the API is running
When I send a GET request to "/account/123456789"
Then the response status code should be 200
And the response should contain the account summary
Scenario: Retrieve user details
Given the API is running
When I send a GET request to "/user/1"
Then the response status code should be 200
And the response should contain the user details
4. Create
another file called test_banking_api.py
and
add the following content:
import requests
import pytest
from pytest_bdd import given, when, then, parsers
@pytest.fixture
def base_url():
return "http://localhost:8000"
@given("the API is running")
def api_running(base_url):
response = requests.get(f"{base_url}/docs")
assert response.status_code == 200
@when(parsers.parse('I send a GET request to "{endpoint}"'))
def send_get_request(base_url, endpoint):
global response
response = requests.get(f"{base_url}{endpoint}")
@then("the response status code should be 200")
def verify_status_code():
assert response.status_code == 200
@then("the response should contain the account summary")
def verify_account_summary():
json_response = response.json()
assert "account_number" in json_response
assert "balance" in json_response
@then("the response should contain the user details")
def verify_user_details():
json_response = response.json()
assert "user_id" in json_response
assert "name" in json_response
assert "email" in json_response
5. Open a
terminal, navigate to the test suite directory, and run pytest
to
execute the tests.
The above code sets up the BDD test cases using pytest-bdd
. It defines
steps using decorators (@given
, @when
, @then
) that
correspond to the Gherkin syntax in the test_banking_api.feature
file.
The steps make use of the requests
library
to send HTTP requests to the API and validate the responses.
Make sure the API is running at http://localhost:8000
or
update the base_url
fixture in the test
file with the appropriate URL.
You can further extend the BDD test cases by adding more scenarios or steps as per your requirements.
Conclusion
FastAPI has emerged as a powerful framework for developing high-performance and secure banking APIs. Its efficient request handling, strong typing, automatic documentation generation, and security features make it an ideal choice for financial institutions aiming to deliver reliable, scalable, and fast banking services. By leveraging FastAPI, banks can build robust APIs that facilitate seamless integration with mobile applications, web portals, and other digital channels, ultimately enhancing customer experience and driving innovation in the banking industry
We Provide consulting, implementation, and management services on DevOps, DevSecOps, DataOps, Cloud, Automated Ops, Microservices, Infrastructure, and Security
Services offered by us: https://www.zippyops.com/services
Our Products: https://www.zippyops.com/products
Our Solutions: https://www.zippyops.com/solutions
For Demo, videos check out YouTube Playlist: https://www.youtube.com/watch?v=4FYvPooN_Tg&list=PLCJ3JpanNyCfXlHahZhYgJH9-rV6ouPro
If this seems interesting, please email us at [email protected] for a call.
Relevant Blogs:
Azure PAM: How to Manage Access With Azure Bastion and Azure PIM
Utilizing Apache Spark for Azure Network Security Group Management
Overcoming Challenges in UI/UX Application Modernization
DevOps vs. DevSecOps: The Debate
Recent Comments
No comments
Leave a Comment
We will be happy to hear what you think about this post