Hello,
Does anyone know how to find the Local IPv4 address of the same device, running python code?
I was able to find this on google: socket.gethostbyname(socket.gethostname())
. It works on my personal laptop, and returns 192.168.1.130
. But returns the following error when ran on a RaspberryPI 3 B+ through the Balena dashboard:
opencv-test Traceback (most recent call last):
opencv-test File "./main.py", line 51, in <module>
opencv-test init()
opencv-test File "./main.py", line 39, in init
opencv-test ip = socket.gethostbyname(socket.gethostname())
opencv-test socket.gaierror: [Errno -5] No address associated with hostname
Does anyone know how to associate the IP address with the hostname
, or if there is another way of retrieving the address?
Hi there Nate,
There reason that socket.gethostname
doesn’t work on a balena device, is because it will run in a container. The container has a UUID as it’s hostname which won’t resolve to a network adapter.
The simplest way to achieve what you want, is to user the balena supervisor API. Here’s how to do it from the shell:
curl -X GET --header "Content-Type:application/json" "$BALENA_SUPERVISOR_ADDRESS/v1/device?apikey=$BALENA_SUPERVISOR_API_KEY"
This will give you the IP amongst some other bits: https://docs.resin.io/reference/supervisor/supervisor-api/ 36
If your application is running multiple containers, you need to add some labels to your docker-compose file: https://docs.resin.io/learn/develop/multicontainer/#labels
To get this into your python app, you can either make the request from the code (using requests, or similar) or you could run the code in a bash script (if that’s your container entrypoint) and put the result into an environment variable which your python can use.
Hope this helps.
Phil
Thank you, I was able to add the labels to the docker-compose, and when I run this command:
root@855dda1:/usr/src/app# curl -X GET --header "Content-Type:application/json" "$BALENA_SUPERVISOR_ADDRESS/v1/device?apikey=$BALENA_SUPERVISOR_API_KEY"
It produces this:
{"api_port":48484,"ip_address":"192.168.1.130","os_version":"balenaOS 2.75.0+rev1","mac_address":"B8:27:EB:88:35:2B B8:27:EB:DD:60:7E","supervisor_version":"12.5.10","update_pending":true,"update_failed":false,"update_downloaded":false,"status":"Idle","download_progress":null}root@855dda1:/usr/src/app#
Which to me indicates that the device IP has made it into the container. I tried print(requests.get("http://127.0.0.1:48484/ip_address").content)
and a couple others, but it produces b'Unauthorized'
. I am wondering if you would be able to show an example for ether using requests, or the environment variable?
Thank you!
Thanks for getting back. Not sure how the local loopback service can access the /ip_address
, but one way you can try this out with request is emulate the balena-supervisor
request like:
''' Assuming Python 3 and above '''
requests.get(f"{BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey={BALENA_SUPERVISOR_API_KEY}", headers={"content-type":"application/json"})
This should be able to provide you IP and all the above info you got via terminal.
Thank you!
I had to change up the code slightly, but I have put it below.
import requests
import os
bsa = os.getenv('BALENA_SUPERVISOR_ADDRESS')
baak = os.getenv('BALENA_SUPERVISOR_API_KEY')
content = requests.get(bsa + "/v1/device?apikey=" + baak, headers={"content-type":"application/json"}).content
-Nate
You might also want to take a look at the ifaddr Python library: