InvenTree Inventory: Self-Hosted Stock Control with REST API

6月8日 Published inManagement Systems

InvenTree provides granular stock control and part tracking, powered by a Python/Django backend. It serves both a web-based administration interface and a robust REST API, allowing for straightforward integration with external scripts or third-party applications. Its modular design includes a plugin system that enables developers to extend functionality without modifying the core codebase.

The Backend Stack: The system is built on Python, utilizing Django for its primary logic. The Django REST Framework handles API construction, while Django Q manages asynchronous task queues. User authentication is facilitated by Django-Allauth.

Data Storage: InvenTree supports PostgreSQL, MySQL, and SQLite. It also utilizes Redis to handle high-speed caching requirements.

The Frontend: The user interface is driven by React, with Lingui managing internationalization and React Router handling navigation. State management is handled through TanStack Query and Zustand, while Mantine serves as the primary component library.

DevOps and Distribution: Deployment is streamlined via Docker containers. The project uses Crowdin for community translations, while Codecov and SonarCloud monitor code quality. Software distribution is managed through Packager.io.

Rapid Deployment: Using Docker is the most efficient way to get started. The project offers a convenient one-line installer:

wget -qO install.sh https://get.inventree.org && bash install.sh

Cloud Environments: InvenTree runs effectively on bare-metal servers or cloud providers like DigitalOcean. Detailed setup instructions are provided in the official documentation.

Mobile Connectivity: Native companion applications are available for both Android and iOS, allowing users to manage stock levels directly from their mobile devices.

REST API Design

The InvenTree API is self-documenting. Once your local instance is active, you can access the documentation by navigating to http://127.0.0.1:8000/api-doc/ in your browser. When running in debug mode, you can interact with the endpoints directly through the web interface.

Authentication

  1. Basic Authentication: Uses a standard username and password. This is useful for initial testing and prototyping.
  2. Token Authentication: For long-term scripting, you can generate a persistent token. This should be included in your request header as Authorization: Token <your-token-value>.
import requests
token = 'your_token_value'
headers = {'Authorization': f'Token {token}'}
response = requests.get('http://localhost:8080/api/part/', headers=headers)
  1. OAuth2/OIDC: This is an experimental feature that must be enabled manually. It supports public clients and PKCE flows for integrated third-party logins.

Permissions

Access is governed by user roles. You can verify your specific access levels by querying the /api/user/roles/ endpoint. While superusers have full read-write access across the entire system, restricted users may only see specific datasets. Any attempt to perform an unauthorized action will trigger a 403 Forbidden error.

Interacting with the API

Command Line Interface: You can use the coreapi-cli tool to load the schema and interact with the database without writing custom code.

pip install coreapi-cli
coreapi get http://127.0.0.1:8000/api-doc/

Programmatic Access: For more complex integrations, the official Python SDK provides a clean wrapper for all API functions.

Python SDK

The official Python package simplifies development for third-party tools. You can install it via pip:

pip3 install inventree

Authentication Methods

Using a username and password:

from inventree.api import InvenTreeAPI
api = InvenTreeAPI('http://127.0.0.1:8000', username='admin', password='your_password')

Using a token:

api = InvenTreeAPI('http://127.0.0.1:8000', token='your_token')

Environment Variables: The SDK can automatically detect your credentials if you set INVENTREE_API_HOST and INVENTREE_API_TOKEN in your environment.

Data Operations

Accessing a Single Record: If the primary key is known, you can instantiate the object directly.

from inventree.part import PartCategory
category = PartCategory(api, 10)  # Fetches the category with ID 10

Filtering Lists: Use the list method to retrieve records based on specific criteria.

from inventree.part import Part
# Returns all assembly parts within category 10
parts = Part.list(api, category=10, assembly=True)

Hierarchical Filtering: For nested structures like categories, use the parent filter to navigate the tree.

child_categories = PartCategory.list(api, parent=10)      # Sub-categories of ID 10
parent_categories = PartCategory.list(api, parent='')     # Root-level categories

Metadata and Relationships

You can programmatically inspect field details:

for field in Part.fieldNames(api):
    print(field, '->', Part.fieldInfo(field, api))

The SDK also includes helper methods for related data. For example, part.getStockItems() retrieves all stock entries associated with a specific part, and similar methods exist for handling attachments and documentation.

Plugin Development

Scaffolding: You can quickly generate the necessary boilerplate for a new plugin using the creator tool.

pip install inventree-plugin-creator
create-inventree-plugin

Structure: Modern plugins should inherit from the InvenTreePlugin class. By defining NAME, SLUG, and VERSION within the class metadata, the system will automatically discover and register the plugin upon startup.