Skip to content

⚡ Bolt: optimize API calls and consumption data handling#174

Open
Moohan wants to merge 1 commit intomainfrom
bolt-optimize-api-and-consumption-6059727436970537527
Open

⚡ Bolt: optimize API calls and consumption data handling#174
Moohan wants to merge 1 commit intomainfrom
bolt-optimize-api-and-consumption-6059727436970537527

Conversation

@Moohan
Copy link
Owner

@Moohan Moohan commented Mar 3, 2026

Optimized the package by reducing redundant API calls during meter metadata retrieval and improving the efficiency of consumption data merging. Specifically, introduced an include_gsp flag to get_meter_details to avoid unnecessary Grid Supply Point lookups and refactored combine_consumption to use logical indexing instead of ifelse() for handling missing values. Verified with benchmarking and test suites.


PR created automatically by Jules for task 6059727436970537527 started by @Moohan

Summary by Sourcery

Introduce an option to skip Grid Supply Point lookups when fetching meter details and streamline NA handling in consumption merging for better performance.

New Features:

  • Add an include_gsp flag to meter metadata retrieval functions to optionally omit GSP lookups.

Enhancements:

  • Avoid redundant GSP API calls when consumers only need basic meter identifiers.
  • Optimize combine_consumption NA handling by replacing ifelse-based logic with in-place logical indexing.
  • Update get_meter_gsp defaults to avoid implicit GSP lookups during meter detail retrieval.

Documentation:

  • Document the new include_gsp behavior and default usage for get_meter_gsp in the reference docs.
  • Add an internal Bolt note capturing performance learnings and decisions around API calls and NA handling.

Summary by CodeRabbit

  • New Features

    • Meter detail retrieval can now be optimised to skip unnecessary data requests, enabling faster API responses and reduced bandwidth usage.
  • Performance

    • Improved efficiency in consumption data processing through optimised handling of missing values in calculations.
  • Documentation

    • Added comprehensive best-practice guidance for efficient API usage patterns and consumption data optimisation strategies.

💡 What:
1. Added `include_gsp = TRUE` parameter to `get_meter_details()` to allow skipping the GSP API call.
2. Updated `get_consumption()` and `get_meter_gsp()` (default arg) to use `include_gsp = FALSE`.
3. Replaced `ifelse()` with logical indexing for `NA` replacement in `combine_consumption()`.

🎯 Why:
- Reduces redundant API traffic (50% reduction in calls for consumption/GSP lookups).
- Improves performance and reduces memory overhead when merging large datasets.

📊 Impact:
- API calls for `get_consumption()` and `get_meter_gsp()` dropped from 2 to 1.
- `combine_consumption()` is ~3x faster and uses ~3x less memory for 100k rows.

🔬 Measurement:
- Verified call reduction with mock-interception script.
- Benchmarked `combine_consumption()` logic with `bench::mark()`:
  - original: 4.5ms, 10.7MB
  - optimized: 1.4ms, 3.1MB

Co-authored-by: Moohan <5982260+Moohan@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 3, 2026

Reviewer's Guide

Introduces an include_gsp flag to meter metadata retrieval to avoid unnecessary GSP API calls and optimizes consumption data merging by replacing ifelse-based NA handling with direct logical indexing, while updating dependent functions and documentation accordingly.

Sequence diagram for optimized meter metadata and GSP lookup

sequenceDiagram
  actor User
  participant get_consumption
  participant get_meter_details
  participant get_meter_gsp
  participant OctopusAPI

  User->>get_consumption: call get_consumption(meter_type, direction, mpan_mprn = NULL, serial_number = NULL)
  get_consumption->>get_meter_details: get_meter_details(meter_type, direction, include_gsp = FALSE)
  activate get_meter_details

  alt missing_mpan_or_serial
    get_meter_details->>OctopusAPI: fetch meter metadata (mpan_mprn, serial_number, direction)
    OctopusAPI-->>get_meter_details: meter metadata
  end

  note over get_meter_details: include_gsp = FALSE
  note over get_meter_details: skip get_meter_gsp call

  get_meter_details-->>get_consumption: meter_details without gsp
  deactivate get_meter_details

  get_consumption-->>User: consumption data using mpan_mprn and serial_number

  rect rgb(230, 250, 230)
  User->>get_meter_gsp: optional get_meter_gsp(mpan)
  get_meter_gsp->>OctopusAPI: fetch GSP for mpan
  OctopusAPI-->>get_meter_gsp: gsp
  get_meter_gsp-->>User: gsp
  end
