Skip to content

Conversation

@mdeshp11
Copy link

@mdeshp11 mdeshp11 commented Aug 7, 2025

Description

This PR implements Task #5: Report Bundle (report.zip) as part of the DreamLayer open source challenge. It adds a one-click report generation feature that packages all necessary artifacts from a generation run into a single, portable report.zip.

Changes Made

  • Added generate_report.py to generate report.zip containing:
    • config.json
    • results.csv
    • grids/<images>
    • README.txt
  • Created test under tests-unit/report_bundle_test/ to verify:
    • All CSV paths resolve to real files
    • Required schema is present
  • Added Flask backend route: POST /api/generate-report
  • Created React button component GenerateReportButton.tsx
  • Integrated the button into the UI (Index.tsx)
  • Button shows alert upon success/failure and hits the backend route

Evidence Required ✅

UI Screenshot

UI Screenshot

Generated Image

Generated Image

Logs

✅ Report generated at: C:/Users/milin/OneDrive/Documents/Projects/DreamLayer/ComfyUI/utils/sample_data/report/report.zip
![report-generation](https://github.com/user-attachments/assets/1afa7941-2464-451f-8727-11a2063c103e)

## Summary by Sourcery

Implement a one-click report bundle generation feature by adding a Python script to assemble report.zip, exposing backend API endpoints, integrating a React UI button, and validating functionality with unit tests.

New Features:
- Add generate_report.py script to package config.json, results.csv, grid images, and a README into report.zip
- Expose POST /api/generate-report and internal /generate_report endpoints in Flask and ComfyUI backends to trigger report generation
- Create GenerateReportButton React component and integrate it into the main UI for one-click report creation

Tests:
- Add unit tests to verify report.zip creation, required files presence, and correct inclusion of referenced images

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added a "Generate Report" button to the main interface, allowing users to generate and download a zipped report of inference results, configurations, and related images.
  * Introduced backend API endpoints to handle report generation requests and return status messages.
  * Included a new workflow example and updated configuration options for enhanced customization.

* **Bug Fixes**
  * Minor whitespace cleanup for improved code consistency.

* **Documentation**
  * Added README files describing the contents and usage of the generated report bundles.

* **Tests**
  * Introduced unit tests to verify the integrity and contents of the generated report archive.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Aug 7, 2025

Reviewer's Guide

Introduces a one-click report bundle feature by adding a Python script that packages inference artifacts into report.zip, exposing API endpoints in both the Flask backend and ComfyUI’s internal server to trigger generation, and integrating a React button in the UI; includes unit tests verifying the ZIP contents.

Sequence diagram for frontend-triggered report bundle generation

sequenceDiagram
    actor User
    participant Frontend as React UI
    participant Backend as Flask API
    participant Script as generate_report.py
    User->>Frontend: Clicks Generate Report button
    Frontend->>Backend: POST /api/generate-report
    Backend->>Script: Run generate_report.py (subprocess)
    Script-->>Backend: Report.zip created (stdout)
    Backend-->>Frontend: JSON response (success/failure)
    Frontend-->>User: Show alert (success/failure)
Loading

Class diagram for new GenerateReportButton React component

classDiagram
    class GenerateReportButton {
      +handleGenerateReport()
      +render()
    }
Loading

Class diagram for generate_report.py script structure

classDiagram
    class generate_report {
      +create_report()
    }
Loading

File-Level Changes

Change Details Files
Report bundle generator script and unit tests
  • Create generate_report.py to assemble report.zip with config.json, results.csv, referenced images, and README
  • Implement zip logic using pathlib, csv parsing, and zipfile module
  • Add unit tests to verify presence of required files and image entries in the ZIP
ComfyUI/utils/generate_report.py
ComfyUI/tests-unit/report_bundle_test/test_generate_report.py
Backend API endpoints for report generation
  • Add POST /api/generate-report route in Flask with subprocess call and JSON success/error responses
  • Introduce /generate_report POST route in ComfyUI internal aiohttp server using subprocess.run for script invocation
  • Include error handling for CalledProcessError and generic exceptions
dream_layer_backend/dream_layer.py
ComfyUI/api_server/routes/internal/internal_routes.py
Frontend integration with Generate Report button
  • Implement GenerateReportButton.tsx component to call the new report endpoint and show alerts based on response
  • Import and render the report button in Index.tsx under the Generation Modules section
dream_layer_frontend/src/components/GenerateReportButton.tsx
dream_layer_frontend/src/pages/Index.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 7, 2025

Walkthrough

This update introduces a complete report generation feature spanning backend, frontend, and utility layers. New endpoints allow report creation via API calls, a React button triggers the process, and a utility script assembles a zipped bundle with results and configuration. Supporting tests, workflow, and configuration files were also added or updated.

Changes

Cohort / File(s) Change Summary
Backend API: Report Generation Endpoints
ComfyUI/api_server/routes/internal/internal_routes.py, dream_layer_backend/dream_layer.py
Added POST endpoints (/generate_report and /api/generate-report) that execute the generate_report.py script via subprocess, returning JSON responses with the outcome. Error handling for subprocess failures is included.
Report Generation Utility
ComfyUI/utils/generate_report.py
New script to generate a zipped report bundle containing inference results, configuration, images, and a README. Handles file existence checks and zip creation.
Frontend Integration
dream_layer_frontend/src/components/GenerateReportButton.tsx, dream_layer_frontend/src/pages/Index.tsx
Added a React button component that calls the backend report endpoint and displays result alerts. Integrated the button into the main page below navigation tabs.
Unit Test for Report Bundle
ComfyUI/tests-unit/report_bundle_test/test_generate_report.py
New test checks the existence and contents of the generated report ZIP, verifying required files and referenced images are present.
Workflow & Sample Data
ComfyUI/user/default/workflows/test.json, ComfyUI/utils/sample_data/config.json
Added JSON files defining node graphs and workflows for image generation in ComfyUI, used for testing and sample data.
Report Bundle Contents
ComfyUI/utils/report/README.txt, ComfyUI/utils/report/report/README.txt, ComfyUI/utils/report/report/config.json
Added README and config files describing the report bundle contents and providing a sample node graph configuration for image generation.
Settings Update
ComfyUI/user/default/comfy.settings.json
Added new configuration keys for color palette, release version, timestamp, and node library bookmarks.

Sequence Diagram(s)

Report Generation Flow (Frontend to Backend to Utility Script)

sequenceDiagram
    participant User
    participant Frontend (React)
    participant Backend (Flask API)
    participant Utility Script (generate_report.py)
    User->>Frontend (React): Click "Generate Report" button
    Frontend->>Backend (Flask API): POST /api/generate-report
    Backend->>Utility Script (generate_report.py): Run script via subprocess
    Utility Script-->>Backend: Return stdout or error
    Backend-->>Frontend: JSON response (success/error)
    Frontend-->>User: Alert with result message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A bunny with code in its paw,
Pressed a button—report, hurrah!
From frontend to backend, scripts zipped with care,
Bundles of data and configs to share.
With tests to ensure all files are in place,
This update brings smiles to the rabbit’s face!
🐇📦✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@sourcery-ai sourcery-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.

Hey @mdeshp11 - I've reviewed your changes - here's some feedback:

Blocking issues:

  • function generate_report is defined inside a function but never used (link)
  • Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)
  • Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)

General comments:

  • The change from if os.environ.get(...) to if True: in dream_layer.py forces CPU mode unconditionally—restore the environment-based check or make CPU mode configurable.
  • The generate_report endpoint implementation is duplicated in both the Flask backend and ComfyUI internal routes—consider centralizing this logic into a shared function or service.
  • In GenerateReportButton.tsx the API URL is hard-coded to http://localhost:5002—externalize the base URL into configuration or use a relative path for better environment flexibility.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The change from `if os.environ.get(...)` to `if True:` in dream_layer.py forces CPU mode unconditionally—restore the environment-based check or make CPU mode configurable.
- The `generate_report` endpoint implementation is duplicated in both the Flask backend and ComfyUI internal routes—consider centralizing this logic into a shared function or service.
- In GenerateReportButton.tsx the API URL is hard-coded to http://localhost:5002—externalize the base URL into configuration or use a relative path for better environment flexibility.

## Individual Comments

### Comment 1
<location> `dream_layer_backend/dream_layer.py:91` </location>
<code_context>

 # Check for environment variable to force ComfyUI CPU mode
-if os.environ.get('DREAMLAYER_COMFYUI_CPU_MODE', 'false').lower() == 'true':
+if True:
     print("Forcing ComfyUI to run in CPU mode as requested.")
     sys.argv.append('--cpu')
</code_context>

<issue_to_address>
Hardcoded CPU mode activation may not be intended for production.

Replacing the environment variable check with 'if True:' forces CPU mode in all cases, overriding user or deployment settings. If this is intentional for development, please clarify with a comment or revert to the original check for production use.
</issue_to_address>

