Skip to content

Conversation

@ryoppippi
Copy link
Member

@ryoppippi ryoppippi commented Dec 18, 2025

Summary

Migrate the HTTP client library from requests to httpx for improved async support potential and modern API design. Also updates the test mocking library from responses to respx.

What Changed

  • Dependencies: Replace requests>=2.32.3 with httpx>=0.28.0
  • Core HTTP logic: Update stackone_ai/models.py to use httpx.request()
  • Exception handling: Refactor to use httpx-specific exceptions:
    • httpx.HTTPStatusError for HTTP error responses (4xx/5xx)
    • httpx.RequestError for connection/network errors
  • Test infrastructure: Migrate from responses to respx library
  • Type stubs: Remove types-requests (no longer needed)

Why

  • httpx provides a more modern API with built-in async support
  • Better exception hierarchy with clearer separation of error types
  • respx integrates seamlessly with httpx for testing
  • Reduces overall dependency footprint

Breaking Change

Error handling now uses httpx exceptions instead of requests exceptions. Code catching RequestException should be updated to catch httpx.HTTPStatusError or httpx.RequestError.


Summary by cubic

Migrated the HTTP client from requests to httpx to enable async-ready usage and clearer error handling. Tests now use respx for HTTP mocking.

  • Refactors

    • Replaced requests with httpx>=0.28.0.
    • Updated stackone_ai/models.py to use httpx.request.
    • Switched to httpx.HTTPStatusError and httpx.RequestError; improved error body parsing for StackOneAPIError.
    • Moved tests from responses to respx; removed types-requests.
  • Migration

    • Replace catches of requests.RequestException with httpx.RequestError or httpx.HTTPStatusError.
    • Update test mocks from responses to respx; patch httpx.request where applicable.
    • Ensure httpx is available; remove any direct requests/type-stub references in downstream code.

Written for commit 9367d1d. Summary will update automatically on new commits.

Replace the synchronous HTTP client library from `requests` to `httpx`
for improved async support potential and modern API design.

Changes include:
- Replace `requests>=2.32.3` with `httpx>=0.28.0` in dependencies
- Update `stackone_ai/models.py` to use httpx.request() instead of
  requests.request()
- Refactor exception handling to use httpx-specific exceptions:
  - httpx.HTTPStatusError for HTTP error responses
  - httpx.RequestError for connection/network errors
- Replace test mocking library from `responses` to `respx`
- Remove `types-requests` type stubs (no longer needed)
- Update all test files to use respx decorators and httpx.Response

BREAKING CHANGE: Error handling now uses httpx exceptions instead of
requests exceptions. Code catching RequestException should be updated
to catch httpx.HTTPStatusError or httpx.RequestError.
Copilot AI review requested due to automatic review settings December 18, 2025 18:26
@ryoppippi ryoppippi changed the title refactor!: migrate HTTP client from requests to httpx fix!: migrate HTTP client from requests to httpx Dec 18, 2025
@ryoppippi ryoppippi enabled auto-merge (squash) December 18, 2025 18:27
Copy link
Contributor

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 migrates the HTTP client library from requests to httpx to enable future async support and leverage a more modern API design. The migration includes updating all HTTP request handling, exception management, and test infrastructure.

Key Changes:

  • Replace requests library with httpx for HTTP operations
  • Update exception handling to use httpx-specific exceptions (HTTPStatusError and RequestError)
  • Migrate test mocking from responses to respx library

Reviewed changes

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

Show a summary per file
File Description
pyproject.toml Updated dependencies: replaced requests>=2.32.3 with httpx>=0.28.0, responses>=0.25.8 with respx>=0.22.0, and removed types-requests
stackone_ai/models.py Refactored HTTP client to use httpx.request() and updated exception handling to catch httpx-specific exceptions
tests/test_tool_calling.py Migrated test mocks from responses to respx, updating mock setup and request body assertions
tests/test_models.py Updated patched module from requests.request to httpx.request and added required mock response attributes
tests/test_meta_tools.py Converted test mocking from responses to respx format
tests/test_feedback.py Refactored all test mocks to use respx, simplified mock setup, and split combined test into separate test methods

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

