Skip to content

Refactor: Extract duplicated patterns into shared utilities#54

Merged
Bryan-Roe merged 8 commits into
mainfrom
copilot/refactor-duplicated-code-again
Feb 17, 2026
Merged

Refactor: Extract duplicated patterns into shared utilities#54
Bryan-Roe merged 8 commits into
mainfrom
copilot/refactor-duplicated-code-again

Conversation

Copilot AI commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

Eliminated ~150 lines of duplicated code across providers, HTTP endpoints, and import patterns by extracting common logic into reusable utilities.

Changes

Provider Response Handling

Extracted OpenAI-compatible streaming/non-streaming response parsing from 3 provider classes into BaseChatProvider helper methods:

class BaseChatProvider:
    @staticmethod
    def _handle_openai_streaming_response(response) -> Generator[str, None, None]:
        """Common handler for OpenAI-style streaming responses"""
        
    @staticmethod
    def _handle_openai_non_streaming_response(response) -> str:
        """Common handler for OpenAI-style non-streaming responses"""

Impact: OpenAIProvider and LMStudioProvider now use shared logic; AzureOpenAIProvider uses it for non-quota cases.

Defensive Import Pattern

Created shared/import_helpers.py to consolidate try/except import blocks with fallbacks:

# Before: 5+ repeated blocks in function_app.py
try:
    from shared.sql_engine import sql_health, engine_stats
except Exception:
    def sql_health(): return {"enabled": False}
    def engine_stats(): return {"enabled": False}

# After: One-liner with fallback factory
sql_funcs = safe_import('shared.sql_engine', 
                       import_names=('sql_health', 'engine_stats'),
                       fallback_factory=create_stub_function)

HTTP Utilities

Created shared/http_utils.py consolidating validation and file serving:

  • validate_messages() - Message format validation (used in 2+ endpoints)
  • create_cors_headers() - CORS header generation
  • serve_static_file() - File serving with error handling

Refactored http_chat/function_app.py and http_chat_web/function_app.py to use shared utilities.

Test Coverage

30 unit tests added covering all utility functions (100% passing).

Additional Refactoring Opportunities

Identified but not implemented:

  • sys.path manipulation (60+ instances, inconsistent patterns)
  • Configuration loading (80+ direct os.getenv() calls without validation)

See docs/REFACTORING_SUMMARY.md for details.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @Copilot! 👋

Your private repo does not have access to Sourcery.

Please upgrade to continue using Sourcery ✨

Copilot AI and others added 3 commits February 17, 2026 10:01
…orts

Co-authored-by: Bryan-Roe <74067792+Bryan-Roe@users.noreply.github.com>
Co-authored-by: Bryan-Roe <74067792+Bryan-Roe@users.noreply.github.com>
Co-authored-by: Bryan-Roe <74067792+Bryan-Roe@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor duplicated code to improve maintainability Refactor: Extract duplicated patterns into shared utilities Feb 17, 2026
Copilot AI requested a review from Bryan-Roe February 17, 2026 10:09
Comment on lines +443 to +449
resp = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=self.temperature,
max_tokens=self.max_output_tokens,
stream=stream,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
Possibly found usage of AI: OpenAI

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by detect-openai.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment on lines +413 to +419
resp = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=self.temperature,
max_tokens=self.max_output_tokens,
stream=stream,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
Possibly found usage of AI: OpenAI

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by detect-openai.

You can view more details about this finding in the Semgrep AppSec Platform.

@bryan-roe-bot

bryan-roe-bot Bot commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

Semgrep found 6 detect-generic-ai-oai findings:

Possibly found usage of AI: OpenAI

Semgrep found 6 return-not-in-function findings:

return only makes sense inside a function

Comment thread shared/http_utils.py
return True, None, None

