HTTP-frameworkia Pythonilla
Luin taannoin CherryPy:n tutoriaalia ja muuta dokumentaatiota. CherryPy on Pythonilla toteuttu HTTP-framework. Se jäsentää HTTP-pyynnön URL:in ja kutsuu sen perusteella Python-ohjelman luokassa olevaa metodia. Kutsuttu metodi palauttaa kysytyn WWW-sivun.
Alla olevassa esimerkissä on määritelty "sivut" seuraaville URL:eille:
- /
- Root-luokan index-metodi
- /page1
- Root-luokan page1-metodi
- /node/
- Node-luokan index-metodi
- /node/page2
- Node-luokan page2-metodi
default-metodeja kutsutaan muille URL:eille.
class Node(object): def index(self, *args): return 'Node index: %s' % ','.join(args) def page2(self): return 'Node page2' def default(self, param1, param2): return 'Node default: %s,%s' % (param1, param2) class Root(object): node = Node() def index(self): return 'Root index' def page1(self, param): return 'Root page1: %s' % param def default(self, *args): return 'Root default: %s' % ','.join(args)
En tutkinut CherryPyn koodia, mutta kokeilin, miten tuon kutsun voisi URL:in perusteella tehdä. Hämmästyin, kuinka yksinkertainen ohjelmasta tuli. Alla on koko ohjelma testikoodeineen.
def get_value(root, name_list): """Calls method and returns value >>> get_value(Root(), []) 'Root index' >>> get_value(Root(), ['index']) 'Root index' >>> get_value(Root(), ['page1', 'a']) 'Root page1: a' >>> get_value(Root(), ['a', 'b', 'c']) 'Root default: a,b,c' >>> get_value(Root(), ['node']) 'Node index: ' >>> get_value(Root(), ['node', 'index', 'a', 'b']) 'Node index: a,b' >>> get_value(Root(), ['node', 'page2']) 'Node page2' >>> get_value(Root(), ['node', 'a', 'b']) 'Node default: a,b' """ if len(name_list) > 0: if name_list[0] == '': return get_value(root, name_list[1:]) try: a = getattr(root, name_list[0]) if callable(a): return a(*name_list[1:]) else: return get_value(a, name_list[1:]) except AttributeError: return root.default(*name_list) else: return root.index() def get(root, path): """Get value from path. >>> get(Root(), '/node/index/a/b/c/d') 'Node index: a,b,c,d' """ return get_value(root, path.split('/')) def _test(): import doctest doctest.testmod() if __name__ == '__main__': _test()
Kun nämä koodit tallentaa tiedostoon
(esimerkiksi calltest.py
) voi ohjelman
testit ajaa komennolla python calltest.py -v
.
Ohjelman testit on tehty Pythonin
doctest-työkaluilla.
CherryPyn vastaava koodi on varmaankin täydellisempi ja siinä on otettu huomioon erikoistapauksia, joihin en ole tässä kiinnittänyt huomiota. En muutenkaan ole varma, kuinka tarkkaan tämä koodi vastaa CherryPyn toimintaa, mutta esimerkistä kuitenkin idea selvinnee ja samalla saa mielikuvan Pythonin ilmaisuvoimasta.
Millainenkohan vastaava toteutus olisi esimerkiksi Javalla tehtynä?
Ystävällisin terveisin
Timo Kankare
Kommentit