Skip to content

Conversation

CoMPaTech
Copy link
Owner

@CoMPaTech CoMPaTech commented Aug 6, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced privacy by redacting sensitive data (e.g., MAC and IP addresses) in logs and exceptions.
    • Expanded device support with new device configurations and fixtures, including additional supported models.
    • Improved robustness with optional fields for device data, addressing edge cases in device status reporting.
    • Updated device discovery to allow configurable listening IP and port.
  • Bug Fixes

    • Improved error handling and logging for device status deserialization errors.
  • Documentation

    • Updated changelog and contribution guidelines to reflect new features, supported devices, and recent changes.
  • Tests

    • Added tests for redacted logging and enhanced coverage for new device types and error scenarios.
  • Chores

    • Updated project version to 0.2.6.
    • Generated and added new fixture files for expanded device scenarios.

@coderabbitai
Copy link

coderabbitai bot commented Aug 6, 2025

Walkthrough

This update introduces new fixture files, enhances sensitive data redaction in exception handling, and adds optional fields to data models. The device discovery function is renamed and its parameters are updated. Contribution and changelog documentation are revised to reflect new devices and features. Tests and fixture generation scripts are also updated accordingly.

Changes

Cohort / File(s) Change Summary
Documentation Updates
CHANGELOG.md, CONTRIBUTE.md, pyproject.toml
Changelog entry for version 0.2.6, new supported devices in contribution guide, project version bumped to 0.2.6.
Discovery Function Refactor
airos/discovery.py, tests/test_discovery.py
Renamed and updated discovery function signature and parameters; tests updated to use new function name.
Sensitive Data Redaction & Data Model Enhancements
airos/airos8.py, airos/data.py
Improved error handling and sensitive data redaction in exceptions; added/modified redaction utilities and made several dataclass fields optional.
Fixture Generation Script
script/generate_ha_fixture.py
Extended script to generate additional AIROS fixture JSON files from userdata files.
Test Enhancements
tests/test_stations.py
Added tests for redacted exception logging and status error handling; expanded fixture reading and test coverage.
New and Updated Fixtures
fixtures/airos_liteapgps_ap_ptmp_40mhz.json, fixtures/airos_mocked_sta-ptmp.json, fixtures/airos_nanobeam5ac_sta_ptmp_40mhz.json, fixtures/airos_loco5ac_ap-ptp.json, fixtures/airos_loco5ac_sta-ptp.json, fixtures/userdata/liteapgps_ap_ptmp_40mhz.json, fixtures/userdata/mocked_invalid_wireless_mode.json, fixtures/userdata/mocked_missing_wireless_mode.json, fixtures/userdata/mocked_sta-ptmp.json, fixtures/userdata/nanobeam5ac_sta_ptmp_40mhz.json
Added new device and test fixture files; updated existing fixtures to include new optional/null fields.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AirOSDevice
    participant Logger
    participant DataRedactor

    User->>AirOSDevice: status()
    AirOSDevice->>AirOSDevice: Call status API
    AirOSDevice->>AirOSDevice: Deserialize JSON
    alt Deserialization fails (InvalidFieldValue or MissingField)
        AirOSDevice->>DataRedactor: redact_data_smart(response_json)
        DataRedactor-->>AirOSDevice: redacted_json
        AirOSDevice->>Logger: Log error/exception with redacted_json
        AirOSDevice->>User: Raise AirOSKeyDataMissingError
    else Success
        AirOSDevice->>User: Return parsed data
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

  • CoMPaTech/python-airos#23: Modifies the status() method with deserialization improvements; related due to overlapping changes in error handling and data processing.
  • CoMPaTech/python-airos#36: Adds fixture generation and derived fixtures; related due to fixture file additions and generation script enhancements.
  • CoMPaTech/python-airos#33: Introduces device discovery implementation; related due to discovery function renaming and parameter changes.

Suggested labels

enhancement

Poem

A rabbit hopped with nimble feet,
Through fields of code both wide and neat.
With fixtures new and redactions smart,
It shielded secrets, played its part.
Discovery renamed, more tests to run—
This burrow’s work is never done!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1391a9b and 508c04f.

📒 Files selected for processing (1)
  • pyproject.toml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • pyproject.toml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Process test coverage
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Aug 6, 2025

Codecov Report

❌ Patch coverage is 95.83333% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.70%. Comparing base (c09dc79) to head (508c04f).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
airos/airos8.py 73.33% 4 Missing ⚠️
airos/data.py 96.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #48      +/-   ##
==========================================
+ Coverage   95.37%   95.70%   +0.32%     
==========================================
  Files           9        9              
  Lines        1168     1281     +113     
==========================================
+ Hits         1114     1226     +112     
- Misses         54       55       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🔭 Outside diff range comments (1)
script/generate_ha_fixture.py (1)

38-65: Refactor duplicated fixture-generation blocks & avoid pseudo-static call
Five nearly identical with open blocks violate DRY and rely on the hacky AirOS.derived_data(None, ...) call (instance method invoked with None). Encapsulate the logic in a helper and iterate over source/target pairs; also create a real AirOS() instance (or make derived_data a @staticmethod).

-# Repeated blocks ...
+fixtures = {
+    "airos_loco5ac_ap-ptp.json": "loco5ac_ap-ptp.json",
+    "airos_loco5ac_sta-ptp.json": "loco5ac_sta-ptp.json",
+    "airos_mocked_sta-ptmp.json": "mocked_sta-ptmp.json",
+    "airos_liteapgps_ap_ptmp_40mhz.json": "liteapgps_ap_ptmp_40mhz.json",
+    "airos_nanobeam5ac_sta_ptmp_40mhz.json": "nanobeam5ac_sta_ptmp_40mhz.json",
+}
+
+air_os = AirOS()  # proper instance
+
+for target, source in fixtures.items():
+    src_path = os.path.join(userdata_dir, source)
+    dst_path = os.path.join(fixture_dir, target)
+    with open(src_path) as src_file, open(dst_path, "w") as dst_file:
+        data = json.load(src_file)
+        derived = air_os.derived_data(data)
+        json.dump(AirOSData.from_dict(derived).to_dict(), dst_file, indent=2, sort_keys=True)
🧹 Nitpick comments (7)
fixtures/userdata/nanobeam5ac_sta_ptmp_40mhz.json (1)

1-1: Consider formatting the JSON for better maintainability.

While functionally correct, the single-line JSON format makes this fixture difficult to read and maintain. Consider formatting it with proper indentation for better developer experience.

-{"chain_names":[{"number":1,"name": "Chain 0"},{"number":2,"name": "Chain 1"}],"host":{"hostname": "NanoBeam-shed1",...
+{
+  "chain_names": [
+    {"number": 1, "name": "Chain 0"},
+    {"number": 2, "name": "Chain 1"}
+  ],
+  "host": {
+    "hostname": "NanoBeam-shed1",
+    ...
+  }
+}
fixtures/userdata/liteapgps_ap_ptmp_40mhz.json (1)

1-1: Consider formatting the JSON for better maintainability.

Like the previous fixture, this single-line JSON format makes the file difficult to read and maintain. Proper indentation would improve developer experience when working with this test data.

fixtures/userdata/mocked_sta-ptmp.json (1)

1-1: Consider a standardized approach to fixture formatting.

This is the third fixture file with single-line JSON format. Consider implementing a standardized approach to format all fixture files for better maintainability across the project.

You might want to create a script to format all fixture JSON files consistently:

# Format all fixture JSON files
find fixtures/ -name "*.json" -exec python -m json.tool {} {}.tmp \; -exec mv {}.tmp {} \;
CONTRIBUTE.md (1)

10-11: Ensure consistent device naming & ordering in fixture list
The two newly added bullets look good, but the list is no longer alphabetically sorted and the capitalisation differs from earlier entries (Nanobeam vs NanoStation). Consider normalising the vendor-style casing (“NanoBeam”, “LiteAP GPS”) and, optionally, sorting the list to keep the section tidy.

tests/test_discovery.py (1)

5-5: Drop the inline “Add this import” comment
Inline comments on import lines add noise once the change is merged. Remove the trailing comment to keep imports clean.

-import socket  # Add this import
+import socket
fixtures/airos_mocked_sta-ptmp.json (1)

29-30: Consider using generic test coordinates instead of real-world locations.

The fixture contains what appear to be real GPS coordinates (Amsterdam area). For test fixtures, it's better to use clearly fake coordinates to avoid any confusion or potential privacy concerns.

-    "lat": 52.379894,
-    "lon": 4.901608
+    "lat": 0.0,
+    "lon": 0.0

Also apply similar changes to lines 527-528, 538-539, 957-958, and 968-969.

Also applies to: 527-528, 538-539, 957-958, 968-969

fixtures/airos_liteapgps_ap_ptmp_40mhz.json (1)

29-30: Use consistent generic test coordinates across all fixtures.

Similar to the previous fixture, this file contains what appear to be real GPS coordinates. For consistency and privacy, use generic test coordinates.

-    "lat": 52.379894,
-    "lon": 4.901608
+    "lat": 0.0,
+    "lon": 0.0

Also apply to the remote GPS data at lines 538-539, 968-969, and 981-982.

Also applies to: 538-539, 968-969, 981-982

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09ba903 and ac4418c.

📒 Files selected for processing (19)
  • CHANGELOG.md (1 hunks)
  • CONTRIBUTE.md (1 hunks)
  • airos/airos8.py (2 hunks)
  • airos/data.py (6 hunks)
  • airos/discovery.py (2 hunks)
  • fixtures/airos_liteapgps_ap_ptmp_40mhz.json (1 hunks)
  • fixtures/airos_loco5ac_ap-ptp.json (2 hunks)
  • fixtures/airos_loco5ac_sta-ptp.json (2 hunks)
  • fixtures/airos_mocked_sta-ptmp.json (1 hunks)
  • fixtures/airos_nanobeam5ac_sta_ptmp_40mhz.json (1 hunks)
  • fixtures/userdata/liteapgps_ap_ptmp_40mhz.json (1 hunks)
  • fixtures/userdata/mocked_invalid_wireless_mode.json (1 hunks)
  • fixtures/userdata/mocked_missing_wireless_mode.json (1 hunks)
  • fixtures/userdata/mocked_sta-ptmp.json (1 hunks)
  • fixtures/userdata/nanobeam5ac_sta_ptmp_40mhz.json (1 hunks)
  • pyproject.toml (1 hunks)
  • script/generate_ha_fixture.py (1 hunks)
  • tests/test_discovery.py (6 hunks)
  • tests/test_stations.py (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
tests/test_discovery.py (1)
airos/discovery.py (1)
  • airos_discover_devices (279-327)
airos/airos8.py (2)
airos/data.py (1)
  • redact_data_smart (62-109)
airos/exceptions.py (3)
  • AirOSKeyDataMissingError (20-21)
  • AirOSDataMissingError (16-17)
  • AirOSDeviceConnectionError (24-25)
fixtures/airos_mocked_sta-ptmp.json (1)
tests/conftest.py (1)
  • airos_device (20-25)
script/generate_ha_fixture.py (1)
airos/airos8.py (2)
  • derived_data (195-248)
  • AirOS (25-386)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Process test coverage
🔇 Additional comments (22)
airos/discovery.py (2)

279-281: LGTM! Good API enhancement.

The function rename from async_discover_devices to airos_discover_devices follows better naming conventions, and adding configurable listen_ip and port parameters with sensible defaults enhances flexibility while maintaining backward compatibility.


306-306: Correct implementation of new parameters.

The new parameters are properly used in the create_datagram_endpoint call, replacing the hardcoded values with the configurable ones.

pyproject.toml (1)

7-7: LGTM! Appropriate version bump.

The version update to 0.2.6a1 correctly reflects the pre-release alpha status and aligns with the new features and enhancements introduced in this pull request.

fixtures/airos_loco5ac_ap-ptp.json (1)

171-177: flex_mode added as null – verify dataclass accepts None
If flex_mode has been added to the Polling dataclass, confirm it is declared as Optional[bool | int] (or similar) so that a null value won’t raise a validation error during from_dict().

CHANGELOG.md (1)

5-17: Changelog entry LGTM
Entry is clear and links to the contributing guide. No issues spotted.

tests/test_discovery.py (1)

164-173: Good fix – explicit socket import resolves type-spec issue
Importing socket eliminates the previous NameError when accessing socket.SOL_SOCKET in the transport test.

fixtures/airos_loco5ac_sta-ptp.json (2)

171-171: LGTM: Added flex_mode field to polling data.

The addition of "flex_mode": null aligns with the enhanced Polling dataclass mentioned in the AI summary, providing consistent structure for optional polling parameters.


523-530: LGTM: Enhanced GPS data structure with additional optional fields.

The new GPS fields (alt, dim, dop, sats, time_synced) provide comprehensive GPS metadata including altitude, dimension, dilution of precision, satellite count, and synchronization status. Setting these to null is appropriate for optional fields in test fixtures.

fixtures/userdata/mocked_missing_wireless_mode.json (1)

35-67: LGTM: Well-structured fixture for testing missing wireless mode scenarios.

This fixture correctly omits the wireless mode field to simulate missing wireless mode data, which is valuable for testing error handling and data validation. The comprehensive device data provides realistic context for these test scenarios.

fixtures/airos_nanobeam5ac_sta_ptmp_40mhz.json (1)

1-652: LGTM: Comprehensive fixture for NanoBeam 5AC device testing.

This fixture provides detailed device data for a NanoBeam 5AC in station point-to-multipoint mode with 40MHz bandwidth. The structure follows established AIROS fixture patterns and includes comprehensive metrics including AirMax data, GPS information, and detailed station statistics, making it valuable for device-specific testing scenarios.

airos/airos8.py (3)

13-13: LGTM: Added redaction utility import.

The import of redact_data_smart enables secure logging of sensitive data, which is used effectively in the enhanced exception handling below.


271-296: Excellent enhancement to exception handling and data privacy.

The restructured exception handling provides several improvements:

  1. Separate handling for InvalidFieldValue vs MissingField exceptions with appropriate logging levels
  2. Data redaction using redact_data_smart protects sensitive information like MAC addresses and IPs in logs
  3. Cleaner control flow with the return statement outside the try-except block
  4. Consistent error mapping to AirOSKeyDataMissingError for both deserialization failures

This significantly improves both error handling robustness and data privacy compliance.


298-303: LGTM: Improved logging levels for error conditions.

Changing from _LOGGER.exception to _LOGGER.error for HTTP errors and client connection errors is appropriate - these are expected error conditions that don't require full stack traces, reducing log noise while maintaining necessary error information.

Also applies to: 308-308

fixtures/userdata/mocked_invalid_wireless_mode.json (2)

37-37: LGTM: Intentionally invalid wireless mode for testing validation.

The "sta-ptp-INVALID" value correctly provides an invalid wireless mode for testing data validation and error handling scenarios. This complements the missing wireless mode fixture and enhances test coverage for edge cases.


1-159: LGTM: Comprehensive fixture for invalid wireless mode testing.

This fixture provides realistic device data with an intentionally invalid wireless mode value, enabling thorough testing of validation logic and error handling pathways. The structure is consistent with other userdata fixtures while serving the specific purpose of testing invalid data scenarios.

fixtures/airos_mocked_sta-ptmp.json (1)

533-533: Good test coverage for optional mode field.

The fixture effectively tests the handling of the optional mode field in remote devices - one with mode: null (line 540) and one with mode: "ap-ptmp" (line 970). The hostnames clearly indicate the test scenario which aids in understanding the test purpose.

Also applies to: 540-540, 963-963, 970-970

tests/test_stations.py (2)

31-83: Well-structured test coverage for exception handling.

The new tests effectively cover both the redaction functionality and error logging paths. The mock setup is comprehensive and the assertions properly verify the expected behavior.

Also applies to: 85-123


47-47: Incorrect missing fixture warning

The fixture file fixtures/userdata/mocked_invalid_wireless_mode.json is present, so the warning about a missing "mocked_invalid_wireless_mode" fixture can be ignored.

Likely an incorrect or invalid review comment.

fixtures/airos_liteapgps_ap_ptmp_40mhz.json (1)

38-38: Good coverage of new optional fields.

The fixture properly tests the new optional fields:

  • height: null at line 38 (Host dataclass)
  • flex_mode: 1 at line 275 (Polling dataclass)
  • Extended GPS fields in remote sections with null values for LiteAP-specific fields

This provides good test coverage for the data model changes.

Also applies to: 275-275, 334-338, 534-542, 964-973

airos/data.py (3)

331-338: Well-structured optional field additions.

The changes to make GPS fields, mode, height, and other fields optional are well thought out:

  • Proper use of | None type hints with default values
  • Comments explaining why fields are optional (e.g., "Investigate why remotes can have no mode set")
  • Aligns with the fixture data showing these fields can be null

Also applies to: 389-391, 490-490


396-396: Good fix for the incorrect log message.

The correction from "Wireless" to "Remote" in the log message ensures accurate debugging information.


62-110: Robust implementation of smart data redaction.

The redact_data_smart function is well-implemented with:

  • Comprehensive list of sensitive keys
  • Proper handling of nested dictionaries and lists
  • Smart detection of MAC addresses, IP addresses, and other sensitive data
  • Maintains data structure while redacting values

@sonarqubecloud
Copy link

sonarqubecloud bot commented Aug 6, 2025

@CoMPaTech CoMPaTech merged commit e82cb88 into main Aug 6, 2025
14 checks passed
@CoMPaTech CoMPaTech deleted the improvements branch August 6, 2025 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant