Python with Django

Step 1: Create Template ViewCopied!

Add container element in your Django template:

<!-- templates/rollout.html -->
{% extends "base.html" %}

{% block content %}
<h1>Your Application</h1>
<div id="rollout-container"></div>
{% endblock %}

{% block extra_js %}
<script src="{% static 'js/rollout.js' %}"></script>
{% endblock %}

Step 2: Add JavaScript InitializationCopied!

Create a static JavaScript file:

// static/js/rollout.js
document.addEventListener('DOMContentLoaded', function() {
  const container = document.getElementById('rollout-container');
  
  // Get CSRF token for Django
  const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
  
  fetch('/rollout-token/', {
    headers: {
      'Content-Type': 'application/json',
      'X-CSRFToken': csrftoken
    }
  })
  .then(response => response.json())
  .then(data => {
    const token = data.token;
    
    // Add required styles
    const styleLink = document.createElement('link');
    styleLink.rel = 'stylesheet';
    styleLink.href = 'https://esm.sh/@rollout/[email protected]/dist/style.css';
    document.body.appendChild(styleLink);

    // Dynamically load Rollout bundle
    import(/* webpackIgnore: true */ 'https://esm.sh/@rollout/[email protected]?bundle=all').then(
      ({ RolloutLinkProvider, CredentialsManager, createElement, createRoot }) => {
        const root = createRoot(container);
        
        root.render(
          createElement(
            RolloutLinkProvider,
            { token },
            createElement(CredentialsManager)
          )
        );
      }
    );
  });
});

Step 3: Add Django URL RouteCopied!

Add route to your urls.py:

# urls.py
from django.urls import path
from .views import RolloutTokenView, CredentialWebhookView

urlpatterns = [
    path('rollout-token/', RolloutTokenView.as_view(), name='rollout-token'),
    path('credential-webhook/', CredentialWebhookView.as_view(), name='credential-webhook'),
]

Step 4: Create Django ViewsCopied!

Implement token generation view:

# views.py
from django.http import JsonResponse
from django.views import View
import jwt
import time

class RolloutTokenView(View):
    def get(self, request):
        """Generate a JWT token that expires in 15 minutes"""
        # Implement your actual token generation logic
        token = jwt.encode(
            {
                "iss": os.environ.get("ROLLOUT_CLIENT_ID"),
                "sub": user_id,
                "iat": int(time.time()),
                "exp": int(time.time()) + 900  # 15 minutes
            },
            os.environ.get("ROLLOUT_CLIENT_SECRET"),
            algorithm="HS512"
        )
        return JsonResponse({'token': token})

class CredentialWebhookView(View):
    def post(self, request):
        # Handle credential storage
        credential_id = request.POST.get('id')
        app_key = request.POST.get('appKey')
        
        # Save to database or trigger other actions
        print(f"Received credential: {credential_id} for {app_key}")
        return JsonResponse({'status': 'success'})

Step 5 (Optional): Handle Credential EventsCopied!

Update the JavaScript to handle events:

// Update the import block
.then(({ RolloutLinkProvider, CredentialsManager, createElement, createRoot }) => {
  const handleCredentialAdded = ({ id, appKey }) => {
    console.log(`New credential added - ID: ${id}, App: ${appKey}`);
    
    // Send to Django backend
    const formData = new FormData();
    formData.append('id', id);
    formData.append('appKey', appKey);

    fetch('/credential-webhook/', {
      method: 'POST',
      headers: {
        'X-CSRFToken': csrftoken
      },
      body: formData
    });
  };

  const root = createRoot(container);
  root.render(
    createElement(
      RolloutLinkProvider,
      { token },
      createElement(CredentialsManager, {
        onCredentialAdded: handleCredentialAdded
      })
    )
  );
});

Step 6: Update CSPCopied!

Add to settings.py:

CSP_STYLE_SRC = ("'self'", "https://esm.sh")
CSP_SCRIPT_SRC = ("'self'", "https://esm.sh")
CSP_CONNECT_SRC = ("'self'", "https://universal.rollout.com")
CSP_IMG_SRC = ("'self'", "data:")