Skip to main content

django-pistoke

PyPI Tox Codecov

Django-laajennos, joka mahdollistaa Websocket-pyyntöjen käsittelemisen Django-näkymien kautta tasavertaisesti HTTP-pyyntöjen rinnalla.

Sisältää seuraavat työkalut:

Käyttöönotto

Järjestelmävaatimukset

  • Python 3.6 tai uudempi
  • Django 3.1 tai uudempi
  • ASGI-palvelinohjelmisto (tuotannossa): Daphne, Uvicorn, Hypercorn tms.

Asennus

pip install django-pistoke

Django-projektiasetukset

Lisää Django-projektiasetuksiin:

  • pistoke.Pistoke asennettuihin sovelluksiin (ennen mahdollista staticfiles-sovellusta) ja
  • pistoke.ohjain.WebsocketOhjain asennettuihin ohjaimiin:
# projekti/asetukset.py
...
INSTALLED_APPS = [
  ...
  'pistoke.Pistoke',
  ...
  'django.contrib.staticfiles', # tarvittaessa
  ...
]
MIDDLEWARE = [
  ...
  'pistoke.ohjain.WebsocketOhjain',
]

Tämä järjestys vaaditaan, jotta käsillä olevan paketin toteuttama runserver-komento ohittaa staticfiles-toteutuksen.

Jakeluun sisältyvä django-protoni-yhteensopiva asetuslaajennos (pistoke/asetukset.py) tekee nämä lisäykset automaattisesti.

ASGI-määritys

Luo tai täydennä Django-projektin ASGI-määritystiedosto. Alla kuvattu esimerkkimääritys:

  • alustaa Django-oletuskäsittelijän HTTP-pyynnöille,
  • alustaa Pistoke-käsittelijän Websocket-pyynnöille ja
  • ajaa kunkin saapuvan ASGI-pyynnön oikean käsittelijän läpi, jolloin pyyntö ohjautuu tavanomaisen Django-reititystaulun (ROOT_URLCONF) mukaiselle näkymälle riippumatta sen tyypistä.
# projekti/asgi.py

import os
from django.core.asgi import get_asgi_application
from pistoke.kasittelija import WebsocketKasittelija

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'projekti.asetukset')

kasittelija = {
  'http': get_asgi_application(),
  'websocket': WebsocketKasittelija(),
}

async def application(scope, receive, send):
  return await kasittelija.get(scope['type'])(scope, receive, send)

Ohjaimet

Ohjaimet HTTP-pyynnöllä

