
Research
SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.
formkit-ninja
Advanced tools
A Django-Ninja framework for FormKit schemas and form submissions
FormKit out of the box has awesome schema support - this lets us integrate FormKit instances as Django models
To use, pip install formkit-ninja and add the following to settings INSTALLED_APPS:
INSTALLED_APPS = [
...
"formkit_ninja",
"ninja",
...
]
⭐ NEW - Create complete data collection apps with minimal coding!
# 1. Create a FormKit schema
./manage.py create_schema --label "Contact Form"
# 2. Bootstrap a complete Django app
./manage.py bootstrap_app --schema-label "Contact Form" --app-name contacts
# 3. Add to INSTALLED_APPS and migrate
# (Edit settings.py to add 'contacts')
./manage.py makemigrations && ./manage.py migrate
# 4. Start collecting data!
./manage.py runserver
See the Quick Start Guide for a complete walkthrough.
⭐ NEW in v0.8.1 - Database-driven code generation! Configure type mappings and field overrides through Django admin without writing Python code.
formkit-ninja can automatically generate Django models, Pydantic schemas, admin classes, and API endpoints from your FormKit schemas.
Configure code generation rules through the Django admin:
# Django Admin → Code generation configs
formkit_type = "text"
node_name = "district"
django_type = "ForeignKey"
django_args = {"to": "pnds_data.zDistrict", "on_delete": "models.CASCADE"}
Generates:
# models.py
district = models.ForeignKey("pnds_data.zDistrict", on_delete=models.CASCADE)
Generate code from all schemas in your database:
./manage.py generate_code --app-name myapp --output-dir ./myapp/generated
Generate code for a specific schema:
./manage.py generate_code --app-name myapp --output-dir ./myapp/generated --schema-label "My Form"
The code generator creates the following files:
models.py - Django models for groups and repeatersschemas.py - Django Ninja output schemasschemas_in.py - Django Ninja input schemas (Pydantic BaseModel)admin.py - Django admin classesapi.py - Django Ninja API endpointsformkit-ninja provides multiple extension points for customizing code generation:
See the Database-Driven Code Generation guide for the new database configuration feature, or the Code Generation Guide for detailed documentation and examples.
Formkit-Ninja provides a REST API for managing FormKit schema nodes. The API requires authentication and specific permissions.
All API endpoints require:
formkit_ninja.change_formkitschemanode permissionUnauthenticated requests receive 401 Unauthorized. Authenticated users without the required permission receive 403 Forbidden.
POST /api/formkit/create_or_update_node
Creates a new node or updates an existing one.
Request Body:
uuid (optional): UUID of node to update. If omitted, a new node is created.parent_id (optional): UUID of parent node (must be a group or repeater)$formkit: FormKit node type (e.g., "text", "group", "repeater")Response:
200 OK: Success, returns NodeReturnType with node data400 Bad Request: Invalid input (e.g., invalid parent, deleted node)403 Forbidden: Insufficient permissions404 Not Found: Node with provided UUID does not exist (for updates)500 Internal Server Error: Server errorUpdate Behavior:
uuid is provided, the node with that UUID is updated404 Not Found400 Bad Requestparent_id is providedDELETE /api/formkit/delete/{node_id}
Soft deletes a node (sets is_active=False).
Response:
200 OK: Success, returns NodeInactiveType403 Forbidden: Insufficient permissions404 Not Found: Node does not existAll successful responses return consistent data structures:
NodeReturnType: For active nodes
key: UUID of the nodenode: FormKit node datalast_updated: Timestamp of last changeprotected: Whether the node is protected from deletionNodeInactiveType: For deleted nodes
key: UUID of the nodeis_active: falselast_updated: Timestamp of last changeprotected: Whether the node is protectedFormKitErrors: For error responses
errors: List of error messagesfield_errors: Dictionary of field-specific errorsThe API validates:
parent_id is provided, the parent node must exist and be a group or repeateruuid is provided for updates, the node must exist and be active$formkit field must be a valid FormKit node typePull the repo:
gh repo clone catalpainternational/formkit-ninja
cd formkit-ninja
uv sync
Tests require PostgreSQL due to the pgtrigger dependency. Start a PostgreSQL container before running tests:
# Using Podman (recommended)
podman run -d --name formkit-postgres -p 5434:5432 -e POSTGRES_HOST_AUTH_METHOD=trust docker.io/library/postgres:14-alpine
# OR using Docker
docker run -d --name formkit-postgres -p 5434:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:14-alpine
Then run tests:
uv run pytest
Some tests require playwright. Install it with:
uv run playwright install
Note: For full development setup with real data, see DEVELOPMENT.md.
Format and lint code using ruff:
# Check formatting
uv run ruff format --check .
# Check linting
uv run ruff check .
uv for package managementSet up the project:
uv sync
uv run playwright install
# Start PostgreSQL (see Database Setup above)
Run tests:
uv run pytest
Check code quality:
uv run ruff format --check .
uv run ruff check .
uv run mypy formkit_ninja
Test Driven Development (TDD):
pytest as the testing frameworkCode Style:
ruff for formatting and lintingCommit Messages:
<type>(<scope>): <subject>If a node's been protected you cannot change or delete it. To do so, you'll need to temporarily disable the trigger which is on it.
./manage.py pytrigger disable protect_node_deletes_and_updates
Make changes
./manage.py pgtrigger enable protect_node_deletes_and_updates
See the documentation for more details: https://django-pgtrigger.readthedocs.io/en/2.3.0/commands.html?highlight=disable
FAQs
A Django-Ninja backend to specify FormKit schemas
We found that formkit-ninja demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.

Company News
Socket is proud to join the OpenJS Foundation as a Silver Member, deepening our commitment to the long-term health and security of the JavaScript ecosystem.

Security News
npm now links to Socket's security analysis on every package page. Here's what you'll find when you click through.