Skip to content

Conversation

@RohanExploit
Copy link
Owner

@RohanExploit RohanExploit commented Feb 7, 2026

This PR addresses critical bugs in the image processing pipeline and schema validation.

Key Changes:

  1. Image Processing Fix: process_uploaded_image was refactored to return both the PIL Image and the BytesIO object. This aligns with the "memory" of optimization (avoiding re-reading files) and fixes the ValueError: too many values to unpack errors in backend/routers/detection.py which was already expecting a tuple.
  2. Router Update: backend/routers/issues.py was updated to handle the new return signature of process_uploaded_image, preventing a regression in the issue creation flow.
  3. HF Service Robustness: backend/hf_api_service.py's _prepare_image_bytes helper was patched to explicitly handle io.BytesIO objects, preventing AttributeError: '_io.BytesIO' object has no attribute 'format' errors during AI detection calls.
  4. Schema Validation: Added a strict validator to ChatRequest.query to forbid whitespace-only strings, ensuring better data integrity and matching test expectations.

These changes restore the stability of detection features and the issue reporting flow.


PR created automatically by Jules for task 12866211084660275983 started by @RohanExploit

Summary by CodeRabbit

  • Improvements
    • Chat query validation now rejects empty or whitespace-only input, ensuring better data quality
    • Enhanced image processing pipeline with improved handling of various image input formats

- Updated `process_uploaded_image` in `backend/utils.py` to return `(Image.Image, io.BytesIO)` to support optimization and avoid double-decoding.
- Updated `backend/routers/issues.py` to correctly unpack the tuple returned by `process_uploaded_image`.
- Fixed `_prepare_image_bytes` in `backend/hf_api_service.py` to handle `io.BytesIO` objects, resolving crashes in detection endpoints.
- Added `validate_query` to `ChatRequest` schema in `backend/schemas.py` to reject empty or whitespace-only queries.
- Verified changes with existing tests `test_schemas.py` and `test_new_features.py`.

Co-authored-by: RohanExploit <178623867+RohanExploit@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.

Copilot AI review requested due to automatic review settings February 7, 2026 11:56
@netlify
Copy link

netlify bot commented Feb 7, 2026

Deploy Preview for fixmybharat canceled.

Name Link
🔨 Latest commit f55f6fa
🔍 Latest deploy log https://app.netlify.com/projects/fixmybharat/deploys/698728843aebc300086774b0

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

🙏 Thank you for your contribution, @RohanExploit!

PR Details:

Quality Checklist:
Please ensure your PR meets the following criteria:

  • Code follows the project's style guidelines
  • Self-review of code completed
  • Code is commented where necessary
  • Documentation updated (if applicable)
  • No new warnings generated
  • Tests added/updated (if applicable)
  • All tests passing locally
  • No breaking changes to existing functionality

Review Process:

  1. Automated checks will run on your code
  2. A maintainer will review your changes
  3. Address any requested changes promptly
  4. Once approved, your PR will be merged! 🎉

Note: The maintainers will monitor code quality and ensure the overall project flow isn't broken.

@github-actions github-actions bot added the size/s label Feb 7, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

The image processing pipeline is refactored to return both the processed PIL Image object and BytesIO representation from utility functions, with corresponding updates to consumers and input handlers to accommodate the new tuple return type.

Changes

Cohort / File(s) Summary
Image Processing Return Type
backend/utils.py
Updated process_uploaded_image_sync and process_uploaded_image to return tuple[Image.Image, io.BytesIO] instead of just io.BytesIO. Both the processed PIL image and output stream are now constructed and returned.
Image Preparation Handler
backend/hf_api_service.py
Extended _prepare_image_bytes function signature to accept io.BytesIO in addition to Image.Image and bytes. Added handling to extract bytes from BytesIO objects via getvalue().
Router Adaptation
backend/routers/issues.py
Updated process_uploaded_image consumption to unpack the new tuple return, discarding the Image.Image component and retaining the BytesIO for further processing.
Query Input Validation
backend/schemas.py
Added validate_query field validator for ChatRequest.query that rejects empty or whitespace-only strings and returns the stripped value.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

size/m

Poem

🐰 The images dance in tuples now,
A PIL and BytesIO bow,
The pipeline flows both swift and clean,
With whitespace trimmed and bytes serene!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: fixing the image processing pipeline and adding ChatRequest validation.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-app-issues-and-optimization-12866211084660275983

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
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 fixes mismatches in the image upload/processing pipeline and tightens request validation for chat inputs, stabilizing detection endpoints and issue creation flows.

