Azure / Azure/azure-iot-sdk-python

create_from_edge_environment()'s get_twin() only returning properties and no other twin values.

Open
#1,206 2 comments 0 reactions 1 assignee Claimed by @cartertinney View on GitHub
bug
Dominant language
Python
Stars
438
Forks
380
Avg merge
22h 17m
Merged PRs (30d)
22

Description

# Context

- **OS and version used:** Oracle Linux 8.10 (Tenable OT OS)
- **Python version:** Python 3.12.11
- **pip version:** uv 0.8.15 used to create docker image, but installed pip 25.0.1 to get package list
- **list of installed packages:**

Click to show package list



(ce-tenable-ot-extractor) appuser@7b4a22d5a924:~$ venv/bin/pip3 list
Package Version
----------------------- ------------------
aiohappyeyeballs 2.6.1
aiohttp 3.12.15
aiosignal 1.4.0
annotated-types 0.7.0
anyio 4.10.0
APScheduler 3.11.0
arrow 1.3.0
attrs 25.3.0
azure-core 1.35.0
azure-iot-device 2.14.0
azure-storage-blob 12.26.0
backoff 2.2.1
ce_tenable_ot_extractor 0.3.2.dev7+ba48086
certifi 2025.8.3
cffi 1.17.1
charset-normalizer 3.4.3
click 8.2.1
cryptography 45.0.7
defusedxml 0.7.1
deprecation 2.1.0
frozenlist 1.7.0
gql 4.0.0
graphql-core 3.2.6
idna 3.10
inflection 0.5.1
isodate 0.7.2
janus 2.0.0
markdown-it-py 4.0.0
marshmallow 3.26.1
mdurl 0.1.2
multidict 6.6.4
numpy 2.3.2
packaging 25.0
paho-mqtt 1.6.1
pandas 2.3.1
pip 25.0.1
propcache 0.3.2
pycparser 2.22
pydantic 2.11.7
pydantic_core 2.33.2
pydantic-extra-types 2.10.5
pydantic-settings 2.10.1
Pygments 2.19.2
PySocks 1.7.1
pyTenable 1.8.4
python-box 7.3.2
python-dateutil 2.9.0.post0
python-dotenv 1.1.1
pytz 2025.2
requests 2.32.5
requests-toolbelt 1.0.0
requests-unixsocket2 1.0.1
restfly 1.5.1
rich 14.1.0
semver 3.0.4
shellingham 1.5.4
six 1.17.0
sniffio 1.3.1
typer 0.17.4
types-python-dateutil 2.9.0.20250822
typing_extensions 4.15.0
typing-inspection 0.4.1
tzdata 2025.2
tzlocal 5.3.1
urllib3 2.5.0
yarl 1.20.1

- **cloned repo:** Not used