Käsillä oleva paketti sisältää tavanomaisen Django/HTTP-ohjaimen pistoke.ohjain.WebsocketOhjain, joka asettaa saapuvalle HTTP-pyynnölle määritteen websocket.

  • tämä sisältää URI-osoitteen, esim. ws://palvelin.org, Websocket-pyyntöjen ohjaamiseksi samalle palvelimelle (http://palvelin.org) kuin kyseinen HTTP-pyyntö;
  • mikäli HTTP-yhteys on salattu (esim. https://palvelin.org), käytetään salattua Websocket-protokollaa: wss://palvelin.org.

Ohjaimet Websocket-pyynnöllä

Tavanomaiset Django-ohjaimet ajetaan Websocket-pyynnölle samalla tavoin kuin HTTP-pyynnölle, pl. HTTP-paluusanoman käsittely.

CSRF-ohjainta muokataan siten, että saapuvan Websocket-pyynnön CSRF-tunnistetta ei yritetä tarkistaa ohjaimessa (sitä ei ole saatavilla ilman POST-dataa). Sen sijaan pyynnölle lisätään metodi tarkista_csrf Websocket-yhteyden kautta vastaanotetun CSRF-datan tarkistamiseksi ajonaikaisesti.

Lisäksi Websocket-pyynnöille käytetään ohjainta, joka tarkistaa web-selaimen asettaman Origin-otsakkeen arvon. Ohjain hyväksyy oletusarvoisesti vain ALLOWED_HOSTS-asetuksen mukaiset pyyntölähteet; muista lähteistä tuleville pyynnöille palautuu hylkäävä paluusanoma (403).

Websocket-protokolla

Kullekin Websocket-pyyntöjä käsittelevälle näkymälle on määriteltävä protokolla, jonka mukaan yhteys luodaan ja katkaistaan ja viestinvälitys tapahtuu.

Näkymä voi joko

  • itse toteuttaa ASGI-määrityksen mukaisen viestinvaihdon ({"type": "websocket.connect"}, {"type": "websocket.send", "text": "..."} jne.),
  • käyttää käsillä olevan paketin tarjoamaa protokollatoteutusta: pistoke.protokolla.WebsocketProtokolla ja sen alaluokat; tai
  • käyttää oletusarvoista protokolla joka otetaan automaattisesti käyttöön.

Protokollaa käytetään sellaisenaan koristeena Websocket-näkymäfunktiolle tai Django-method_decoratorin avulla koristeena näkymäluokan websocket-metodille.

Huomaa, että samaan näkymään liittyvien koristeiden keskinäisellä määritysjärjestyksellä on merkitystä. Kun Websocket-näkymässä käytetään protokollan P lisäksi esimerkiksi Django-pääsynhallintaan liittyvää koristetta D:

  • Mikäli protokolla P on sisempänä (alempana) kuin D, palautuu käyttäjälle tavanomainen HTTP-virhesanoma 401 tai 403, kun oikeudet eivät riitä.
  • Mikäli protokolla P on ulompana (ylempänä) kuin D, avautuu Websocket-yhteys normaalisti myös silloin, kun oikeudet eivät riitä. Yhteys kuitenkin päättyy tällöin heti poikkeukseen.

Huomaa, että käsillä olevan paketin toteuttama automaattinen protokollamääritys muodostaa aina uloimman kerroksen näkymän ympärillä.

Yleiskäyttöisen kantaluokan (WebsocketProtokolla) lisäksi käytettävissä ovat seuraavat, rajatumpiin tilanteisiin soveltuvat protokollat:

  • WebsocketAliProtokolla("protokolla-a", "protokolla-b"): Websocket-aliprotokollamääritys
  • WebsocketJSONProtokolla: JSON-muotoinen viestinvaihto.

Yhteensopivuus: django-pistoke v0.x vs. v1.x

Yhteensopivuuden varmistamiseksi taaksepäin käytetään versioon 1.1 asti seuraavaa automatiikkaa:

  • mikäli Websocket-näkymälle on asetettu jokin edellä mainittu protokolla, sitä käytetään sellaisenaan
  • muussa tapaksessa näkymä koristellaan automaattisesti WebsocketProtokolla-tyyppiseksi.

Versioon 1.2 asti on lisäksi käytettävissä seuraava ohitus edellämainittuun automatiikkaan:

  • mikäli näkymäluokka toteuttaa itse ASGI-viestinvaihdon, tämä voidaan määrittää TyhjaWebsocketProtokolla-koristetta käyttäen.

Websocket-näkymä

Websocket-käsittelijä ohjaa saapuvat pyynnöt Django-näkymille tavanomaisen urlpatterns-reititystaulun mukaisesti. Websocket-pyynnön metodiksi (request.method) asetetaan Websocket. Näkymän toteutus voi olla funktio- tai luokkapohjainen:

  • django.views.generic.View.dispatch ohjaa WS-pyynnön käsiteltäväksi näkymäluokan websocket-metodiin;
  • funktiopohjainen näkymä voi vastata pyynnön metodin perusteella eri tavoin HTTP- ja Websocket-pyyntöihin.

Kummassakin tapauksessa WS-pyynnön käsittelystä vastaavan metodin tai funktion tulee olla tyyppiä async def.

Huomaa, että luokkapohjaisen näkymän tapauksessa Websocket-metodi pitää erikseen sallia näkymäluokalle (HTTP-metodien kuten GET ja POST ohella), jotta tämän tyyppiset pyynnöt sallitaan. Saateluokka pistoke.nakyma:WebsocketNakyma tekee tämän automaattisesti.

Seuraava listaus on esimerkki yhdysrakenteisesta, luokkapohjaisesta näkymätoteutuksesta, joka

  • palauttaa GET-pyynnöllä Django-sivuaihion ja
  • vastaa Websocket-pyyntöön jatkuvana viestivaihtona:
# sovellus/nakyma.py

from django.urls import path
from django.utils.decorators import method_decorator
from django.views import generic

from pistoke.nakyma import WebsocketNakyma
from pistoke.protokolla import WebsocketProtokolla

@method_decorator(WebsocketProtokolla(), name='websocket')
class Nakyma(WebsocketNakyma, generic.TemplateView):
  template_name = 'sovellus/nakyma.html'

  async def websocket(self, request, *args, **kwargs):
    while True:
      syote = await request.receive()
      if isinstance(syote, str):
        await request.send(
          f'Kirjoitit "{syote}".'
        )
      elif isinstance(syote, bytes):
        await request.send(
          f'Kirjoitit "{syote.decode("latin-1")}".'.encode('latin-1')
        )
     # white True
   # async def websocket
 # class Nakyma

urlpatterns = [path('nakyma/', Nakyma.as_view())]

Esimerkki tähän näkymään liittyvästä HTML-aihiosta:

<!-- sovellus/templates/sovellus/nakyma.html -->
<input
  id="syote"
  type="text"
  placeholder="Syötä viesti"
  />
<button
  onclick="websocket.send(document.getElementById('syote').value);"
  >Lähetä</button>
<script>
  websocket = new WebSocket(
    "{{ request.websocket }}{{ request.path }}"
  );
  websocket.onmessage = function (e) { alert(e.data); };
</script>

ASGI-kehityspalvelin

Paketti sisältää runserver-ylläpitokomentototeutuksen (Django-kehityspalvelin), joka periytetään joko:

  • Djangon tavanomaisesta runserver-komennosta tai
  • django.contrib.staticfiles-sovelluksen periyttämästä komennosta, mikäli tämä on asennettu.

Käsillä olevan paketin toteuttama runserver lisää seuraavat vivut edellä mainittuihin toteutuksiin nähden:

  • vipu --wsgi käynnistää tavanomaisen (sisäänrakennetun) WSGI-palvelimen;
  • vipu --asgi käynnistää ASGI-palvelimen (uvicorn-pakettia käyttäen);
  • oletus näistä on ASGI, jos ja vain jos uvicorn on asennettu.

Huomaa, että --asgi-vipu edellyttää Uvicorn-paketin asentamisen ja aiheuttaa poikkeuksen, mikäli tätä ei löydy.

Vakiona runserver-komennon hyväksymä --verbose-vipu hyväksyy, silloin kuin käytössä on --asgi-tila, tavanomaisten numeroarvojensa (0–3) lisäksi myös uvicorn --log-level-vivun hyväksymät tekstimuotoiset määreet:

  • critical: vastaa Django-tasoa 0
  • error
  • warning
  • info: vastaa Django-tasoa 1
  • debug: vastaa Django-tasoa 2
  • trace: vastaa Django-tasoa 3

Palvelinasennus

Palvelinasennukseen sopii hyvin vaikkapa yhdistelmä Nginx + Circus + Uvicorn; ks. https://www.uvicorn.org/deployment/#running-behind-nginx.

Käyttöesimerkkejä

  • Reaaliaikainen keskusteluyhteys kahden käyttäjän välillä: django-juttulaatikko
  • Datan reaaliaikainen, kaksisuuntainen synkronointi Django-palvelimen ja selaimen välillä Websocket-yhteyden välityksellä: django-synkroni
  • Xterm-pääteyhteys Django-sovelluksena: django-xterm
  • Django-ilmoitusten (messages) reaaliaikainen toimitus selaimelle Celery-pinon ja Websocket-yhteyden avulla: django-celery-ilmoitus
  • jQuery-Datatables-liitännäinen Websocket-pohjaiseen tiedonsiirtoon erillisten Ajax-pyyntöjen asemesta: datatables-websocket

Metadata

Release files for django-pistoke 0.9.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-pistoke 0.9.11
File Size Uploaded
django_pistoke-0.9.11.tar.gz 26.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-pistoke 0.9.11
File Interpreter ABI Platform
django_pistoke-0.9.11-py3-none-any.whl Python 3 none any Details

Total release size: 56.9 kB

Release files / django_pistoke-0.9.11.tar.gz

Download URL django_pistoke-0.9.11.tar.gz
Size 26.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2c79e9e08b8f061a600eb09a25993d73b72ba391c8f5618e5d62513b4955e7b8
BLAKE2b-256 checksum
How to use checksums
1f20cd9e6e2073be725e3677eddcc0b47589cba0e8bfc974aaf5b25dbd80f208
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2025.

Transparency log

Release files / django_pistoke-0.9.11-py3-none-any.whl

Download URL django_pistoke-0.9.11-py3-none-any.whl
Size 30.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bf3cdc1e7f6321f3cb50fbc410a3378b3637ec1b5eb0b4ceb27bc623f94dface
BLAKE2b-256 checksum
How to use checksums
6e2bf68dbef0307e8ee8cb5cd7727f34cdc7722c6e474bcf47abf672b793455a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.11 This release

2 release files

0.9.10

2 release files

0.9.8

2 release files

0.9.7

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9

2 release files

0.8

2 release files

0.7.1

2 release files

0.5.3

2 release files

0.2.2

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page