Changes:

  • Updated process_uploaded_image to return a (PIL.Image, BytesIO) tuple to match router expectations.
  • Adjusted issue creation to unpack the new image-processing return signature.
  • Made HF image-byte preparation robust to io.BytesIO inputs.
  • Added a strict validator to reject whitespace-only ChatRequest.query values.

Reviewed changes

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

File Description
backend/utils.py Changes process_uploaded_image* to return both a processed PIL image and a BytesIO buffer.
backend/routers/issues.py Updates issue creation flow to unpack the new (image, bytes) return signature.
backend/hf_api_service.py Extends _prepare_image_bytes to accept io.BytesIO and convert it to raw bytes safely.
backend/schemas.py Adds ChatRequest.query validator to reject whitespace-only queries and normalize input via .strip().
Comments suppressed due to low confidence (1)

backend/hf_api_service.py:55

  • _prepare_image_bytes now supports io.BytesIO, but the rest of the module still annotates most public detector helpers as accepting only Union[Image.Image, bytes]. Since router code passes the processed image buffer around, updating those function type hints (and any relevant docstrings) to include io.BytesIO would keep the API contract consistent and avoid confusion for callers and static analysis.
def _prepare_image_bytes(image: Union[Image.Image, bytes, io.BytesIO]) -> bytes:
    if isinstance(image, bytes):
        return image
    if isinstance(image, io.BytesIO):
        return image.getvalue()
    img_byte_arr = io.BytesIO()
    fmt = image.format if image.format else 'JPEG'
    image.save(img_byte_arr, format=fmt)
    return img_byte_arr.getvalue()

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

Comment on lines 141 to 206
@@ -179,15 +179,15 @@
# Strip EXIF
img_no_exif = Image.new(img.mode, img.size)
img_no_exif.paste(img)

# Save to BytesIO
output = io.BytesIO()
# Preserve format or default to JPEG
fmt = img.format or 'JPEG'
img_no_exif.save(output, format=fmt, quality=85)
output.seek(0)

return output
return img_no_exif, output

except Exception as pil_error:
logger.error(f"PIL processing failed: {pil_error}")
@@ -202,7 +202,7 @@
logger.error(f"Error processing file: {e}")
raise HTTPException(status_code=400, detail="Unable to process file.")

async def process_uploaded_image(file: UploadFile) -> io.BytesIO:
async def process_uploaded_image(file: UploadFile) -> tuple[Image.Image, io.BytesIO]:
return await run_in_threadpool(process_uploaded_image_sync, file)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

process_uploaded_image/process_uploaded_image_sync now return a tuple, but there are no unit tests asserting the new return contract (PIL image + BytesIO) or that the BytesIO is rewound and usable for downstream consumers. Adding a focused test here would prevent regressions like unpacking errors or non-seeked buffers.

Copilot uses AI. Check for mistakes.
Comment on lines +73 to 76
_, processed_image = await process_uploaded_image(image)

# Save processed image to disk
await run_in_threadpool(save_processed_image, processed_image, image_path)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

The local name processed_image is now an io.BytesIO (image bytes), not a PIL image. Renaming it to something like processed_image_io / processed_image_bytes would make the code clearer and reduce the chance of accidentally treating it as an Image.Image later.

Suggested change
_, processed_image = await process_uploaded_image(image)
# Save processed image to disk
await run_in_threadpool(save_processed_image, processed_image, image_path)
_, processed_image_bytes = await process_uploaded_image(image)
# Save processed image to disk
await run_in_threadpool(save_processed_image, processed_image_bytes, image_path)

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +190
# Strip EXIF
img_no_exif = Image.new(img.mode, img.size)
img_no_exif.paste(img)

# Save to BytesIO
output = io.BytesIO()
# Preserve format or default to JPEG
fmt = img.format or 'JPEG'
img_no_exif.save(output, format=fmt, quality=85)
output.seek(0)

return output
return img_no_exif, output
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

The returned img_no_exif is created via Image.new(...), so it will typically have image.format == None even when the original upload was PNG/WebP/etc. Since the function now exposes the PIL image to callers, consider preserving the original format in the returned image (or documenting that callers must not rely on .format and should use the returned BytesIO for encoding).

Copilot uses AI. Check for mistakes.
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.

1 participant