ERPlora SDK
Build modules for ERPlora — the modular POS system.
How It Works
The ERPlora SDK lets you create modules for ERPlora Hub locally on your machine, without needing access to the Hub source code. You develop against the SDK's dev environment (SQLite, built-in templates, PIN login), and your module code runs identically in production.
Install SDK → Create module → Develop locally → Push to GitHub → Available in Marketplace
Getting Started
1. Install the SDK
pip install erplora-sdk
2. Create a new module
erplora startmodule reservations
This generates a complete module scaffold:
reservations/
├── module.py # Metadata: name, icon, navigation, permissions
├── models.py # Django models (extend HubBaseModel)
├── views.py # Views with @htmx_view, @with_module_nav
├── urls.py # URL patterns
├── forms.py # Django forms
├── ai_tools.py # AI assistant tools
├── templates/reservations/
│ ├── pages/ # Full page templates
│ └── partials/ # HTMX partial templates
├── static/reservations/ # CSS, JS, images
├── migrations/
└── tests/
3. Start the dev server
erplora devserver
This automatically:
- Creates a SQLite database (zero configuration)
- Runs migrations for your models
- Creates a dev user with PIN: 1234
- Starts the server at http://localhost:8000
4. Develop your module
Edit your files — models, views, templates, AI tools — and see changes live at http://localhost:8000.
5. Publish when ready
git init
git add .
git commit -m "Initial module"
git remote add origin https://github.com/your-user/module-reservations.git
git push -u origin main
Register your module in the ERPlora Marketplace and it becomes available to all ERPlora Hubs via automatic sync.
What's Included
| Feature | Description |
|---|---|
| Base Models | HubBaseModel with UUID primary key, soft delete, audit trail |
| HTMX Decorators | @htmx_view for SPA navigation without writing JavaScript |
| Auth Decorators | @login_required, @permission_required, @admin_required |
| Navigation | @with_module_nav for automatic tab bar rendering |
| AI Tools | AssistantTool base class — let users interact with your module via AI chat |
| Templates | Base templates with UX CSS library (161 components, dark mode) |
| Events | Signals, hooks (WordPress-style), and UI slots for extensibility |
| Services | CSV/Excel export, image handling, file import parsing |
| Dev Server | SQLite, auto-migrations, PIN auth, module auto-discovery |
Import Compatibility
Your module code uses the exact same import paths as production ERPlora Hubs. The SDK maps them automatically:
# These work identically in the SDK and in production
from apps.core.htmx import htmx_view
from apps.core.models.base import HubBaseModel
from apps.accounts.decorators import login_required, permission_required
from apps.modules_runtime.navigation import with_module_nav
from assistant.tools import AssistantTool, register_tool
Write once, run anywhere — no code changes needed when your module goes to production.
View Pattern
Every module view follows this decorator pattern:
from apps.accounts.decorators import login_required, permission_required
from apps.modules_runtime.navigation import with_module_nav
from apps.core.htmx import htmx_view
@login_required
@permission_required('reservations.view')
@with_module_nav('reservations', 'overview')
@htmx_view('reservations/pages/overview.html', 'reservations/partials/overview.html')
def overview(request):
from .models import Reservation
return {'reservations': Reservation.objects.all()}
- Normal request (direct URL) → renders the full page template
- HTMX request (
hx-get) → renders only the partial (SPA navigation)
AI Tools
Give your module AI capabilities by defining tools in ai_tools.py:
from assistant.tools import AssistantTool, register_tool
from .models import Reservation
@register_tool
class ListReservations(AssistantTool):
name = 'reservations_list'
description = 'List upcoming reservations'
parameters = {
'type': 'object',
'properties': {
'date': {
'type': 'string',
'description': 'Filter by date (YYYY-MM-DD)',
},
},
}
def execute(self, request, date=None):
qs = Reservation.objects.filter(is_active=True)
if date:
qs = qs.filter(date=date)
return {'reservations': list(qs.values('id', 'name', 'date', 'time'))}
Users can then interact with your module through the AI assistant: "Show me today's reservations".
module.py
Every module has a module.py that defines its metadata:
from django.utils.translation import gettext_lazy as _
MODULE_ID = 'reservations'
MODULE_NAME = _('Reservations')
MENU = {
'label': _('Reservations'),
'icon': 'calendar-outline',
'order': 30,
}
NAVIGATION = [
{'label': _('Overview'), 'icon': 'home-outline', 'id': 'overview'},
{'label': _('Calendar'), 'icon': 'calendar-outline', 'id': 'calendar'},
{'label': _('Settings'), 'icon': 'settings-outline', 'id': 'settings'},
]
PERMISSIONS = [
'reservations.view',
'reservations.edit',
'reservations.delete',
]
Publishing to the Marketplace
| Type | Description | Revenue |
|---|---|---|
| Free | Open source, available to all | — |
| Premium | Set your own price | You keep 85% |
- Push your module to GitHub (
your-user/module-name) - Register it in the ERPlora Marketplace
- After review, it's available to all ERPlora Hubs
- The sync pipeline automatically distributes updates when you push
CLI Commands
erplora startmodule <name> # Create a new module scaffold
erplora devserver # Start dev server (SQLite, PIN: 1234)
erplora version # Show SDK version
erplora help # Show help
Requirements
- Python 3.12+
- Django 6.0+
Installed automatically: Django, djicons (icon template tags), Pillow (image handling).
Links
License
MIT
Metadata
Release files for erplora-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| erplora_sdk-0.1.0.tar.gz | 19.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| erplora_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 54.9 kB
Release files / erplora_sdk-0.1.0.tar.gz
| Download URL | erplora_sdk-0.1.0.tar.gz |
|---|---|
| Size | 19.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
faa039351cf9064655434f10df286d92996166df45ced8741ac86061fe4e97b9
|
|
BLAKE2b-256 checksum How to use checksums |
98c5ae63ea176aa87c9e26422fa8fb3563ad245de09640a6ed2e32b614f19f45
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 23, 2026.
Transparency logRelease files / erplora_sdk-0.1.0-py3-none-any.whl
| Download URL | erplora_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 35.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
178ce9b9a27f55b2f3d34ef358590b85a07427d9615c2a3b2988281e62e24821
|
|
BLAKE2b-256 checksum How to use checksums |
5aa2662e36af9376443e8b1babe8b62f356c00e8b68b35c9f1944f99de623c90
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 23, 2026.
Transparency log