Buenas tardes amigos. En previsión del inicio del curso
Python Web Developer, tradicionalmente compartimos una traducción útil con usted.

Verá una guía frente a usted que le dice cómo crear una aplicación de chat en Python, Django y React.A diferencia de otros manuales, no uso Python y Django para las conexiones WebSocket. A pesar de que suena genial desde un punto de vista técnico, funciona bastante lento y en sí mismo es costoso, especialmente si tiene un número decente de usuarios. Lenguajes como C ++, Go y Elixir hacen un trabajo mucho mejor del núcleo del chat.
En este tutorial, utilizaremos Stream, una
API de chat que se encarga de las conexiones WebSocket y otros aspectos pesados utilizando Go, Raft y RocksDB.
Contenido:
- Reaccionar interfaz de chat de demostración
- Instalar Django / Python
- Autorización de usuario
- Django rest framework
- Generación de tokens para acceder al servidor de Stream de chat
- Integración de Autorización de Reacción
- Enviar mensajes desde un servidor Python
- Últimos pensamientos
Repositorio de Github con código de un artículo
¡Empecemos!
Paso 1: Reaccionar la interfaz de chat de demostración
Antes de comenzar a pensar en la parte de Python, implementemos una interfaz simple en React para que tengamos algo hermoso y visual:
$ yarn global add create-react-app $ brew install node && brew install yarn
Reemplace el código en
src/App.js
con lo siguiente:
import React from "react"; import { Chat, Channel, ChannelHeader, Thread, Window } from "stream-chat-react"; import { MessageList, MessageInput } from "stream-chat-react"; import { StreamChat } from "stream-chat"; import "stream-chat-react/dist/css/index.css"; const chatClient = new StreamChat("qk4nn7rpcn75"); // Demo Stream Key const userToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1za3ktOSJ9.mhikC6HPqPKoCP4aHHfuH9dFgPQ2Fth5QoRAfolJjC4"; // Demo Stream Token chatClient.setUser( { id: "cool-sky-9", name: "Cool sky", image: "https://getstream.io/random_svg/?id=cool-sky-9&name=Cool+sky" }, userToken ); const channel = chatClient.channel("messaging", "godevs", { // image and name are required, however, you can add custom fields image: "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png", name: "Talk about Go" }); const App = () => ( <Chat client={chatClient} theme={"messaging light"}> <Channel channel={channel}> <Window> <ChannelHeader /> <MessageList /> <MessageInput /> </Window> <Thread /> </Channel> </Chat> ); export default App;
¡Ahora, use el comando de
yarn start
para ver el chat en acción!
Paso 2: Instale Django / Python (omita este paso si ya tiene todo lo que necesita)
Asegúrese de tener Python 3.7 y se está ejecutando:
$ brew install python3 $ pip install virtualenv virtualenvwrapper $ export WORKON_HOME=~/Envs $ source /usr/local/bin/virtualenvwrapper.sh $ mkvirtualenv chatexample -p `which python3` $ workon chatexample
Si no funciona, intente con el siguiente código:
$ python3 -m venv chatexample $ source chatexample/bin/activate
Ahora que está en su entorno virtual, debería ver python 3 al inicio:
$ python --version
Para crear un nuevo proyecto en Django, use el siguiente código:
$ pip install django $ django-admin startproject mychat
Y ejecuta la aplicación:
$ cd mychat $ python manage.py runserver
Ahora, cuando abra
http://localhost:8000
, verá lo siguiente:

Paso 3: Autorización de usuario
El siguiente paso es configurar la autorización del usuario en Django.
$ python manage.py migrate $ python manage.py createsuperuser $ python manage.py runserver
Vaya a
http://localhost:8000/admin/
e inicie sesión. Voila!
Verá una pestaña de administrador similar a la siguiente:

