Stage 3 of 4, lesson 14 of 31. Beginner
Your first HTTP request: ask the practice API
Make a real HTTP request from Python to this site's practice API and read the account summary it sends back. It introduces GET, status codes, headers and checking a reply before you trust it.
Risk warning: CFDs and spread bets are complex instruments and come with a high risk of losing money rapidly due to leverage. You can lose money on these products, and each provider publishes its own loss figure under FCA rules. You should consider whether you understand how they work and whether you can afford to take the high risk of losing your money. Automated and API trading can amplify losses through bugs, connectivity failures and runaway orders.
You need: The lesson on reading an API response, and an internet connection. No broker account. No key.
In the last lesson the answer was already in a file. This time your script fetches it. It sends a request across the internet to an address, a server answers, and the script reads the answer. That round trip is all an API call is.
The address belongs to this site's practice API: a handful of fixed files of invented values, in the shape a trading API answers in. It is not any broker's API. It needs no account and no key, it cannot place a trade, and you can call it as often as you like while you learn.
The script uses urllib, which comes with Python, so there is nothing to install. A request has a method, here GET, which means please send me this. The answer has a status, a number that says how it went, and a body. A status of 200 means it worked.
The assert line is the check. Every reply from the practice API carries practice set to true. A script that checks what it was sent before using it will stop, loudly, on the day it is pointed at the wrong place. Keep that habit when the figures are real.
If this is your first script, the set up is the one the first lesson walks through in six steps: install Python from python.org, save the code below as first_request.py in a folder you can find again, open a terminal (PowerShell on Windows, Terminal on a Mac), move it to that folder with cd, then run python first_request.py. On Windows, if python is not recognised, type py first_request.py; on a Mac, python3 first_request.py. The first lesson is linked at the foot of this page if any of those steps is new.
Run it. If the last line reads Check passed, you have made your first HTTP request. Nothing in this lesson signs in to anything. Signing in comes later in this stage, and only ever on a demo account.
The practice API this lesson calls
Practice data, not any broker's API: fixed files of invented values on this site. Each opens in a browser tab, so you can read what the script will be sent.
The code
# Your first real HTTP request. It asks this site's practice API for an account summary.
# The practice API is a set of fixed files of invented values. It is not any broker's API.
# It needs no account and no key, and it cannot place a trade.
import json
import os
import urllib.request
# The address of the practice API. Leave it alone, unless you are running a copy on your own machine,
# in which case set PRACTICE_API to the address of the copy.
BASE_URL = os.environ.get("PRACTICE_API", "https://openbrokerapi.com/mock/v1")
def get(path):
# A request is an address plus headers. These two say what we want back and who is asking.
request = urllib.request.Request(
BASE_URL + path,
headers={"Accept": "application/json", "User-Agent": "first-http-request-lesson"},
)
with urllib.request.urlopen(request, timeout=10) as reply:
print("GET", path, "answered with status", reply.status)
return json.load(reply)
data = get("/account.json")
# The check. Every reply from the practice API says that it is practice data.
# If this line stops the script, you are not talking to the practice API.
assert data["practice"] is True, "this reply is not practice data"
account = data["account"]
print("Account:", account["name"], "(" + account["type"] + ")")
print("Balance:", account["balance"], account["currency"])
print("Profit or loss:", account["profitLoss"], account["currency"])
print("Available:", account["available"], account["currency"])
print("Check passed: the reply says it is practice data.")What you should see
GET /account.json answered with status 200 Account: Practice account (DEMO) Balance: 10000 GBP Profit or loss: 67.5 GBP Available: 8794 GBP Check passed: the reply says it is practice data.
Run with Python 3.12 on Windows against a copy of the practice API files served over HTTP on the same machine, with PRACTICE_API set to the address of the copy. They are the files this site serves. No account and no key.
Check yourself
Answer each question from the code above before you open it. The answers were written from the script on this page and what it printed.
The first line of output ends with status 200. Which line of the script printed it, and what does 200 mean?
The print inside get, which reads reply.status. 200 is the status a server sends when the request worked and the body holds what you asked for.
What would the script do if the reply carried practice set to false?
The assert would stop it with an AssertionError and the message this reply is not practice data. None of the lines below it would run, so no figure from an unexpected source would be printed.
Where does the 10000 on the Balance line come from?
json.load turns the body of the reply into a dictionary. The script takes the account object out of it, and balance is one of the names inside that object.
Exercise
After the check has passed, make a second request, for /positions.json, and print the name, direction and size of each position. Pause for a second between the two calls, as you would with a real API.
What the changed script prints
GET /account.json answered with status 200 Account: Practice account (DEMO) Balance: 10000 GBP Profit or loss: 67.5 GBP Available: 8794 GBP Check passed: the reply says it is practice data. GET /positions.json answered with status 200 Harbour 100 (invented index) BUY 2 Lantern Metals (invented share) SELL 50
Captured from a run of the solution on . Run with Python 3.12 on Windows against a copy of the practice API files served over HTTP on the same machine, with PRACTICE_API set to the address of the copy. They are the files this site serves. No account and no key.
One solution
# Exercise solution: the lesson script with the one change the exercise asks for.
# Your first real HTTP request. It asks this site's practice API for an account summary.
# The practice API is a set of fixed files of invented values. It is not any broker's API.
# It needs no account and no key, and it cannot place a trade.
import json
import os
import time
import urllib.request
# The address of the practice API. Leave it alone, unless you are running a copy on your own machine,
# in which case set PRACTICE_API to the address of the copy.
BASE_URL = os.environ.get("PRACTICE_API", "https://openbrokerapi.com/mock/v1")
def get(path):
# A request is an address plus headers. These two say what we want back and who is asking.
request = urllib.request.Request(
BASE_URL + path,
headers={"Accept": "application/json", "User-Agent": "first-http-request-lesson"},
)
with urllib.request.urlopen(request, timeout=10) as reply:
print("GET", path, "answered with status", reply.status)
return json.load(reply)
data = get("/account.json")
# The check. Every reply from the practice API says that it is practice data.
# If this line stops the script, you are not talking to the practice API.
assert data["practice"] is True, "this reply is not practice data"
account = data["account"]
print("Account:", account["name"], "(" + account["type"] + ")")
print("Balance:", account["balance"], account["currency"])
print("Profit or loss:", account["profitLoss"], account["currency"])
print("Available:", account["available"], account["currency"])
print("Check passed: the reply says it is practice data.")
time.sleep(1) # a pause between calls, as you would leave with a real API
for position in get("/positions.json")["positions"]:
print(position["instrumentName"], position["direction"], position["size"])Your progress
Your marks are kept in this browser only, in its local storage. They are not sent anywhere, there is no account, and they will not follow you to another browser or device. To remove them, use Clear my progress on the learning track page, or clear this site's data in your browser's settings. Marking needs JavaScript. With scripts off the track reads the same, without the ticks.
This browser refused to store anything for this page, so marks cannot be kept here.
Where this sits in the path
Stage 3 of 4: Talking to a broker. What an API sends back, real requests to a practice API that needs no account, how to keep a key safe, a first read only call on a demo account, and histories that arrive in pages.
- Read an API responseDone
- First HTTP requestDoneYou are here
- Positions and exposureDone
- Keys and demo accountsDone
- First API callDone
- Paged resultsDone
- Follow the next pageDone
- Price history to CSVDone