How to build an online python code editor using Ace
Agnes
Posted on February 14, 2024
In this article, you will learn how to employ the Ace library and Django framework to develop a sample Python code editor. We will cover the following :
- Creating and configuring a Django application.
- Linking the Ace library to your Django app.
- Your code editor front-end.
- Your code editor server-side.
Prerequisites
- A text editor (e.g., Visual Studio Code)
- Some basic Django framework and JavaScript knowledge.
Creating and configuring the Django project
Step 1: Open the terminal and in your root folder execute the following command.
django-admin startproject codeEditor
Note : Replace _codeEditor_
with the actual name of your app.
Step 2: Next, still in your terminal, navigate to your new project then run the command below to create a new Django app .
python manage.py startapp codeEditorApp
Note : Replace _codeEditorApp_
with the actual name of your app.
Step 3: Next, In the project settings, register your new app in INSTALLED_APPS
, as shown below.
Step 4: Navigate to your app and create a new urls.py
file.
Step 5: Back in your project, register your apps’ urls.py
in your projects’ urls.py
as shown below.
Step 6: In the app folder, create a new folder names templates
Your new project structure should look like the one shown below:
codeEditor/
__init__.py
settings.py
urls.py
wsgi.py
asgi.
codeEditorApp/
__init__.py
templates
admin.py
apps.py
models.py
tests.py
urls.py
views.py
manage.py
Step 7: Back in your project,Follow the steps highlighted here to create a virtual environment below.
Creating the code editor front-end
In the templates folder, create a new file named main.html
and add the code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Python Code Editor</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src/ace.css" type="text/css" media="screen" charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src/ace.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script type="text/javascript"> var csrftoken = getCookie('csrftoken');
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// Function to get the current time of day
function getTimeOfDay() {
var now = new Date();
var hours = now.getHours();
if (hours >= 5 && hours < 12) {
return "Good morning, ready for some Python?";
} else if (hours >= 12 && hours < 18) {
return "Good afternoon, ready for some Python?";
} else {
return "Good evening , ready for some Python?";
}
}
// Set the salutation based on the time of day
var salutation = getTimeOfDay();
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('salutation').innerText = salutation;
}); </script>
<style> body {
font-family: 'Arial', sans-serif;
background-color: #f7f7f7;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
}
h1, h2, h3 {
color: #333;
margin-bottom: 10px;
}
h1{
text-decoration: underline;
text-decoration-color: #2ecc71;
}
h2#salutation {
font-size: 24px;
color: #2ecc71;
text-align: center;
}
#editor {
height: 500px;
width: 100%;
max-width: 600px;
margin-bottom: 20px;
}
button {
padding: 10px;
font-size: 16px;
background-color: #3498db;
color: #fff;
border: none;
cursor: pointer;
left:0;
padding: 10px;
margin-bottom: 10px;
}
#outputArea {
background-color: #ecf0f1;
padding: 20px;
border-radius: 8px;
width: 100%;
max-width: 600px;
}
#output {
white-space: pre-wrap;
} </style>
</head>
<body>
<h1>Python Code Editor</h1>
<h2 id="salutation"></h2>
<div id="editor"></div>
<button onclick="runCode()">Run</button>
<div id="outputArea">
<h3>Output:</h3>
<pre id="output"></pre>
</div>
<script> // Initialize Ace code editor
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/python");
editor.setFontSize("16px");
// Function to run the code in the Ace editor
function runCode() {
var code = editor.getValue();
// Make an AJAX request to the Django server for code execution
$.ajax({
type: "POST",
url: "/run_code/", // URL of your Django view
headers: {
'X-CSRFToken': csrftoken // Include CSRF token in the request header
},
data: {
code: code,
language: 'python' // Fixed to Python
},
success: function(data) {
if (data.result) {
document.getElementById("output").innerText = data.result;
} else {
document.getElementById("output").innerText = data.error;
}
},
error: function() {
document.getElementById("output").innerText = "Error communicating with the server.";
}
});
} </script>
</body>
</html>
The above code starts off with a JavaScript function that handles user salutations , based on the time of the day they are using the editor. Next, there is both CSS and HTML code that handles the Ace code editor structure and styling. We then incorporate a simple JavaScript script which retrieves the Python code from the editor, sends an AJAX (Asynchronous JavaScript and XML) request to the Django server (/run_code/
), and handles the server's response. The server response is then displayed in the designated output area (#output
) , if the request was successful, or an error is otherwise.
Execute the command below to show what your front-end looks like
python3 manage.py runserver
Your server should display an editor similar to the one below:
Code editor server-side (Django back-end)
To make the above code editor functional, follow the steps below to build its back-end.
Step 1: Inside the apps’ views.py
, add the code below
from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import subprocess
# Create your views here.
def home(request):
return render(request, 'main.html')
@csrf_exempt
def run_code(request):
if request.method == 'POST':
try:
code = request.POST.get('code', '')
language = request.POST.get('language', '')
if language == 'python':
result = run_python_code(code)
else:
result = "Language not supported for execution."
return JsonResponse({'result': result})
except Exception as e:
return JsonResponse({'error': str(e)})
return JsonResponse({'error': 'Invalid request method'})
# Functions for python code execution
def run_python_code(code):
try:
result = subprocess.check_output(['python3', '-c', code], text=True, timeout=5)
return result
except subprocess.CalledProcessError as e:
return f"Error: {e}"
The above view handles the back-end functionalities by checking whether the code you entered follows Python syntax, then provides the appropriate JsonResponse based on the condition. If the code follows the correct Python syntax, it is then executed and the ouput is displayed in the editor.
Step 2: Next, in the apps’ urls.py
, register the url path for the newly created view, as shown below
from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', views.home, name='home'),
path("run_code/", views.run_code, name='run_code')
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Note: The same _url_
path, (_/run_code/_
) , was used in the html template.
Having done all this, your code editor should now be able to properly execute python code.
Posted on February 14, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.