Skip to content

🎨 Palette: Smart Profile ID Extraction from URLs#135

Merged
abhimehro merged 1 commit intomainfrom
palette-smart-profile-id-extraction-4363998502891798168
Jan 27, 2026
Merged

🎨 Palette: Smart Profile ID Extraction from URLs#135
abhimehro merged 1 commit intomainfrom
palette-smart-profile-id-extraction-4363998502891798168

Conversation

@abhimehro
Copy link
Owner

🎨 Palette: Smart Profile ID Extraction

💡 What:
Added smart extraction logic that allows users to paste the full Control D Dashboard URL (e.g., https://controld.com/dashboard/profiles/12345/filters) when prompted for a Profile ID. The system automatically extracts the ID (12345) and proceeds.

🎯 Why:
Users often copy the full URL from their browser address bar. Previously, this caused a validation error because the script expected only the alphanumeric ID. This change removes that friction and prevents manual copy-paste errors.

♿ Accessibility/UX:

  • Reduces cognitive load (no need to identify where the ID starts/ends).
  • Provides immediate success instead of an error message for a common user behavior.
  • Updated prompt text clearly states "or just paste the URL".

PR created automatically by Jules for task 4363998502891798168 started by @abhimehro

- Added `extract_profile_id` helper to `main.py` to handle Control D dashboard URLs.
- Updated `main()` to use extraction for both CLI arguments and interactive input.
- Updated interactive prompt text to inform users they can paste the full URL.
- Added comprehensive tests for extraction logic and interactive flow in `test_main.py`.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
@google-labs-jules
Copy link

👋 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.

Copilot AI review requested due to automatic review settings January 26, 2026 23:04
@trunk-io
Copy link

trunk-io bot commented Jan 26, 2026

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

@gemini-code-assist
Copy link

Summary of Changes

Hello @abhimehro, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user experience of the Palette tool by introducing intelligent parsing for Control D Profile IDs. Previously, users were required to manually extract the alphanumeric ID from a URL, often leading to validation errors. Now, the system automatically extracts the correct ID when a full Control D Dashboard URL is provided, whether through interactive prompts or environment variables. This change reduces cognitive load, prevents common user errors, and streamlines the workflow for obtaining profile IDs.

Highlights

  • Smart Profile ID Extraction: Implemented a new extract_profile_id function that intelligently parses Control D Dashboard URLs to automatically extract the profile ID, accommodating various URL formats and handling whitespace.
  • Improved User Experience: Integrated the new extraction logic into the main application flow, allowing users to paste full URLs instead of just the ID when prompted interactively or when providing IDs via environment variables.
  • Enhanced User Prompts: Updated the interactive prompt for profile ID input to explicitly inform users that they can now paste a full URL, reducing cognitive load and potential errors.
  • Comprehensive Testing: Added new unit tests to validate the extract_profile_id function's behavior across different input types and to confirm that the interactive input correctly extracts IDs from URLs.
  • Documentation Update: Documented the learning and action related to smart input extraction in the project's .Jules/palette.md file, providing a record of this UX improvement.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

# Case 8: extract_profile_id correctly extracts ID from URL or returns input
def test_extract_profile_id():
# Regular ID
assert main.extract_profile_id("12345") == "12345"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""
assert main.extract_profile_id(None) == ""

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Verify sync_profile called with extracted ID
args, _ = mock_sync.call_args
assert args[0] == "extracted_id"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Verify prompt text update
captured = capsys.readouterr()
assert "(or just paste the URL)" in captured.out

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
if not profile_ids:
print(f"{Colors.CYAN}ℹ Profile ID is missing.{Colors.ENDC}")
print(f"{Colors.CYAN} You can find this in the URL of your profile in the Control D Dashboard.{Colors.ENDC}")
print(f"{Colors.CYAN} You can find this in the URL of your profile in the Control D Dashboard (or just paste the URL).{Colors.ENDC}")

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (146/100) Warning

Line too long (146/100)
assert "Network failure" in str(mock_log.error.call_args)

# Case 8: extract_profile_id correctly extracts ID from URL or returns input
def test_extract_profile_id():

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning test

Missing function docstring
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (102/100) Warning test

Line too long (102/100)
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (102/100) Warning test

Line too long (102/100)
assert main.extract_profile_id(None) == ""

# Case 9: Interactive input handles URL pasting
def test_interactive_input_extracts_id(monkeypatch, capsys):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning test

Missing function docstring
monkeypatch.delenv("TOKEN", raising=False)

# Reload main with isatty=True
m = reload_main_with_env(monkeypatch, isatty=True)

Check warning

Code scanning / Pylint (reported by Codacy)

Variable name "m" doesn't conform to snake_case naming style Warning test

Variable name "m" doesn't conform to snake_case naming style
if not profile_ids:
print(f"{Colors.CYAN}ℹ Profile ID is missing.{Colors.ENDC}")
print(f"{Colors.CYAN} You can find this in the URL of your profile in the Control D Dashboard.{Colors.ENDC}")
print(f"{Colors.CYAN} You can find this in the URL of your profile in the Control D Dashboard (or just paste the URL).{Colors.ENDC}")

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (146/100) Warning

Line too long (146/100)
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (102/100) Warning test

Line too long (102/100)
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (102/100) Warning test

Line too long (102/100)
# Case 8: extract_profile_id correctly extracts ID from URL or returns input
def test_extract_profile_id():
# Regular ID
assert main.extract_profile_id("12345") == "12345"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""
assert main.extract_profile_id(None) == ""

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Verify sync_profile called with extracted ID
args, _ = mock_sync.call_args
assert args[0] == "extracted_id"

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Verify prompt text update
captured = capsys.readouterr()
assert "(or just paste the URL)" in captured.out

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a smart profile ID extraction feature, allowing users to paste full Control D dashboard URLs instead of just the ID. This is a great usability improvement. The implementation is clean and the new logic is well-covered by tests. I've added a couple of minor suggestions: one to improve type hinting for better code correctness and another to refactor a test for better maintainability using pytest.parametrize. Overall, this is a solid contribution.


return True

def extract_profile_id(text: str) -> str:

Choose a reason for hiding this comment

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

medium

The type hint for text is str, but the function logic and tests handle None as a valid input. To make the function signature more accurate and prevent potential type checker issues, it's better to use Optional[str]. You'll need to ensure from typing import Optional is present.

Suggested change
def extract_profile_id(text: str) -> str:
def extract_profile_id(text: Optional[str]) -> str:

Comment on lines +324 to +339
def test_extract_profile_id():
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""
assert main.extract_profile_id(None) == ""

Choose a reason for hiding this comment

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

medium

This test function contains multiple assert statements for different test cases. To improve readability and make it easier to add new test cases in the future, consider refactoring it to use pytest.mark.parametrize. This will also provide more granular feedback if one of the cases fails.

Suggested change
def test_extract_profile_id():
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""
assert main.extract_profile_id(None) == ""
@pytest.mark.parametrize(
"input_text, expected_id",
[
("12345", "12345"),
("https://controld.com/dashboard/profiles/12345/filters", "12345"),
("https://controld.com/dashboard/profiles/12345", "12345"),
("https://controld.com/dashboard/profiles/12345?foo=bar", "12345"),
(" 12345 ", "12345"),
("random-string", "random-string"),
("", ""),
(None, ""),
],
)
def test_extract_profile_id(input_text, expected_id):
assert main.extract_profile_id(input_text) == expected_id

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds smart URL parsing capability to extract profile IDs from full Control D Dashboard URLs, reducing user friction when providing profile IDs.

Changes:

  • Added extract_profile_id() function that uses regex to extract profile IDs from URLs or returns the input as-is
  • Applied extraction logic to all profile ID input points (environment variables, CLI arguments, and interactive prompts)
  • Updated interactive prompt text to explicitly mention URL pasting support
  • Added comprehensive test coverage for the new functionality
  • Documented the learning in palette.md

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
main.py Added extract_profile_id() function and integrated it into profile ID processing logic; updated interactive prompt text
test_main.py Added unit tests for extract_profile_id() covering multiple URL formats and edge cases; added integration test verifying URL extraction in interactive mode
.Jules/palette.md Documented the learning and action for smart input extraction pattern

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

text = text.strip()
# Pattern for Control D Dashboard URLs
# e.g. https://controld.com/dashboard/profiles/12345abc/filters
match = re.search(r"controld\.com/dashboard/profiles/([^/?#\s]+)", text)
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The regex pattern for extracting profile IDs from URLs is case-sensitive and will not match URLs with uppercase letters in the domain (e.g., "https://ControlD.com/..." or "HTTPS://CONTROLD.COM/..."). Consider making the pattern case-insensitive by adding the re.IGNORECASE flag or by explicitly handling both cases in the pattern. Domain names are case-insensitive per RFC standards, so users might paste URLs with different casing.

Suggested change
match = re.search(r"controld\.com/dashboard/profiles/([^/?#\s]+)", text)
match = re.search(r"controld\.com/dashboard/profiles/([^/?#\s]+)", text, re.IGNORECASE)

Copilot uses AI. Check for mistakes.
Comment on lines +324 to +339
def test_extract_profile_id():
# Regular ID
assert main.extract_profile_id("12345") == "12345"
# URL with /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345/filters") == "12345"
# URL without /filters
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345") == "12345"
# URL with params
assert main.extract_profile_id("https://controld.com/dashboard/profiles/12345?foo=bar") == "12345"
# Clean up whitespace
assert main.extract_profile_id(" 12345 ") == "12345"
# Invalid input returns as is (cleaned)
assert main.extract_profile_id("random-string") == "random-string"
# Empty input
assert main.extract_profile_id("") == ""
assert main.extract_profile_id(None) == ""
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

Add a test case for URLs with uppercase letters in the domain (e.g., "HTTPS://CONTROLD.COM/dashboard/profiles/12345/filters" or "https://ControlD.com/dashboard/profiles/12345"). Domain names are case-insensitive per RFC standards, but the current regex pattern is case-sensitive and may not handle these cases correctly.

Copilot uses AI. Check for mistakes.
@abhimehro abhimehro merged commit 7e072ba into main Jan 27, 2026
24 checks passed
@abhimehro abhimehro deleted the palette-smart-profile-id-extraction-4363998502891798168 branch January 27, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants