A demo online store built with Django, showcasing integration with Customer’s Canvas Hub for product personalization.
This project demonstrates how to perform the key integration steps between an online store built with Python / Django and Customer’s Canvas Hub, including:
- Authorization using OAuth 2.0 Client Credentials
- Mapping store products to Customer’s Canvas products
- Working with editors (Workflow Elements):
- Initializing the editor with product data
- Displaying the editor
- Completing the design editing session
- Temporary storage of personalization data within orders
- Launching Customer’s Canvas Hub projects for print file rendering
- Monitoring project statuses
- Downloading final print-ready files (artifacts)
git clone https://github.com/aurigma/cchub-IntegrationSample-PythonApp.git
cd cchub-IntegrationSample-PythonApppython -m venv venv
venv\Scripts\activatepip install -r requirements.txtAfter cloning the repository, configure the .env file:
- Create a copy of .env.sample
- Rename it to .env
- Fill in your Customer’s Canvas credentials
CCHUB_BASEURL- depending on your instance, it is either https://customerscanvashub.com (US), https://eu.customerscanvashub.com (Europe), or https://au.customerscanvashub.com (Australia).CCHUB_STOREFRONT_ID- a storefront record ID, created as per Help Center > Admin's Guide > Settings > Integrations.CCHUB_CLIENTIDandCCHUB_CLIENTSECRET- an OAuth2 Client Credentials of your app, registered in your tenant as per Help Center > Admin's Guide > Settings > External AppsCCHUB_TENANT_ID- specify your tenant ID - see the Help Center > Admin's Guide > Settings > Tenant.CCHUB_ENVIRONMENT- a Customer's Canvas instance location -us,eu, orau
SECRET_KEY— Django cryptographic secret key. Generate it using:
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"This is a demo project, so a test database and migrations are already included in the repository and can be used as-is.
If you modify the data models, you will need to create and apply migrations:
python manage.py makemigrations store cart orders
python manage.py migrateYou can also configure a different database by updating its parameters in settings.py.
The test database already contains a superuser:
- login:
admin - password:
admin
Alternatively, you can create your own:
python manage.py createsuperuserpython manage.py runserverIf successful, the site will be available at:
http://127.0.0.1:8000/
- Open the Django admin panel:
http://127.0.0.1:8000/admin/ - Create product categories (
store → Category) - Create Product Groups (
ProductGroup)
Their IDs will be used as Product Reference values in the Customer’s Canvas API - Create Product Variants (
ProductVariant) with unique SKUs
Make sure to save the Product Group ID and Product Variant SKU — they will be required when mapping products in Customer’s Canvas.
Create a pipeline following the official documentation
Example pipeline:
{
"tasks": [
{
"description": "Extract design from project",
"name": "extract",
"namespace": "customers-canvas",
"type": "extract-project-design",
"parameters": {},
"outputArtifacts": ["design"]
},
{
"description": "Render design",
"name": "render-hires",
"namespace": "customers-canvas",
"type": "render-hires",
"inputArtifacts": ["design"],
"parameters": {
"hiResOutputDpi": 300,
"hiResOutputFileFormat": "pdf",
"hiResOutputColorSpace": "cmyk",
"hiResOutputPdfFormat": "X4",
"hiResOutputCompression": "Jpeg",
"hiResOutputJpegCompressionQuality": 90
},
"outputArtifacts": ["result*"]
},
{
"description": "Configure print file access",
"name": "configure-access",
"namespace": "customers-canvas",
"type": "configure-artifacts",
"inputArtifacts": ["result*"],
"parameters": {
"final": "true",
"anonymousAccess": "true"
}
},
{
"description": "Finalize",
"name": "finalize",
"namespace": "customers-canvas",
"type": "finalize",
"finalArtifacts": ["result*"]
}
]
}In this demo, the pipeline enables anonymous access to artifact for simplicity.
For more advanced scenarios (authenticated access or webhook-based delivery), see:
https://customerscanvas.com/dev/backoffice/howto/download-artifacts.html
You must create a configuration for the editor attached to the product (Personalization Workflow).
This demo supports only Workflow Elements (e.g., Handy Editor).
Documentation:
Minimal Handy Editor configuration example:
{
"configVersion": 2,
"component": "handy-editor",
"tagName": "au-handy-editor",
"settings": {},
"resources": {
"assetLibrary": {
"clipartsFolder": "Clipart",
"imagesFolder": "Images"
}
}
}- Create a Product in Customer’s Canvas
- Attach the required assets
(see documentation: https://customerscanvas.com/help/admin-guide/pim/intro.html)
- Create a Connection and specify the
ProductGroup.idfrom the Django app - Open the variants list and set the SKU value matching the Product Variant SKU in Django
The application provides a category-based product catalog where users can:
- Browse product categories
- View detailed product information
The flow depends on the product type:
- The product page displays an “Add to Cart” button
- Clicking it immediately adds the product to the cart
- The product page displays a “Personalize” button
- Clicking it opens the editor for creating a unique design
- After finishing personalization, the user is redirected back to the store
- The product is added to the cart with all personalization data attached
The checkout flow is unified for all product types:
- The user reviews items in the cart
- Enters an email address for communication and order confirmation
- The system detects whether the order contains personalized items
- The order status is set accordingly
This is a demo project — payment is not implemented.
Non-personalized items are immediately marked as ready.
Personalized items become ready once their artifacts are generated.
If an order contains personalized products:
- The order status is set to
processing - A Customer’s Canvas Hub project is created for each personalized item
- Background monitoring tracks project execution
- Once all projects complete successfully, the order status changes to
completed - The user receives download links for the final files
Users can:
- View a list of all their orders
- Track the processing status of each order
- Download final files for completed personalized orders
The application follows a modular Django architecture.
Contains global Django project configuration:
settings.py— database, middleware, installed appsurls.py— main URL routingtemplates/— base site templates
Manages the product catalog:
- Data models —
Category → ProductGroup → ProductVariant - Views — category, product group, and product pages
- Urls — catalog navigation URLs
- Templates — UI for browsing products
(product_detail_cchub.htmldemonstrates editor initialization)
Shopping cart functionality:
- Views — add, remove, update cart items
- Session-based model — cart tied to the user session
- Templates — cart UI
Order processing and management:
- Models —
Order,OrderItem - Views — order creation, status display, file download
- Service layer (
services/) — business logic, project creation, status monitoring - Templates — order management UI
Dedicated module for Customer’s Canvas API interaction:
- Configuration (
config.py) — loads environment variables - Services (
services/):auth.py— access token retrieval (OAuth 2.0 Client Credentials)product_service.py— Customer’s Canvas product queriesproject_service.py— project creation and managementuser_service.py— Customer’s Canvas user handling
media/— uploaded files (product images)requirements.txt— Python dependencies.env— sensitive configuration (never commit this file)db.sqlite3— SQLite database (development only)manage.py— Django management utility
After reviewing this project, you should be able to implement a similar integration in your own system. Below are several practical recommendations.
If your application architecture allows, move all Customer’s Canvas Hub–related logic into a dedicated module.
This improves maintainability and enables reuse across projects.
While it is possible to use raw HTTP calls (httpx, urllib3) or generate clients from OpenAPI specs, we strongly recommend using the official API clients published on PyPI.
This project uses:
pip install aurigma-storefront-api-clientAdditional Customer’s Canvas API clients are also available on PyPI.
In this demo:
- A Product Variant (SKU) represents a sellable item
- Variants are grouped into Product Groups
ProductGroup.ididentifies the Customer’s Canvas product- SKU identifies the specific variant
Other eCommerce systems may model products closer to Customer’s Canvas, where a product contains selectable options that generate variants.
Avoid creating a separate Customer’s Canvas product for every variant unless truly necessary.
Using options inside Customer’s Canvas products often simplifies management.
Customer’s Canvas Hub is designed so that:
- Different products can use different editors
- Editors can have different configurations
- Editor configuration is managed in the admin UI, not in code
While it may be tempting to hardcode a single editor (e.g., Handy Editor), we strongly recommend loading editor configuration dynamically from Customer’s Canvas.
Possible approaches:
- Server-side templates — use different HTML templates per workflow type
- Dynamic frontend loading — inject editor scripts dynamically
- SPA frameworks — create dedicated components for each editor type (React, Angular, Vue)
Workflow Elements editors are largely unified, while UI Framework differs from Workflow Elements significantly. You can reuse one component for Workflow Elements and separate ones for UI Framework editors.
To optimize performance, fetch as much Customer’s Canvas data as possible on the backend (preferably with caching).
In this demo, personalization is performed using anonymous users tied to a Django session.
This means uploaded assets and designs are lost once the session expires.
If you want users to:
- Resume work on designs later
- Retain uploaded assets
If a customer is signed in, you should pass your store user IDs when requesting a Storefront User Token instead of session ID.
Customer’s Canvas also supports user data merging when an anonymous user logs in later:
https://customerscanvas.com/dev/backoffice/api/storefront/register-customers.html
This demo uses a simple polling approach:
- The backend checks rendering status every 30 seconds
- Once completed, artifact download links are retrieved directly
For production systems, a webhook-based approach is recommended.
This requires adding an invoke URL task to the rendering pipeline.
See details here:
https://customerscanvas.com/dev/backoffice/howto/download-artifacts.html