Django package: an owner-only server endpoint
A trusted server app with a valid manifest, AppConfig, URL and permission-checked read view.
Goal and prerequisites
Expose GET /examples/status/ for the authenticated installation owner. It returns the public Python API version and no campaign content. This is an independent generic server integration, not a companion for an RPG system.
Target host: 0.3.0, SDK 1.0.0. Sample interface strings are English. Preserve the requested version when adapting.
Complete files
These are complete unsigned sources. After reviewing the code, test with Install from ZIP on a disposable host. Marketplace publication uses the signature/catalog described in signing and activation. No private signing key is included.
Complete manifest
{
"id": "example.server-status",
"name": "Example server status",
"version": "1.0.0",
"sdk": {
"requires": ">=1.0.0 <2.0.0",
"tested": "1.0.0"
},
"description": "Trusted owner-only read endpoint with no models or background tasks.",
"author": "Gravewright documentation examples",
"license": "GPL-3.0-only",
"django": {
"apps": [
"example_status.apps.ExampleStatusConfig"
]
}
}Example code
example_status/init.py
example_status/apps.py
from django.apps import AppConfig
class ExampleStatusConfig(AppConfig):
name = "example_status"
label = "example_status"
gravewright_urlconf = "example_status.urls"example_status/urls.py
from django.urls import path
from .views import status
urlpatterns = [path("examples/status/", status, name="example_status")]example_status/views.py
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_GET
from api import API_VERSION
@login_required
@require_GET
def status(request):
if request.user.role != "owner":
return JsonResponse({"error": "permission_denied"}, status=403)
return JsonResponse({"ok": True, "apiVersion": API_VERSION})How to run
Review all Python sources. In an isolated host, install the source ZIP through Modules → Install from ZIP. For Marketplace publication, the signed catalog record must carry type: django.
Installation validates/extracts only. Activate the trusted app explicitly using the managed Runner or main.py and the documented uv-backed supervisor.
After restart, open /examples/status/ as owner, participant and an anonymous browser. Deactivate and restart to remove the route.
Expected result and lifecycle
Owner GET returns 200 with ok and apiVersion. An authenticated participant receives 403. An anonymous request follows the normal login redirect. An authenticated non-GET receives 405. No models, migrations or background tasks are added.
Errors and limits
Missing AppConfig package, duplicate app labels or invalid manifest/pins fail installation/activation. Django manifests cannot include entry, system or locales. Python execution requires owner activation; do not paste server code into a browser manifest.
How to validate
Use Django RequestFactory or an isolated Client to check owner/participant/anonymous/method behavior.
Confirm the route appears only after activation and no database content changes during reads.
Review supervisor checks/recovery; deactivation does not generally undo app migrations, although this example defines none.
How to use AI with this example
Adapt example_status into a read-only owner administration endpoint for [generic task]. Keep authentication, require_GET, explicit owner authorization, a distinct AppConfig label and no startup side effects. If campaign data is needed, call the supported Python API with a real authorized Context. Do not bypass permissions with ORM writes.