provider_lower = provider_choice.lower()
valid_providers = {'auto', 'openai', 'azure', 'local', 'lora', 'lmstudio'}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
Possibly found usage of AI: OpenAI

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by detect-generic-ai-oai.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment thread shared/http_utils.py
"""Validate provider choice and model override.

Args:
provider_choice: The requested provider ('auto', 'openai', 'azure', 'local', 'lora')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
Possibly found usage of AI: OpenAI

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by detect-generic-ai-oai.

You can view more details about this finding in the Semgrep AppSec Platform.

@Bryan-Roe Bryan-Roe requested review from Copilot and removed request for Bryan-Roe February 17, 2026 10:46
@Bryan-Roe Bryan-Roe marked this pull request as ready for review February 17, 2026 10:46

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @Bryan-Roe! 👋

Your private repo does not have access to Sourcery.

Please upgrade to continue using Sourcery ✨

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Refactors duplicated provider/HTTP/import patterns into shared utilities, and adds unit tests to lock in behavior.

Changes:

  • Extracted shared OpenAI-compatible streaming/non-streaming response parsing into BaseChatProvider.
  • Added shared/import_helpers.py and refactored optional imports in function_app.py to use safe_import().
  • Added shared/http_utils.py and refactored HTTP endpoints to use shared validation/CORS/static-file serving helpers.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/test_provider_response_handling.py Adds tests for the new BaseChatProvider response helper methods.
tests/test_import_helpers.py Adds tests for safe_import() and create_stub_function().
tests/test_http_utils.py Adds tests for shared HTTP validation/header/static-file helpers.
talk-to-ai/src/chat_providers.py Introduces shared response handlers and refactors providers to use them.
shared/import_helpers.py New module to consolidate defensive import + fallback patterns.
shared/http_utils.py New module for message/provider validation and static file serving helpers.
http_chat_web/function_app.py Refactors static file serving to use serve_static_file().
http_chat/function_app.py Refactors message validation + CORS header creation via shared helpers.
function_app.py Refactors optional imports to use safe_import() utilities.
docs/REFACTORING_SUMMARY.md Adds documentation summarizing refactor scope and impact.

Comment thread shared/http_utils.py Outdated
Comment thread shared/http_utils.py
Comment on lines +125 to +129
def serve_static_file(
file_path: Path,
mimetype: str,
use_cache_headers: bool = False
) -> Tuple[Optional[str], int, Dict[str, str]]:

Copilot AI Feb 17, 2026

Copy link

Choose a reason for hiding this comment

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

use_cache_headers is misleading: when it's True, the function adds no-cache headers via create_no_cache_headers(). This is likely to confuse callers/maintainers and contradicts the intent implied by the name. Rename the parameter to something like disable_cache / no_cache (and update docstring accordingly), or invert the behavior so use_cache_headers=True actually enables cache-friendly headers.

Copilot uses AI. Check for mistakes.
Comment thread shared/http_utils.py
Args:
file_path: Path to the file to serve
mimetype: MIME type for the response (e.g., 'text/html', 'application/javascript')
use_cache_headers: Whether to add no-cache headers (default: False for better caching)

Copilot AI Feb 17, 2026

Copy link

Choose a reason for hiding this comment

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

use_cache_headers is misleading: when it's True, the function adds no-cache headers via create_no_cache_headers(). This is likely to confuse callers/maintainers and contradicts the intent implied by the name. Rename the parameter to something like disable_cache / no_cache (and update docstring accordingly), or invert the behavior so use_cache_headers=True actually enables cache-friendly headers.

Copilot uses AI. Check for mistakes.
Comment thread shared/http_utils.py
Comment on lines +165 to +167
headers = {}
if use_cache_headers:
headers.update(create_no_cache_headers())

Copilot AI Feb 17, 2026

Copy link

Choose a reason for hiding this comment

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

use_cache_headers is misleading: when it's True, the function adds no-cache headers via create_no_cache_headers(). This is likely to confuse callers/maintainers and contradicts the intent implied by the name. Rename the parameter to something like disable_cache / no_cache (and update docstring accordingly), or invert the behavior so use_cache_headers=True actually enables cache-friendly headers.

Copilot uses AI. Check for mistakes.
Comment thread http_chat_web/function_app.py Outdated
Comment thread http_chat/function_app.py Outdated
Comment thread tests/test_provider_response_handling.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 016f6c9f68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread function_app.py
from datetime import datetime

# Import defensive import helper
from shared.import_helpers import safe_import, create_stub_function

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Guard import_helpers import to preserve startup fallbacks

This unconditional top-level import introduces a hard dependency on the shared package at module import time. In environments where shared is not on sys.path (the same scenario the surrounding code previously handled with defensive try/except imports), function_app.py now fails to load before any fallback stubs are installed, which can prevent the Functions worker from starting at all.

Useful? React with 👍 / 👎.

Bryan-Roe and others added 3 commits February 17, 2026 06:43
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Bryan-Roe Bryan-Roe merged commit 44e2dea into main Feb 17, 2026
6 of 13 checks passed
@Bryan-Roe Bryan-Roe deleted the copilot/refactor-duplicated-code-again branch February 17, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

azure-functions chat-interface documentation Improvements or additions to documentation tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants