Skip to main content
Build a production-ready online coding platform where students can submit code, run test cases, and receive instant feedback. This cookbook demonstrates how to create a platform similar to LeetCode or HackerRank using HopX for secure code execution.

Overview

Online coding platforms enable students to practice programming by solving problems and submitting solutions. The platform executes code securely, validates against test cases, and provides feedback.

Prerequisites

  • HopX API key (Get one here)
  • Python 3.8+ or Node.js 16+
  • Understanding of test case validation
  • Basic knowledge of educational platform architecture

Architecture

┌──────────────┐
│   Student    │ Submits code
└──────┬───────┘


┌─────────────────┐
│  Platform API   │ Validates & queues
└──────┬──────────┘


┌─────────────────┐
│  HopX Sandbox   │ Execute code
└──────┬──────────┘


┌─────────────────┐
│  Test Runner    │ Validate results
└──────┬──────────┘


┌─────────────────┐
│  Feedback       │ Return results
└─────────────────┘

Implementation

Step 1: Basic Code Submission and Execution

Create a system that accepts code submissions and executes them:
from hopx_ai import Sandbox
import os
import json
from typing import Dict, List, Any

class CodingPlatform:
    def __init__(self, api_key: str):
        self.api_key = api_key
    
    def execute_submission(self, code: str, language: str, timeout: int = 10) -> Dict[str, Any]:
        """Execute student code submission"""
        sandbox = None
        try:
            # Create isolated sandbox for this submission
            sandbox = Sandbox.create(
                template="code-interpreter",
                api_key=self.api_key,
                timeout_seconds=timeout + 5  # Extra buffer
            )
            
            # Execute code
            result = sandbox.run_code(code, language=language, timeout=timeout)
            
            return {
                "success": result.success,
                "stdout": result.stdout,
                "stderr": result.stderr,
                "exit_code": result.exit_code,
                "execution_time": result.execution_time,
                "timeout": result.execution_time >= timeout
            }
            
        except Exception as e:
            return {
                "success": False,
                "error": str(e),
                "stderr": str(e)
            }
        finally:
            if sandbox:
                sandbox.kill()
    
    def validate_solution(self, code: str, test_cases: List[Dict], language: str = "python") -> Dict[str, Any]:
        """Validate solution against test cases"""
        results = []
        all_passed = True
        
        for i, test_case in enumerate(test_cases):
            # Prepare test code
            test_code = self._prepare_test_code(code, test_case, language)
            
            # Execute
            execution_result = self.execute_submission(test_code, language, timeout=5)
            
            # Check result
            passed = self._check_test_result(execution_result, test_case)
            
            results.append({
                "test_case": i + 1,
                "passed": passed,
                "input": test_case.get("input"),
                "expected": test_case.get("expected"),
                "actual": execution_result.get("stdout", "").strip(),
                "error": execution_result.get("stderr") if not passed else None
            })
            
            if not passed:
                all_passed = False
        
        return {
            "all_passed": all_passed,
            "total_tests": len(test_cases),
            "passed_tests": sum(1 for r in results if r["passed"]),
            "results": results
        }
    
    def _prepare_test_code(self, code: str, test_case: Dict, language: str) -> str:
        """Prepare code with test case"""
        if language == "python":
            input_data = test_case.get("input", "")
            expected = test_case.get("expected", "")
            
            # Wrap student code with test
            test_code = f"""
{code}

# Test case
test_input = {input_data}
result = solution(test_input)  # Assuming function named 'solution'
expected = {expected}

if result == expected:
    print("PASS")
else:
    print(f"FAIL: Expected {{expected}}, got {{result}}")
"""
            return test_code
        else:
            # Similar for other languages
            return code
    
    def _check_test_result(self, execution_result: Dict, test_case: Dict) -> bool:
        """Check if test case passed"""
        if not execution_result.get("success"):
            return False
        
        stdout = execution_result.get("stdout", "").strip()
        return "PASS" in stdout or stdout == str(test_case.get("expected", "")).strip()

# Usage
platform = CodingPlatform(api_key=os.getenv("HOPX_API_KEY"))

# Student submission
student_code = """
def solution(nums):
    return sum(nums)
"""

# Test cases
test_cases = [
    {"input": "[1, 2, 3]", "expected": 6},
    {"input": "[10, 20, 30]", "expected": 60},
    {"input": "[]", "expected": 0}
]

# Validate
result = platform.validate_solution(student_code, test_cases)
print(json.dumps(result, indent=2))

Step 2: Multi-Language Support

Support multiple programming languages:
class MultiLanguagePlatform(CodingPlatform):
    SUPPORTED_LANGUAGES = {
        "python": {
            "template": "code-interpreter",
            "extension": ".py",
            "runner": "python"
        },
        "javascript": {
            "template": "code-interpreter",
            "extension": ".js",
            "runner": "node"
        },
        "java": {
            "template": "code-interpreter",
            "extension": ".java",
            "runner": "javac && java"
        }
    }
    
    def execute_submission(self, code: str, language: str, timeout: int = 10) -> Dict[str, Any]:
        """Execute code in specified language"""
        if language not in self.SUPPORTED_LANGUAGES:
            return {
                "success": False,
                "error": f"Unsupported language: {language}"
            }
        
        lang_config = self.SUPPORTED_LANGUAGES[language]
        sandbox = None
        
        try:
            sandbox = Sandbox.create(
                template=lang_config["template"],
                api_key=self.api_key,
                timeout_seconds=timeout + 5
            )
            
            # Write code to file
            filename = f"/workspace/solution{lang_config['extension']}"
            sandbox.files.write(filename, code)
            
            # Execute based on language
            if language == "python":
                result = sandbox.run_code(code, language="python", timeout=timeout)
            elif language == "javascript":
                result = sandbox.run_code(code, language="javascript", timeout=timeout)
            elif language == "java":
                # Compile and run Java
                compile_result = sandbox.commands.run(
                    f"javac {filename}",
                    timeout=5
                )
                if not compile_result.exit_code == 0:
                    return {
                        "success": False,
                        "stderr": compile_result.stderr,
                        "error": "Compilation failed"
                    }
                
                # Run compiled class
                result = sandbox.commands.run(
                    "java -cp /workspace Solution",
                    timeout=timeout
                )
            
            return {
                "success": result.success if hasattr(result, 'success') else result.exit_code == 0,
                "stdout": result.stdout if hasattr(result, 'stdout') else result.stdout,
                "stderr": result.stderr if hasattr(result, 'stderr') else result.stderr,
                "exit_code": result.exit_code if hasattr(result, 'exit_code') else result.exit_code,
                "language": language
            }
            
        except Exception as e:
            return {
                "success": False,
                "error": str(e),
                "language": language
            }
        finally:
            if sandbox:
                sandbox.kill()

# Usage
platform = MultiLanguagePlatform(api_key=os.getenv("HOPX_API_KEY"))

# Python submission
python_code = "print('Hello from Python!')"
result = platform.execute_submission(python_code, "python")
print(result)

# JavaScript submission
js_code = "console.log('Hello from JavaScript!');"
result = platform.execute_submission(js_code, "javascript")
print(result)

Step 3: Resource Limits and Timeout Management

Implement resource limits to prevent abuse:
class ResourceLimitedPlatform(CodingPlatform):
    def __init__(self, api_key: str, max_execution_time: int = 10, max_memory_mb: int = 512):
        super().__init__(api_key)
        self.max_execution_time = max_execution_time
        self.max_memory_mb = max_memory_mb
    
    def execute_submission(self, code: str, language: str, timeout: int = None) -> Dict[str, Any]:
        """Execute with resource limits"""
        # Enforce maximum timeout
        actual_timeout = min(timeout or self.max_execution_time, self.max_execution_time)
        
        sandbox = None
        try:
            # Create sandbox with resource limits
            sandbox = Sandbox.create(
                template="code-interpreter",  # Template defines resources
                api_key=self.api_key,
                timeout_seconds=actual_timeout + 2  # Small buffer
            )
            
            # Set environment variables for resource monitoring
            sandbox.env.set_all({
                "MAX_EXECUTION_TIME": str(actual_timeout),
                "MAX_MEMORY_MB": str(self.max_memory_mb)
            })
            
            # Execute with strict timeout
            result = sandbox.run_code(code, language=language, timeout=actual_timeout)
            
            # Check if timeout was exceeded
            if result.execution_time >= actual_timeout:
                return {
                    "success": False,
                    "error": "Execution timeout exceeded",
                    "timeout": True,
                    "execution_time": result.execution_time
                }
            
            # Check memory usage (if available)
            metrics = sandbox.get_metrics_snapshot()
            memory_used = metrics.get('memory_usage_mb', 0) if hasattr(metrics, 'get') else 0
            
            if memory_used > self.max_memory_mb:
                return {
                    "success": False,
                    "error": f"Memory limit exceeded: {memory_used}MB > {self.max_memory_mb}MB",
                    "memory_exceeded": True
                }
            
            return {
                "success": result.success,
                "stdout": result.stdout,
                "stderr": result.stderr,
                "execution_time": result.execution_time,
                "memory_used_mb": memory_used
            }
            
        except Exception as e:
            return {
                "success": False,
                "error": str(e)
            }
        finally:
            if sandbox:
                sandbox.kill()

# Usage
platform = ResourceLimitedPlatform(
    api_key=os.getenv("HOPX_API_KEY"),
    max_execution_time=5,  # 5 second limit
    max_memory_mb=256       # 256MB limit
)

result = platform.execute_submission("print('Hello')", "python")
print(result)

Step 4: Grading and Feedback System

Create a comprehensive grading system:
class GradingSystem:
    def __init__(self, platform: CodingPlatform):
        self.platform = platform
    
    def grade_submission(self, code: str, problem: Dict, language: str = "python") -> Dict[str, Any]:
        """Grade a student submission"""
        # Validate solution
        validation_result = self.platform.validate_solution(
            code,
            problem.get("test_cases", []),
            language
        )
        
        # Calculate score
        score = self._calculate_score(validation_result, problem)
        
        # Generate feedback
        feedback = self._generate_feedback(validation_result, problem)
        
        return {
            "score": score,
            "max_score": problem.get("max_score", 100),
            "percentage": (score / problem.get("max_score", 100)) * 100,
            "all_tests_passed": validation_result["all_passed"],
            "test_results": validation_result["results"],
            "feedback": feedback,
            "submission_time": self._get_timestamp()
        }
    
    def _calculate_score(self, validation_result: Dict, problem: Dict) -> float:
        """Calculate score based on test results"""
        if validation_result["all_passed"]:
            return problem.get("max_score", 100)
        
        # Partial credit based on passed tests
        passed = validation_result["passed_tests"]
        total = validation_result["total_tests"]
        max_score = problem.get("max_score", 100)
        
        return (passed / total) * max_score
    
    def _generate_feedback(self, validation_result: Dict, problem: Dict) -> str:
        """Generate feedback for student"""
        if validation_result["all_passed"]:
            return "Excellent! All test cases passed."
        
        failed_tests = [r for r in validation_result["results"] if not r["passed"]]
        feedback = f"Some test cases failed ({len(failed_tests)}/{validation_result['total_tests']}).\n\n"
        
        for test in failed_tests[:3]:  # Show first 3 failures
            feedback += f"Test {test['test_case']}: Expected {test['expected']}, got {test['actual']}\n"
            if test.get("error"):
                feedback += f"  Error: {test['error']}\n"
        
        return feedback
    
    def _get_timestamp(self) -> str:
        from datetime import datetime
        return datetime.now().isoformat()

# Usage
platform = CodingPlatform(api_key=os.getenv("HOPX_API_KEY"))
grader = GradingSystem(platform)

problem = {
    "title": "Sum of Array",
    "description": "Write a function that returns the sum of all elements in an array",
    "max_score": 100,
    "test_cases": [
        {"input": "[1, 2, 3]", "expected": 6},
        {"input": "[10, 20, 30]", "expected": 60},
        {"input": "[]", "expected": 0}
    ]
}

student_code = """
def solution(nums):
    return sum(nums)
"""

grade = grader.grade_submission(student_code, problem)
print(json.dumps(grade, indent=2))

Best Practices

Security

Always create a fresh sandbox for each student submission to ensure complete isolation between submissions.
  1. Sandbox Isolation: Never reuse sandboxes between different students
  2. Code Validation: Check for dangerous patterns before execution
  3. Resource Limits: Enforce strict timeouts and memory limits
  4. Input Sanitization: Validate all inputs before processing

Performance

Use parallel execution for multiple test cases when possible, but ensure each test case runs in isolation.
  1. Sandbox Pooling: Consider sandbox pooling for high-volume platforms
  2. Caching: Cache problem definitions and test cases
  3. Async Processing: Process submissions asynchronously for better scalability
  4. Resource Monitoring: Monitor sandbox usage and optimize accordingly

Educational Value

  1. Clear Feedback: Provide detailed, actionable feedback
  2. Progressive Difficulty: Structure problems from easy to hard
  3. Hints System: Offer hints without revealing solutions
  4. Performance Metrics: Track execution time and memory usage

Real-World Examples

This pattern is used by:
  • LeetCode: Online coding interview platform
  • HackerRank: Competitive programming platform
  • Codecademy: Interactive coding lessons
  • Educational Platforms: Various platforms that provide secure code execution for students

Next Steps

  1. Implement your problem database
  2. Add user authentication and submission tracking
  3. Create a web interface for code submission
  4. Implement leaderboards and progress tracking
  5. Add support for more programming languages