Build a Python API Response Validator With Error Logging
by ggbond0821 in Circuits > Computers
12 Views, 0 Favorites, 0 Comments
Build a Python API Response Validator With Error Logging
Getting an HTTP 200 response feels reassuring, but it only means that the server successfully handled the HTTP request. The JSON body could still be empty, malformed, or missing the field your program needs.
I ran into this while experimenting with public APIs. A short script that directly accessed response.json()["data"][0]["price"] worked during the first test, but it was far too easy to break.
In this project, we will build a small Python tool that:
- Sends a request with explicit timeouts
- Checks the HTTP status
- Confirms that the response is valid JSON
- Handles more than one top-level response structure
- Validates the symbol and price fields
- Preserves price precision with Decimal
- Records successful checks and errors in a log file
I use a public futures ticker endpoint as the test data source, but the same structure can be adapted to weather, transport, inventory, or other JSON APIs.
Supplies
You will need:
- A computer running Windows, macOS, or Linux
- Python 3.9 or newer
- A text editor, such as Visual Studio Code
- An internet connection
- The Python Requests package
- A terminal or command prompt
No API key is required for the public endpoint used in this project.
Create the Project and Install Requests
Create a new folder named api-validator, open a terminal inside it, and create a virtual environment:
On Windows, activate it with:
On macOS or Linux, use:
Install Requests:
Finally, create a file named:
Using a virtual environment keeps this project’s packages separate from other Python projects on the computer.
Add the Configuration and Logger
Open api_validator.py and add the following code:
The logger will create a file named api_validator.log in the project folder.
The endpoint used here is part of BYDFi’s public market-data API. Notice the fapi section of the path: it identifies this as a futures endpoint. The returned value should not automatically be described as a spot-market price.
The symbol is stored separately so it can be changed without editing the validation functions.
Request JSON Safely
Below the configuration, add this function:
The timeout tuple contains two separate values:
- Three seconds for establishing the connection
- Five seconds for waiting between received data
It does not guarantee that the entire operation will always finish within eight seconds.
raise_for_status() converts unsuccessful HTTP responses into exceptions, while the JSON exception prevents an HTML error page or empty response from being processed as data.
Normalize the Response Structure
Some APIs return a list directly. Others place the list inside an object containing fields such as code, message, and data.
Add this function below request_json():
This function separates HTTP success from application-level success. Even when the server returns HTTP 200, the payload may still report an error or contain no usable records.
Accepting two known top-level structures also makes the program less dependent on a single response example. It does not mean that every possible response should be accepted.
Validate the Price Record
Now add a function that validates the first record:
Financial APIs frequently encode prices as strings. Using Decimal preserves the decimal value more predictably than immediately converting it to a binary floating-point number.
The function also checks that the returned symbol matches the requested symbol. This prevents the application from silently displaying a valid price for the wrong instrument.
Connect the Functions
Add the main function at the bottom of the file:
The current value is printed to the terminal, but it is deliberately not written to the log. For many applications, the log only needs to show whether validation succeeded and provide enough information to investigate failures.
Run the program with:
A successful run should print:
The exact price will naturally change over time.
Test the Error Handling
A validator is not very useful if we only test the successful path.
Try changing:
to an invalid value and run the program again. Depending on the API response, the script should report an HTTP, application, empty-record, or symbol-validation error instead of crashing with an unclear traceback.
You can also temporarily change the expected symbol passed to validate_price_record() to confirm that the mismatch check works.
After testing, open:
You should see entries similar to:
Restore the correct symbol after finishing the tests.
Avoid repeatedly sending requests in a fast loop. API limits may differ between public market-data endpoints and authenticated trading operations, so polling behavior should always be based on the current documentation for the specific endpoint.
Ideas for Improving the Project
This is a small validator, but it provides a useful foundation. Possible improvements include:
- Adding limited retries with exponential backoff
- Saving validated records to CSV
- Validating every record instead of only the first
- Defining the expected schema in a separate configuration file
- Adding automated tests with saved sample responses
- Reading the endpoint and symbol from command-line arguments
- Rotating log files so they do not grow indefinitely
The important lesson is that receiving JSON is not the same as receiving trustworthy application data. A reliable integration checks the transport status, response structure, business status, field types, and numerical validity before using a value.