субота, 20 априла, 2024
Слободни професионалац

Пуштање Пајтон веб пројеката у рад

Пропратни проблеми и нека решења

Аутор: Никола Харди

PHP је доминантан, али постоје и друге могућности

PHP је још увек доминантан језик у сфери web програмирања, али одувек је присутна и алтернатива. Некада су „озбиљне“ web апликације писане у Javi, хакерима је био занимљив Perl, а љубитеље MS технологије су привлачили ASP, ADO и други. У последње време су JavaScript, Ruby и Python врло популарни, а и у нашем часопису смо у више наврата писали о web програмирању у Python-у, па и сада желимо да поделимо нека наша искуства.

Шта је проблем и шта је циљ

Многе колеге и пријатеље, који већ дуго користе PHP, покушавамо полако да наговоримо да пређу на Python и упорно им показујемо нове вратоломије које изводимо, али они још увек имају један снажан аргумент, а он је: „Где ћу ја то да hostujem?“.

Хајде да се укратко присетимо шта је потребно за покретање једне PHP и једне Python web апликације и каква све решења имамо у понуди.

Класичан „sharedweb hosting план обухвата простор за складиштење датотека на серверу са FTP приступом (File Trynsfer Protocol), одређени број база података и неку врсту контролне табле, као што је то рецимо Cpanel. Наравно, уз све то нас чека и web сервер подешен за наш сајт и чију конфигурацију углавном у оваквој ситуацији не можемо да прилагођавамо. Када се одлучимо за овакво решење, све нас лепо чека подешено и ми само треба да поставимо свој ко̂д, подесимо базу података уколико је то неопходно – и можемо да користимо наш нови сајт.

Са друге стране, постоје и „vritual private server“ (VPS) решења која подразумевају да на располагању имамо цео рачунар. Hosting провајдер нам обезбеди виртуелну машину са жељеном дистрибуцијом, односно оперативним системом и достави нам параметре за приступање тој машни путем SSH протокола (Secure Socket Shell). Као root можемо да радимо шта хоћемо, а за једну python апликацију то значи следеће: инсталирати потребне пакете, обезбедити сервис који ће покретати апликацију (рецимо uwsgi или gunicorn), proxy сервер за прихватање спољашњих захтева и прослеђивање тих захтева претходно поменутом сервису (практично је то у питању proxy и Nginx је сјајан избор) и базу података која нам одговара.

Морамо још једном да нагласимо да је на клијенту обавеза да обезбеди ове ресурсе и подеси их за рад јер је добио рачунар на којем је инсталиран само оперативни систем. За PHP нас је све чекало подешено и било је потребно само да поставимо ко̂д нашег сајта.

Постоји и трећа страна коју још увек нисмо сретали у понудама hosting компанија из региона. У питању су такозвана PaaS решења (Platform as a Service), а реч је о томе да компанија клијентима нуди разне платформе већ подешене за различита окружења која су врло свежа, занимљива и можда егзотична. Осим избора платформе, имамо могућност и за скалирање, да изаберемо колико нам је сервера потребно, који ће шта да ради, да направимо cluster према нашим потребама. Овом приликом споменућемо Heroku сервис и компанију која има сјајне услове за бесплатне апликације и која је избор многих web програмера који се баве овим новим, шареним технологијама. Сервис као што је Heroku можемо и сами да одржавамо јер су присутни пројекти као што је OpenShift. Heroku и OpenShift су једна сасвим посебна прича.

Помоћни алати

Многе компаније у својем IT арсеналу често имају и сервере о којима се брину, имају запослене који су одговорни када нешто закаже (тзв. sysadmini) и донекле разрађену инфраструктуру. Наравно, највише шта можете да очекујете да ћете затећи у таквом окружењу су редован web сервер и евентуално неко Java решење (Tomcat или .NET, ASP, ADO и дружина). Наравно, то нам не одговара за Python и можемо, или да се договоримо са запосленим да на неку од постојећих машина инсталирају и подесе оно шта нам је потребно за рад, или да нам обезбеде једну посебну машину коју ћемо спремити себи онако како нама одговара. Следи објашњење зашто је добро имати посебну машину и неколико корисних алата који ће нам олакшати да то све средимо.