Comment on lines 256 to 269
except httpx.HTTPStatusError as exc:
status = "error"
error_message = str(exc)
response_body = None
if exc.response.text:
try:
response_body = exc.response.json()
except json.JSONDecodeError:
response_body = exc.response.text
raise StackOneAPIError(
str(exc),
exc.response.status_code,
response_body,
) from exc
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

The variables status and error_message are assigned but never used before raising the exception. These assignments should be removed to avoid confusion.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

assert error_result["status"] == "error"
assert "401 Client Error: Unauthorized" in error_result["error"]
error_result = next(r for r in result["results"] if r["account_id"] == "acc_unauthorized")
assert error_result["status"] == "error"
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

The error message assertion was removed from the test. The test should verify that the error result contains the expected error information to ensure proper error handling and reporting.

Copilot uses AI. Check for mistakes.
Copy link

@cubic-dev-ai cubic-dev-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.

1 issue found across 7 files

Prompt for AI agents (all 1 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="tests/test_feedback.py">

<violation number="1" location="tests/test_feedback.py:202">
P2: Test coverage reduced: the assertion verifying error message content was removed. The original test checked `assert &quot;401 Client Error: Unauthorized&quot; in error_result[&quot;error&quot;]` to ensure error details were properly captured. Consider adding an assertion to verify that `error_result[&quot;error&quot;]` is non-empty or contains expected error information.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

assert error_result["status"] == "error"
assert "401 Client Error: Unauthorized" in error_result["error"]
error_result = next(r for r in result["results"] if r["account_id"] == "acc_unauthorized")
assert error_result["status"] == "error"
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 18, 2025

Choose a reason for hiding this comment

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

P2: Test coverage reduced: the assertion verifying error message content was removed. The original test checked assert "401 Client Error: Unauthorized" in error_result["error"] to ensure error details were properly captured. Consider adding an assertion to verify that error_result["error"] is non-empty or contains expected error information.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/test_feedback.py, line 202:

<comment>Test coverage reduced: the assertion verifying error message content was removed. The original test checked `assert &quot;401 Client Error: Unauthorized&quot; in error_result[&quot;error&quot;]` to ensure error details were properly captured. Consider adding an assertion to verify that `error_result[&quot;error&quot;]` is non-empty or contains expected error information.</comment>

<file context>
@@ -55,165 +56,150 @@ def test_multiple_account_ids_validation(self) -&gt; None:
-            assert error_result[&quot;status&quot;] == &quot;error&quot;
-            assert &quot;401 Client Error: Unauthorized&quot; in error_result[&quot;error&quot;]
+        error_result = next(r for r in result[&quot;results&quot;] if r[&quot;account_id&quot;] == &quot;acc_unauthorized&quot;)
+        assert error_result[&quot;status&quot;] == &quot;error&quot;
 
     def test_tool_integration(self) -&gt; None:
</file context>

✅ Addressed in 9b023ed

- Remove unused error_message variable in exception handlers
- Restore error assertion in test_multiple_account_ids_mixed_success
@ryoppippi ryoppippi requested a review from glebedel December 19, 2025 15:06
Copy link
Contributor

@glebedel glebedel left a comment

Choose a reason for hiding this comment

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

LGTM but you do have a conflict in the tests

@ryoppippi ryoppippi disabled auto-merge December 22, 2025 12:01
Resolved conflicts in:
- pyproject.toml: Added new ty dependency from main
- tests/test_meta_tools.py: Updated test URLs to use hibob while keeping httpx/respx approach
- uv.lock: Regenerated to incorporate changes from both branches

All tests passing after merge.
@ryoppippi ryoppippi merged commit 9d180ef into main Dec 22, 2025
15 checks passed
@ryoppippi ryoppippi deleted the refactor/migrate-requests-to-httpx branch December 22, 2025 12:03
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.

3 participants