Step-by-Step Guide to Consume CubeMaster API with Python
This guide walks you through integrating the CubeMaster API (https://api.cubemaster.net/loads
) using Python to build a load with the POST method. It includes signing up for an API key, handling legacy data, and debugging API calls.
To use the CubeMaster API, you need an API key (TokenID) for authentication. Here's how to get started:
- Visit the CubeMaster website: https://cubemaster.net.
- Locate the "Sign In" option (typically found in the top-right corner).
- Fill out the registration form with your details (e.g., name, email, password, company information).
- After signing up, log in to your account dashboard.
- Navigate to the "Settings" - "Integration" section to generate your API key (TokenID).
- Generate an API key. Once generated, you’ll receive a unique
TokenID
(e.g.,abc123xyz789
). Copy this key and store it securely, as it will be used in the HTTP headers of your API requests. - Copy the TokenID and store it securely.
Note: The TokenID will be used in the HTTP headers of your POST request for authentication.
A RESTful API (Representational State Transfer) is a way for software to communicate over the internet using standard HTTP methods. Here’s a beginner-friendly explanation:
- HTTP Methods: REST uses methods like GET (retrieve data), POST (send data), PUT (update data), and DELETE (remove data). We’ll use POST to send load data to CubeMaster.
- Endpoints: These are specific URLs (e.g.,
https://api.cubemaster.net/loads
) where the API accepts requests. - JSON: Data is often sent and received in JSON format, a lightweight, human-readable structure.
- Authentication: APIs require a key (like our TokenID) to verify your identity.
- Response: The API returns data or a status message after processing your request.
In this guide, we’ll use Python’s requests
library to make a POST request to the CubeMaster API, sending JSON data and receiving a JSON response.
Prepare your Python environment with the necessary tools:
- Install Python: Download and install Python (version 3.7+) from python.org. Verify installation by typing
python --version
in your terminal. - Install PyCharm or VS Code: Use an IDE like PyCharm or Visual Studio Code for a better coding experience. In PyCharm, create a new project via
File > New Project
, and in VS Code, open a folder withFile > Open Folder
. - Install the
requests
Library: Open your terminal or PyCharm’s terminal (bottom panel) and run:pip install requests
. This library simplifies HTTP requests. - Create a Python File: In your IDE, create a new file (e.g.,
cubemaster_api.py
) by right-clicking the project folder, selectingNew > Python File
, and naming it.
Your environment is now ready to write and execute the API integration code.
Assume your customer’s legacy database (e.g., SQLite) stores order or shipment data. Here’s how to fetch it:
- Install SQLite Library: If not already installed, run
pip install pysqlite3
in your terminal. - Connect to Database: In your Python file, add code to connect to the database and query shipment data.
- Map Data: Convert the retrieved data into the CubeMaster API’s JSON format.
import sqlite3
# Connect to legacy database
conn = sqlite3.connect('legacy_database.db')
cursor = conn.cursor()
# Query shipment data
cursor.execute("SELECT item_name, length, width, height, weight, qty FROM shipments")
shipments = cursor.fetchall()
# Map to API format
cargoes = []
for shipment in shipments:
cargo = {
"Name": shipment[0],
"Length": shipment[1],
"Width": shipment[2],
"Height": shipment[3],
"Weight": shipment[4],
"Qty": shipment[5],
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": False,
"ColorKnownName": "Brown" # Default color
}
cargoes.append(cargo)
conn.close()
This code retrieves shipment details and formats them as Cargoes
for the API request.
Construct the POST request with the JSON payload and TokenID in the headers:
- Import Libraries: Add
import requests
andimport json
at the top of your file. - Define the Payload: Use the provided request JSON, integrating legacy data if applicable.
- Set Headers: Include the TokenID for authentication.
import requests
import json
# API endpoint
url = "https://api.cubemaster.net/loads"
# Request JSON (example with hardcoded data)
payload = {
"Title": "New Mixed Truck Load",
"Description": "Hello Web API",
"Cargoes": [
{
"Name": "ITEM001",
"Length": 72,
"Width": 30,
"Height": 75,
"Weight": 1002.45,
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": False,
"Qty": 16,
"ColorKnownName": "Brown"
},
{
"Name": "ITEM002",
"Length": 27.31,
"Width": 37.5,
"Height": 76.67,
"Weight": 521.45,
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": False,
"Qty": 28,
"ColorKnownName": "Aqua"
},
{
"Name": "SKU0005",
"Length": 27.31,
"Width": 9.5,
"Height": 75.67,
"Weight": 501.45,
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": True,
"Qty": 24,
"ColorKnownName": "Beige"
},
{
"Name": "SKU0005",
"Qty": 23
},
{
"Name": "SKU0008",
"Qty": 34
}
],
"Containers": [
{
"VehicleType": "Dry",
"Name": "53FT-Intermodal",
"Length": 630,
"Width": 98,
"Height": 106,
"ColorKnownName": "Blue"
}
],
"Rules": {
"IsWeightLimited": True,
"IsSequenceUsed": False,
"FillDirection": "FrontToRear",
"CalculationType": "MixLoad"
}
}
# Headers with TokenID
headers = {
"Content-Type": "application/json",
"Authorization": "TokenID YOUR_TOKEN_ID"
}
In PyCharm, you’ll see this code in the editor window with syntax highlighting. Replace YOUR_TOKEN_ID
with your actual TokenID.
Send the POST request to the CubeMaster API:
# Send POST request
response = requests.post(url, headers=headers, data=json.dumps(payload))
# Check the raw response
print("Status Code:", response.status_code)
print("Response Text:", response.text)
In your IDE, run this code by clicking the “Run” button (green triangle in PyCharm) or pressing F5
. The terminal at the bottom will display the status code and response.
Process the API response to check success and extract useful data:
- Check Status: Verify if the request succeeded (status code 200 or 201).
- Parse JSON: Convert the response to a Python dictionary.
- Extract Data: Access key information like load summary or errors.
# Handle response
if response.status_code in [200, 201]:
response_data = response.json()
print("API Call Succeeded!")
print("Status:", response_data["status"])
print("Message:", response_data["message"])
print("Calculation Time:", response_data["document"]["calculationTimeInSeconds"], "seconds")
print("Cargoes Loaded:", response_data["loadSummary"]["cargoesLoaded"])
print("Volume Loaded:", response_data["loadSummary"]["volumeLoaded"])
# Example: Access image links
for container in response_data["filledContainers"]:
print("3D Diagram:", container["graphics"]["images"]["path3DDiagram"])
elif response.status_code == 401:
print("Authentication Failed: Check your TokenID")
else:
print(f"Error {response.status_code}: {response.text}")
# Example response JSON
example_response = {
"status": "succeed",
"message": "Engine created. 5 cargoes. 1 empty containers. Calculation started. Calculation ended. The load built successfully. The load saved to the cloud database.",
"calculationError": "InvalidCargoSize",
"document": {
"title": "New Mixed Truck Load",
"description": "Hello Web API",
"isShared": True,
"isAutoSaved": True,
"isPending": False,
"calculationTimeInSeconds": 0.6152743,
"processId": "",
"batchId": "",
"createdBy": "CHANG@LOGEN.CO.KR",
"createdAt": "2023-02-11T01:17:01.7392204+09:00",
"updatedAt": "0001-01-01T00:00:00"
},
"loadSummary": {
"cargoesLoaded": 68,
"piecesLoaded": 68,
"cargoesLeft": 0,
"piecesLeft": 57,
"unitloadsLoaded": 0,
"volumeLoaded": 5261723.4606,
"weightLoaded": 42674.59999999999,
"priceLoaded": 0,
"containersLoaded": 1
},
"filledContainers": [
{
"name": "#1 53FT-Intermodal",
"sequence": 1,
"loadSummary": {
"cargoesLoaded": 68,
"piecesLoaded": 68,
"unitloadsLoaded": 0,
"volumeLoaded": 5261723.4606,
"volumeUtilization": 80.39990374424703,
"floorLoaded": 57090.75,
"floorUtilization": 92.46963070942662,
"weightLoaded": 42674.59999999999,
"weightTotal": 42674.59999999999,
"dimWeight": 39424.33734939759,
"priceLoaded": 0,
"cargoesPerLayer": 14,
"layersPerUnitload": 0
},
"actualSize": {
"length": 630,
"width": 98,
"height": 106
},
"loadSize": {
"length": 625.6499999999999,
"width": 97.5,
"height": 105.17
},
"graphics": {
"images": {
"path3DDiagram": "https://api.cubemaster.net/runtimes/b28413ca_51ed_44c9_b92e_13147363fd61.PNG",
"pathComposite": "https://api.cubemaster.net/runtimes/7eb09974_2f1d_41bc_9371_2002658dce07.PNG"
}
}
}
]
}
The terminal will display the parsed data. You can expand this to log results or save them to a file.
Ensure your API integration is robust by monitoring and debugging:
- Enable Logging: Use Python’s
logging
module to track requests and responses. - Inspect Headers: Verify the TokenID and content type in the headers.
- Use Debugging Tools: In PyCharm, set breakpoints by clicking next to line numbers, then run in Debug mode (bug icon) to step through code.
- Handle Timeouts: Add a timeout to avoid hanging requests.
import logging
# Set up logging
logging.basicConfig(level=logging.DEBUG, filename='cubemaster_api.log',
format='%(asctime)s - %(levelname)s - %(message)s')
# Log request details
logging.info(f"Sending request to {url} with payload: {json.dumps(payload, indent=2)}")
logging.debug(f"Headers: {headers}")
# Send request with timeout
try:
response = requests.post(url, headers=headers, data=json.dumps(payload), timeout=10)
logging.info(f"Response: {response.status_code} - {response.text}")
except requests.exceptions.Timeout:
logging.error("Request timed out after 10 seconds")
except requests.exceptions.RequestException as e:
logging.error(f"Request failed: {str(e)}")
# Debug in IDE
print("Debugging complete. Check 'cubemaster_api.log' for details.")
Run this code and check the cubemaster_api.log
file in your project folder for detailed logs. In PyCharm, the Debug panel (bottom) shows variable values when you hit a breakpoint.