Loading

Class diagram for updated meter and consumption functions

classDiagram
  class get_meter_details {
    +character meter_type
    +character direction
    +logical include_gsp
    +list return_octopus_meter_point
  }

  class testing_meter {
    +character meter_type
    +logical include_gsp
    +list return_octopus_meter_point
  }

  class get_consumption {
    +character meter_type
    +character direction
    +character mpan_mprn
    +character serial_number
    +data_frame return_consumption
  }

  class get_meter_gsp {
    +character mpan
    +character return_gsp
  }

  class combine_consumption {
    +data_frame import_data
    +data_frame export_data
    +data_frame result
  }

  get_consumption ..> get_meter_details : uses
  get_meter_details ..> get_meter_gsp : optionally_calls
  testing_meter ..> get_meter_gsp : optionally_calls
  get_meter_gsp ..> get_meter_details : default_mpan_from
  combine_consumption : +import_consumption
  combine_consumption : +export_consumption
  combine_consumption : logical_indexing_for_NA
Loading

Flow diagram for optimized NA handling in combine_consumption

flowchart TD
  A[Start combine_consumption] --> B[Merge import_data and export_data into result]
  B --> C["Set result.import_consumption <- result.consumption_import"]
  C --> D["Set result.import_consumption[is.na(import_consumption)] <- 0"]
  D --> E["Set result.export_consumption <- result.consumption_export"]
  E --> F["Set result.export_consumption[is.na(export_consumption)] <- 0"]
  F --> G[Remove result.consumption_import]
  G --> H[Remove result.consumption_export]
  H --> I[Return result]
Loading

File-Level Changes

Change Details Files
Add an include_gsp flag to meter metadata retrieval to make GSP lookup optional and avoid redundant API calls, including in testing paths.
  • Extend get_meter_details signature with an include_gsp parameter defaulting to TRUE and thread it through internal logic.
  • Guard GSP lookup so get_meter_gsp is only called for electricity meters when include_gsp is TRUE, using a pre-initialised NA placeholder.
  • Propagate include_gsp through the testing_meter helper and update its GSP resolution logic to respect the flag.
R/meter_details.R
Ensure consumers of meter metadata skip unnecessary GSP resolution when they only need identifiers.
  • Update get_consumption to call get_meter_details with include_gsp = FALSE when auto-fetching meter details.
  • Adjust get_meter_gsp default mpan argument to call get_meter_details with include_gsp = FALSE, avoiding an automatic nested GSP lookup.
  • Sync the Rd documentation for get_meter_gsp with the new default argument usage.
R/get_consumption.R
R/get_meter_gsp.R
man/get_meter_gsp.Rd
Optimize NA handling in consumption merging by replacing ifelse with in-place logical indexing.
  • Replace ifelse-based construction of import_consumption and export_consumption with direct assignment followed by in-place NA replacement using logical indexing.
  • Remove the now redundant consumption_import and consumption_export columns after remapping to the new fields.
R/meter_details.R
Document performance learnings and decisions for future maintenance and optimization work.
  • Add a Bolt note explaining the redundant GSP lookup issue in get_meter_details and the include_gsp toggle solution.
  • Add a Bolt note describing performance differences between ifelse and logical indexing for NA handling in large vectors.
.jules/bolt.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 3, 2026

Walkthrough

The PR introduces an include_gsp parameter to meter detail retrieval functions, allowing conditional fetching of GSP data to avoid redundant API calls. It updates internal function calls and refactors NA handling for consumption fields using direct assignment instead of ifelse().

Changes

