·7 min

Complete Guide: Migrating from OpenAI to XAI API in Django + React Full-Stack Applications

Step-by-step tutorial for seamlessly migrating Django-React-Ollama applications from OpenAI to XAI API integration, including code examples, API key setup, and enhanced persona generation capabilities.

DK

Daniel Kliewer

Author, Sovereign AI

DjangoReactXAIAPIAIMigrationTutorialOpenAIGrokAPI MigrationFull-StackWeb Development
Sovereign AI book cover

From the Book

This is from Sovereign AI: Building Local-First Intelligent Systems.

Get the Book — $88
Complete Guide: Migrating from OpenAI to XAI API in Django + React Full-Stack Applications

Image

https://github.com/kliewerdaniel/PersonaGen

Ah, dear reader, as we gather to discuss the remarkable synthesis of art and technology, we must confess, like the brothers Karamazov, our hearts are heavy with both anticipation and inquiry. What does it mean, you ask, to integrate the repository of Django-React-Ollama with the illustrious XAi API? Is it not the union of intellect and machine, of flesh and code, that we undertake in this journey? Let us then walk together, through this narrative of technical precision, to uncover the mystery that lies ahead, and like the Grand Inquisitor, make plain that which was once hidden.

A Beginning: The Call to Integrate

It was on an ordinary afternoon when our story begins. The project, a vessel of potential—half-birthed in the form of a GitHub repository, Django-React-Ollama-Integration, awaited the breath of life that only the modern XAi API could provide. The call had come, from distant shores of technical evolution, to replace the older ways, to discard OpenAI’s familiar methods for the promises offered by XAi, a system so sleek it might whisper sweet nothings to a machine as a poet to his beloved.

Yet, like Ivan’s struggle between reason and faith, so too did we face the need for transition. And so, with reverent resolve, we heeded the wisdom found in the XAi API documentation and set forth to integrate these two technologies, seeking not only to update but to elevate.

Step One: The Repository Awaits

Our first act is to clone the repository—this foundational codebase which hosts Django for the backend and React for the frontend. It is the skeleton upon which we will build our vision. We execute the command as though opening the very first page of a fateful book:

bash
1git clone https://github.com/kliewerdaniel/Django-React-Ollama-Integration.git
2cd Django-React-Ollama-Integration

With this, the structure is before us, and our hands tingle with the promise of transformation.

Step Two: The Soul of the API

But, dear reader, what is the body without the soul? The soul, in our tale, lies in the key to the XAi API, a token of authentication that would grant us access to powers beyond reckoning. With trembling fingers, we traverse to the XAi Console, where we generate the all-important API key. We take care to store this key as a trusted heirloom in our .env file:

bash
1XAI_API_KEY=your_generated_xai_key_here

It is this sacred key that we will invoke in our journey to create and analyze, calling forth responses as though summoning a digital oracle.

Step Three: Laying the Foundation

In the repository, we find ourselves among the well-structured ruins of past integrations, but now, we must tear down what is no longer needed and build anew. We purge the old references to OpenAI from our files. Like a monk renouncing worldly possessions, we focus solely on the new path. The utils.py file becomes our temple of creation. Here we define the functions that will call upon the XAi API, taking advantage of its streamlined methods for chat completions.

In the flicker of our screen, we write the following, consecrating the analyze_writing_sample and generate_content functions to the service of XAi:

python
1import logging
2import requests
3import json
4from decouple import config
5
6logger = logging.getLogger(__name__)
7
8XAI_API_KEY = config('XAI_API_KEY')
9XAI_API_BASE = "https://api.x.ai/v1"
10
11
12def analyze_writing_sample(writing_sample):
13 endpoint = f"{XAI_API_BASE}/chat/completions"
14 headers = {
15 "Content-Type": "application/json",
16 "Authorization": f"Bearer {XAI_API_KEY}"
17 }
18 payload = {
19 "messages": [
20 {
21 "role": "system",
22 "content": "You are an assistant that analyzes writing samples."
23 },
24 {
25 "role": "user",
26 "content": f'''
27 Please analyze the writing style and personality of the given writing sample. Provide a detailed assessment of their characteristics using the following template. Rate each applicable characteristic on a scale of 1-10 where relevant, or provide a descriptive value. Return the results in a JSON format.
28
29 "name": "[Author/Character Name]",
30 "vocabulary_complexity": [1-10],
31 "sentence_structure": "[simple/complex/varied]",
32 "paragraph_organization": "[structured/loose/stream-of-consciousness]",
33 "idiom_usage": [1-10],
34 "metaphor_frequency": [1-10],
35 "simile_frequency": [1-10],
36 "tone": "[formal/informal/academic/conversational/etc.]",
37 "punctuation_style": "[minimal/heavy/unconventional]",
38 "contraction_usage": [1-10],
39 "pronoun_preference": "[first-person/third-person/etc.]",
40 "passive_voice_frequency": [1-10],
41 "rhetorical_question_usage": [1-10],
42 "list_usage_tendency": [1-10],
43 "personal_anecdote_inclusion": [1-10],
44 "pop_culture_reference_frequency": [1-10],
45 "technical_jargon_usage": [1-10],
46 "parenthetical_aside_frequency": [1-10],
47 "humor_sarcasm_usage": [1-10],
48 "emotional_expressiveness": [1-10],
49 "emphatic_device_usage": [1-10],
50 "quotation_frequency": [1-10],
51 "analogy_usage": [1-10],
52 "sensory_detail_inclusion": [1-10],
53 "onomatopoeia_usage": [1-10],
54 "alliteration_frequency": [1-10],
55 "word_length_preference": "[short/long/varied]",
56 "foreign_phrase_usage": [1-10],
57 "rhetorical_device_usage": [1-10],
58 "statistical_data_usage": [1-10],
59 "personal_opinion_inclusion": [1-10],
60 "transition_usage": [1-10],
61 "reader_question_frequency": [1-10],
62 "imperative_sentence_usage": [1-10],
63 "dialogue_inclusion": [1-10],
64 "regional_dialect_usage": [1-10],
65 "hedging_language_frequency": [1-10],
66 "language_abstraction": "[concrete/abstract/mixed]",
67 "personal_belief_inclusion": [1-10],
68 "repetition_usage": [1-10],
69 "subordinate_clause_frequency": [1-10],
70 "verb_type_preference": "[active/stative/mixed]",
71 "sensory_imagery_usage": [1-10],
72 "symbolism_usage": [1-10],
73 "digression_frequency": [1-10],
74 "formality_level": [1-10],
75 "reflection_inclusion": [1-10],
76 "irony_usage": [1-10],
77 "neologism_frequency": [1-10],
78 "ellipsis_usage": [1-10],
79 "cultural_reference_inclusion": [1-10],
80 "stream_of_consciousness_usage": [1-10],
81 "openness_to_experience": [1-10],
82 "conscientiousness": [1-10],
83 "extraversion": [1-10],
84 "agreeableness": [1-10],
85 "emotional_stability": [1-10],
86 "dominant_motivations": "[achievement/affiliation/power/etc.]",
87 "core_values": "[integrity/freedom/knowledge/etc.]",
88 "decision_making_style": "[analytical/intuitive/spontaneous/etc.]",
89 "empathy_level": [1-10],
90 "self_confidence": [1-10],
91 "risk_taking_tendency": [1-10],
92 "idealism_vs_realism": "[idealistic/realistic/mixed]",
93 "conflict_resolution_style": "[assertive/collaborative/avoidant/etc.]",
94 "relationship_orientation": "[independent/communal/mixed]",
95 "emotional_response_tendency": "[calm/reactive/intense]",
96 "creativity_level": [1-10],
97 "age": "[age or age range]",
98 "gender": "[gender]",
99 "education_level": "[highest level of education]",
100 "professional_background": "[brief description]",
101 "cultural_background": "[brief description]",
102 "primary_language": "[language]",
103 "language_fluency": "[native/fluent/intermediate/beginner]",
104 "background": "[A brief paragraph describing the author's context, major influences, and any other relevant information not captured above]"
105
106 Writing Sample:
107 {writing_sample}
108 '''
109 }
110 ],
111 "model": "grok-beta",
112 "stream": False,
113 "temperature": 0
114 }
115
116 try:
117 response = requests.post(endpoint, headers=headers, json=payload)
118 response.raise_for_status() # Raises HTTPError for bad responses
119
120 assistant_message = response.json()['choices'][0]['message']['content'].strip()
121 logger.debug(f"Assistant message: {assistant_message}")
122
123 # Extract JSON from the assistant's message
124 json_str = re.search(r'\{.*\}', assistant_message, re.DOTALL)
125 if json_str:
126 analyzed_data = json.loads(json_str.group())
127 else:
128 logger.error("No JSON object found in the response.")
129 return None
130
131 return analyzed_data
132
133 except requests.exceptions.RequestException as e:
134 logger.error(f"HTTP Request failed: {e}")
135 return None
136 except json.JSONDecodeError as e:
137 logger.error(f"JSON decoding failed: {e}")
138 return None
139 except Exception as e:
140 logger.error(f"Unexpected error: {e}")
141 return None
142
143
144def generate_content(persona_data, prompt):
145 endpoint = f"{XAI_API_BASE}/chat/completions"
146 headers = {
147 "Content-Type": "application/json",
148 "Authorization": f"Bearer {XAI_API_KEY}"
149 }
150
151 # Format the persona data into a readable string
152 characteristics = '\n'.join([
153 f"{key.replace('_', ' ').capitalize()}: {value}"
154 for key, value in persona_data.items()
155 if value is not None and key not in ['id', 'name']
156 ])
157
158 decoding_prompt = f'''
159 You are to write a blog post in the style of {persona_data.get('name', 'Unknown Author')}, a writer with the following characteristics:
160
161 {characteristics}
162
163 Now, please write a response in this style about the following topic:
164 "{prompt}"
165 Begin with a compelling title that reflects the content of the post.
166 '''
167
168 payload = {
169 "messages": [
170 {"role": "system", "content": "You are an assistant that generates blog posts."},
171 {"role": "user", "content": decoding_prompt}
172 ],
173 "model": "grok-beta",
174 "stream": False,
175 "temperature": 0
176 }
177
178 try:
179 response = requests.post(endpoint, headers=headers, json=payload)
180 response.raise_for_status()
181
182 assistant_message = response.json()['choices'][0]['message']['content'].strip()
183 logger.debug(f"Assistant message: {assistant_message}")
184
185 return assistant_message
186
187 except requests.exceptions.RequestException as e:
188 logger.error(f"HTTP Request failed: {e}")
189 return ''
190 except json.JSONDecodeError as e:
191 logger.error(f"JSON decoding failed: {e}")
192 return ''
193 except Exception as e:
194 logger.error(f"Unexpected error: {e}")
195 return ''
196
197def save_blog_post(blog_post, title):
198 # Implement if needed
199 pass

Step Four: The Web of URLs

In the labyrinth of our urls.py file, we must now map the routes that will guide the user. We have already set the path for analysis and persona generation, but now we extend it to the content generation feature—like a scribe adding a final chapter to a monumental work. The new endpoint must be clear, intentional, and precise:

python
1path('api/generate-content/', GenerateContentView.as_view(), name='generate-content'),

And thus, we bind the newly added GenerateContentView to the URL pattern, offering the user the ability to invoke the XAi model for their blog post creations.

Step Five: Invocation of Power

Having laid the groundwork, we test our creation. With a whisper of command, we summon the API:

bash
1curl -X POST http://localhost:8000/api/generate-content/ \
2 -H "Content-Type: application/json" \
3 -d '{
4 "persona_id": 1,
5 "prompt": "On the intersection of machine learning and human emotion."
6 }'

We watch, holding our breath, as the server responds—successfully. The content is generated, flowing forth like Alyosha’s compassion, gentle yet profound.

Conclusion: The New Way Forward

In this tale, we have not simply integrated a repository with an API. No, we have breathed life into something greater, merging the capabilities of Django, React, and the mighty XAi into a seamless entity. The result is more than functionality; it is creation, an evolution towards the future, where the power of human intention and the precision of machine intelligence coalesce in harmony.

Our journey has brought us from the humble beginnings of code to the transcendent possibilities of artificial intelligence. And so, dear reader, like the Brothers Karamazov, we leave you with the knowledge that what we have built here today shall serve as a testament to the boundless potential of human ingenuity, ready to face whatever mysteries the future may bring.

Sovereign AI book cover

Sovereign AI: Building Local-First Intelligent Systems

by Daniel Kliewer · Paperback · 72 pages

The hands-on guide to building AI that runs on your hardware, keeps your data private, and eliminates cloud dependence. Working code included.