Сви ми на нашим рачунарима имамо гомилу софтвера за које ни не знамо да су присутни. Подешавали смо системе на свакакве начине и мала је вероватноћа да ћемо наићи на исту конфигурацију, а у продукцији и то може да доведе до врло озбиљних проблема када наше ново испрограмирано чедо преселимо на други рачунар и многе ствари више не раде. Чак и ако успемо брзо да похватамо шта је недостајало и правило проблеме, следећи пут када нешто изменимо, не можемо бити сигурни да ли је та промена успешно обављена само на нашем систему или ће проћи безболно и у продукцији. Решење је да сваки програмер који ради на одређеном пројекту има на располагању и окружење какво га очекује у продукцији и пре пуштања новог ко̂да или сервиса да може да га тестира у условима који верно пресликавају стварно стање.

Vagrant и Puppet

Sysadmini већ имају неку своју рутину у подешавању разноразних сервиса и то се своди на „инсталираш ово, и онда измениш ону датотеку, рестартујеш онај даемон, а све ти то пише на нашем wiki-ју“. То тамо пише, али је упутство застарело, компликовано је или програмер не жели да се бави тиме. Срећом на располагању су нам виртуелизација и софтвер који тај посао још више поједностављује. Алатима као што су Vagrant и Puppet можемо да креирамо нову виртуелну машину на нашем рачунару са жељеним инсталираним оперативним системом, а Puppet може да нам обезбеди инсталирање и подешавање осталих сервиса. Окружење из продукције можемо да добијемо у три команде: vagrant init, vagrant up и vagrant ssh. Врло корисна стварчица, јер ако кренемо уназад, и прво тако припремимо наше развојно окружење, онда немамо проблема са креирањем окружења за продукцију, јер ће Puppet исто тако једноставно инсталирати и подесити све сервисе који смо изабрали. Причу о Vagrantu и Puppetu ћемо остати дужни за неки други број, а до тада проверите сами о чему се ради.

Други врло битан проблем који Puppet донекле решава су различите верзије софтвера за који развијамо наш ко̂д и који ће нас дочекати у продукцији. Python то решава на врло елегантан начин помоћу виртуелних окружења (virtualenvvirtual environment) и алата за управљање Python модулима. Предност virtualenv+pip комбинације у односу на инсталирање Python пакета из званичних ризница наше дистрибуције је у томе што за сваки пројекат можемо да направимо посебно радно окружење са својим сетом пакета и са одређеним верзијама тих пакета. Тако да, ако одлучимо да развијамо пројекат у односу на Django 1.4.x серију, а наша дистрибуција нуди 1.3.x или 1.5.x, virtualenv може да реши овај проблем. Штавише, ако имамо два пројекта на истој машини који захтевају различите верзије пакета, то је сасвим нормална ситуација која се решава са два радна окружења. Уз python и pip је обавезно споменути и virtualenvwrapper, помоћну скрипту за bash која олакшава управљање и активирање виртуалних окружења, и наравно њихово креирање.

Библиотека Fabric

Сада већ имамо завидан сет алата у нашој радионици: Vagrant и Puppet за инсталирање и подешавање машине и потребних сервиса на њој, pip и виртуелне да обезбеде жељене верзије и да окружење независно од остатка оперативног система који смо наменили за продукцију. Уз ова два пара врло корисних алата, веома је користан и fabric. Fabric је python библиотека за аутоматизацију задатака разних врста. Предности које пружа fabric су скриптовање у pythonu, једноставна интеграција са virtualenv и многим другим алатима и подршка за управљање удаљеним машинама путем SSH протокола помоћу парамико библиотеке. Циљ је да у једној датотеци (најчешће fabfile.py) дефинишемо функције и задамо упутства за аутоматизациу одређених задатака. Eво неколико идеја:

  1. fab deploy: покрени тестове, ако се тестови успешно изврше додај нов ко̂д у репозиторијум, повежи се на сервер и освежи ко̂д на њему, рестартуј сервисе на серверу и провери да ли је све завршено како треба;
  2. fab test: покрени тестове и провери да ли су нове измене у ко̂ду можда пореметиле нешто;
  3. fab init: повежи се на удаљени сервер, преузми конфигурациону датотеку за puppet (манифест), постави потребне сервисе, подеси радно окружење, инсталирај зависности, преузми моју апликацију и иницијализуј базу података, рестартуј сервисе и провери да ли је све у реду.

