Skip to content

Instantly share code, notes, and snippets.

@mrhalix
Last active May 9, 2023 13:01
Show Gist options
  • Save mrhalix/588d9d1318db4f2cd5d841b12cee63c6 to your computer and use it in GitHub Desktop.
Save mrhalix/588d9d1318db4f2cd5d841b12cee63c6 to your computer and use it in GitHub Desktop.
Hetzner Price Export
# This script exports price / cost csv out of hetzner api server list
# Just watch requests with network tools and pass the bearer token into request headers:
import json
import requests
def get_servers(page=1):
headers = {
'authority': 'api.hetzner.cloud',
'accept': 'application/json, text/plain, */*',
'accept-language': 'en-US,en;q=0.9,fa;q=0.8',
'authorization': 'Bearer XXXXXXXX',
'content-type': 'application/json',
'origin': 'https://console.hetzner.cloud',
'referer': 'https://console.hetzner.cloud/',
'sec-ch-ua': '"Google Chrome";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
}
params = {
'page': page,
'per_page': '100',
}
servers = []
response = requests.get('https://api.hetzner.cloud/v1/servers', params=params, headers=headers)
jdata = json.loads(response.text)
servers += jdata['servers']
if jdata['meta']:
while jdata['meta']['pagination']['next_page']:
params['page'] = jdata['meta']['pagination']['next_page']
response = requests.get('https://api.hetzner.cloud/v1/servers', params=params, headers=headers)
jdata = json.loads(response.text)
servers += jdata['servers']
return servers
def get_server_costs(server_id):
headers = {
'authority': 'api.hetzner.cloud',
'accept': 'application/json, text/plain, */*',
'accept-language': 'en-US,en;q=0.9,fa;q=0.8',
'authorization': 'Bearer XXXX',
'content-type': 'application/json',
'origin': 'https://console.hetzner.cloud',
'referer': 'https://console.hetzner.cloud/',
'sec-ch-ua': '"Google Chrome";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
}
response = requests.get('https://api.hetzner.cloud/v1/servers/' + str(server_id) + '/_costs', headers=headers)
return response.text
servers = get_servers()
csv = "name, ip, monthly_price, location"
count = 0
for server in servers:
count += 1
print("Fetching server: " + str(count) + "/" + str(len(servers)) + " " + server['name'])
server_csv = ""
server_csv += server['name'] + ", "
if server['private_net']:
server_csv += server['private_net'][0]['ip'] + ", "
else:
server_csv += server['public_net']['ipv4']['ip'] + ", "
datacenter_name = server['datacenter']['location']['name']
cost = json.loads(get_server_costs(server['id']))
server_csv += str(cost['server_cost']['price']['price_monthly']['gross']) + ", "
server_csv += datacenter_name
csv += "\n" + server_csv
f = open("misc-vms.csv", "w")
f.write(csv)
f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment