PythonAnywhere
PythonAnywhere on selaimessa toimiva Python-ympäristö, johon saa julkaistua web-sovelluksen ilman omaa palvelinta tai asennuksia. Kurssilla sitä käytetään viikkotehtävissä 1 ja 3.
Kurssin aikana samanlaisia Flask-sovelluksia ajetaan kolmella eri tavalla:
PythonAnywheressä WSGI-rajapinnan
kautta, users.jyu.fi-palvelimella
CGI-ohjelmana ja
lopuksi Cloud Runissa konttina. Sovelluskoodi on kaikissa sama; vain
käynnistystapa ja ympäristön rajoitukset vaihtuvat. Siksi kannattaa opetella,
mikä kussakin on erilaista.
Tili
Rekisteröityessä valittu käyttäjänimi näkyy sovelluksen osoitteessa muodossa
https://kayttajanimi.pythonanywhere.com/, eikä sitä voi jälkikäteen
vaihtaa. Valitse siis nimi, jonka kehtaa laittaa palautukseen.
Ilmaistili riittää kurssin tehtäviin, mutta sen ehdot ovat kiristyneet vuoden 2026 alusta. Olennaisimmat:
- Käyttämätön web-sovellus vanhenee kuukaudessa. Sovellus on käytävä uusimassa Web-välilehdeltä painikkeella, muuten se lakkaa toimimasta kesken kurssin. Tämä tulee vastaan käytännössä jokaisella.
- Tuki on yhteisöpohjaista. Ilmaistileille ei anneta henkilökohtaista tukea, vaan apua haetaan foorumilta ja ohjesivuilta.
- Uusilla ilmaistileillä ei ole MySQL-kantaa eikä ajastettuja tehtäviä. Ne ovat siirtyneet maksullisiin tasoihin. Kurssin tehtäviin riittää SQLite, joka on tavallinen tiedosto eikä vaadi erillistä tietokantapalvelinta.
Muutokset on kuvattu palvelun blogikirjoituksessa Changes on PythonAnywhere Free Accounts. Ehdot muuttuvat aika ajoin, joten tarkista voimassa olevat rajat palvelun omilta sivuilta.
Käyttöliittymä
| Välilehti | Mitä siellä tehdään |
|---|---|
| Consoles | Bash-pääte ja Python-tulkki selaimessa. Täällä luodaan virtuaaliympäristö, asennetaan paketteja ja haetaan koodi versionhallinnasta. |
| Files | Tiedostojen selaaminen, lataaminen ja selaimessa toimiva editori. |
| Web | Web-sovelluksen asetukset: WSGI-konfiguraatiotiedosto, virtuaaliympäristön polku, staattiset tiedostot, lokit ja Reload-painike. |
| Databases | MySQL- ja Postgres-kannat. Ilmaistilillä ei käytettävissä. |
| Tasks | Ajastetut tehtävät. Ilmaistilillä ei käytettävissä. |
Web-sovelluksen luominen
Web-välilehdellä valitaan Add a new web app. Kysymyksiä tulee kolme:
- Osoite. Ilmaistilillä se on
kayttajanimi.pythonanywhere.com, eikä vaihtoehtoja ole. - Sovelluskehys. Valitse Manual configuration, jos haluat kirjoittaa WSGI-konfiguraatiotiedoston itse, tai Flask, jolloin palvelu luo valmiin runkosovelluksen. Kurssin kannalta manuaalinen on opettavaisempi, koska silloin näkee, mikä sovelluksen oikeasti käynnistää.
- Python-versio. Tätä ei voi vaihtaa jälkikäteen — version vaihtaminen tarkoittaa sovelluksen poistamista ja uuden luomista. Valitse sama versio, jota käytät omalla koneellasi.
Sovellus syntyy kotihakemistoosi, oletuksena kansioon mysite.
Valmis sovellus vastaa heti osoitteessaan; HTTPS-varmenne tulee automaattisesti
pythonanywhere.com-alidomainille.
WSGI-konfiguraatiotiedosto
Tämä on se kohta, joka hämmentää eniten. PythonAnywhere ei suorita
sovellustiedostoasi suoraan, vaan lukee Web-välilehdellä mainitun
WSGI configuration file -tiedoston ja etsii siitä
application-nimistä oliota. Flask-sovelluksessa se on oma
app-olio uudelleen nimettynä:
import sys
#Oman koodin kansio on lisättävä hakupolkuun, muuten importti ei löydä sitä.
polku = "/home/oma_tunnus/mysite"
if polku not in sys.path:
sys.path.insert(0, polku)
#oma.py sisältää rivin app = Flask(__name__)
from oma import app as application
Sisällöltään tämä vastaa users.jyu.fi-palvelimen
flask.cgi-tiedostoa: molemmat ovat käärekoodia, joka kertoo
palvelimelle, mistä sovellus löytyy.
Virtuaaliympäristö
Palvelussa on valmiina joukko yleisiä kirjastoja, myös Flask. Virtuaaliympäristöä tarvitaan, kun haluat tietyn version kirjastosta tai paketin, jota ei ole valmiina. Se luodaan Consoles-välilehden bash-päätteessä:
mkvirtualenv --python=/usr/bin/python3.12 oma-ymparisto
pip install Flask Flask-WTF
Tämän jälkeen ympäristön polku on kirjoitettava Web-välilehden
Virtualenv-kenttään, esimerkiksi
/home/oma_tunnus/.virtualenvs/oma-ymparisto. Pelkkä asentaminen ei
riitä: ilman kenttään kirjoitettua polkua sovellus käyttää yhä järjestelmän omaa
Pythonia eikä löydä asentamiasi paketteja. Tämä on yksi yleisimmistä
ImportError-virheen syistä.
Reload
WSGI-sovelluksessa Python-tulkki jää muistiin pyyntöjen välillä. Muokattu koodi tulee käyttöön vasta, kun sovellus käynnistetään uudelleen Web-välilehden Reload-painikkeella. Sama koskee virtuaaliympäristön ja asetusten muutoksia.
Tämä on ylivoimaisesti yleisin hämmennyksen aihe: koodi on muutettu ja
tallennettu, mutta selain näyttää yhä vanhaa. Huomaa ero
users.jyu.fi-palvelimeen, jossa CGI käynnistää tulkin joka pyynnöllä
uudelleen eikä uudelleenkäynnistystä tarvita.
Lokit ja virheiden etsiminen
Kun sovellus ei toimi, selaimeen tulee lakoninen Something went wrong -sivu. Varsinainen virheilmoitus on lokitiedostoissa, jotka löytyvät Web-välilehden Log files -kohdasta.
| Loki | Sisältö |
|---|---|
error.log |
Virheilmoitukset ja pinolistaukset eli kaikki standardivirheeseen kirjoitettu. Katso tänne ensin. |
server.log |
Sovelluksen käynnistykset ja standarditulostus, eli myös
print-kutsujen tulosteet. |
access.log |
Kuka on ladannut minkäkin resurssin ja milloin. |
import sys
print("tämä näkyy server.logissa")
print("tämä näkyy error.logissa", file=sys.stderr)
Virheet saa myös suoraan selaimeen lisäämällä WSGI-konfiguraatiotiedoston loppuun:
from werkzeug.debug import DebuggedApplication
application.debug = True
application = DebuggedApplication(application)
Muista, että pinolistaukset paljastavat lähdekoodia kaikille sivun avaajille, joten tämä on vain kehitysapu.
PythonAnywheressä print menee lokiin ja on siksi kelvollinen
pikainen debuggauskeino. users.jyu.fi-palvelimella sama rivi menisi
CGI-ohjelmassa suoraan selaimelle ja rikkoisi vastauksen. Jos haluat kirjoittaa
koodia, joka toimii molemmissa, käytä
app.logger-lokitusta.
Staattiset tiedostot
Tyylitiedostot, kuvat ja skriptit kannattaa tarjoilla palvelimelta suoraan eikä Flaskin läpi. Web-välilehden Static files -taulukkoon lisätään rivi, jossa vasemmalla on osoite ja oikealla hakemistopolku:
/static/ /home/oma_tunnus/mysite/static/
Templateissa osoitteet muodostetaan tästä huolimatta tavalliseen tapaan
url_for-funktiolla:
<link rel="stylesheet" href="{{ url_for('static', filename='tyyli.css') }}" />
Koodin siirtäminen palvelimelle
Vaihtoehtoja on kolme: selaimen editori Files-välilehdellä, tiedoston lataaminen ja versionhallinta. Käytä versionhallintaa. Kurssilla koodi on joka tapauksessa GitLabissa, ja silloin muutokset siirtyvät yhdellä komennolla eivätkä versiot pääse eroamaan toisistaan:
git clone https://gitlab.jyu.fi/oma_tunnus/vt1.git
cd vt1
git pull #jatkossa muutokset haetaan näin
Muista git pull -komennon jälkeen Reload.
Tietokanta
Uusilla ilmaistileillä MySQL ei ole käytettävissä. Se ei haittaa, koska kurssin tehtävissä käytetään SQLiteä, joka on yhdessä tiedostossa eikä vaadi tietokantapalvelinta.
Sijoita kantatiedosto kansioon, jota ei tarjoilla staattisena hakemistona — muuten kuka tahansa voi ladata koko kannan selaimellaan. Sama koskee sessiotiedostoja ja lokeja.
Salaiset avaimet ja asetukset
Salaista avainta tai tunnuksia ei kirjoiteta lähdekoodiin eikä versionhallintaan. PythonAnywheressä ne on helpointa asettaa ympäristömuuttujiksi WSGI-konfiguraatiotiedostossa, joka ei ole osa versionhallittua projektia:
import os
os.environ["SECRET_KEY"] = "tähän arvottu avain"
from oma import app as application
Sovellus lukee arvon tavalliseen tapaan:
app.secret_key = os.environ["SECRET_KEY"]
Avaimen voi arpoa komennolla
python3 -c "import secrets; print(secrets.token_hex(32))". Huomaa, että
ympäristömuuttujat on asetettava ennen sovelluksen tuontia.
Ilmaistilin rajoitukset
- Ulkoiset verkkoyhteydet toimivat vain sallittujen sivustojen listalta. Kurssin oma palvelin ei ole listalla, joten esimerkiksi viikkotehtävän 2 asetustiedostoa ei voisi hakea täältä. Tämä on yksi syy siihen, miksi kaikkia tehtäviä ei tehdä PythonAnywheressä.
- Prosessoriaikaa on päivittäinen kiintiö. Kun se loppuu, sovellus ei kaadu mutta hidastuu selvästi. Kiintiö nollautuu vuorokausittain.
- Yksi web-sovellus tiliä kohti.
- Ei ajastettuja tehtäviä eikä MySQL-kantaa uusilla ilmaistileillä.
- Oma verkkotunnus vaatii maksullisen tilin.
Erot users.jyu.fi-palvelimeen
| PythonAnywhere (WSGI) | users.jyu.fi (CGI) | |
|---|---|---|
| Käynnistystiedosto | WSGI-konfiguraatiotiedosto | flask.cgi |
| Prosessimalli | Tulkki jää muistiin | Uusi tulkki joka pyynnölle |
| Koodimuutos käyttöön | Reload-painikkeella | Heti seuraavalla pyynnöllä |
print-tuloste |
Menee lokiin | Menee selaimelle ja rikkoo vastauksen |
| Lokit | Luettavissa Web-välilehdeltä | Ei pääsyä; kirjoitettava omaan tiedostoon |
| Tiedosto-oikeudet | Ei tarvitse säätää | Tarkat vaatimukset, ks. pääteohjaus 1 |
| Ulkoiset yhteydet | Vain sallitulta listalta | Vapaasti |
Kummassakaan ympäristössä sovelluksen tilaa ei voi säilyttää globaalissa muuttujassa: CGI:ssä tulkki nollautuu joka pyynnöllä, ja WSGI-sovelluskin käynnistetään uudelleen milloin tahansa.
Yleisimmät virheet
| Oire | Todennäköinen syy |
|---|---|
| Muutokset eivät näy selaimessa | Reload painamatta |
ImportError lokissa |
Virtualenv-kenttä tyhjä, väärä polku
sys.path-lisäyksessä tai väärä moduulin nimi |
| Something went wrong | Sovellus kaatui käynnistyessä — katso error.log |
| Tyylitiedosto tai kuva 404 | Static files -rivi puuttuu tai polun lopusta puuttuu kauttaviiva |
| Ulkoinen haku ei toimi | Osoite ei ole sallittujen listalla |
| Sovellus lakkasi toimimasta itsestään | Käyttämätön web-sovellus vanheni — uusi se Web-välilehdeltä |
| Sivu latautuu hitaasti | Päivittäinen prosessoriaikakiintiö täynnä |
Lisätietoa
- PythonAnywhere Help — ohjesivut ja tutoriaalit
- PythonAnywhere Forums — palvelun oma keskustelufoorumi. Ilmaistileillä tuki on yhteisöpohjaista, joten tämä on ensisijainen paikka hakea apua. Moni pulma on jo kysytty ja vastattu.
- Flask PythonAnywheressä
- Sallittujen sivustojen lista
- Changes on PythonAnywhere Free Accounts
- WSGI, CGI ja Flask ja Flask
Käyttäjien kommentit