Schreibe einen Chat in Python und Django

Guten Tag, Freunde. Im Vorgriff auf den Start des Python Web Developer- Kurses teilen wir Ihnen traditionell eine nützliche Übersetzung mit.




Vor Ihnen sehen Sie eine Anleitung, die Ihnen erklärt, wie Sie eine Chat-Anwendung in Python, Django und React erstellen.

Im Gegensatz zu anderen Handbüchern verwende ich Python und Django nicht für WebSocket-Verbindungen. Obwohl es aus technischer Sicht cool klingt, funktioniert es ziemlich träge und ist an sich teuer, insbesondere wenn Sie eine anständige Anzahl von Benutzern haben. Sprachen wie C ++, Go und Elixir machen den Chatkern viel besser.

In diesem Tutorial werden wir Stream verwenden, eine Chat-API , die sich mit Go, Raft und RocksDB um WebSocket-Verbindungen und andere wichtige Aspekte kümmert.

Inhalt:

  • Demo-Chat-Oberfläche reagieren
  • Installieren Sie Django / Python
  • Benutzerberechtigung
  • Django Rest Framework
  • Token-Generierung für den Zugriff auf den Chat-Stream-Server
  • Integration der Reaktionsberechtigung
  • Senden von Nachrichten von einem Python-Server
  • Letzte Gedanken

Github-Repository mit Code aus einem Artikel

Fangen wir an!

Schritt 1: Reagieren Sie auf die Demo-Chat-Oberfläche


Bevor wir uns mit dem Python-Teil befassen, wollen wir eine einfache Oberfläche für React bereitstellen, damit wir etwas Schönes und Visuelles haben:

$ yarn global add create-react-app $ brew install node && brew install yarn # skip if installed $ create-react-app chat-frontend $ cd chat-frontend $ yarn add stream-chat-react 

Ersetzen Sie den Code in src/App.js durch den folgenden Code:

 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; 

Verwenden Sie jetzt den Befehl yarn start , um den Chat in Aktion zu sehen!

Schritt 2: Django / Python installieren (überspringen Sie diesen Schritt, wenn Sie bereits alles haben, was Sie brauchen)


Stellen Sie sicher, dass Sie Python 3.7 verwenden und es ausgeführt wird:

 $ brew install python3 $ pip install virtualenv virtualenvwrapper $ export WORKON_HOME=~/Envs $ source /usr/local/bin/virtualenvwrapper.sh $ mkvirtualenv chatexample -p `which python3` $ workon chatexample 

Wenn es nicht funktioniert, probieren Sie den folgenden Code:

 $ python3 -m venv chatexample $ source chatexample/bin/activate 

Jetzt, da Sie sich in Ihrer virtuellen Umgebung befinden, sollten Sie Python 3 beim Start sehen:

 $ python --version 

Verwenden Sie den folgenden Code, um ein neues Projekt in Django zu erstellen:

 $ pip install django $ django-admin startproject mychat 

Führen Sie die Anwendung aus:

 $ cd mychat $ python manage.py runserver 

Wenn Sie nun http://localhost:8000 öffnen, sehen Sie Folgendes:



Schritt 3: Benutzerautorisierung


Der nächste Schritt ist die Konfiguration der Benutzerautorisierung in Django.

 $ python manage.py migrate $ python manage.py createsuperuser $ python manage.py runserver 

Gehen Sie zu http://localhost:8000/admin/ und melden Sie sich an. Voila!

Sie sehen eine Administratorregisterkarte ähnlich der folgenden:



Schritt 4: Django Rest Framework


Eines meiner Lieblingspakete für die Integration von React in Django ist das Django Rest Framework. Damit es funktioniert, müssen Sie Endpunkte erstellen für:

  • Benutzerregistrierung
  • Benutzeranmeldung.

Wir könnten sie selbst herstellen, aber es gibt ein Paket namens Djoser , das dieses Problem löst. Es werden die erforderlichen API-Endpunkte für die Benutzerregistrierung, die Anmeldung, das Zurücksetzen des Kennworts usw. konfiguriert.

Verwenden Sie zum Installieren von Djoser Folgendes:

 $ pip install djangorestframework djoser 

Bearbeiten Sie danach urls.py und ändern Sie den Inhalt der Datei wie folgt:

 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')), ] 

Wenn Sie fertig sind, bearbeiten Sie settings.py und nehmen Sie Änderungen vor:

 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', ) } 

Weitere Informationen zu den von Djoser bereitgestellten API-Endpunkten finden Sie im Folgenden:

https://djoser.readthedocs.io/en/latest/sample_usage.html

Nun machen wir weiter und testen den Registrierungsendpunkt:

 $ curl -X POST http://127.0.0.1:8000/auth/users/ --data 'username=djoser&password=alpine12' 

Schritt 5: Generieren Sie Token, um auf den Chat-Stream-Server zuzugreifen


Jetzt müssen wir Djoser-Ansichten konfigurieren, um Stream-Token zu generieren. Also fangen wir an.
Lassen Sie uns unsere Dateien ein wenig organisieren und einen Chat-Anwendungsordner in unserem Projekt erstellen (stellen Sie sicher, dass Sie sich im richtigen Verzeichnis befinden):

 $ python manage.py startapp auth 

Installieren Sie den Stream-Chat:

 $ pip install stream-chat 

Erstellen Sie einen benutzerdefinierten Serializer in auth/serializers.py mit der folgenden Logik:

 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 

Verwenden Sie zuletzt einen benutzerdefinierten Serializer, um die Datei settings.py zu aktualisieren:

 STREAM_API_KEY = YOUR_STREAM_API_KEY # https://getstream.io/dashboard/ STREAM_API_SECRET = YOUR_STREAM_API_SECRET DJOSER = { 'SERIALIZERS': { 'token': 'auth.serializers.StreamTokenSerializer', } } 

Starten Sie die Migration neu:

 $ python manage.py migrate 

Um zu überprüfen, ob es funktioniert, rufen Sie den Endpunkt mit einer POST-Anforderung auf:

 $ curl -X POST http://127.0.0.1:8000/auth/token/login/ --data 'username=djoser&password=alpine12' 

Return sollte auth_token und stream_token .

Schritt 6: React Authorization einbinden


Aus offensichtlichen Gründen ist das Hinzufügen von Berechtigungen zum Frontend ein wichtiger Schritt. In unserem Fall ist dies besonders nützlich, da wir das Benutzertoken aus der API (die auf Python ausgeführt wird) extrahieren und beim Senden von Nachrichten dynamisch verwenden können.

Installieren Sie zunächst CORS, das Middleware-Paket für Django:

 $ pip install django-cors-headers 

Ändern Sie anschließend die Datei settings.py , um auf die djors-cors-header zu verweisen:

 INSTALLED_APPS = ( ... 'corsheaders', ... ) MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ] 

Fügen Sie Ihrer settings.py Datei abschließend Folgendes hinzu:

 CORS_ORIGIN_ALLOW_ALL = True 

Der nächste Schritt erfordert einige Änderungen an Ihrer Benutzeroberfläche. Bevor Sie beginnen, müssen Sie sicherstellen, dass alle Abhängigkeiten über Woll installiert sind:

 $ yarn add axios react-dom react-router-dom 

Erstellen Sie als Nächstes die folgenden Dateien im Verzeichnis 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; 

Ersetzen Sie YOUR_STREAM_APP_ID durch die gültige Stream-App-ID, die im Dashboard YOUR_STREAM_APP_ID .

Starten Sie die Anwendung auf dem Frontend neu und Sie sehen die Autorisierung! Geben Sie Ihre E-Mail-Adresse und Ihr Passwort ein. Der Token wird angefordert und lokal gespeichert.

Schritt 7: Senden von Nachrichten vom Python-Server


Wenn Sie plötzlich eine Chat-API mit Ihrem Backend in Python erstellen möchten, gibt es einen speziellen Befehl, den Sie verwenden können.

Stellen Sie sicher, dass die installierten Anwendungen in settings.py folgendermaßen aussehen:

 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', ] 

Als nächstes erstellen Sie das Verzeichnis chat / management / commands. Fügen Sie in diesem Verzeichnis eine Datei mit dem Namen broadcast.py mit folgendem Inhalt hinzu:

 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'])) 

Sie können versuchen, eine Chat-Nachricht wie folgt zu senden:

 $ python manage.py broadcast --message hello 

Und Sie werden diese Antwort sehen:



Letzte Gedanken


Ich hoffe, Ihnen hat dieses Tutorial zum Erstellen einer Chat-Anwendung in Django, Python und React gefallen!

Eine interaktive Tour durch Stream Chat finden Sie in unserer Anleitung zum Erstellen einer API auf der Stream-Website . Wenn Sie gerne im Code für Stream Chat React-Komponenten stöbern, finden Sie die vollständige Dokumentation hier . Wenn Sie einen Chat auf Stream erstellen möchten, bieten wir verschiedene SDKs für gängige Sprachen und Frameworks bis zum neuesten iOS (Swift) an .

Das ist alles. Wir sehen uns beim offenen Webinar zu Django ORM Tricks .

Source: https://habr.com/ru/post/de475672/


All Articles