-**support bundle:**
[support_bundle_2025_09_07_21_33_44_UTC.zip](https://github.com/user-attachments/files/22198690/support_bundle_2025_09_07_21_33_44_UTC.zip)

## Description of the issue

I am experiencing the same issue as this person: https://github.com/Azure/azure-iot-sdk-python/issues/821

When I use `IoTHubModuleClient.create_from_edge_environment().get_twin()`, I only get the properties, but not other module twin data.

### Expected twin

This is the twin data I get from the Azure Portal:

```json
{
"etag": "AAAAAAAAAAM=",
"deviceId": "kim-tenable-ot-01",
"deviceEtag": "ODEzNTY3NDk=",
"moduleId": "tenable-ot-extractor",
"version": 51625,
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2025-07-24T17:56:03.5921753Z",
"$lastUpdatedVersion": 3,
"settings": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2,
"tenable_ot_api_key": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2
},
"tenable_ot_url": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2
},
"upload_interval": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2
}
},
"test-settings": {
"$lastUpdated": "2025-07-24T17:56:03.5921753Z",
"$lastUpdatedVersion": 3,
"foo": {
"$lastUpdated": "2025-07-24T17:56:03.5921753Z",
"$lastUpdatedBy": "deployment_dev_v0_1_5-0-g41cdd32",
"$lastUpdatedByDigest": "638792387321632884",
"$lastUpdatedVersion": 3
}
}
},
"$version": 3,
"settings": {
"tenable_ot_api_key": "XXX=",
"tenable_ot_url": "https://host.docker.internal",
"upload_interval": "30"
}
},
"reported": {
"$metadata": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z",
"connectionStatus": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z"
},
"lastHeartbeatTime": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z"
},
"moduleStatus": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z"
}
},
"$version": 51622,
"connectionStatus": "connected",
"lastHeartbeatTime": "2025-09-07T19:51:02.516048+00:00",
"moduleStatus": "running"
}
},
"configurations": {
"deployment_dev_v0_1_3-0-ga3244e0": {
"status": "Targeted"
},
"deployment_dev_v0_1_4-0-gc44df30": {
"status": "Targeted"
},
"deployment_dev_v0_1_4-1-g95f3fc7": {
"status": "Targeted"
},
"deployment_dev_v0_1_5-0-g41cdd32": {
"status": "Applied"
}
},
"modelId": "",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00.0000000Z",
"lastActivityTime": "2025-09-07T19:49:30.2062010Z",
"connectionState": "Connected",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas"
}
```

### Actually received twin

This is what my python code actually gets. As you can see, it's only the `properties` key, but it doesn't even include the `properties` key itself and no metadata.

```json
{
"desired": {
"$version": 3,
"settings": {
"tenable_ot_api_key": "XXX=",
"tenable_ot_url": "https://host.docker.internal",
"upload_interval": "30"
},
"test-settings": {
"foo": "bar"
}
},
"reported": {
"$version": 51699,
"connectionStatus": "connected",
"lastHeartbeatTime": "2025-09-07T21:20:13.223778+00:00",
"moduleStatus": "running"
}
}
```

## Attempted solutions

I tried all the suggestions in the other issue, but they didn't help.

I added the dns section to my `/etc/docker/daemon.json`:
```
[Kim@tenable-q82xbzqn ~]$ cat /etc/docker/daemon.json
{
"bip": "172.17.0.254/24",
"fixed-cidr": "172.17.0.128/25",
"mtu": 9000,
"log-driver": "local",
"dns": ["1.1.1.1"]
}
```

I also tried the OPs suggestion of adjusting the `/etc/aziot/config.toml` to add `/etc/hosts` binds:
```
# [agent.config]
# image = "mcr.microsoft.com/azureiotedge-agent:1.5"
createOptions = { HostConfig = { Binds = ["/iotedge/storage:/iotedge/storage", "/etc/hosts:/etc/hosts"] } }
```

I did run `sudo iotedge config apply` and tried rebooting. But none of this helped.

And I am not using a proxy.

## Code sample exhibiting the issue

```python
from pprint import pprint
from azure.iot.device import IoTHubModuleClient

def get_module_twin_edge_env():
print('Creating client from edge environment...')
client = IoTHubModuleClient.create_from_edge_environment()

print('Getting twin...')
twin = client.get_twin()
pprint(twin)

print('Shutting down client...')
client.shutdown()

def main():
get_module_twin_edge_env()

if __name__ == "__main__":
main()
```

## Console log of the issue

The easiest way to reproduce is to exec a shell in an existing IoT Edge module that has python installed and isn't already connected to the IoTHub.

If the main process is already connected, you will get errors like `'azure.iot.device.common.transport_exceptions.ConnectionDroppedError: Unexpected disconnection\n'`.

```bash
[Kim@tenable-q82xbzqn ~]$ docker ps | grep extractor
6aa2f8e46529 crcentryproduks.azurecr.io/tenable-ot-extractor:develop-0.3.2.dev8-b20084e "ce_tenable_ot_extra…" 8 minutes ago Up 8 minutes tenable-ot-extractor
[Kim@tenable-q82xbzqn ~]$ docker exec -it 6aa2f8e46529 bash
appuser@6aa2f8e46529:~$ cat > test.py
from pprint import pprint
from azure.iot.device import IoTHubModuleClient

def get_module_twin_edge_env():
print('Creating client from edge environment...')
client = IoTHubModuleClient.create_from_edge_environment()

print('Getting twin...')
twin = client.get_twin()
pprint(twin)

print('Shutting down client...')
client.shutdown()

def main():
get_module_twin_edge_env()

if __name__ == "__main__":
main()
appuser@6aa2f8e46529:~$ python test.py
Creating client from edge environment...
Getting twin...
{'desired': {'$version': 3,
'settings': {'tenable_ot_api_key': 'XXX=',
'tenable_ot_url': 'https://host.docker.internal',
'upload_interval': '30'},
'test-settings': {'foo': 'bar'}},
'reported': {'$version': 51699,
'connectionStatus': 'connected',
'lastHeartbeatTime': '2025-09-07T21:20:13.223778+00:00',
'moduleStatus': 'running'}}
Shutting down client...
appuser@6aa2f8e46529:~$
```

## Conclusion

Thank you so much in advance for your help.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.