Bonjour mes amis. En prévision du début du cours
Python Web Developer, nous partageons traditionnellement une traduction utile avec vous.

Vous voyez un guide devant vous qui vous explique comment créer une application de chat en Python, Django et React.Contrairement à d'autres manuels, je n'utilise pas Python et Django pour les connexions WebSocket. Malgré le fait que cela semble cool d'un point de vue technique, cela fonctionne plutôt lentement et en soi, c'est cher, surtout si vous avez un nombre décent d'utilisateurs. Les langages comme C ++, Go et Elixir font un bien meilleur travail du noyau de chat.
Dans ce tutoriel, nous utiliserons Stream, une
API de chat qui prend en charge les connexions WebSocket et d'autres aspects lourds en utilisant Go, Raft et RocksDB.
Contenu:
- Interface de chat de démonstration React
- Installez Django / Python
- Autorisation utilisateur
- Cadre de repos Django
- Génération de jetons pour l'accès au serveur de Chat Stream
- Intégration de l'autorisation React
- Envoi de messages depuis un serveur Python
- Dernières pensées
Dépôt Github avec le code d'un article
Commençons!
Étape 1: React Demo Chat Interface
Avant de commencer à penser à la partie Python, déployons une interface simple sur React afin d'avoir quelque chose de beau et de visuel:
$ yarn global add create-react-app $ brew install node && brew install yarn
Remplacez le code dans
src/App.js
par ce qui suit:
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;
Maintenant, utilisez la commande
yarn start
pour voir le chat en action!
Étape 2: Installez Django / Python (ignorez cette étape si vous avez déjà tout ce dont vous avez besoin)
Assurez-vous que vous avez Python 3.7 et qu'il fonctionne:
$ 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 cela ne fonctionne pas, essayez le code suivant:
$ python3 -m venv chatexample $ source chatexample/bin/activate
Maintenant que vous êtes dans votre environnement virtuel, vous devriez voir python 3 au démarrage:
$ python --version
Pour créer un nouveau projet dans Django, utilisez le code suivant:
$ pip install django $ django-admin startproject mychat
Et exécutez l'application:
$ cd mychat $ python manage.py runserver
Maintenant, lorsque vous ouvrez
http://localhost:8000
, vous verrez ce qui suit:

Étape 3: Autorisation utilisateur
L'étape suivante consiste à configurer l'autorisation utilisateur dans Django.
$ python manage.py migrate $ python manage.py createsuperuser $ python manage.py runserver
AccĂ©dez Ă
http://localhost:8000/admin/
et connectez-vous. Voila!
Vous verrez un onglet administrateur similaire Ă celui ci-dessous:

Étape 4: Django Rest Framework
L'un de mes packages préférés pour l'intégration de React avec Django est le Django Rest Framework. Pour le faire fonctionner, vous devez créer des points de terminaison pour:
- Inscription des utilisateurs
- Connexion utilisateur.
Nous pourrions les fabriquer nous-mêmes, mais il existe un package appelé
Djoser qui résout ce problème. Il configurera les points de terminaison API nécessaires pour l'enregistrement des utilisateurs, la connexion, la réinitialisation du mot de passe, etc.
Pour installer Djoser, utilisez ce qui suit:
$ pip install djangorestframework djoser
Après cela, modifiez
urls.py
et modifiez le contenu du fichier comme suit:
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')), ]
Une fois terminé, modifiez
settings.py
et apportez les modifications:
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', ) }
Pour plus d'informations sur les points de terminaison API fournis par Djoser, consultez les éléments suivants:
https://djoser.readthedocs.io/en/latest/sample_usage.htmlMaintenant, continuons et testons le point de terminaison d'enregistrement:
$ curl -X POST http://127.0.0.1:8000/auth/users/ --data 'username=djoser&password=alpine12'
Étape 5: Générez des jetons pour accéder au serveur de flux de conversation
Nous devons maintenant configurer les vues Djoser pour générer des jetons Stream. Commençons donc.
Organisons un peu nos fichiers et créons un dossier d'application de chat dans notre projet (assurez-vous d'être dans le bon répertoire):
$ python manage.py startapp auth
Installez stream-chat:
$ pip install stream-chat
Créez un sérialiseur personnalisé dans
auth/serializers.py
utilisant la logique suivante:
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
Enfin, utilisez un sérialiseur personnalisé pour mettre à jour le fichier
settings.py
:
STREAM_API_KEY = YOUR_STREAM_API_KEY
Redémarrez la migration:
$ python manage.py migrate
Pour vérifier que cela fonctionne, accédez au point de terminaison à l'aide d'une demande POST:
$ curl -X POST http://127.0.0.1:8000/auth/token/login/ --data 'username=djoser&password=alpine12'
Le retour doit ĂŞtre
auth_token
et
stream_token
.
Étape 6: Intégrer l'autorisation React
Pour des raisons évidentes, l'ajout d'une autorisation au frontend est une étape importante. Dans notre cas, cela est particulièrement utile, car nous pouvons extraire le jeton utilisateur de l'API (qui s'exécute sur Python) et l'utiliser dynamiquement lors de l'envoi de messages.
Tout d'abord, installez CORS, le progiciel middleware pour Django:
$ pip install django-cors-headers
Modifiez ensuite le fichier
settings.py
pour faire référence au
djors-cors-header
:
INSTALLED_APPS = ( ... 'corsheaders', ... ) MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ]
Enfin, ajoutez ce qui suit Ă votre fichier
settings.py
:
CORS_ORIGIN_ALLOW_ALL = True
L'étape suivante nécessitera quelques modifications de votre interface. Pour commencer, vous devrez vous assurer que toutes les dépendances sont installées via yarn:
$ yarn add axios react-dom react-router-dom
Ensuite, créez les fichiers suivants dans le répertoire
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;
Assurez-vous de remplacer
YOUR_STREAM_APP_ID
par l'ID d'application Stream valide, qui se trouve sur le
tableau de bord .
Redémarrez l'application sur le front-end et vous verrez l'autorisation! Entrez votre adresse e-mail et votre mot de passe, le jeton sera demandé et stocké dans le stockage local.
Étape 7: envoi de messages depuis le serveur Python
Si vous souhaitez soudainement créer une API de chat à l'aide de votre backend en Python, il existe une commande spéciale que vous pouvez utiliser.
Assurez-vous que les applications installées ressemblent à ceci dans
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', ]
Ensuite, créez le répertoire chat / gestion / commandes. Dans ce répertoire, ajoutez un fichier appelé
broadcast.py
avec le contenu suivant:
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']))
Vous pouvez essayer d'envoyer un message de discussion comme suit:
$ python manage.py broadcast --message hello
Et vous verrez cette réponse:

Dernières pensées
J'espère que vous avez apprécié ce tutoriel sur la création d'une application de chat dans Django, Python et React!
Pour une visite interactive de
Stream Chat , veuillez consulter notre guide sur la création d'une
API sur le site Web de Stream . Si vous aimez fouiller dans le code des composants Stream Chat React, vous pouvez trouver la documentation complète
ici . Si vous souhaitez créer un chat sur Stream, nous sommes heureux de vous proposer divers
SDK pour les langages et frameworks populaires jusqu'au dernier
iOS (Swift) .
C’est tout. Rendez-vous au
webinaire ouvert sur Django ORM Tricks .