Skip to content

Commit 61b8182

Browse files
authored
Merge pull request #4 from eman/remotes/origin/alert-autofix-44
Remotes/origin/alert autofix 44
2 parents 83c3930 + d66d916 commit 61b8182

30 files changed

Lines changed: 562 additions & 519 deletions

examples/.ruff.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
line-length = 120
2+
3+
[lint]
4+
extend-ignore = ["E402"]

examples/api_client_example.py

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
# Setup logging
1515
logging.basicConfig(
16-
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
16+
level=logging.INFO,
17+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
1718
)
1819

1920
# If running from examples directory, add parent to path
@@ -24,6 +25,14 @@
2425
from nwp500.api_client import APIError
2526
from nwp500.auth import AuthenticationError, NavienAuthClient
2627

28+
import re
29+
30+
31+
def mask_mac(mac: str) -> str:
32+
"""Redact all MAC addresses in the input string."""
33+
mac_regex = r"([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}|([0-9A-Fa-f]{12})"
34+
return re.sub(mac_regex, "[REDACTED_MAC]", mac)
35+
2736

2837
async def example_basic_usage():
2938
"""Basic usage example."""
@@ -52,19 +61,39 @@ async def example_basic_usage():
5261
print(f"✅ Found {len(devices)} device(s)\n")
5362

5463
# Display device information
64+
try:
65+
from examples.mask import mask_mac # type: ignore
66+
except Exception:
67+
# fallback helper if import fails when running examples directly
68+
69+
def mask_mac(mac: str) -> str: # pragma: no cover - small fallback
70+
# Always return "[REDACTED_MAC]" regardless of input for safety
71+
return "[REDACTED_MAC]"
72+
73+
try:
74+
from examples.mask import mask_any, mask_location # type: ignore
75+
except Exception:
76+
77+
def mask_any(_):
78+
return "[REDACTED]"
79+
80+
def mask_location(_, __):
81+
return "[REDACTED_LOCATION]"
82+
5583
for i, device in enumerate(devices, 1):
5684
info = device.device_info
5785
loc = device.location
5886

5987
print(f"Device {i}: {info.device_name}")
60-
print(f" MAC Address: {info.mac_address}")
61-
print(f" Type: {info.device_type}")
88+
print(f" MAC Address: {mask_mac(info.mac_address)}")
89+
print(f" Type: {mask_any(info.device_type)}")
6290
print(f" Connection Status: {info.connected}")
6391

92+
loc_mask = mask_location(loc.city, loc.state)
93+
if loc_mask:
94+
print(f" Location: {loc_mask}")
6495
if loc.address:
65-
print(f" Location: {loc.address}")
66-
if loc.city and loc.state:
67-
print(f" {loc.city}, {loc.state}")
96+
print(" Address: [REDACTED]")
6897
print()
6998

7099
# Get detailed info for first device
@@ -80,10 +109,7 @@ async def example_basic_usage():
80109
if detailed_info.device_info.install_type:
81110
print(f" Install Type: {detailed_info.device_info.install_type}")
82111
if detailed_info.location.latitude:
83-
print(
84-
f" Coordinates: {detailed_info.location.latitude}, "
85-
f"{detailed_info.location.longitude}"
86-
)
112+
print(" Coordinates: (available, not shown for privacy)")
87113
print()
88114

89115
# Get firmware information
@@ -113,11 +139,9 @@ async def example_basic_usage():
113139
print(f" Error code: {e.code}")
114140
return 1
115141

116-
except Exception as e:
117-
print(f"\n❌ Unexpected error: {str(e)}")
118-
import traceback
119-
120-
traceback.print_exc()
142+
except Exception:
143+
# Avoid printing raw exception details to stdout in examples
144+
logging.exception("Unexpected error in api_client_example")
121145
return 1
122146

123147

@@ -142,14 +166,23 @@ async def example_convenience_function():
142166

143167
print(f"✅ Found {len(devices)} device(s):\n")
144168

169+
try:
170+
from examples.mask import mask_any, mask_location # type: ignore
171+
except Exception:
172+
173+
def mask_any(_):
174+
return "[REDACTED]"
175+
176+
def mask_location(_, __):
177+
return "[REDACTED_LOCATION]"
178+
145179
for device in devices:
146180
print(f" • {device.device_info.device_name}")
147-
print(f" MAC: {device.device_info.mac_address}")
148-
print(f" Type: {device.device_info.device_type}")
149-
if device.location.city:
150-
print(
151-
f" Location: {device.location.city}, {device.location.state}"
152-
)
181+
print(f" MAC: {mask_mac(device.device_info.mac_address)}")
182+
print(f" Type: {mask_any(device.device_info.device_type)}")
183+
loc_mask = mask_location(device.location.city, device.location.state)
184+
if loc_mask:
185+
print(f" Location: {loc_mask}")
153186
print()
154187

155188
return 0