### Comment 2
<location> `dream_layer_backend/dream_layer.py:329` </location>
<code_context>
+@app.route('/api/generate-report', methods=['POST'])
+def handle_generate_report():
+    try:
+        script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
+        result = subprocess.run(["python", script_path], capture_output=True, text=True, check=True)
+        return jsonify({
</code_context>

<issue_to_address>
Backslash in path may cause issues on non-Windows systems.

Use os.path.join or pathlib.Path to ensure the path works across all operating systems.
</issue_to_address>

### Comment 3
<location> `dream_layer_backend/dream_layer.py:330` </location>
<code_context>
+def handle_generate_report():
+    try:
+        script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
+        result = subprocess.run(["python", script_path], capture_output=True, text=True, check=True)
+        return jsonify({
+            "status": "success",
</code_context>

<issue_to_address>
Invoking 'python' may not use the correct interpreter.

Use sys.executable instead of 'python' to ensure the subprocess runs with the same interpreter as the parent process.

Suggested implementation:

```python
        result = subprocess.run([sys.executable, script_path], capture_output=True, text=True, check=True)

```

```python
    print("Forcing ComfyUI to run in CPU mode as requested.")
    sys.argv.append('--cpu')

import sys

```
</issue_to_address>

### Comment 4
<location> `ComfyUI/api_server/routes/internal/internal_routes.py:73` </location>
<code_context>
+        async def generate_report(request):
+            try:
+                script_path = Path(__file__).parent.parent.parent / "utils" / "generate_report.py"
+                result = subprocess.run(["python", str(script_path)], capture_output=True, text=True, check=True)
+                return web.json_response({
+                    "status": "success",
</code_context>

<issue_to_address>
Subprocess call may not use the correct Python interpreter.

Consider replacing 'python' with sys.executable to ensure the subprocess uses the current Python interpreter.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
                result = subprocess.run(["python", str(script_path)], capture_output=True, text=True, check=True)
=======
                import sys
                result = subprocess.run([sys.executable, str(script_path)], capture_output=True, text=True, check=True)
>>>>>>> REPLACE

</suggested_fix>

### Comment 5
<location> `ComfyUI/utils/generate_report.py:41` </location>
<code_context>
+                        zipf.write(image_file, arcname=f"grids/{image_file.name}")
+
+        # Add readme
+        readme_path = REPORT_DIR / "README.txt"
+        with open(readme_path, 'w') as f:
+            f.write(README_CONTENT)
+        zipf.write(readme_path, arcname="README.txt")
+
+    print(f"Report generated at: {REPORT_ZIP.resolve()}")
</code_context>

<issue_to_address>
Temporary README.txt file is left in the report directory.

Consider writing the README directly to the zip with ZipFile.writestr, or deleting the temporary file after archiving to avoid clutter in REPORT_DIR.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
        # Add readme
        readme_path = REPORT_DIR / "README.txt"
        with open(readme_path, 'w') as f:
            f.write(README_CONTENT)
        zipf.write(readme_path, arcname="README.txt")
=======
        # Add readme directly to the zip
        zipf.writestr("README.txt", README_CONTENT)
>>>>>>> REPLACE

</suggested_fix>

### Comment 6
<location> `ComfyUI/tests-unit/report_bundle_test/test_generate_report.py:20` </location>
<code_context>
+        assert "README.txt" in names, "Missing README.txt in ZIP"
+
+        # Check image references in CSV exist in ZIP
+        with zipf.open("results.csv") as csvfile:
+            reader = csv.DictReader(line.decode('utf-8') for line in csvfile)
+            for row in reader:
+                image_name = f"grids/{row['image_file']}"
</code_context>

<issue_to_address>
Potential issue with reading CSV from ZIP file.

Using `io.TextIOWrapper` to wrap the file object ensures proper handling of newlines and encodings, making CSV reading more reliable.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
        with zipf.open("results.csv") as csvfile:
            reader = csv.DictReader(line.decode('utf-8') for line in csvfile)
            for row in reader:
                image_name = f"grids/{row['image_file']}"
                assert image_name in names, f"Missing image file {image_name} in ZIP"
=======
        with zipf.open("results.csv") as csvfile:
            with io.TextIOWrapper(csvfile, encoding='utf-8', newline='') as textfile:
                reader = csv.DictReader(textfile)
                for row in reader:
                    image_name = f"grids/{row['image_file']}"
                    assert image_name in names, f"Missing image file {image_name} in ZIP"
>>>>>>> REPLACE

</suggested_fix>

## Security Issues

### Issue 1
<location> `ComfyUI/api_server/routes/internal/internal_routes.py:69` </location>

<issue_to_address>
**security (python.lang.maintainability.useless-inner-function):** function `generate_report` is defined inside a function but never used

*Source: opengrep*
</issue_to_address>

### Issue 2
<location> `ComfyUI/api_server/routes/internal/internal_routes.py:73` </location>

<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

*Source: opengrep*
</issue_to_address>

### Issue 3
<location> `dream_layer_backend/dream_layer.py:330` </location>

<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

*Source: opengrep*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.


# Check for environment variable to force ComfyUI CPU mode
if os.environ.get('DREAMLAYER_COMFYUI_CPU_MODE', 'false').lower() == 'true':
if True:
Copy link
Contributor

Choose a reason for hiding this comment

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

issue: Hardcoded CPU mode activation may not be intended for production.

Replacing the environment variable check with 'if True:' forces CPU mode in all cases, overriding user or deployment settings. If this is intentional for development, please clarify with a comment or revert to the original check for production use.

@app.route('/api/generate-report', methods=['POST'])
def handle_generate_report():
try:
script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
Copy link
Contributor

Choose a reason for hiding this comment

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

issue: Backslash in path may cause issues on non-Windows systems.

Use os.path.join or pathlib.Path to ensure the path works across all operating systems.

def handle_generate_report():
try:
script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
result = subprocess.run(["python", script_path], capture_output=True, text=True, check=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (bug_risk): Invoking 'python' may not use the correct interpreter.

Use sys.executable instead of 'python' to ensure the subprocess runs with the same interpreter as the parent process.

Suggested implementation:

        result = subprocess.run([sys.executable, script_path], capture_output=True, text=True, check=True)
    print("Forcing ComfyUI to run in CPU mode as requested.")
    sys.argv.append('--cpu')

import sys

async def generate_report(request):
try:
script_path = Path(__file__).parent.parent.parent / "utils" / "generate_report.py"
result = subprocess.run(["python", str(script_path)], capture_output=True, text=True, check=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (bug_risk): Subprocess call may not use the correct Python interpreter.

Consider replacing 'python' with sys.executable to ensure the subprocess uses the current Python interpreter.

Suggested change
result = subprocess.run(["python", str(script_path)], capture_output=True, text=True, check=True)
import sys
result = subprocess.run([sys.executable, str(script_path)], capture_output=True, text=True, check=True)

Comment on lines +40 to +44
# Add readme
readme_path = REPORT_DIR / "README.txt"
with open(readme_path, 'w') as f:
f.write(README_CONTENT)
zipf.write(readme_path, arcname="README.txt")
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Temporary README.txt file is left in the report directory.

Consider writing the README directly to the zip with ZipFile.writestr, or deleting the temporary file after archiving to avoid clutter in REPORT_DIR.

Suggested change
# Add readme
readme_path = REPORT_DIR / "README.txt"
with open(readme_path, 'w') as f:
f.write(README_CONTENT)
zipf.write(readme_path, arcname="README.txt")
# Add readme directly to the zip
zipf.writestr("README.txt", README_CONTENT)

Comment on lines +69 to +84
@self.routes.post('/generate_report')
async def generate_report(request):
try:
script_path = Path(__file__).parent.parent.parent / "utils" / "generate_report.py"
result = subprocess.run(["python", str(script_path)], capture_output=True, text=True, check=True)
return web.json_response({
"status": "success",
"message": "Report generated successfully.",
"output": result.stdout
})
except subprocess.CalledProcessError as e:
return web.json_response({
"status": "error",
"message": "Report generation failed.",
"error": e.stderr
}, status=500)
Copy link
Contributor

Choose a reason for hiding this comment

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

security (python.lang.maintainability.useless-inner-function): function generate_report is defined inside a function but never used

Source: opengrep

async def generate_report(request):
try:
script_path = Path(__file__).parent.parent.parent / "utils" / "generate_report.py"
result = subprocess.run(["python", str(script_path)], capture_output=True, text=True, check=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Source: opengrep

def handle_generate_report():
try:
script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
result = subprocess.run(["python", script_path], capture_output=True, text=True, check=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Source: opengrep

Comment on lines +22 to +24
for row in reader:
image_name = f"grids/{row['image_file']}"
assert image_name in names, f"Missing image file {image_name} in ZIP"
Copy link
Contributor

Choose a reason for hiding this comment

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

issue (code-quality): Avoid loops in tests. (no-loop-in-tests)

ExplanationAvoid complex code, like loops, in test functions.

Google's software engineering guidelines says:
"Clear tests are trivially correct upon inspection"
To reach that avoid complex code in tests:

  • loops
  • conditionals

Some ways to fix this:

  • Use parametrized tests to get rid of the loop.
  • Move the complex logic into helpers.
  • Move the complex part into pytest fixtures.

Complexity is most often introduced in the form of logic. Logic is defined via the imperative parts of programming languages such as operators, loops, and conditionals. When a piece of code contains logic, you need to do a bit of mental computation to determine its result instead of just reading it off of the screen. It doesn't take much logic to make a test more difficult to reason about.

Software Engineering at Google / Don't Put Logic in Tests

Comment on lines 90 to 93
# Check for environment variable to force ComfyUI CPU mode
if os.environ.get('DREAMLAYER_COMFYUI_CPU_MODE', 'false').lower() == 'true':
if True:
print("Forcing ComfyUI to run in CPU mode as requested.")
sys.argv.append('--cpu')
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (code-quality): Remove redundant conditional (remove-redundant-if)

Suggested change
# Check for environment variable to force ComfyUI CPU mode
if os.environ.get('DREAMLAYER_COMFYUI_CPU_MODE', 'false').lower() == 'true':
if True:
print("Forcing ComfyUI to run in CPU mode as requested.")
sys.argv.append('--cpu')
print("Forcing ComfyUI to run in CPU mode as requested.")
sys.argv.append('--cpu')

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
ComfyUI/utils/report/README.txt (1)

1-7: Remove duplicate README files in utils/report

Both ComfyUI/utils/report/README.txt and ComfyUI/utils/report/report/README.txt contain identical content and are not referenced anywhere in the codebase. Maintaining two copies can lead to drift and confusion.

• Locations to address:

  • ComfyUI/utils/report/README.txt
  • ComfyUI/utils/report/report/README.txt

Action: Remove one of these files (or consolidate them) unless there’s a specific reason to keep both, and update any documentation or packaging scripts accordingly.

♻️ Duplicate comments (1)
ComfyUI/utils/report/report/config.json (1)

1-385: Same observations as the sample_data copy

All remarks left on utils/sample_data/config.json (duplicate UUID, hard-coded checkpoint, duplicated file) apply here verbatim. Please address them once at the source of truth to avoid split-brain edits.

🧹 Nitpick comments (9)
ComfyUI/utils/report/report/README.txt (1)

1-7: LGTM! Consider adding more detailed descriptions.

The README clearly describes the report bundle contents and aligns well with the PR objectives for generating comprehensive report bundles.

Consider adding more detailed descriptions to help users understand the bundle contents better:

 # DreamLayer Inference Report

 This bundle contains:
-- Inference results (results.csv)
-- Configuration used (config.json)
-- Grid images with seeds and parameters
+- Inference results (results.csv) - Generated image metadata including paths, parameters, and settings
+- Configuration used (config.json) - ComfyUI workflow configuration that produced these results  
+- Grid images with seeds and parameters - Visual outputs from the generation process
dream_layer_frontend/src/pages/Index.tsx (1)

59-62: LGTM! Well-integrated button placement.

The GenerateReportButton is appropriately placed in the UI hierarchy between navigation and content, with proper styling using the my-4 margin class. The placement makes sense for a global report generation feature.

Consider adding semantic meaning to the wrapper div:

-          {/* Generate Report Button */}
-          <div className="my-4">
+          {/* Generate Report Button */}
+          <div className="my-4" role="toolbar" aria-label="Report generation actions">
             <GenerateReportButton />
           </div>
ComfyUI/tests-unit/report_bundle_test/test_generate_report.py (1)

26-29: Add missing newline at end of file.

The success message is appropriate for standalone test execution, but the file should end with a newline as flagged by static analysis.

Apply this diff:

 if __name__ == "__main__":
-    test_report_zip()
+    test_report_zip()
+
dream_layer_frontend/src/components/GenerateReportButton.tsx (1)

4-21: Consider improving URL configuration and user feedback.

The async handler logic is solid, but consider these improvements:

  1. Hardcoded URL: The localhost URL should be configurable via environment variables for different environments.
  2. User feedback: Using alert() is not very user-friendly. Consider using toast notifications or inline status messages.

For the URL, consider using an environment variable:

-      const res = await fetch("http://localhost:5002/api/generate-report", {
+      const res = await fetch(`${process.env.REACT_APP_API_URL || 'http://localhost:5002'}/api/generate-report`, {
ComfyUI/api_server/routes/internal/internal_routes.py (1)

91-91: Add missing newline at end of file.

The file should end with a newline as flagged by static analysis.

Apply this diff:

-        return self._app
+        return self._app
+
ComfyUI/utils/generate_report.py (2)

1-5: Remove unused imports.

Static analysis correctly identified that os and json imports are unused in this file.

Apply this diff:

-import os
 import csv
-import json
 import zipfile
 from pathlib import Path

48-49: Add missing newline at end of file.

The main execution block is correct, but the file should end with a newline as flagged by static analysis.

Apply this diff:

 if __name__ == "__main__":
-    create_report()
+    create_report()
+
ComfyUI/utils/sample_data/config.json (2)

168-168: Absolute/implicit model filename reduces portability

"v1-5-pruned-emaonly.safetensors" assumes the file exists in the current ComfyUI checkpoint search path.
For users cloning the repo or running in CI this model may be missing, causing graph load failures.

Recommend:

-        "v1-5-pruned-emaonly.safetensors"
+        "./checkpoints/v1-5-pruned-emaonly.safetensors"   # or make path configurable

… or resolve the checkpoint via an environment variable / CLI argument instead of a hard-coded relative name.


1-385: Duplicate graph JSON – consider de-duplication

This file is byte-for-byte identical to utils/report/report/config.json. Keeping two copies:

  • Bloats the repo (future edits must touch both).
  • Risks them silently diverging.

If they serve different purposes (sample vs. report template) store a single canonical JSON and reference it from both locations (symlink, import at runtime, or copy in the report generator).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e628e6 and 1a8984d.

⛔ Files ignored due to path filters (7)
  • ComfyUI/utils/report/report.zip is excluded by !**/*.zip
  • ComfyUI/utils/report/report/grids/grid_001.png is excluded by !**/*.png
  • ComfyUI/utils/report/report/grids/grid_002.png is excluded by !**/*.png
  • ComfyUI/utils/report/report/results.csv is excluded by !**/*.csv
  • ComfyUI/utils/sample_data/grid_001.png is excluded by !**/*.png
  • ComfyUI/utils/sample_data/grid_002.png is excluded by !**/*.png
  • ComfyUI/utils/sample_data/results.csv is excluded by !**/*.csv
📒 Files selected for processing (12)
  • ComfyUI/api_server/routes/internal/internal_routes.py (2 hunks)
  • ComfyUI/tests-unit/report_bundle_test/test_generate_report.py (1 hunks)
  • ComfyUI/user/default/comfy.settings.json (1 hunks)
  • ComfyUI/user/default/workflows/test.json (1 hunks)
  • ComfyUI/utils/generate_report.py (1 hunks)
  • ComfyUI/utils/report/README.txt (1 hunks)
  • ComfyUI/utils/report/report/README.txt (1 hunks)
  • ComfyUI/utils/report/report/config.json (1 hunks)
  • ComfyUI/utils/sample_data/config.json (1 hunks)
  • dream_layer_backend/dream_layer.py (2 hunks)
  • dream_layer_frontend/src/components/GenerateReportButton.tsx (1 hunks)
  • dream_layer_frontend/src/pages/Index.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: in report_bundler/bundler.py, the required_columns set intentionally contains only essential fields ...
Learnt from: rachanavarsha
PR: DreamLayer-AI/DreamLayer#80
File: report_bundler/bundler.py:7-7
Timestamp: 2025-08-06T18:59:31.412Z
Learning: In report_bundler/bundler.py, the REQUIRED_COLUMNS set intentionally contains only essential fields (image_path, sampler, steps, cfg, preset, seed) needed for bundling logic. Additional columns like width, height, grid_label, and notes are treated as optional metadata.

Applied to files:

  • ComfyUI/utils/report/README.txt
  • ComfyUI/utils/report/report/README.txt
🪛 Ruff (0.12.2)
ComfyUI/tests-unit/report_bundle_test/test_generate_report.py

26-26: print found

Remove print

(T201)


29-29: No newline at end of file

Add trailing newline

(W292)

ComfyUI/api_server/routes/internal/internal_routes.py

91-91: No newline at end of file

Add trailing newline

(W292)

ComfyUI/utils/generate_report.py

1-1: os imported but unused

Remove unused import: os

(F401)


3-3: json imported but unused

Remove unused import: json

(F401)


46-46: print found

Remove print

(T201)


49-49: No newline at end of file

Add trailing newline

(W292)

dream_layer_backend/dream_layer.py

329-329: SyntaxError: Got unexpected unicode

🔇 Additional comments (18)
dream_layer_frontend/src/pages/Index.tsx (1)

13-13: LGTM! Clean component import.

The import statement correctly references the new GenerateReportButton component using appropriate relative path.

ComfyUI/user/default/comfy.settings.json (1)

2-8: Timestamp Verified – Approving Configuration Updates

The provided timestamp (1754554707284 ms) converts to 2025-08-07 08:18:27 UTC, which is within the expected range. All added settings—including color palette, version, timestamp, and the “KSamplerAdvanced” bookmark—are valid and consistent with ComfyUI conventions.

ComfyUI/tests-unit/report_bundle_test/test_generate_report.py (5)

1-4: LGTM!

The imports are appropriate and all are used within the test function.


5-8: LGTM!

The path construction using pathlib is clean and the relative navigation to find the report.zip file is correct.


9-9: LGTM!

The assertion with descriptive error message is appropriate for testing file existence.


11-17: LGTM!

The ZIP file validation logic is comprehensive and uses good practices like context managers and descriptive assertions.


19-24: LGTM!

The CSV validation logic effectively ensures data integrity by verifying that all referenced images are included in the ZIP. The text decoding handling is correctly implemented for reading CSV from within the ZIP file.

dream_layer_frontend/src/components/GenerateReportButton.tsx (3)

1-3: LGTM!

Standard React component setup with appropriate imports and functional component syntax.


23-30: LGTM!

The button implementation is well-styled with appropriate hover states and visual feedback. The emoji icon adds a nice touch to the UI.


32-33: LGTM!

Standard React component export.

ComfyUI/api_server/routes/internal/internal_routes.py (2)

7-8: LGTM!

The new imports are appropriate for the route functionality that executes external scripts with path manipulation.


69-84: LGTM!

The route implementation is well-structured with:

  • Correct path navigation to the generate_report.py script
  • Appropriate subprocess execution parameters for capturing output
  • Proper error handling with CalledProcessError
  • Consistent JSON response format with appropriate HTTP status codes
dream_layer_backend/dream_layer.py (1)

91-93: Verify the unconditional CPU mode change.

The condition was changed from an environment variable check to if True:, which means CPU mode will always be forced. Please confirm if this is intentional or if it should revert to the original conditional logic.

If this was meant to be conditional, apply this diff:

-if True:
+if os.environ.get('FORCE_CPU_MODE', '').lower() == 'true':
ComfyUI/utils/generate_report.py (4)

7-18: LGTM!

The path definitions using pathlib are clean and the README content appropriately describes the report bundle contents.


20-23: LGTM!

Proper directory creation and ZIP file handling with compression and context manager usage.


24-38: LGTM!

The file inclusion logic properly handles optional files and maintains the correct directory structure in the ZIP. The CSV processing ensures all referenced images are included in the bundle.


40-46: LGTM!

The README creation and completion logic is sound. The print statement provides useful feedback for a utility script, which is appropriate despite static analysis flagging it.

ComfyUI/utils/sample_data/config.json (1)

2-2: Hard-coded UUID collides with another config file

Both utils/sample_data/config.json and utils/report/report/config.json embed the same "id": "cc1b2b54-eec0-4305-ae97-16299b26e39a".
If these configs are ever loaded simultaneously (e.g., listed in a UI, imported into the DB, etc.), the duplicate primary key may clash or overwrite metadata.

  • Generate a fresh UUID for one of the files or drop the id field if it is not required at runtime.
  • Consider adding a brief comment in the README explaining that the UUID is arbitrary.

@@ -0,0 +1 @@
{"id":"cc1b2b54-eec0-4305-ae97-16299b26e39a","revision":0,"last_node_id":12,"last_link_id":12,"nodes":[{"id":8,"type":"VAEDecode","pos":[1385.1756591796875,225.75196838378906],"size":[210,46],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":7},{"localized_name":"vae","name":"vae","type":"VAE","link":11}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","slot_index":0,"links":[9]}],"properties":{"Node name for S&R":"VAEDecode"},"widgets_values":[]},{"id":5,"type":"EmptyLatentImage","pos":[488.48797607421875,706.76806640625],"size":[315,106],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"batch_size","name":"batch_size","type":"INT","widget":{"name":"batch_size"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","slot_index":0,"links":[2]}],"properties":{"Node name for S&R":"EmptyLatentImage"},"widgets_values":[512,512,1]},{"id":7,"type":"CLIPTextEncode","pos":[413.4464416503906,393.6659240722656],"size":[425.27801513671875,180.6060791015625],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":10},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","slot_index":0,"links":[6]}],"properties":{"Node name for S&R":"CLIPTextEncode"},"widgets_values":["text, watermark"],"color":"#323","bgcolor":"#535"},{"id":4,"type":"CheckpointLoaderSimple","pos":[12.355875015258789,538.53125],"size":[315,98],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"ckpt_name","name":"ckpt_name","type":"COMBO","widget":{"name":"ckpt_name"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","slot_index":0,"links":[12]},{"localized_name":"CLIP","name":"CLIP","type":"CLIP","slot_index":1,"links":[3,10]},{"localized_name":"VAE","name":"VAE","type":"VAE","slot_index":2,"links":[11]}],"properties":{"Node name for S&R":"CheckpointLoaderSimple"},"widgets_values":["v1-5-pruned-emaonly.safetensors"]},{"id":9,"type":"SaveImage","pos":[1456.6739501953125,425.198486328125],"size":[210,270],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":9},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null}],"outputs":[],"properties":{},"widgets_values":["ComfyUI"]},{"id":3,"type":"KSampler","pos":[1028.920166015625,474.3313293457031],"size":[315,262],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":12},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":4},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":6},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":2},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"cfg","name":"cfg","type":"FLOAT","widget":{"name":"cfg"},"link":null},{"localized_name":"sampler_name","name":"sampler_name","type":"COMBO","widget":{"name":"sampler_name"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"denoise","name":"denoise","type":"FLOAT","widget":{"name":"denoise"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","slot_index":0,"links":[7]}],"properties":{"Node name for S&R":"KSampler"},"widgets_values":[157166686672613,"randomize",20,8,"euler","normal",1]},{"id":6,"type":"CLIPTextEncode","pos":[436.2958984375,132.760009765625],"size":[422.84503173828125,164.31304931640625],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":3},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","slot_index":0,"links":[4]}],"properties":{"Node name for S&R":"CLIPTextEncode"},"widgets_values":["cute little golden retriever puppies"],"color":"#223","bgcolor":"#335"}],"links":[[2,5,0,3,3,"LATENT"],[3,4,1,6,0,"CLIP"],[4,6,0,3,1,"CONDITIONING"],[6,7,0,3,2,"CONDITIONING"],[7,3,0,8,0,"LATENT"],[9,8,0,9,0,"IMAGE"],[10,4,1,7,0,"CLIP"],[11,4,2,8,1,"VAE"],[12,4,0,3,0,"MODEL"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6115909044841489,"offset":[522.8425740808559,15.336086631059548]}},"version":0.4} No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Improve JSON formatting and validate hardcoded references.

This minified JSON is difficult to read and maintain. Consider formatting it for better readability, and verify that hardcoded references like "v1-5-pruned-emaonly.safetensors" correspond to actual available models.

Apply this formatting for better readability:

-{"id":"cc1b2b54-eec0-4305-ae97-16299b26e39a","revision":0,"last_node_id":12,"last_link_id":12,"nodes":[...
+{
+  "id": "cc1b2b54-eec0-4305-ae97-16299b26e39a",
+  "revision": 0,
+  "last_node_id": 12,
+  "last_link_id": 12,
+  "nodes": [
+    ...
+  ],
+  ...
+}

Verify that the referenced model and workflow components exist:


🏁 Script executed:

#!/bin/bash
# Verify model file and workflow validity
echo "Checking for referenced model file..."
fd "v1-5-pruned-emaonly.safetensors" --type f

echo "Validating JSON structure..."
python3 -c "
import json
import sys
try:
    with open('ComfyUI/user/default/workflows/test.json', 'r') as f:
        workflow = json.load(f)
    print(f'Valid JSON with {len(workflow.get(\"nodes\", []))} nodes')
    
    # Check for required node types
    node_types = [node.get('type') for node in workflow.get('nodes', [])]
    required_types = ['CheckpointLoaderSimple', 'CLIPTextEncode', 'KSampler', 'VAEDecode', 'SaveImage']
    missing = [t for t in required_types if t not in node_types]
    if missing:
        print(f'Missing node types: {missing}')
    else:
        print('All required node types present')
except Exception as e:
    print(f'JSON validation failed: {e}')
    sys.exit(1)
"

Length of output: 1034


Ensure JSON readability and model availability

The workflow JSON is valid and includes all required nodes, but it’s still minified and references a model file that isn’t present in the repo. Please:

  • Format ComfyUI/user/default/workflows/test.json for readability:

    -{"id":"cc1b2b54-eec0-4305-ae97-16299b26e39a","revision":0,"last_node_id":12,"last_link_id":12,"nodes":[...],"version":0.4}
    +{
    +  "id": "cc1b2b54-eec0-4305-ae97-16299b26e39a",
    +  "revision": 0,
    +  "last_node_id": 12,
    +  "last_link_id": 12,
    +  "nodes": [
    +    {
    +      "id": 4,
    +      "type": "CheckpointLoaderSimple",
    +      "widgets_values": ["v1-5-pruned-emaonly.safetensors"],
    +      ...
    +    },
    +    ...
    +  ],
    +  "version": 0.4
    +}
  • Verify or include the referenced model:

    • The script fd "v1-5-pruned-emaonly.safetensors" --type f returned no matches.
    • Either add v1-5-pruned-emaonly.safetensors to your model directory, update the filename to one that exists, or mock the checkpoint for testing.

ComfyUI workflows should be both maintainable and immediately executable without missing dependencies.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In ComfyUI/user/default/workflows/test.json at line 1, the JSON content is
minified and references a model file "v1-5-pruned-emaonly.safetensors" that is
missing from the repository. To fix this, pretty-print the JSON to improve
readability by formatting it with proper indentation and line breaks.
Additionally, verify the presence of the referenced model file in the model
directory; if it is missing, either add the actual
"v1-5-pruned-emaonly.safetensors" file, update the JSON to reference an existing
model file, or create a mock checkpoint file for testing purposes to ensure the
workflow can run without missing dependencies.

Comment on lines +326 to +346
@app.route('/api/generate-report', methods=['POST'])
def handle_generate_report():
try:
script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
result = subprocess.run(["python", script_path], capture_output=True, text=True, check=True)
return jsonify({
"status": "success",
"message": "Report generated successfully.",
"output": result.stdout
})
except subprocess.CalledProcessError as e:
return jsonify({
"status": "error",
"message": f"Failed to generate report: {e.stderr}"
}), 500
except Exception as e:
return jsonify({
"status": "error",
"message": f"Unexpected error: {str(e)}"
}), 500

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the path construction syntax error.

The path construction has a critical syntax error with literal backslashes and will not work cross-platform.

Apply this diff to fix the path construction:

-        script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
+        script_path = os.path.join(os.path.dirname(__file__), '..', 'ComfyUI', 'utils', 'generate_report.py')

This uses proper path separators that work cross-platform and fixes the unicode syntax error flagged by static analysis.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@app.route('/api/generate-report', methods=['POST'])
def handle_generate_report():
try:
script_path = os.path.join(os.path.dirname(__file__), '..\ComfyUI\utils\generate_report.py')
result = subprocess.run(["python", script_path], capture_output=True, text=True, check=True)
return jsonify({
"status": "success",
"message": "Report generated successfully.",
"output": result.stdout
})
except subprocess.CalledProcessError as e:
return jsonify({
"status": "error",
"message": f"Failed to generate report: {e.stderr}"
}), 500
except Exception as e:
return jsonify({
"status": "error",
"message": f"Unexpected error: {str(e)}"
}), 500
@app.route('/api/generate-report', methods=['POST'])
def handle_generate_report():
try:
script_path = os.path.join(os.path.dirname(__file__), '..', 'ComfyUI', 'utils', 'generate_report.py')
result = subprocess.run(
["python", script_path],
capture_output=True,
text=True,
check=True
)
return jsonify({
"status": "success",
"message": "Report generated successfully.",
"output": result.stdout
})
except subprocess.CalledProcessError as e:
return jsonify({
"status": "error",
"message": f"Failed to generate report: {e.stderr}"
}), 500
except Exception as e:
return jsonify({
"status": "error",
"message": f"Unexpected error: {str(e)}"
}), 500
🧰 Tools
🪛 Ruff (0.12.2)

329-329: SyntaxError: Got unexpected unicode

🤖 Prompt for AI Agents
In dream_layer_backend/dream_layer.py around lines 326 to 346, the script_path
is constructed using a string with literal backslashes, causing syntax errors
and cross-platform issues. Replace the string concatenation with os.path.join
using separate arguments for each path component to ensure proper path
separators and avoid unicode errors. This will make the path construction
cross-platform compatible and fix the syntax error.

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.

1 participant