pythonanywhere

Z Wikiverzity

pythonanywhere je webhosting, zaměřený na python v cloudu. Rovněž má výhodnou nabídku pro učitele, kteří chtějí učit své žáky python, což přímo svádí k tomu, založit takový kurs zde na Wikiverzitě.

Na této stránce budeme zkoumat možnosti, které tento projekt nabízí.

Info[editovat]

Podstránky[editovat]

Účastníci kursu:

Beginner: Free![editovat]

Bezplatný účet, který nabízí limitovaný account na jednu webovou sajtnu ve tvaru username.pythonanywhere.com.

Vytvoření účtu[editovat]

  • Jdeme na stránku: https://www.pythonanywhere.com/pricing/
  • Klikneme na Create a Beginner account
  • Zvolíme si uživatelské jméno (username), uvedeme svůj e-mail, zvolíme heslo a zaškrtneme souhlas s podmínkami.
  • Klikneme na Register
  • Jsme přesměrováni na krátký úvodní kurs (tour):

Consoles[editovat]

Máme k disposici dva druhy konsolí (příkazových řádků):

  1. python – provádí příkazy pythonu
  2. bash – provádí systémové příkazy (terminál)

U pythoní konsole si mohu vybrat verzi Pythonu: 2.7, 3.6, 3.7

Files[editovat]

Panel ukazuje nedávno editované soubory; můžeme rovněž otevřít jiný soubor anebo založit nový

Webs apps[editovat]

Kliknutím na záložku Open Web spustíme webovou aplikaci.

Notebooks[editovat]

Jupyter Notebooks – pouze pro placené účty.

Dashboard[editovat]

Nástěnka či hlavní panel – pomocí tabů vybíráme a otavíráme výše zmíněné konsoly, soubory a aplikace a také nastavujeme databáze a úlohy (tasks).

Další zdroje informací[editovat]

URL[editovat]

  • Webová stránka ve tvaru: username.pythonanywhere.com
  • Dashboard ve tvaru: username.pythonanywhere.com/user/username/

Konfirmace e-mailové adresy[editovat]

Na naši e-mailovou adresu nám mezitím dorazil e-mail, kde kliknutím potvrdíme správnost našeho e-mailu; to nám později umožní např. resetovat zapomenuté heslo.

Omezení[editovat]

Účet Beginner: Free! má oproti placeným účtům svá omezení:

Console[editovat]

Pod svým účtem mohu mít otevřeny najednou maximálně 2 konsole. Do jisté míry se to dá obejít tím, že si mohu udělat více účtů (pro jednoduchost je mohu udělat svými studenty – viz níže) a můžu si je vzájemně sdílet mezi sebou.

Soubory[editovat]

  • Quota: 512.0 MB

Education beta[editovat]

Projekt umožňuje, že si studenti vyberou svého učitele, se kterým si pak mohou prohlížet a sdílet své soubory, konsole, databáze a webové aplikace:

  • Pokud chci být v roli studenta, kliknu vpravo nahoře na Account
  • V tabech kliknu na Teacher
  • Zobrazí se: Nominate your teacher a upozornění, že učitel bude mít přístup k mým souborům atd., takže nominuji pouze toho, v koho mám plnou důvěru
  • 'Enter your teacher's username: vložím username svého učitele, například kychot
  • Pokud už nechci, aby byl mým učitelem, kliknu na něj a mohu jej opět zrušit

Omezení:

  • server-side prostředí, komunikuje se pouze textově, bez grafiky. Pokud by to začátečníkům vadilo, mohou zkusit https://trinket.io/
  • věk 13 let a výše
  • sdílení konsolí je dynamické, editační sezení prozatím nikoli

Další informace:

Až budeme mít vytvořený účet, spustíme si následující tutoriál:

Nasazení aplikace[editovat]

Máme aplikaci, kterou jsme si vyvinuli a otestovali třeba na lokálním počítači, a chceme ji nasadit (deployment) na PythonAnywhere. Dejme tomu se učíme Flask podle seriálu Flask/Grinberg. A zkusíme si na PythonAnywhere uploadovat třeba hned ten nejjednodušší příklad: Flask/Grinberg/01 - Nazdárek!#A "Hello, World" Flask Application

Jak to udělat? Pomoc najdeme na:

Postup:

  1. upload kódu na PythonAnywhere
  2. nastavení virtualenv, pokud ho potřebujeme
  3. konfigurace aplikace pomocí WSGI

Upload kódu[editovat]

Je vícero možností, které jsou podrobněji popsány zde: https://help.pythonanywhere.com/pages/UploadingAndDownloadingFiles :

  • Otevřeme si tab Files a jednotlivé soubory uploadujeme oranžovým ťuflíkem ⮉ Upload a file
  • Pokud máme svůj kód na Gitlab, Github apod., otevřeme si bash consoli a uděláme git klon
  • Naše soubory si zazipujeme, uploadujeme a rozzipujeme
  • Další možnosti jsou pouze pro placené acounty:

Z nějakého důvodu mi nejde kliknutím vytvořit nový adresář, např. mysite. Ale z bash console to jde udělat. A nemusím zipovat, můžu i tarovat anebo co chci.

virtualenv[editovat]

Nemusíme používat, pouze pokud máme nějaké problémy, že ta aplikace vytvořená doma nebude fungovat v prostředí, které je na PythonAnywhere. Co tu mají nainstalovaného, to najdeme na:

Pokud chceme něco navíc, co tu nemají, musíme si to udělat sami přes virtualenv, viz návod zde:

Virtuální prostředí si uděláme v adresáři /home/myusername/.virtualenvs/virtualenvname

Konfigurace naší aplikace[editovat]

Manuální WSGI konfigurace: Musíme nakonfigurovat WSGI soubor, který importuje naši aplikaci jako Pythonovskou proměnnou. To znamená, že musíme dát vědět dvě věci:

  1. cestu k pythonímu souboru, obsahujícímu WSGI soubor naší aplikace
  2. jméno aplikace

V případě Flasku je WSGI aplikace invokována kódem:

app = Flask(__name__)

Jdeme tedy na tab Web, klikneme na Add new web app a zvolíme Manual configuration. Pak klikneme na End. Tím nám bude vygenerován WSGI soubor, který můžeme editovat. Ten soubor se vytvoří zde:

  • /var/www/username_pythonanywhere_com_wsgi.py

Tento soubor může vypadat například takto:

# This file contains the WSGI configuration required to serve up your
# web application at http://<your-username>.pythonanywhere.com/
# It works by setting the variable 'application' to a WSGI handler of some
# description.
#
# The below has been auto-generated for your Flask project

import sys

# add your project directory to the sys.path
project_home = u'/home/kychot/mysite'
if project_home not in sys.path:
    sys.path = [project_home] + sys.path

# import flask app but need to call it "application" for WSGI to work
from flask_app import app as application  # noqa

Problém s konfigurací[editovat]

My máme v konfiguračním souboru:

import sys
path = '/home/kychot/mysite'
if path not in sys.path:
    sys.path.append(path)

from flask_app import app as application  # ⚠️ výstražný trojúhelník – něco zde je špatně!

Když aplikaci spustíme, dostaneme:

Something went wrong :-(
Error code: Unhandled Exception

Podíváme se tedy do error.log, jak nám radí dále:

Error running WSGI application
ModuleNotFoundError: No module named 'flask_app'
File "/var/www/hesla_pythonanywhere_com_wsgi.py", line 6, in <module>
     from flask_app import app as application

Modul v pythonu je to, co je v nějakém podadresáři, jestli to správně chápu. A já mám celou aplikaci v podadresáři:

/home/kychot/mysite/app/

Tedy právě kromě toho jediného souboru flask_app, který mám o adresář výše, tedy:

/home/kychot/mysite/

Protože na konfigurační stránce Web mám nastaveno:

Source code: /home/kychot/mysite

Ale možná, že ten můj soubor /home/kychot/mysite/flask_app je teď už zbytečný, když má jen jediný řádek:

from app import app

a v podstatě ten samý už mám v tom výše uvedeném konfiguračním souboru /var/www/kychot_pythonanywhere_com_wsgi.py

Takže možná stačí jen na té konfigurační stránce Web mám nastavit skutečně ten adresář s moduly:

Source code: /home/kychot/mysite/app

A ještě musím kliknout na Reload.

No … nepomohlo. Ale vzpomínám, jak Grinberg vysvětloval tu záludnost s tím, když psal from app import app, takže do kychot_pythonanywhere_com_wsgi.py napíšeme:

from app import app as application

a voilà, funguje!

Ale stejně nám na tom řádku pořád svítí ten výstražný žlutý trojúhelníček říkající: 'app.app as application' imported but unused

Ale když to as application vyhodím a spustím, tak mi error.log zase zahlásí:

Error running WSGI application
AttributeError: module 'kychot_pythonanywhere_com_wsgi' has no attribute 'application'

Tak to zase vrátím zpátky a asi to už nebudu řešit.

Tím pádem skutečně ten soubor /home/kychot/mysite/flask_app mohu klidně vymazat. Jo jo, funguje to i bez něj!

Náš objev nám teď ukázal možnost, mít v adresáři /home/kychot/mysite/ hromadu různých podadresářů s různými aplikacemi, a vybírat si z nich pouze přenastavením Source code na konfigurační stránce Web.

Tak tedy přejmenujeme /home/kychot/mysite/app na /home/kychot/mysite/app01 a stejně tak změníme to nastavení. To se mi ale nepodařilo naklikat, takže si musím otevřít bash konsoli:

~/mysite $ mv app app01

Spustím – aha! Není to tak jednoduché, ještě to musím změnit v tom kychot_pythonanywhere_com_wsgi.py:

from app01 import app as application

Hmmm… a ještě ne. Error log zase hlásí:

Error running WSGI application
ModuleNotFoundError: No module named 'app'
  File "/var/www/hesla_pythonanywhere_com_wsgi.py", line 48, in <module>
    from app01 import app as application # noqa

  File "/home/hesla/mysite/app01/__init__.py", line 5, in <module>
    from app import routes

Tak to asi bude složitější… Zkusíme tedy zvolit jinou obezličku – vrátime konfiguraci zpátky na app, jenom ten adresář necháme přejmenovaný na app01 a pomůžeme si symlinkem:

~/mysite $

– tedy v opačném pořadí – nejdříve ten symlink a pak změnu konfigurace, porotože jinak nám to zase vynadá, že ten adresář neexistuje.

Hurá! sežralo to.

Webforms[editovat]

Postupně jsme vyzkoušeli všechny naše aplikace, které nám na lokálu běželi, a to až do kapitoly Flask/Grinberg/03 - Formuláře – kde se opět objevil nějaký problém. A kupodivu ten samý, co předtím:

Error running WSGI application
ModuleNotFoundError: No module named 'app'
  File "/var/www/hesla_pythonanywhere_com_wsgi.py", line 48, in <module>
    from app import app as application

Tuším problém – protože tady jsme v lokální implementaci nad adresářem /app měli ještě soubor config.py, ve kterém bylo:

import os

class Config(object):
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'

Když tento soubor vyndáme z lokální implementace, dostaneme chybu:

Error: While importing "app", an ImportError was raised:

Traceback (most recent call last):
  File "/home/petr/.local/lib/python3.6/site-packages/flask/cli.py", line 240, in locate_app
    __import__(module_name)
  File "/p7/DATAp7/www/py/flask/local/blog.miguelgrinberg.com/03a-WebForms/app/__init__.py", line 2, in <module>
    from config import Config
ModuleNotFoundError: No module named 'config'

Ale proč ta samá chyba tedy nevyjede v error.log na PythonAnywhere? Asi jsme blbě koukali či co, teď už to tam máme"

Error running WSGI application
ModuleNotFoundError: No module named 'config'
  File "/var/www/kychot_pythonanywhere_com_wsgi.py", line 48, in <module>
    from app import app as application
 
   File "/home/kychot/mysite/app/__init__.py", line 2, in <module>
     from config import Config

Tak co s tím? Že bychom tyto řádky z config.py dodali do kychot_pythonanywhere_com_wsgi.py ?

Zkusíme to – a zase nic :-(

Hmm, tak tu konfiguraci asi musíme strčit do /app/__init__.py

Hurá, to zabralo!

Akorát, že zase dostaneme tu známou chybu Method Not Allowed, kterou jsme naštěstí už řešili – viz Flask/Grinberg/03 - Formuláře. Takže asi musíme spustit tu opravenou verzi.

Databáze[editovat]

Zkusime uploadovat náš pokus podle Flask/Grinberg/04 - Databáze. A ejhle, první problém:

Error running WSGI application
ModuleNotFoundError: No module named 'flask_migrate'
  File "/var/www/kychot_pythonanywhere_com_wsgi.py", line 48, in <module>
    from app import app as application # noqa

  File "/home/kychot/mysite/app/__init__.py", line 9, in <module>
    from flask_migrate import Migrate

A tak googluji: flask_migrate site:pythonanywhere.com

A najdu např.: blog.pythonanywhere.com/158/ – Migrations

Zkusím dát do příkazové řádky:

pip3 install Flask-Migrate

a dojedu na očekávatelnou hlášku:

Installing collected packages: Flask-Migrate
Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/usr/lib/python3.7/site-packages/flask_migrate'
Consider using the `--user` option or check the permissions.

Ještě si ověřím

python3 --version
   Python 3.7.0

a pak se podívám do adresáře

/usr/lib/python3.7/site-packages

a skutečně, adresář Flask-Migrate tam nikde nevidím :-(

Mé zlé tušení se potvvrdí, když čtu pozorněji hned první větu toho blogu: OK, so now we have a virtualenv; …

Takže práce v prostředí virtualenv, které jsem se chtěl vyhnout, nás asi nemine.

Ale ještě zkusíme jednu obezličku:

Flask-Migrate je dobrý pro vývoj aplikace – a aplikaci si vyvíjím na lokále, takže si myslím, že na produkčním serveru by to být nemuselo.