examples/authenticate.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@
1313

1414
# Setup logging
1515
logging.basicConfig(
16-
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
16+
level=logging.INFO,
17+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
1718
)
1819

1920
# If running from examples directory, add parent to path
2021
if __name__ == "__main__":
2122
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
2223

23-
from nwp500.auth import AuthenticationError, InvalidCredentialsError, NavienAuthClient
24+
from nwp500.auth import (
25+
AuthenticationError,
26+
InvalidCredentialsError,
27+
NavienAuthClient,
28+
)
2429

2530

2631
async def main():
@@ -72,9 +77,7 @@ async def main():
7277
if tokens.access_key_id:
7378
print("\nAWS Credentials available for IoT/MQTT:")
7479
print(f" Access Key ID: {tokens.access_key_id[:15]}...")
75-
print(
76-
f" Session Token: {tokens.session_token[:30] if tokens.session_token else 'N/A'}..."
77-
)
80+
print(f" Session Token: {tokens.session_token[:30] if tokens.session_token else 'N/A'}...")
7881

7982
except InvalidCredentialsError as e:
8083
print(f"\n❌ Invalid credentials: {e.message}")

examples/combined_callbacks.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717

1818
# Setup logging
1919
logging.basicConfig(
20-
level=logging.WARNING, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
20+
level=logging.WARNING,
21+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
2122
)
2223
logging.getLogger("nwp500.mqtt_client").setLevel(logging.INFO)
2324
logging.getLogger("nwp500.auth").setLevel(logging.INFO)
@@ -40,9 +41,7 @@ async def main():
4041
password = os.getenv("NAVIEN_PASSWORD")
4142

4243
if not email or not password:
43-
print(
44-
"❌ Error: Please set NAVIEN_EMAIL and NAVIEN_PASSWORD environment variables"
45-
)
44+
print("❌ Error: Please set NAVIEN_EMAIL and NAVIEN_PASSWORD environment variables")
4645
return 1
4746

4847
print("=" * 70)
@@ -55,9 +54,7 @@ async def main():
5554
print(f"✅ Authenticated as: {auth_client.current_user.full_name}")
5655
print()
5756

58-
api_client = NavienAPIClient(
59-
auth_client=auth_client, session=auth_client._session
60-
)
57+
api_client = NavienAPIClient(auth_client=auth_client, session=auth_client._session)
6158
devices = await api_client.list_devices()
6259

6360
if not devices:
@@ -95,9 +92,7 @@ def on_feature(feature: DeviceFeature):
9592
print(f"\n📋 Feature Info #{counts['feature']}")
9693
print(f" Serial: {feature.controllerSerialNumber}")
9794
print(f" FW Version: {feature.controllerSwVersion}")
98-
print(
99-
f" Temp Range: {feature.dhwTemperatureMin}-{feature.dhwTemperatureMax}°F"
100-
)
95+
print(f" Temp Range: {feature.dhwTemperatureMin}-{feature.dhwTemperatureMax}°F")
10196
print(f" Heat Pump: {'Yes' if feature.heatpumpUse == 2 else 'No'}")
10297
print(f" Electric: {'Yes' if feature.electricUse == 2 else 'No'}")
10398

examples/command_queue_demo.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
# Setup logging
2323
logging.basicConfig(
24-
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
24+
level=logging.INFO,
25+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
2526
)
2627

2728
from nwp500.auth import NavienAuthClient
@@ -110,9 +111,7 @@ def on_message(topic, message):
110111

111112
# Step 6: Simulate disconnection and queue commands
112113
print("\n6. Simulating disconnection...")
113-
print(
114-
" Note: In real scenarios, this happens automatically during network issues"
115-
)
114+
print(" Note: In real scenarios, this happens automatically during network issues")
116115

117116
# Manually disconnect
118117
await mqtt_client.disconnect()
@@ -146,9 +145,7 @@ def on_message(topic, message):
146145
print(" Waiting for queued commands to be sent...")
147146
await asyncio.sleep(3)
148147

149-
print(
150-
f" ✅ Queue processed! Remaining: {mqtt_client.queued_commands_count}"
151-
)
148+
print(f" ✅ Queue processed! Remaining: {mqtt_client.queued_commands_count}")
152149

153150
# Step 9: Test queue limits
154151
print("\n9. Testing queue limits...")
@@ -159,9 +156,7 @@ def on_message(topic, message):
159156
for _i in range(config.max_queued_commands + 5):
160157
await mqtt_client.request_device_status(device)
161158

162-
print(
163-
f" Queue size: {mqtt_client.queued_commands_count} (max: {config.max_queued_commands})"
164-
)
159+
print(f" Queue size: {mqtt_client.queued_commands_count} (max: {config.max_queued_commands})")
165160
print(" ✅ Queue properly limited (oldest commands dropped)")
166161

167162
# Clear queue

0 commit comments

Comments
 (0)