Paso 4: Django Rest Framework
Uno de mis paquetes favoritos para integrar React con Django es el Django Rest Framework. Para que funcione, debe crear puntos finales para:
- Registro de usuario
- Inicio de sesión de usuario.
Podríamos hacerlos nosotros mismos, sin embargo, hay un paquete llamado
Djoser que resuelve este problema. Configurará los puntos finales API necesarios para el registro de usuarios, inicio de sesión, restablecimiento de contraseña, etc.
Para instalar Djoser, use lo siguiente:
$ pip install djangorestframework djoser
Después de eso, edite
urls.py
y cambie el contenido del archivo de la siguiente manera:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('auth/', include('djoser.urls')), path('auth/', include('djoser.urls.authtoken')), ]
Cuando termine, edite
settings.py
y realice cambios:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'djoser', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', ) }
Para obtener más información sobre los puntos finales de API que proporciona Djoser, consulte lo siguiente:
https://djoser.readthedocs.io/en/latest/sample_usage.htmlAhora continuemos y pruebe el punto final de registro:
$ curl -X POST http://127.0.0.1:8000/auth/users/ --data 'username=djoser&password=alpine12'
Paso 5: generar tokens para acceder al servidor de Stream de chat
Ahora necesitamos configurar las vistas de Djoser para generar tokens de Stream. Entonces comencemos.
Organicemos un poco nuestros archivos y creemos una carpeta de aplicación de chat en nuestro proyecto (asegúrese de estar en el directorio correcto):
$ python manage.py startapp auth
Instalar stream-chat:
$ pip install stream-chat
Cree un serializador personalizado en
auth/serializers.py
usando la siguiente lógica:
from djoser.serializers import TokenSerializer from rest_framework import serializers from djoser.conf import settings as djoser_settings from stream_chat import StreamChat from django.conf import settings class StreamTokenSerializer(TokenSerializer): stream_token = serializers.SerializerMethodField() class Meta: model = djoser_settings.TOKEN_MODEL fields = ('auth_token','stream_token') def get_stream_token(self, obj): client = StreamChat(api_key=settings.STREAM_API_KEY, api_secret=settings.STREAM_API_SECRET) token = client.create_token(obj.user.id) return token
Por último, use un serializador personalizado para actualizar el archivo
settings.py
:
STREAM_API_KEY = YOUR_STREAM_API_KEY
Reiniciar la migración:
$ python manage.py migrate
Para verificar que funciona, vaya al punto final utilizando una solicitud POST:
$ curl -X POST http://127.0.0.1:8000/auth/token/login/ --data 'username=djoser&password=alpine12'
El retorno debería ser
auth_token
y
stream_token
.
Paso 6: Integrar la autorización de reacción
Por razones obvias, agregar autorización a la interfaz es un paso importante. En nuestro caso, esto es especialmente útil, ya que podemos extraer el token de usuario de la API (que se ejecuta en Python) y usarlo dinámicamente al enviar mensajes.
Primero, instale CORS, el paquete de middleware para Django:
$ pip install django-cors-headers
Luego modifique el archivo
settings.py
para referirse al
djors-cors-header
:
INSTALLED_APPS = ( ... 'corsheaders', ... ) MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ]
Finalmente, agregue lo siguiente a su archivo
settings.py
:
CORS_ORIGIN_ALLOW_ALL = True
El siguiente paso requerirá algunos cambios en su interfaz. Para comenzar, deberá asegurarse de tener todas las dependencias instaladas a través de hilo:
$ yarn add axios react-dom react-router-dom
A continuación, cree los siguientes archivos en el directorio
src/
:
- AuthedRoute.js
- UnauthedRoute.js
- withSession.js
- Login.js
- Chat.js
App.js
import React from "react"; import { BrowserRouter as Router, Switch } from "react-router-dom"; import Chat from "./Chat"; import Login from "./Login"; import UnauthedRoute from "./UnauthedRoute"; import AuthedRoute from "./AuthedRoute"; const App = () => ( <Router> <Switch> <UnauthedRoute path="/auth/login" component={Login} /> <AuthedRoute path="/" component={Chat} /> </Switch> </Router> ); export default App;
AuthedRoute.js
import React from "react"; import { Redirect, Route } from "react-router-dom"; const AuthedRoute = ({ component: Component, loading, ...rest }) => { const isAuthed = Boolean(localStorage.getItem("token")); return ( <Route {...rest} render={props => loading ? ( <p>Loading...</p> ) : isAuthed ? ( <Component history={props.history} {...rest} /> ) : ( <Redirect to={{ pathname: "/auth/login", state: { next: props.location } }} /> ) } /> ); }; export default AuthedRoute;
UnauthedRoute.js
import React from "react"; import { Redirect, Route } from "react-router-dom"; const AuthedRoute = ({ component: Component, loading, ...rest }) => { const isAuthed = Boolean(localStorage.getItem("token")); return ( <Route {...rest} render={props => loading ? ( <p>Loading...</p> ) : !isAuthed ? ( <Component history={props.history} {...rest} /> ) : ( <Redirect to={{ pathname: "/" }} /> ) } /> ); }; export default AuthedRoute;
withSession.js
import React from "react"; import { withRouter } from "react-router"; export default (Component, unAuthed = false) => { const WithSession = ({ user = {}, streamToken, ...props }) => user.id || unAuthed ? ( <Component userId={user.id} user={user} session={window.streamSession} {...props} /> ) : ( <Component {...props} /> ); return withRouter(WithSession); };
Login.js
import React, { Component } from "react"; import axios from "axios"; class Login extends Component { constructor(props) { super(props); this.state = { loading: false, email: "", password: "" }; this.initStream = this.initStream.bind(this); } async initStream() { await this.setState({ loading: true }); const base = "http://localhost:8000"; const formData = new FormData(); formData.set("username", this.state.email); formData.set("password", this.state.password); const registration = await axios({ method: "POST", url: `${base}/auth/users/`, data: formData, config: { headers: { "Content-Type": "multipart/form-data" } } }); const authorization = await axios({ method: "POST", url: `${base}/auth/token/login/`, data: formData, config: { headers: { "Content-Type": "multipart/form-data" } } }); localStorage.setItem("token", authorization.data.stream_token); await this.setState({ loading: false }); this.props.history.push("/"); } handleChange = e => { this.setState({ [e.target.name]: e.target.value }); }; render() { return ( <div className="login-root"> <div className="login-card"> <h4>Login</h4> <input type="text" placeholder="Email" name="email" onChange={e => this.handleChange(e)} /> <input type="password" placeholder="Password" name="password" onChange={e => this.handleChange(e)} /> <button onClick={this.initStream}>Submit</button> </div> </div> ); } } export default Login;
Chat.js
import React, { Component } from "react"; import { Chat, Channel, ChannelHeader, Thread, Window } from "stream-chat-react"; import { MessageList, MessageInput } from "stream-chat-react"; import { StreamChat } from "stream-chat"; import "stream-chat-react/dist/css/index.css"; class App extends Component { constructor(props) { super(props); this.client = new StreamChat("<YOUR_STREAM_APP_ID>"); this.client.setUser( { id: "cool-sky-9", name: "Cool Sky", image: "https://getstream.io/random_svg/?id=cool-sky-9&name=Cool+sky" }, localStorage.getItem("token") ); this.channel = this.client.channel("messaging", "godevs", { image: "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png", name: "Talk about Go" }); } render() { return ( <Chat client={this.client} theme={"messaging light"}> <Channel channel={this.channel}> <Window> <ChannelHeader /> <MessageList /> <MessageInput /> </Window> <Thread /> </Channel> </Chat> ); } } export default App;
Asegúrese de reemplazar
YOUR_STREAM_APP_ID
con el ID válido de la aplicación Stream, que se puede encontrar en el
tablero .
Reinicie la aplicación en el front end y verá la autorización. Ingrese su dirección de correo electrónico y contraseña, el token será solicitado y almacenado en el almacenamiento local.
Paso 7: Enviar mensajes desde el servidor Python
Si de repente quieres crear una API de chat usando tu backend en Python, hay un comando especial que puedes usar.
Asegúrese de que las aplicaciones instaladas se vean así en
settings.py
:
INSTALLED_APPS = [ 'corsheaders', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'djoser', ]
A continuación, cree el directorio chat / management / command. En este directorio, agregue un archivo llamado
broadcast.py
con el siguiente contenido:
from django.core.management.base import BaseCommand, CommandError from django.conf import settings from stream_chat import StreamChat class Command(BaseCommand): help = 'Broadcast the message on your channel' def add_arguments(self, parser): parser.add_argument('--message') def handle(self, *args, **options): client = StreamChat(api_key=settings.STREAM_API_KEY, api_secret=settings.STREAM_API_SECRET) client.update_user({"id": "system", "name": "The Server"}) channel = client.channel("messaging", "kung-fu") channel.create("system") response = channel.send_message({"text": "AMA about kung-fu"}, 'system') self.stdout.write(self.style.SUCCESS('Successfully posted a message with id "%s"' % response['message']['id']))
Puede intentar enviar un mensaje de chat de la siguiente manera:
$ python manage.py broadcast --message hello
Y verá esta respuesta:

Últimos pensamientos
¡Espero que hayas disfrutado este tutorial sobre cómo crear una aplicación de chat en Django, Python y React!
Para un recorrido interactivo de
Stream Chat , consulte nuestra guía sobre cómo crear una
API en el sitio web de Stream . Si le gusta explorar el código de los componentes de Stream Chat React, puede encontrar la documentación completa
aquí . Si desea crear un chat en Stream, nos complace ofrecer varios
SDK para idiomas y marcos populares hasta el último
iOS (Swift) .
Eso es todo. Nos vemos en el
seminario web abierto sobre Trucos de Django ORM .