Skip to content

feat: Add object storage support for PDF and Image extraction - #88

Merged
gomesrocha merged 1 commit into
mainfrom
refactor/object-storage-support-7752691853998699012
Feb 17, 2026
Merged

feat: Add object storage support for PDF and Image extraction#88
gomesrocha merged 1 commit into
mainfrom
refactor/object-storage-support-7752691853998699012

Conversation

@gomesrocha

@gomesrocha gomesrocha commented Feb 17, 2026

Copy link
Copy Markdown
Owner

Refactors /extract_pdf and /extract_text endpoints to support processing files from S3-compatible object storage (S3, Minio, OCI). Introduces tenant configuration via tenants.json and a storage service using boto3.


PR created automatically by Jules for task 7752691853998699012 started by @gomesrocha

Summary by CodeRabbit

  • New Features
    • PDF extraction now supports uploading files or retrieving from object storage
    • Text extraction now supports uploading images or retrieving from object storage
    • Added validation to prevent ambiguous extraction requests with proper error messaging

Refactors /extract_pdf and /extract_text endpoints to support processing files from S3-compatible object storage (S3, Minio, OCI). Introduces tenant configuration via tenants.json and a storage service using boto3.

Co-authored-by: gomesrocha <3893269+gomesrocha@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
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.

@coderabbitai

coderabbitai Bot commented Feb 17, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This pull request introduces multi-source file extraction capabilities for both PDF and text extraction endpoints, adding support for retrieving files from AWS S3-compatible object storage alongside direct file uploads. It includes new tenant configuration management, an S3 storage service module, and comprehensive test coverage for the new functionality.

Changes

Cohort / File(s) Summary
API Endpoints
app/api/pdf_extract.py, app/api/text_extract.py
Enhanced both endpoints with multi-source support; added source parameter ("upload" or "object_storage"), client_id, and object_key/object_keys parameters; implemented validation to prevent ambiguous requests; updated file handling logic to branch based on source and delegate to storage service.
Core Infrastructure
app/core/tenants.py
Introduced new TenantConfig model to define per-tenant S3 credentials; implemented in-memory cache with load_tenants and get_tenant_config functions to manage tenant-specific configurations.
Storage Service
app/services/storage.py
Added new module with download_file_from_storage function to retrieve files from S3 using tenant-specific boto3 client configuration; handles file temporary storage and error propagation.
Configuration & Dependencies
pyproject.toml, tenants.json
Added boto3>=1.42.50 dependency; created tenants.json with sample tenant configuration for "client_a" containing S3 bucket and credential details.
Test Coverage
tests/test_storage_extract.py
Added comprehensive test suite validating both /extract_pdf and /extract_text endpoints with upload and object_storage sources; covers successful extraction, parameter validation, ambiguous requests, and PDF header validation.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API as API Endpoint
    participant TenantMgr as Tenant Config
    participant Storage as Storage Service
    participant S3 as S3 Object Storage
    participant OCR as OCR Processor
    participant Response

    Client->>API: POST /extract_pdf (source='object_storage', client_id, object_key)
    API->>TenantMgr: get_tenant_config(client_id)
    TenantMgr-->>API: TenantConfig
    API->>Storage: download_file_from_storage(client_id, object_key)
    Storage->>S3: Download file using tenant credentials
    S3-->>Storage: PDF file
    Storage->>Storage: Validate PDF header
    Storage-->>API: temp_file_path
    API->>OCR: process_pdf(temp_file_path)
    OCR-->>API: extracted_text
    API->>Storage: Cleanup temp file
    API-->>Response: TextExtractDocument
    Response-->>Client: HTTP 200
Loading
sequenceDiagram
    participant Client
    participant API as API Endpoint
    participant Validation as Input Validation
    participant FileHandler as File Handler
    participant OCR as OCR Processor
    participant Response

    Client->>API: POST /extract_pdf (source='upload', input_file)
    API->>Validation: Check source='upload' & input_file present
    Validation-->>API: Validation passed
    API->>FileHandler: Validate PDF header & save to temp
    FileHandler-->>API: temp_file_path
    API->>OCR: process_pdf(temp_file_path)
    OCR-->>API: extracted_text
    API->>FileHandler: Cleanup temp file
    API-->>Response: TextExtractDocument
    Response-->>Client: HTTP 200
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #87: Directly related; extends /extract_pdf endpoint with object_storage source support and storage service integration.
  • PR #84: Related; prior modifications to text_extract.py and OCR utilities that this PR builds upon with multi-source functionality.

Poem

🐰 Hops with glee across the storage lanes,
Where uploads meet the cloud in joyful chains!
From S3 buckets to tenant configs bright,
PDFs and images dance in multi-source delight!

✨ 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 refactor/object-storage-support-7752691853998699012

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.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Comment thread app/services/storage.py
region_name=config.region_name
)

s3_client.download_fileobj(config.bucket_name, object_key, tmp_file)

Check failure

Code scanning / SonarCloud

S3 operations should verify bucket ownership using ExpectedBucketOwner parameter High

Add the 'ExpectedBucketOwner' to the 'ExtraArgs' parameter to verify S3 bucket ownership. See more on SonarQube Cloud
Comment thread app/services/storage.py
return tmp_file.name

except ClientError as e:
log.error(f"S3 ClientError downloading {object_key}: {e}")

Check notice

Code scanning / SonarCloud

Logging should not be vulnerable to injection attacks Low

Change this code to not log user-controlled data. See more on SonarQube Cloud
Comment thread app/services/storage.py
log.error(f"S3 ClientError downloading {object_key}: {e}")
raise e
except Exception as e:
log.error(f"Unexpected error downloading {object_key}: {e}")

Check notice

Code scanning / SonarCloud

Logging should not be vulnerable to injection attacks Low

Change this code to not log user-controlled data. See more on SonarQube Cloud
@gomesrocha
gomesrocha merged commit cc68460 into main Feb 17, 2026
2 of 6 checks passed
@gomesrocha
gomesrocha deleted the refactor/object-storage-support-7752691853998699012 branch February 17, 2026 14:19
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.

2 participants