Cohort / File(s) Summary
Documentation
.jules/bolt.md, man/get_meter_gsp.Rd
Added performance notes documenting redundant API calls and NA handling optimisations; updated usage example to demonstrate include_gsp = FALSE parameter.
Core Implementation
R/meter_details.R
Added include_gsp parameter (default TRUE) to get_meter_details() and testing_meter() functions; conditionally retrieves GSP data only when flag is TRUE and meter type is electricity; refactored consumption NA handling from ifelse() to direct assignment.
Function Calls Updated
R/get_consumption.R, R/get_meter_gsp.R
Updated calls to get_meter_details() to pass include_gsp = FALSE where GSP data is not required, preventing unnecessary API calls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main optimizations: reducing API calls (via include_gsp flag) and improving consumption data handling (ifelse to logical indexing).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bolt-optimize-api-and-consumption-6059727436970537527

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.jules/bolt.md:
- Line 1: Add a top-level H1 as the very first line of .jules/bolt.md to satisfy
markdownlint MD041; for example insert a descriptive H1 (e.g., "# Changelog" or
"# 2025-01-24 - Redundant API Calls in Metadata Retrieval") above the existing
"## 2025-01-24 - Redundant API Calls in Metadata Retrieval" heading so the file
begins with an H1.

In `@R/meter_details.R`:
- Around line 120-123: The variable meter_gsp is initialized with plain NA which
results in a logical type when GSP is skipped; change initializations of
meter_gsp (and any other NA placeholders for GSP) to NA_character_ so the gsp
column stays character across branches—update the blocks using meter_gsp (the if
(include_gsp && meter_type == "electricity") { meter_gsp <- get_meter_gsp(mpan =
mpan_mprn) } pattern and the other occurrences noted around lines 131, 164-170,
178) to set meter_gsp <- NA_character_ where appropriate and ensure returned
values from get_meter_gsp remain character.

ℹ️ Review info

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74f7003 and 57da7d4.

📒 Files selected for processing (5)
  • .jules/bolt.md
  • R/get_consumption.R
  • R/get_meter_gsp.R
  • R/meter_details.R
  • man/get_meter_gsp.Rd

@@ -0,0 +1,11 @@
## 2025-01-24 - Redundant API Calls in Metadata Retrieval
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a top-level H1 to satisfy markdownlint MD041.

The file starts with an H2, which triggers the configured lint rule for first-line heading.

Suggested fix
+# Bolt learnings
+
 ## 2025-01-24 - Redundant API Calls in Metadata Retrieval
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## 2025-01-24 - Redundant API Calls in Metadata Retrieval
# Bolt learnings
## 2025-01-24 - Redundant API Calls in Metadata Retrieval
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.jules/bolt.md at line 1, Add a top-level H1 as the very first line of
.jules/bolt.md to satisfy markdownlint MD041; for example insert a descriptive
H1 (e.g., "# Changelog" or "# 2025-01-24 - Redundant API Calls in Metadata
Retrieval") above the existing "## 2025-01-24 - Redundant API Calls in Metadata
Retrieval" heading so the file begins with an H1.

Comment on lines +120 to +123
meter_gsp <- NA
if (include_gsp && meter_type == "electricity") {
meter_gsp <- get_meter_gsp(mpan = mpan_mprn)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use typed NA_character_ for gsp to keep output types stable.

Initialising meter_gsp with plain NA yields a logical type when GSP is skipped. Use NA_character_ to keep gsp consistently character-like.

Suggested fix
-        meter_gsp <- NA
+        meter_gsp <- NA_character_
         if (include_gsp && meter_type == "electricity") {
           meter_gsp <- get_meter_gsp(mpan = mpan_mprn)
         }
@@
-    meter_gsp <- NA
+    meter_gsp <- NA_character_
     if (include_gsp) {
       meter_gsp <- if (identical(mpan, "sk_test_mpan")) {
         "J"

Also applies to: 131-131, 164-170, 178-178

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/meter_details.R` around lines 120 - 123, The variable meter_gsp is
initialized with plain NA which results in a logical type when GSP is skipped;
change initializations of meter_gsp (and any other NA placeholders for GSP) to
NA_character_ so the gsp column stays character across branches—update the
blocks using meter_gsp (the if (include_gsp && meter_type == "electricity") {
meter_gsp <- get_meter_gsp(mpan = mpan_mprn) } pattern and the other occurrences
noted around lines 131, 164-170, 178) to set meter_gsp <- NA_character_ where
appropriate and ensure returned values from get_meter_gsp remain character.

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