plua 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plua-0.1.0/PKG-INFO +420 -0
- plua-0.1.0/README.md +382 -0
- plua-0.1.0/pyproject.toml +78 -0
- plua-0.1.0/setup.cfg +4 -0
- plua-0.1.0/src/plua/__init__.py +12 -0
- plua-0.1.0/src/plua/__main__.py +8 -0
- plua-0.1.0/src/plua/api_server.py +726 -0
- plua-0.1.0/src/plua/fibaro_api_endpoints.py +3508 -0
- plua-0.1.0/src/plua/fibaro_api_models.py +45427 -0
- plua-0.1.0/src/plua/generate_typed_fibaro_api.py +558 -0
- plua-0.1.0/src/plua/html_extensions.py +270 -0
- plua-0.1.0/src/plua/interpreter.py +376 -0
- plua-0.1.0/src/plua/luafuns_lib.py +962 -0
- plua-0.1.0/src/plua/main.py +280 -0
- plua-0.1.0/src/plua/network.py +1893 -0
- plua-0.1.0/src/plua/repl.py +248 -0
- plua-0.1.0/src/plua/runtime.py +383 -0
- plua-0.1.0/src/plua/syncsocket.py +301 -0
- plua-0.1.0/src/plua.egg-info/PKG-INFO +420 -0
- plua-0.1.0/src/plua.egg-info/SOURCES.txt +33 -0
- plua-0.1.0/src/plua.egg-info/dependency_links.txt +1 -0
- plua-0.1.0/src/plua.egg-info/entry_points.txt +2 -0
- plua-0.1.0/src/plua.egg-info/requires.txt +14 -0
- plua-0.1.0/src/plua.egg-info/top_level.txt +2 -0
- plua-0.1.0/tests/test_advanced_network.py +400 -0
- plua-0.1.0/tests/test_api_server.py +199 -0
- plua-0.1.0/tests/test_callbacks.py +161 -0
- plua-0.1.0/tests/test_config.py +110 -0
- plua-0.1.0/tests/test_dotenv.py +129 -0
- plua-0.1.0/tests/test_file_operations.py +184 -0
- plua-0.1.0/tests/test_interpreter.py +59 -0
- plua-0.1.0/tests/test_network.py +239 -0
- plua-0.1.0/tests/test_performance.py +317 -0
- plua-0.1.0/tests/test_runtime.py +67 -0
- plua-0.1.0/tests/test_websocket.py +361 -0
plua-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plua
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python-Lua async runtime with timer support
|
|
5
|
+
Author-email: Jan Gabrielsson <jan@gabrielsson.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jangabrielsson/plua
|
|
8
|
+
Project-URL: Documentation, https://github.com/jangabrielsson/plua/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/jangabrielsson/plua.git
|
|
10
|
+
Project-URL: Issues, https://github.com/jangabrielsson/plua/issues
|
|
11
|
+
Keywords: lua,async,timer,coroutine
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: lupa>=2.0
|
|
26
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
27
|
+
Requires-Dist: fastapi>=0.104.0
|
|
28
|
+
Requires-Dist: uvicorn[standard]>=0.24.0
|
|
29
|
+
Requires-Dist: psutil>=5.9.0
|
|
30
|
+
Requires-Dist: requests>=2.28.0
|
|
31
|
+
Requires-Dist: httpx>=0.24.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
35
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
36
|
+
Requires-Dist: flake8>=5.0; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
38
|
+
|
|
39
|
+
# plua
|
|
40
|
+
|
|
41
|
+
Python-Lua async runtime with timer support
|
|
42
|
+
|
|
43
|
+
## Overview
|
|
44
|
+
|
|
45
|
+
plua is a Python package that provides an async runtime environment for executing Lua scripts with JavaScript-like timer functionality. It bridges Python's asyncio with Lua's coroutines, allowing for sophisticated async programming patterns.
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- **Interactive REPL**: Lua-like interactive prompt with plua features
|
|
50
|
+
- **JavaScript-like timers**: `setTimeout()` and `clearTimeout()` in Lua
|
|
51
|
+
- **Async/await bridge**: Python asyncio integrated with Lua coroutines
|
|
52
|
+
- **Context safety**: All Lua execution happens in the same Python context
|
|
53
|
+
- **Timer management**: Named asyncio tasks with cancellation support
|
|
54
|
+
- **Network simulation**: Built-in `netWorkIO()` function for async operations
|
|
55
|
+
- **Coroutine support**: Full Lua coroutine functionality with yielding
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Install in development mode
|
|
61
|
+
pip install -e .
|
|
62
|
+
|
|
63
|
+
# Or install with development dependencies
|
|
64
|
+
pip install -e ".[dev]"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
### Command Line Usage
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Interactive REPL (no file specified)
|
|
73
|
+
plua
|
|
74
|
+
|
|
75
|
+
# Run a Lua file directly
|
|
76
|
+
plua script.lua
|
|
77
|
+
|
|
78
|
+
# Run with time limit
|
|
79
|
+
plua --duration 10 script.lua
|
|
80
|
+
|
|
81
|
+
# Start with REST API server
|
|
82
|
+
plua --api # Default port 8888
|
|
83
|
+
plua --api 8877 # Custom port
|
|
84
|
+
plua --api 8877 --api-host 127.0.0.1 # Custom host and port
|
|
85
|
+
|
|
86
|
+
# Run built-in examples
|
|
87
|
+
plua --example 2 --duration 10
|
|
88
|
+
plua --example cancel --duration 5
|
|
89
|
+
|
|
90
|
+
# Run inline Lua code
|
|
91
|
+
plua --script 'print("Hello from Lua"); setTimeout(function() print("Timer fired!") end, 1000)' --duration 5
|
|
92
|
+
|
|
93
|
+
# Run forever (until Ctrl+C)
|
|
94
|
+
plua script.lua
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Interactive REPL
|
|
98
|
+
|
|
99
|
+
plua provides an interactive REPL (Read-Eval-Print Loop) when no Lua file is specified:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
$ plua
|
|
103
|
+
Plua v0.1.0 Interactive REPL
|
|
104
|
+
Running Lua 5.4 with async runtime support
|
|
105
|
+
|
|
106
|
+
Quick start:
|
|
107
|
+
help() - Show available commands
|
|
108
|
+
print('Hello, plua!') - Basic Lua
|
|
109
|
+
json.encode({name='test'}) - JSON encoding
|
|
110
|
+
setTimeout(function() print('Hi!') end, 2000) - Async timer
|
|
111
|
+
|
|
112
|
+
Type 'exit()' or press Ctrl+D to quit
|
|
113
|
+
|
|
114
|
+
plua> print("Hello, world!")
|
|
115
|
+
Hello, world!
|
|
116
|
+
plua> x = 42
|
|
117
|
+
plua> x + 10
|
|
118
|
+
52
|
|
119
|
+
plua> client = net.HTTPClient()
|
|
120
|
+
plua> setTimeout(function() print("Timer fired!") end, 2000)
|
|
121
|
+
plua> -- Timer fires after 2 seconds
|
|
122
|
+
Timer fired!
|
|
123
|
+
plua> exit()
|
|
124
|
+
Goodbye!
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The REPL supports:
|
|
128
|
+
- All plua features (timers, JSON, networking)
|
|
129
|
+
- Built-in `json` and `net` modules (no require needed)
|
|
130
|
+
- Persistent variables and functions
|
|
131
|
+
- Background async operations
|
|
132
|
+
- Built-in help and state inspection
|
|
133
|
+
- Error recovery
|
|
134
|
+
|
|
135
|
+
### Python API Usage
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
import asyncio
|
|
139
|
+
from plua import LuaAsyncRuntime
|
|
140
|
+
|
|
141
|
+
async def main():
|
|
142
|
+
runtime = LuaAsyncRuntime()
|
|
143
|
+
|
|
144
|
+
script = """
|
|
145
|
+
print("Starting...")
|
|
146
|
+
setTimeout(function()
|
|
147
|
+
print("Timer 1 fired!")
|
|
148
|
+
setTimeout(function() print("Timer 2 fired!") end, 500)
|
|
149
|
+
end, 1000)
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
await runtime.start(script=script, duration=5)
|
|
153
|
+
|
|
154
|
+
asyncio.run(main())
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### REST API Server
|
|
158
|
+
|
|
159
|
+
plua includes a built-in REST API server that allows remote execution of Lua code:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Start plua with REST API on default port 8888
|
|
163
|
+
plua --api
|
|
164
|
+
|
|
165
|
+
# Start on specific port with custom host
|
|
166
|
+
plua --api 8877 --api-host 127.0.0.1
|
|
167
|
+
|
|
168
|
+
# Access the web REPL interface
|
|
169
|
+
# Open browser to: http://localhost:8888/web
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### API Endpoints
|
|
173
|
+
|
|
174
|
+
- `GET /` - API information and available endpoints
|
|
175
|
+
- `GET /web` - Web-based REPL interface
|
|
176
|
+
- `POST /plua/execute` - Execute Lua code remotely
|
|
177
|
+
- `GET /plua/status` - Get runtime status
|
|
178
|
+
- `GET /plua/info` - Get API and runtime information
|
|
179
|
+
|
|
180
|
+
#### Web REPL
|
|
181
|
+
|
|
182
|
+
The web REPL provides a modern browser-based interface for plua:
|
|
183
|
+
|
|
184
|
+
- **HTML Rendering**: Supports HTML tags in output for colored and formatted text
|
|
185
|
+
- **Real-time Execution**: Share interpreter state with local REPL
|
|
186
|
+
- **Timer Support**: Background timers work seamlessly
|
|
187
|
+
- **Modern UI**: Responsive design with syntax highlighting
|
|
188
|
+
|
|
189
|
+
Example HTML output in web REPL:
|
|
190
|
+
```lua
|
|
191
|
+
print("<font color='red'>Red text</font>")
|
|
192
|
+
print("<b>Bold text</b> | <i>Italic text</i>")
|
|
193
|
+
print("<span style='background-color: yellow;'>Highlighted</span>")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Remote Code Execution
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Execute Lua code via API
|
|
200
|
+
curl -X POST http://localhost:8888/plua/execute \
|
|
201
|
+
-H 'Content-Type: application/json' \
|
|
202
|
+
-d '{"code":"return 2 + 2", "timeout": 10.0}'
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Response:
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"success": true,
|
|
209
|
+
"result": 4,
|
|
210
|
+
"output": "",
|
|
211
|
+
"error": null,
|
|
212
|
+
"execution_time_ms": 0.123,
|
|
213
|
+
"request_id": "uuid-here"
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The API server and local REPL share the same Lua interpreter instance, so:
|
|
218
|
+
- Variables persist between API calls and REPL commands
|
|
219
|
+
- Timers set via API continue running in the background
|
|
220
|
+
- State is shared seamlessly between web and terminal interfaces
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Lua API
|
|
224
|
+
|
|
225
|
+
### Timer Functions
|
|
226
|
+
|
|
227
|
+
```lua
|
|
228
|
+
-- Set a timer
|
|
229
|
+
local timer_id = setTimeout(function()
|
|
230
|
+
print("This runs after 1 second")
|
|
231
|
+
end, 1000)
|
|
232
|
+
|
|
233
|
+
-- Cancel a timer
|
|
234
|
+
clearTimeout(timer_id)
|
|
235
|
+
|
|
236
|
+
-- Sleep (yields current coroutine)
|
|
237
|
+
sleep(500) -- Sleep for 500ms
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Network Simulation
|
|
241
|
+
|
|
242
|
+
```lua
|
|
243
|
+
-- Simulate async network operation
|
|
244
|
+
netWorkIO(function(data)
|
|
245
|
+
print("Received data:", data) -- "xyz" after 1 second
|
|
246
|
+
end)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Coroutines
|
|
250
|
+
|
|
251
|
+
```lua
|
|
252
|
+
local function asyncFunction()
|
|
253
|
+
print("Start")
|
|
254
|
+
local co = coroutine.running()
|
|
255
|
+
|
|
256
|
+
setTimeout(function()
|
|
257
|
+
coroutine.resume(co, "result")
|
|
258
|
+
end, 1000)
|
|
259
|
+
|
|
260
|
+
local result = coroutine.yield()
|
|
261
|
+
print("Got result:", result)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
coroutine.wrap(asyncFunction)()
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Examples
|
|
268
|
+
|
|
269
|
+
### Example 1: Repeating Timer
|
|
270
|
+
|
|
271
|
+
```lua
|
|
272
|
+
local function loop()
|
|
273
|
+
print("PING")
|
|
274
|
+
netWorkIO(function(data)
|
|
275
|
+
print("Network callback", data)
|
|
276
|
+
end)
|
|
277
|
+
setTimeout(loop, 5000) -- Repeat every 5 seconds
|
|
278
|
+
end
|
|
279
|
+
setTimeout(loop, 100) -- Start after 100ms
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Example 2: Coroutine Yielding
|
|
283
|
+
|
|
284
|
+
```lua
|
|
285
|
+
local function foo()
|
|
286
|
+
print("A")
|
|
287
|
+
local co = coroutine.running()
|
|
288
|
+
setTimeout(function()
|
|
289
|
+
coroutine.resume(co)
|
|
290
|
+
print("D")
|
|
291
|
+
end, 1000)
|
|
292
|
+
print("B")
|
|
293
|
+
coroutine.yield()
|
|
294
|
+
print("C")
|
|
295
|
+
end
|
|
296
|
+
coroutine.wrap(foo)()
|
|
297
|
+
-- Output: A, B, (1 second delay), D, C
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Example 3: Timer Cancellation
|
|
301
|
+
|
|
302
|
+
```lua
|
|
303
|
+
-- Set a timer
|
|
304
|
+
local timer_id = setTimeout(function()
|
|
305
|
+
print("This should be cancelled!")
|
|
306
|
+
end, 2000)
|
|
307
|
+
|
|
308
|
+
-- Cancel it after 500ms
|
|
309
|
+
setTimeout(function()
|
|
310
|
+
print("Cancelling timer")
|
|
311
|
+
clearTimeout(timer_id)
|
|
312
|
+
end, 500)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Architecture
|
|
316
|
+
|
|
317
|
+
### Components
|
|
318
|
+
|
|
319
|
+
- **`LuaInterpreter`**: Manages Lua runtime and script execution
|
|
320
|
+
- **`LuaAsyncRuntime`**: Handles asyncio integration and timer management
|
|
321
|
+
- **Timer System**: Maps Lua timer calls to Python asyncio tasks
|
|
322
|
+
- **Callback Loop**: Executes Lua callbacks in the correct context
|
|
323
|
+
|
|
324
|
+
### Flow
|
|
325
|
+
|
|
326
|
+
1. Lua calls `setTimeout(callback, delay)`
|
|
327
|
+
2. Python creates an asyncio task that waits for `delay`
|
|
328
|
+
3. When timer fires, Python queues the callback ID
|
|
329
|
+
4. Callback loop executes the Lua callback in the same context
|
|
330
|
+
5. Lua coroutines can yield and be resumed by timers
|
|
331
|
+
|
|
332
|
+
## 📚 Documentation
|
|
333
|
+
|
|
334
|
+
Comprehensive documentation is available in the `docs/` directory:
|
|
335
|
+
|
|
336
|
+
- **[Documentation Index](docs/README.md)** - Complete documentation overview
|
|
337
|
+
- **[Web REPL HTML Examples](docs/WEB_REPL_HTML_EXAMPLES.md)** - HTML rendering guide for web interface
|
|
338
|
+
- **[REST API Documentation](docs/api/README.md)** - Complete API reference and examples
|
|
339
|
+
- **[Developer Documentation](docs/dev/README.md)** - Implementation details and development guides
|
|
340
|
+
|
|
341
|
+
### Quick Links
|
|
342
|
+
- 🚀 **Getting Started**: This README
|
|
343
|
+
- 🌐 **Web Interface**: [Web REPL Examples](docs/WEB_REPL_HTML_EXAMPLES.md)
|
|
344
|
+
- 📡 **API Integration**: [REST API Docs](docs/api/README.md)
|
|
345
|
+
- 🔧 **Contributing**: [Developer Docs](docs/dev/README.md)
|
|
346
|
+
|
|
347
|
+
## Fibaro HC3 API Integration
|
|
348
|
+
|
|
349
|
+
plua includes a comprehensive Fibaro Home Center 3 API emulator with full type safety and documentation:
|
|
350
|
+
|
|
351
|
+
### Generated API Endpoints
|
|
352
|
+
|
|
353
|
+
The Fibaro API endpoints are auto-generated from official Swagger/OpenAPI specifications:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Regenerate Fibaro API endpoints and models
|
|
357
|
+
python src/plua/generate_typed_fibaro_api.py
|
|
358
|
+
|
|
359
|
+
# Generate with custom paths
|
|
360
|
+
python src/plua/generate_typed_fibaro_api.py --docs-dir fibaro_api_docs --output-dir src/plua
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
This generates:
|
|
364
|
+
- **`fibaro_api_models.py`**: 305+ Pydantic models with full type validation
|
|
365
|
+
- **`fibaro_api_endpoints.py`**: 267+ FastAPI endpoints with proper documentation
|
|
366
|
+
|
|
367
|
+
### Fibaro API Features
|
|
368
|
+
|
|
369
|
+
- **Complete Coverage**: All major Fibaro HC3 API endpoints
|
|
370
|
+
- **Type Safety**: Full Pydantic validation for request/response data
|
|
371
|
+
- **Swagger Documentation**: Auto-generated API docs at `/docs`
|
|
372
|
+
- **Lua Integration**: All calls delegate to `_PY.fibaro_api_hook(method, path, data)`
|
|
373
|
+
- **Easy Testing**: Use web interface or curl to test endpoints
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Start server with Fibaro API
|
|
377
|
+
plua --api-port 8888 --fibaro
|
|
378
|
+
|
|
379
|
+
# Test an endpoint
|
|
380
|
+
curl -X GET "http://localhost:8888/devices" -H "accept: application/json"
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Development
|
|
384
|
+
|
|
385
|
+
### Setup Development Environment
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
# Clone and setup
|
|
389
|
+
git clone <repository>
|
|
390
|
+
cd plua
|
|
391
|
+
pip install -e ".[dev]"
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Run Tests
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
pytest
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Code Formatting
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
black src/ tests/
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Type Checking
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
mypy src/
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## License
|
|
413
|
+
|
|
414
|
+
MIT License
|
|
415
|
+
|
|
416
|
+
## Requirements
|
|
417
|
+
|
|
418
|
+
- Python 3.8+
|
|
419
|
+
- lupa (Python-Lua bridge)
|
|
420
|
+
- asyncio (built-in)
|