63 Commits

Author SHA1 Message Date
Lerking be1af3ad05 Merge pull request 'Updated project description. /JL' (#35) from 0.3.3 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/35
2025-03-29 13:59:42 +00:00
Lerking 0c8108d4d8 Updated project description. /JL 2025-03-29 14:58:49 +01:00
Lerking bcc9b864d1 Merge pull request 'README updated. /JL' (#34) from update_readme into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/34
2025-03-28 17:29:35 +00:00
Lerking a4c552d6f5 README updated. /JL 2025-03-28 18:28:58 +01:00
Lerking 34c7927601 Merge pull request '0.3.0' (#33) from 0.3.0 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/33
2025-03-28 17:23:38 +00:00
Lerking ebf31756b5 #31 Done. /JL 2025-03-28 18:22:16 +01:00
Lerking 406c1b77ed #31 - Creating thread with callback, on pre_load(). /JL 2025-03-28 17:26:58 +01:00
Lerking 1be429c5cd Update xtendr/xtendrsystem.py 2025-03-27 20:33:19 +00:00
Lerking a093b3f56c Update plugins/example_plugin/example_plugin.py 2025-03-27 20:31:12 +00:00
Lerking 1dc0c81d84 Update plugins/example_plugin/example_plugin.py 2025-03-27 20:30:23 +00:00
Lerking 3e38cabf81 Update xtendr/xtendrsystem.py 2025-03-27 20:25:12 +00:00
Lerking 63f649af25 #31 Added **self.use_pre_load:bool = False** and pre_load() method. 2025-03-27 19:30:41 +00:00
Lerking b6efe1b1df Update xtendr/xtendrbase.py
#31 Added pre_load() method
2025-03-27 19:23:59 +00:00
Lerking c5ee073d65 Update setup.py 2025-03-27 19:20:30 +00:00
Lerking 3bcf01dc26 Merge pull request '0.2.1 Updated to include keyword arguments in run() method. /JL' (#30) from 0.2.1 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/30
2025-03-27 09:47:53 +00:00
Jan Lerking dd5904c273 0.2.1 Updated to include keyword arguments in run() method. /JL 2025-03-27 10:46:05 +01:00
Lerking b763308aa9 Merge pull request 'Added plugin.run() with arguments. /JL' (#29) from 0.2.0 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/29
2025-03-27 08:57:26 +00:00
Jan Lerking 34ba757bc6 Added plugin.run() with arguments. /JL 2025-03-27 09:35:29 +01:00
Lerking b5d2e1b0be Merge pull request '0.1.3 #26 bug-fix corrected variable name. /JL' (#28) from 0.1.3 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/28
2025-03-09 14:28:53 +00:00
Lerking d3031952bf 0.1.3 #26 bug-fix corrected variable name. /JL 2025-03-09 15:21:08 +01:00
Lerking 3312f2da28 Merge pull request '0.1.2 #26 Added possibility to choose your own plugins folder. /JL' (#27) from 0.1.2 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/27
2025-03-09 14:14:37 +00:00
Lerking a21122671d 0.1.2 #26 Added possibility to choose your own plugins folder. /JL 2025-03-09 15:06:32 +01:00
Lerking 9effa4be3e Merge pull request '0.1.1 Updated doctest. /JL' (#25) from 0.1.1 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/25
2025-03-08 17:34:52 +00:00
Lerking 217038b863 0.1.1 Updated doctest. /JL 2025-03-08 18:34:04 +01:00
Lerking 8c19c4a97b Merge pull request '0.1.0 #23 Added 'Autorun' flag to XtendRSystem Attach() method. Also added a new version() method. /JL' (#24) from 0.1.0 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/24
2025-03-08 17:28:27 +00:00
Lerking c7662a5d47 0.1.0 #23 Added 'Autorun' flag to XtendRSystem Attach() method. Also added a new version() method. /JL 2025-03-08 18:20:34 +01:00
Lerking 68d3aa3ed2 Merge pull request '0.0.9 build. /JL' (#22) from 0.0.9 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/22
2025-03-01 20:14:52 +00:00
Lerking 2ea29fe5ea 0.0.9 build. /JL 2025-03-01 21:14:15 +01:00
Lerking 1195d399b6 Merge pull request '0.0.8 update. /JL' (#21) from 0.0.8 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/21
2025-03-01 12:19:32 +00:00
Lerking b709e4d942 0.0.8 update. /JL 2025-03-01 13:18:10 +01:00
Lerking 96bb0f0f3d Merge pull request '0.0.7' (#20) from 0.0.7 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/20
2025-02-25 06:28:11 +00:00
Lerking 993617976f Add Makefile 2025-02-25 06:27:47 +00:00
Lerking 828213912e Update setup.py 2025-02-25 06:26:29 +00:00
Lerking 44136c33b8 Merge pull request 'Update setup.py' (#17) from lerking-patch-1 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/17
2025-02-25 06:22:07 +00:00
Lerking 490423e94a Update setup.py 2025-02-25 06:21:51 +00:00
Lerking fa2c25d6c5 Merge pull request 'Update setup.py' (#15) from lerking-patch-1 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/15
2025-02-24 16:08:07 +00:00
Lerking 0db2e1dfca Update setup.py 2025-02-24 16:07:16 +00:00
Lerking 7200cb0bf8 Merge pull request 'Updated. /JL' (#14) from 0.0.6 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/14
2025-02-24 11:19:02 +00:00
Jan Lerking da3d09d3b1 Updated. /JL 2025-02-24 12:17:07 +01:00
Lerking 00173e73ae Merge pull request '0.0.5' (#12) from 0.0.5 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/12
2025-02-24 08:23:28 +00:00
Jan Lerking c849d32f73 0.0.5 #8 Cleaned up unused imports. /JL 2025-02-24 09:20:08 +01:00
Lerking ffc7baa394 Update README.md 2025-02-24 08:16:07 +00:00
Lerking ea1ba5d5ab Update README.md 2025-02-24 08:15:18 +00:00
Lerking b01a9cca3e Update README.md 2025-02-24 07:29:42 +00:00
Lerking 485d7a28d8 Merge pull request 'main' (#11) from main into 0.0.5
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/11
2025-02-24 07:28:21 +00:00
Lerking f711cdcf06 Update README.md 2025-02-24 07:26:47 +00:00
Lerking 2199d18c79 Update README.md 2025-02-24 07:26:27 +00:00
Lerking d22861622b Merge pull request 'main' (#10) from main into 0.0.5
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/10
2025-02-24 07:24:30 +00:00
Lerking 13858e433f Update README.md 2025-02-24 07:23:58 +00:00
Lerking 37cad62835 Update README.md 2025-02-24 07:19:43 +00:00
Lerking b4ad8fee0c Update README.md 2025-02-24 07:19:01 +00:00
Lerking 4e51fd06f0 Update README.md 2025-02-24 07:17:57 +00:00
Lerking dd780864a6 Update README.md 2025-02-24 07:03:53 +00:00
Lerking 83db451e1b Update README.md 2025-02-24 07:03:28 +00:00
Lerking b58be97d1f Update setup.py 2025-02-24 06:53:16 +00:00
Lerking eb03302323 Update xtendr/xtendrsystem.py 2025-02-24 06:16:04 +00:00
Lerking dec115c596 Merge pull request 'v0.0.4' (#6) from v0.0.4 into main
Reviewed-on: https://gitea.com/Lerking/XtendR/pulls/6
2025-02-24 05:57:57 +00:00
Lerking 591cc49933 Update README.md 2025-02-24 05:56:26 +00:00
Lerking 36807b7aa6 Update README.md 2025-02-24 05:55:53 +00:00
Lerking afc38c32b3 Update README.md 2025-02-24 05:41:13 +00:00
Lerking 798165c501 Update README.md 2025-02-24 05:40:54 +00:00
Lerking fc247d4888 Update README.md 2025-02-24 05:39:10 +00:00
Lerking 394f72d383 Update setup.py 2025-02-24 05:19:45 +00:00
8 changed files with 114 additions and 21 deletions
+13
View File
@@ -0,0 +1,13 @@
dist:
python -m build
test:
twine upload --repository testpypi dist/*
publish:
twine upload --repository pypi dist/*
all:
$(dist)
$(test)
$(publish)
+29 -1
View File
@@ -1,3 +1,31 @@
# XtendR
A python 3 extension system to ease the use of plugins.
A very basic Python 3.12 friendly plugin system based on the K.I.S.S principle.
I was in need of a new plugin system, which should meet these requirements:
:heavy_plus_sign: Simple to use
:heavy_plus_sign: Work well with Python 3.12
:heavy_plus_sign: Maintainable - Don't expect to see new releases every month. __If it ain't broken, don't fix it!!!__
I previously used yapsy, but it doesn't meet the requirements anymore.
:x: No longer simple, and simple to use (Simplicity in use has been sacrificed for more complexity. It has become bloated)
:x: Not workink with Python 3.12
:x: No longer maintained (Hasn't been maintained for a few years)
I didn't find anything that suited my needs, so I decided to make my own plugin system.
It simply contains 2 classes, one for the plugin system and one abstraction base class for the plugins themselves.
At the moment only 4 functions are available:
- Attach - including call to pre-load data in plugin.
- Run
- Stop
- Detach
Attach and Detach are used for registrering/unregistrering a module on the system.
The Run and Stop functions are mandatory in the plugin modules.
The system expects a folder called 'plugins', placed at the root, along side your main python file.
Each plugin should be placed in subfolders, named as the plugin, inside the 'plugins' folder.
The example.py along with the plugins/example_plugin/example_plugin.py and plugins/example_plugin/example_plugin.json shows the workings of this plugin system.
+13 -2
View File
@@ -1,5 +1,9 @@
import time
from xtendr.xtendrsystem import XtendRSystem
def my_callback():
print("'example_plugin is finished pre-loading")
if __name__ == "__main__":
"""Example usage of the PluginSystem.
@@ -15,7 +19,14 @@ if __name__ == "__main__":
Detached plugin 'example_plugin'.
"""
system = XtendRSystem()
system.attach("example_plugin") # Assuming 'example_plugin/plugin_info.json' exists
system.run("example_plugin")
system.attach("example_plugin", my_callback) # Assuming 'example_plugin/plugin_info.json' exists
for i in range(3):
print(f"Main program is running iteration {i+1}...")
time.sleep(2)
system.run("example_plugin", test="Hello!")
system.stop("example_plugin")
system.run("example_plugin", 25)
system.stop("example_plugin")
system.run("example_plugin", "Hello!", 25)
system.stop("example_plugin")
system.detach("example_plugin")
+24 -2
View File
@@ -1,3 +1,5 @@
import threading
import time
from xtendr.xtendrbase import XtendRBase
class ExamplePlugin(XtendRBase):
@@ -5,13 +7,33 @@ class ExamplePlugin(XtendRBase):
Example:
>>> plugin = ExamplePlugin()
>>> plugin.run()
>>> plugin.run("Hello!", 25)
Passed arguments 2:
Argument 0: Hello!
Argument 1: 25
ExamplePlugin is running!
>>> plugin.stop()
ExamplePlugin has stopped!
"""
def run(self):
def run(self, *args, **kwargs):
arglen = len(args)
keylen = len(kwargs)
if arglen > 0:
print(f"Passed arguments {arglen}:")
for idx, a in enumerate(args):
print(f"Argument {idx}: {a}")
if keylen > 0:
print(f"Keyword arguments passed {keylen}")
if not "test" in kwargs:
raise ValueError("Didn't get expected 'test' keyword!")
for kw in kwargs:
print(f"Argument {kw}: {kwargs[kw]}")
print("ExamplePlugin is running!")
def stop(self):
print("ExamplePlugin has stopped!")
def pre_load(self, callback):
time.sleep(5) # Indicate long running pre-load.
callback()
+1
View File
@@ -0,0 +1 @@
setuptools==68.2.2
+10 -5
View File
@@ -1,19 +1,24 @@
if __name__ == "__main__":
from setuptools import setup, find_packages
from pathlib import Path
this_directory = Path(__file__).parent
long_description = (this_directory / "README.md").read_text()
setup(
name="XtendR",
version="0.0.3",
version="0.3.3.1",
packages=find_packages(),
install_requires=[],
author="Jan Lerking",
author_email="",
description="A modular plugin system for Python.",
url="",
url="https://www.gitea.com/Lerking/XtendR",
classifiers=[
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.11",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.12',
python_requires='>=3.11',
long_description=long_description,
long_description_content_type='text/markdown'
)
+6 -5
View File
@@ -1,7 +1,3 @@
import importlib
import sys
import os
import json
from abc import ABC, abstractmethod
class XtendRBase(ABC):
@@ -21,9 +17,14 @@ class XtendRBase(ABC):
Stopping TestPlugin
"""
@abstractmethod
def run(self):
def run(self, *args, **kwargs):
pass
@abstractmethod
def stop(self):
pass
@abstractmethod
def pre_load(self, *args):
pass
+18 -6
View File
@@ -2,15 +2,19 @@ import importlib
import sys
import os
import json
from abc import ABC, abstractmethod
import threading
from xtendr.xtendrbase import XtendRBase
__version__ = "0.3.3.1"
class XtendRSystem:
"""Plugin system to manage plugins.
Example:
>>> system = XtendRSystem()
>>> system.attach("example_plugin") # Assuming 'example_plugin/plugin_info.json' exists
>>> system.version()
XtendR v0.1.3
>>> system.attach("example_plugin") # Assuming 'example_plugin/example_plugin.json' exists
>>> system.run("example_plugin")
ExamplePlugin is running!
>>> system.stop("example_plugin")
@@ -18,16 +22,20 @@ class XtendRSystem:
>>> system.detach("example_plugin")
Detached plugin 'example_plugin'.
"""
def __init__(self):
def __init__(self, pluginpath = "plugins"):
self.pluginspath = pluginpath
self.plugins = {}
def attach(self, name: str) -> None:
def version(self) -> str:
return "XtendR v" + __version__
def attach(self, name: str, callback) -> None:
"""Dynamically load a plugin from its folder."""
if name in self.plugins:
print(f"Plugin '{name}' is already attached.")
return
plugin_path = os.path.join(os.getcwd(), "plugins", name)
plugin_path = os.path.join(os.getcwd(), self.pluginspath, name)
info_path = os.path.join(plugin_path, name + ".json")
print(plugin_path + "\n" + info_path)
@@ -56,9 +64,13 @@ class XtendRSystem:
self.plugins[name] = {
'instance': instance,
'running': False,
'info': plugin_info
'info': plugin_info,
'autorun': False
}
print(f"Attached plugin '{name}'.")
print(f"Running pre-load on '{name}'.")
thread = threading.Thread(target=self.plugins[name]['instance'].pre_load, args=(callback,))
thread.start()
except (ModuleNotFoundError, json.JSONDecodeError, AttributeError) as e:
print(f"Failed to attach plugin '{name}': {e}")