Три сложена примера, који су наизглед компликовани да се искодирају, али врло брзо ћете се уходати и након тога ћете без размишљања бити спремни да клијенту у року од 15 минута решите проблем и надоградите му систем са потпуном сигурношћу да ће све проћи без проблема јер ако ради код вас, мора да ради и код њега.

Тестирање као саставни део програмирања

У претходном одељку смо више пута споменули тестирање. Један важан део развоја софтвера заузимају и разне врсте тестирања. Морамо бити уверени пре свега да је ко̂д синтаксно исправан, да може да буде покренут. Након тога, треба тестирати и семантику целог система и видети да ли се ко̂д понаша очекивано. Тестирају се поузданост, робусност, перформансе и још много ствари. Почетком 2000-их година се појавио термин „agile software develpment“ који обухвата разне технике за развој софтвера на такав начин да се нове могућности брзо додају, грешке што примећују и исправљају и да се скрати време потребно за путовање ко̂да од развојног окружења до пуштања у рад.

Саставни део оваквог начина развоја софтвера је писање тестова и појавили су се термини као што су Test Driven Development (TDD, развој вођен тестирањем) и Behaviour Driven Development (BDD, развој вођен понашањем софтвера). Два врло слична приступа, TDD је нешто старији него BDD, али оба приступа деле врло битне принципе. Један је да прво напишемо тест за могућност коју треба да имплементирамо, а потом додајемо или мењамо ко̂д све док та могућност не проради. Други принцип се директно надовезује на претходни и подразумева да измене у ко̂ду не смеју да покваре ни један други тест, односно нисмо завршили посао све док имамо неуспешних тестова.

У чему је предност и зашто би неко писао неколико пута више линија ко̂да за тестове него за сам ко̂д који представља функционалност? Показало се да током животног века пројекта, 90% ко̂да буде врло брзо написано, а потом следи пакао исправљања грешака. Управо ови тестови нам дају слободу да се слободно крећемо по ко̂ду и безбрижно га мењамо, јер ћемо у сваком тренутку знати шта смо када покварили и моћи ћемо да погледамо чак и део ко̂да који је у том тренутку измењен и ко га је изменио. Код TDD-а, тестови су у надлежности програмера, јер је он дужан да осмисли и имплементира тест примере. BDD је отишао корак даље и омогућио послодавцима да напишу тест примере језиком који разумеју, а потом програмери на врло једноставан начин креирају парсирање и извршавање тих примера. Добит за програмере је непроцењива. Пре свега, послодавци су натерани да добро размисле о својим идејама и жељама које су некада толико фантастичне, да ни они сами не могу да их запишу речима, а очекују од програмера да их преточе у ко̂д. Друго, ако тестови који представљају све њихове тест примере успешно пролазе, а они се жале да нешто још не ради, увек можете од њих да затражите да вам покажу у којем се то примеру налази, а углавном ће они бити криви, јер ту могућност нису задали у спецификацији. Пројекти вредни пажње су Cucumber, Nose Test, Lettuce, Robot Framework, Selenium и мноштво других.

Закључак

Представили смо неколико практичних проблема у развоју софтвера уопште и неколико решења која су углавном везана за Python свет, али наравно да еквиваленти постоје и за друге „програмерске културе“. Писали смо о проблему постављања инфраструктуре који решавају vagrant и puppet, о томе да је важно да окружење за развој и за продукцију буде што сличнији, у чему нам помажу pip и virtualenv. Споменули смо и пример како на једноставан начин можемо наше исправке брзо да пласирамо клијенту и о све популарнијем начину развоја пројеката вођеним писањем тестова. Ово је само врх леденог брега, само појмови, алати и вештине сакупљене на једном месту. Било би врло добро када бисмо могли да поразговарамо, разменимо искуства и можда мало скренемо пажњу hosting компанијама на PaaS услуге као што пружа Heroku, јер је то у интересу свима нама.