118 lines
4.3 kB
1
defmodule BlogWeb.PythonLive.Index do
2
use BlogWeb, :live_view
3
alias Blog.PythonRunner
4
require Logger
5
6
@python_example """
7
import random
8
9
# Roll some dice
10
dice = [random.randint(1, 6) for _ in range(3)]
11
f"You rolled: {dice} (sum: {sum(dice)})"
12
"""
13
14
@impl true
15
def mount(_params, _session, socket) do
16
# Get Python environment information
17
python_info = PythonRunner.get_python_info()
18
19
# Initialize the Python environment
20
python_status = case PythonRunner.init() do
21
:ok -> :available
22
{:error, reason} -> {:unavailable, reason}
23
end
24
25
# Get the hello world result if Python is available
26
hello_result = PythonRunner.hello_world()
27
28
{:ok, assign(socket,
29
code: @python_example,
30
result: "",
31
hello_result: hello_result,
32
python_status: python_status,
33
python_info: python_info
34
)}
35
end
36
37
@impl true
38
def handle_event("run-code", %{"code" => code}, socket) do
39
result = PythonRunner.run_code(code)
40
Logger.info("Python code execution result: #{inspect(result)}")
41
{:noreply, assign(socket, result: result)}
42
end
43
44
@impl true
45
def render(assigns) do
46
~H"""
47
<div class="container mx-auto p-4">
48
<h1 class="text-2xl font-bold mb-4">Python Integration Demo</h1>
49
50
<div class="mb-6 p-4 rounded bg-gray-100">
51
<h2 class="text-xl font-semibold mb-2">Python Status</h2>
52
<%= if @python_status == :available do %>
53
<div class="text-green-600 font-bold">✅ Python is available</div>
54
<% else %>
55
<div class="text-red-600 font-bold">❌ Python is unavailable</div>
56
<div class="mt-2 p-2 bg-yellow-100 rounded">
57
<p>Reason: <%= if is_tuple(@python_status), do: elem(@python_status, 1), else: @python_status %></p>
58
</div>
59
<% end %>
60
61
<div class="mt-4">
62
<h3 class="text-lg font-semibold">Python Environment Info</h3>
63
<div class="bg-white p-2 rounded mt-2 text-sm font-mono">
64
<div><span class="font-bold">Pythonx Version:</span> <%= @python_info.pythonx_version %></div>
65
<div><span class="font-bold">Python Path:</span> <%= @python_info.python_path %></div>
66
<div><span class="font-bold">Cache Dir:</span> <%= @python_info.cache_dir %></div>
67
<div><span class="font-bold">Cache Exists:</span> <%= @python_info.cache_dir_exists %></div>
68
<div><span class="font-bold">Cache Writable:</span> <%= @python_info.cache_dir_writable %></div>
69
<div><span class="font-bold">/tmp Writable:</span> <%= @python_info.tmp_writable %></div>
70
<div><span class="font-bold">/app/.cache Writable:</span> <%= @python_info.app_cache_writable %></div>
71
<div><span class="font-bold">Current Dir Writable:</span> <%= @python_info.current_dir_writable %></div>
72
<div><span class="font-bold">Inets Started:</span> <%= @python_info.inets_started %></div>
73
<div><span class="font-bold">On Gigalixir:</span> <%= @python_info.on_gigalixir %></div>
74
</div>
75
</div>
76
</div>
77
78
<div class="mb-6 p-4 rounded bg-gray-100">
79
<h2 class="text-xl font-semibold mb-2">Hello from Python</h2>
80
<div class="p-2 bg-white rounded border">
81
<%= @hello_result %>
82
</div>
83
</div>
84
85
<div class="mb-6">
86
<h2 class="text-xl font-semibold mb-2">Try Python Code</h2>
87
<form phx-submit="run-code">
88
<div class="mb-4">
89
<textarea
90
name="code"
91
rows="10"
92
class="w-full p-2 border rounded font-mono"
93
placeholder="Enter Python code here"
94
disabled={@python_status != :available}
95
><%= @code %></textarea>
96
</div>
97
<button
98
type="submit"
99
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
100
disabled={@python_status != :available}
101
>
102
Run Code
103
</button>
104
</form>
105
</div>
106
107
<%= if @result != "" do %>
108
<div class="mt-4">
109
<h3 class="text-lg font-semibold mb-2">Result</h3>
110
<div class="p-4 bg-gray-100 rounded font-mono whitespace-pre-wrap">
111
<%= @result %>
112
</div>
113
</div>
114
<% end %>
115
</div>
116
"""
117
end
118
end
119