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: FastAPIBaseModel from pydanticpyodbcload_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_idname, 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_idname, 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