Skip to content

Script Project

A Script Project owns one complete source tree and the settings for its Scripts. The tree also forms the Python package boundary used when loading and executing those Scripts.

Fields

FK means foreign key. Fields marked auto are assigned or maintained by the plugin rather than supplied as editable configuration.

Field Type Required Notes
name string yes Display name. Can be changed
key slug yes Unique public identifier. Cannot change after creation
storage_key UUID auto Internal storage and runtime identity, assigned on creation and immutable
source_type choice yes upload (default) or data_source. Cannot change after creation
data_source FK conditional Required for a Data Source Project. Not allowed for uploads
data_path string conditional Required for a Data Source Project. Names a directory within the Data Source, not its root. Not allowed for uploads
activation_policy choice yes manual (default) or automatic_if_valid
active_revision FK auto Revision currently served by the Project. Managed by activation and deactivation
enabled boolean yes Whether Scripts in this Project may run. Defaults to true
description string no Short description of the Project
comments text no Operational notes

Use enabled to control execution. Use activation and deactivation to choose which revision the Project serves. These are separate controls.

Relationships

Relationship Target Required Notes
data_source core.DataSource conditional on_delete=PROTECT, no reverse relation. Set only for source_type=data_source
revisions ScriptProjectRevision no Reverse of the revision's project, with on_delete=CASCADE. Revisions recorded for this Project
active_revision ScriptProjectRevision no on_delete=SET_NULL, reverse name active_revision_for. Managed by activation and deactivation

A Project's immutable source snapshots are Script Project Revisions. Its declared source modules are Script Files, and the classes published by activation are Scripts.

API

Surface Endpoint or field
REST /api/plugins/netbox-scripts/projects/
GraphQL netbox_script_project / netbox_script_project_list

The Script Files tab selects the source modules used for discovery. The Project's detail page lists its declarations. REST provides the same selection operation at projects/<id>/script-files/. See Script File for its request format and permissions.

The Revision Files tab lists each file in the current revision, with its size, short checksum and enabled Script File status. It identifies the revision being displayed and links to the selection tab. A missing declared path is labelled to distinguish a file absent from the source from one waiting in a newer, inactive revision. The tab is empty until a revision contains stored source.

Activation policy

activation_policy controls whether a validated revision activates automatically or waits for an operator:

Value Behaviour
manual The revision remains valid until an operator activates it. A one-off upload activation request is separate
automatic_if_valid An eligible revision activates automatically once it has a valid verdict

On the upload form, Activate this upload requests activation for that upload without changing the policy for later revisions. When the checkbox is clear, the activation policy still applies. The form defaults to manual.

If automatic activation is refused, for example because stored content no longer matches its manifest, the validation Job fails. The validation verdict and the previously active revision remain unchanged.

For a Data Source Project, choose manual to review synchronized changes before serving them. Choose automatic_if_valid to activate eligible validated changes automatically. See Data Source Projects.

Only validated revisions can be activated. A retired revision remains eligible for explicit activation, allowing an operator to return to earlier source. Automatic activation also checks the accepted source and selection, as described below.

Invariants

Invariant Enforcement
key cannot change after creation clean(), disabled edit-form field, HTTP 400 on REST changes
source_type cannot change after creation clean(), disabled edit-form field, HTTP 400 on REST changes. No source-transition workflow is provided
storage_key never changes save() guard, excluded from forms and read-only in REST
data_path is canonical: POSIX-style, relative, single separators, no leading ./ or trailing / clean() and the REST serializer normalize it. Absolute paths, .. traversal and backslashes are rejected
data_source Projects require a data_source and non-empty data_path clean() and the enforce_source_ownership database constraint
upload Projects have no data_source or data_path clean() and the enforce_source_ownership database constraint
Changing activation_policy, data_source or data_path requires both activate and change Object-scoped authorization against the stored Project, followed by the locked save() guard. See the write rules below
active_revision belongs to this Project clean()
Only activation and deactivation write active_revision A full save() restores the stored pointer. The services include it explicitly in update_fields
Removing the active revision clears the Project's pointer SET_NULL on active_revision allows the Project's revision cascade to complete

Source-setting writes. The serializer's validate(), the edit form's clean() and both bulk views' save hooks check activation permission against the stored Project. Project creation and unchanged submitted values are exempt from this additional check. The locked save() guard rejects unauthorized or intervening source-setting changes rather than overwriting them from a stale instance. See Permissions.

Code that bypasses validation, such as QuerySet.update() or raw SQL, must supply canonical values. The database constraint enforces source ownership, not path spelling.

Deleting a Project cascades to its revisions. Their stored identities and manifests are captured before deletion so background cleanup can reclaim their source. The deleting process queues cleanup rather than removing stored files itself. An untrusted manifest refuses the deletion, preserving the row and its cleanup inventory.

Public and storage identifiers

Use key or the object ID when integrating with a Project. storage_key is read-only and exposed for troubleshooting, not as a public identifier. It names stored content, runtime packages and cache paths and never changes.

NetBox Branching

All five plugin models are installation-global. A revision's storage path uses its Project's storage_key and its own digest, with no branch or schema component. The same revision therefore names the same stored content in every branch. See NetBox Branching for the exemption setting, the routing check and the execution policy.

For developers adding models: retain ordinary NetBox Branching behavior unless the model represents installation-wide content. Check both its scope and its relationships. A main-schema row must not depend on a related row that exists only in a branch. Global source identities also must not be duplicated as branch-local rows, where deletion could remove content still served by main.

Limitations

Limitation Impact
A Project uses one source type source_type is immutable. Moving between uploads and a Data Source requires a new Project
Revisions cannot be edited directly REST and GraphQL expose read-only history. Source actions stage revisions, and activation remains a Project action

Saving a changed Script File selection queues a refresh of the accepted stored source. Saving the single preselected candidate for the first time also counts as a change. A Data Source Project with no stored revision still needs its first reconciliation.

Accepted source and active source are separate. A repeated upload or selection can reuse an older immutable revision and make it the accepted source again. Later uploads build on that accepted source, not the newest row by creation time.

Automatic activation checks that the validated revision is still the accepted source and that its declaration snapshot matches the current selection. Explicit historical activation does not change the source base for later uploads.