Skip to content

Conversation

@simonw
Copy link
Owner

@simonw simonw commented Dec 31, 2025

The quickjs.html demo has a fetch() mechanism which allows code in QuickJS to make fetch() calls

Figure out if the same thing could be added to micropython.html

Wether or not that is possible update micropython.html to have the same design as quickjs.html and also add comparable examples with similar buttons to run them

  • Redesign micropython.html to match quickjs.html layout and styling
  • Add fetch() capability via MicroPython's js module interop (import js; await js.fetch())
  • Add example buttons with Python equivalents: Hello World, Factorial, Fibonacci, List Comprehensions, Dictionaries & JSON, Prime Numbers, String Fun, FizzBuzz, Sorting, Classes, and Fetch Data
  • Add URL hash management for code sharing
  • Add copy button for output
  • Add keyboard shortcuts (Ctrl/Cmd+Enter to run, Tab for indentation)
  • Add fetch test to the test suite
  • Preserve existing Run Tests functionality

https://gisthost.github.io/?2c4d32513791acd6b1d9a5fed34a158d/index.html

- Redesign micropython.html to match quickjs.html layout and styling
- Add fetch() capability via MicroPython's js module interop (import js; await js.fetch())
- Add example buttons with Python equivalents: Hello World, Factorial, Fibonacci, List Comprehensions, Dictionaries & JSON, Prime Numbers, String Fun, FizzBuzz, Sorting, Classes, and Fetch Data
- Add URL hash management for code sharing
- Add copy button for output
- Add keyboard shortcuts (Ctrl/Cmd+Enter to run, Tab for indentation)
- Add fetch test to the test suite
- Preserve existing Run Tests functionality
@claude
Copy link
Contributor

claude bot commented Dec 31, 2025

Claude Code is working…

I'll analyze this and get back to you.

View job run

@simonw
Copy link
Owner Author

simonw commented Dec 31, 2025

The print() thing doen't add newlines - the classes example put out:

Buddy is 3 years oldBuddy says woof!Max is 5 years oldMax says woof!

With linebuffer:true, each stdout callback receives a complete line
but without the trailing newline character. Add \n when capturing.
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 31, 2025

Deploying tools with  Cloudflare Pages  Cloudflare Pages

Latest commit: cffdaf9
Status: ✅  Deploy successful!
Preview URL: https://62013f6d.tools-b1q.pages.dev
Branch Preview URL: https://claude-micropython-fetch-sup.tools-b1q.pages.dev

View logs

@claude
Copy link
Contributor

claude bot commented Dec 31, 2025

Claude finished @simonw's task —— View job


PR Review: Add fetch support to MicroPython demo

Review Checklist:

  • Read and understand the micropython.html changes
  • Analyze code quality and best practices
  • Check for potential bugs (including the print() newline issue)
  • Review security considerations
  • Assess performance implications
  • Evaluate test coverage
  • Provide comprehensive feedback

Summary

This PR successfully adapts the QuickJS demo design to MicroPython, maintaining visual consistency while implementing Python-specific functionality. The implementation is well-structured and addresses the core requirements.

Identified Issues

🐛 Critical Bug: Missing Newlines in Print Output

Confirmed Issue: As noted by simonw, print() statements don't add newlines. In the Classes example:

  • Expected: Each print on a new line
  • Actual: Buddy is 3 years oldBuddy says woof!Max is 5 years oldMax says woof!

Root Cause (micropython.html:454-461): The output capture function automatically adds newlines to captured text:

function pushOutput(kind, text) {
    if (!text) return;
    if (activeCapture) {
        activeCapture[kind] += text + '\n';  // ← Adds newline to every output
    }
    // ...
}

Solution: Remove the automatic newline addition in pushOutput() since MicroPython's print() already includes newlines when using linebuffer: true.

Code Quality & Best Practices

✅ Strengths

  • Excellent design consistency: UI/UX perfectly matches quickjs.html
  • Proper Python examples: All 11 examples are idiomatic Python with good educational value
  • Clean architecture: Well-structured code with clear separation of concerns
  • Good error handling: Comprehensive try-catch blocks and user feedback
  • Accessibility: Proper semantic HTML, keyboard shortcuts, focus management

🔄 Areas for Improvement

1. Fetch Implementation Inconsistency (micropython.html:369-382):

# Uses await js.fetch() (async) vs QuickJS synchronous fetch()
response = await js.fetch(repo_url)
data = json.loads(await response.text())
  • Issue: Different from QuickJS sync API, may confuse users switching between demos
  • Consideration: This is actually correct for Python async/await patterns

2. Error Message Clarity (micropython.html:523-530):

if (err?.stdout) output += String(err.stdout).trimEnd();
if (err?.stderr) {
    if (output) output += '\n';
    output += String(err.stderr).trimEnd();
}
if (output) output += '\n';
output += String(err?.message ?? err);
  • Issue: Potential for confusing error output mixing stdout, stderr, and error messages
  • Suggestion: Clearer formatting/labeling of different output streams

Security Considerations

✅ Security Strengths

  • Sandboxed execution: MicroPython WebAssembly provides isolation
  • No eval() usage: Code execution goes through proper MicroPython API
  • Safe clipboard API: Proper error handling for clipboard operations
  • URL encoding: Proper encoding/decoding for hash-based code sharing

⚠️ Minor Security Notes

  • Network requests: fetch() can make arbitrary HTTP requests, but this is expected functionality
  • No CSP headers: Consider adding Content-Security-Policy for defense-in-depth

Performance Considerations

✅ Performance Strengths

  • CDN loading: Uses jsDelivr CDN for fast MicroPython loading
  • Efficient DOM updates: Minimal DOM manipulation
  • Proper cleanup: Good memory management in execution

🔄 Performance Notes

  • Large bundle: MicroPython WASM is ~1.5MB (acceptable for functionality provided)
  • Execution timing: Good performance monitoring with execution time display

Test Coverage

✅ Test Coverage Strengths

  • Comprehensive test suite: 7 well-designed tests covering:
    • Basic output (print('hello world'))
    • Arithmetic operations
    • State persistence
    • Exception handling
    • Standard library (math module)
    • Unicode support
    • New: Fetch functionality via js module

📈 Test Quality

  • Good assertions: Tests verify exact expected output
  • Error scenarios: Includes exception testing
  • Real functionality: fetch test uses actual GitHub API
  • Clear reporting: Good pass/fail feedback with details

Recommendations

🔥 High Priority

  1. Fix print() newline bug by modifying pushOutput() function
  2. Consider fetch API consistency - document the async difference from QuickJS

🔧 Medium Priority

  1. Improve error message formatting for clearer debugging
  2. Add CSP headers for additional security

💡 Low Priority

  1. Consider adding more Python-specific examples (decorators, context managers)

Overall Assessment

Score: 8.5/10

This is a high-quality implementation that successfully achieves the PR objectives. The critical print() newline bug prevents it from being perfect, but once fixed, this will be an excellent Python code playground. The design consistency, comprehensive examples, and solid test coverage make this a valuable addition.

The fetch implementation via import js; await js.fetch() is actually more idiomatic for Python than forcing a synchronous API, and the comprehensive test suite provides confidence in the implementation.


Branch: claude/micropython-fetch-support-Q19mR
Job run: https://github.com/simonw/tools/actions/runs/20624391812

@simonw simonw merged commit 33c2309 into main Dec 31, 2025
2 of 4 checks passed
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