Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

GHC

Facilitator Training
http://eden.sahanafoundation.org/wiki/GHC2010

  • Be the first to comment

GHC

  1. 1. Sahana Eden: Emergency Development Environment 15 September 2010, Grace Hopper Celebration Fran Boon [email_address]
  2. 2. Agenda <ul><li>Stack Overview </li></ul><ul><li>Getting Set up </li></ul><ul><li>Model View Controller </li></ul><ul><ul><li>Filesystem Layout </li></ul></ul><ul><li>Web2Py execution model </li></ul><ul><li>Build a New Module </li></ul><ul><li>S3 REST Controller </li></ul>
  3. 3. Stack Overview <ul><li>Server </li></ul>Client Browser Eclipse Firebug Sahana Eden (S3) Web2Py Python HTML JavaScript CSS
  4. 4. Installation: Virtual Machine <ul><li>Simplest way to start: </li></ul><ul><li>http://eden.sahanafoundation.org/wiki/InstallationGuidelinesVirtualMachine </li></ul><ul><li>Full Developer Environment: </li></ul><ul><li>Eclipse </li></ul><ul><li>Codebase (Web2Py/Sahana Eden) </li></ul><ul><li>Launch Eclipse to get started… </li></ul>
  5. 5. Model-View-Controller <ul><li>web2py/applications/ eden / </li></ul><ul><li>controllers </li></ul><ul><li>models </li></ul><ul><li>views </li></ul>
  6. 6. Model-View-Controller <ul><li>Models </li></ul><ul><ul><li>Define Tables in the Database </li></ul></ul><ul><li>Controllers </li></ul><ul><ul><li>Workflow, Logic </li></ul></ul><ul><li>Views </li></ul><ul><ul><li>HTML / JS Templates parsed server-side </li></ul></ul><ul><ul><li>JS functions then run client-side in browser </li></ul></ul>
  7. 7. Model-View-Controller <ul><li>Static </li></ul><ul><ul><li>no server-side processing </li></ul></ul><ul><ul><li>Images </li></ul></ul><ul><ul><li>CSS </li></ul></ul><ul><ul><li>JavaScript </li></ul></ul><ul><li>Modules </li></ul><ul><ul><li>Python libraries </li></ul></ul>
  8. 8. Modules <ul><li>Sahana concept </li></ul><ul><ul><li>Logical grouping of user-facing functionality </li></ul></ul><ul><ul><li>Not to be confused with Python modules </li></ul></ul><ul><ul><ul><li>i.e. not web2py/applications/eden/modules </li></ul></ul></ul><ul><li>Consist of: </li></ul><ul><ul><li>Model(s) </li></ul></ul><ul><ul><li>Controller </li></ul></ul><ul><ul><li>Views </li></ul></ul>
  9. 9. Sahana Modules <ul><li>pr - Person Registry </li></ul><ul><li>org - Organisation Registry </li></ul><ul><li>gis - Mapping </li></ul><ul><li>msg - Messaging </li></ul><ul><li>cr - Shelter Registry </li></ul><ul><li>hms - Hospital Management </li></ul><ul><li>rms - Request Management </li></ul><ul><li>vol – Volunteer Management </li></ul>
  10. 10. Request processing <ul><li>Web2Py environment setup </li></ul><ul><li>All Models executed </li></ul><ul><li>Controller executed </li></ul><ul><li>Controller Function executed </li></ul><ul><li>View parsed </li></ul><ul><li>HTML returned to browser </li></ul>
  11. 11. eden module resource
  12. 12. Emergency <ul><li>We have to build a module before bed! </li></ul>
  13. 13. Adding a new module <ul><li>Vehicle Tracking System </li></ul><ul><li>Name: vts </li></ul><ul><li>Resources: </li></ul><ul><ul><li>vehicle </li></ul></ul><ul><ul><li>driver </li></ul></ul><ul><ul><li>location </li></ul></ul>
  14. 14. Model: Define Table <ul><li>models/vts.py </li></ul><ul><li># Vehicle resource </li></ul><ul><li>table = db.define_table(&quot;vts_vehicle&quot;, </li></ul><ul><li>Field(&quot;registration&quot;), </li></ul><ul><li>Field(&quot;make&quot;), </li></ul><ul><li>Field(&quot;model&quot;), </li></ul><ul><li>Field(&quot;supplier&quot;), </li></ul><ul><li>) </li></ul>
  15. 15. Controllers <ul><li>Entire Controller is executed </li></ul><ul><ul><li>Manipulation done outside of functions is visible to all functions </li></ul></ul><ul><li>Function which has been called is executed </li></ul><ul><li>Functions with no arguments are automatically visible via URLs </li></ul>
  16. 16. Controller: S3 REST <ul><li>controllers/vts.py </li></ul><ul><li>def vehicle(): </li></ul><ul><li>return shn_ rest _controller(&quot;vts&quot;, &quot;vehicle&quot;) </li></ul>
  17. 17. View <ul><li>None needed at 1st – can RAD without them </li></ul><ul><li>& then polish later  </li></ul><ul><li>Try: </li></ul><ul><li>http://127.0.0.1:8000/eden/vts/vehicle </li></ul><ul><li>Create a vehicle. </li></ul><ul><li>View in different formats: </li></ul><ul><ul><li>.json, .xml, .xls, .pdf </li></ul></ul><ul><ul><li>http:// 127.0.0.1:8000/eden/vts/vehicle/1.json </li></ul></ul>
  18. 18. S3 REST Controller <ul><li>GET args: </li></ul><ul><ul><li>/read, /create , /update, /delete </li></ul></ul><ul><li>HTTP verbs: </li></ul><ul><ul><li>GET, PUT (POST), DELETE </li></ul></ul><ul><li>Representations: </li></ul><ul><ul><li>.html, .json, .xml, .xls, .pdf </li></ul></ul>
  19. 19. Models <ul><li>All executed every request </li></ul><ul><li>In alphabetical order </li></ul><ul><li>Within web2py environment </li></ul>
  20. 20. Models <ul><li>Define Tables in Database </li></ul><ul><ul><li>Live Migrations: Tables created/altered in database </li></ul></ul><ul><li>Utility functions & variables which are used by multiple controllers </li></ul>
  21. 21. Core Models <ul><li>000_config.py </li></ul><ul><ul><li>deployment settings for easy customisation </li></ul></ul><ul><li>00_db.py </li></ul><ul><ul><li>connect to the database </li></ul></ul><ul><ul><li>instantiate classes </li></ul></ul><ul><li>00_settings.py </li></ul><ul><ul><li>read deployment settings & action them </li></ul></ul>
  22. 22. Core Models (continued) <ul><li>00_tables.py </li></ul><ul><ul><li>define some re-usable fields for tables </li></ul></ul><ul><ul><li>define admin tables </li></ul></ul><ul><li>00_utils.py </li></ul><ul><ul><li>patch session </li></ul></ul><ul><ul><li>utility functions </li></ul></ul><ul><li>01_crud.py </li></ul><ul><ul><li>REST Controller front-end </li></ul></ul>
  23. 23. Core Models (continued) <ul><li>01_menu.py </li></ul><ul><ul><li>build the Menus </li></ul></ul><ul><li>zzz_1st_run.py </li></ul><ul><ul><li>Import default data on 1 st run (needs all tables defined 1 st ) </li></ul></ul>
  24. 24. Views: S3 REST <ul><li>REST has defaults </li></ul><ul><ul><li>create.html </li></ul></ul><ul><ul><li>display.html </li></ul></ul><ul><ul><li>list.html </li></ul></ul><ul><ul><li>List_create.html </li></ul></ul><ul><ul><li>update.html </li></ul></ul>
  25. 25. Views: Web2Py <ul><li>Python code inside {{ }} is parsed server-side </li></ul><ul><li>Views can extend & include other views </li></ul><ul><li>Extend ‘ layout ’ for overall look/feel </li></ul><ul><ul><li>{{extend &quot;layout.html&quot;}} </li></ul></ul><ul><li>Defaults (non-REST) to views/controller/function.html </li></ul>
  26. 26. Views: Custom <ul><li>REST views can be customised: </li></ul><ul><li>views/vts/vehicle_list_create.html </li></ul><ul><li>{{extend &quot;layout.html&quot;}} </li></ul><ul><li>{{rheader=&quot;Register a new vehicle in the system:&quot;}} </li></ul><ul><li>{{include &quot;_list_create.html&quot;}} </li></ul>
  27. 27. Views <ul><li>Variables only visible to views if: </li></ul><ul><li>explicitly passed in return dict() </li></ul><ul><li>stored in global variables: </li></ul><ul><ul><ul><li>request , response , session </li></ul></ul></ul><ul><ul><ul><li>http://127.0.0.1:8000/eden/default/about </li></ul></ul></ul>
  28. 28. SQL constraints / Validators <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(&quot;vts_vehicle&quot;, </li></ul><ul><li>Field(&quot;registration&quot;, unique=True ), </li></ul><ul><li>Field(&quot;make&quot;), </li></ul><ul><li>Field(&quot;model&quot;), </li></ul><ul><li>Field(&quot;supplier&quot;), </li></ul><ul><li>) </li></ul>
  29. 29. Field Types <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(&quot;vts_vehicle&quot;, </li></ul><ul><li>Field(&quot;registration&quot;, unique=True), </li></ul><ul><li>Field(&quot;make&quot;), </li></ul><ul><li>Field(&quot;model&quot;), </li></ul><ul><li>Field(&quot;purchase_date&quot;, &quot; date &quot;), </li></ul><ul><li>Field(&quot;supplier&quot;), </li></ul><ul><li>) </li></ul>
  30. 30. Default Values <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(&quot;vts_vehicle&quot;, </li></ul><ul><li>Field(&quot;registration&quot;, unique=True), </li></ul><ul><li>Field(&quot;make&quot;), </li></ul><ul><li>Field(&quot;model&quot;), </li></ul><ul><li>Field(&quot;purchase_date&quot;, &quot;date&quot;, default=request.utcnow ), </li></ul><ul><li>Field(&quot;supplier&quot;), </li></ul><ul><li>) </li></ul>
  31. 31. Labels <ul><li>models/vts.py </li></ul><ul><li>table.registration. label = &quot;License Plate&quot; </li></ul>
  32. 32. Internationalisation <ul><li>models/vts.py </li></ul><ul><li>table.registration. label = T (&quot;License Plate&quot;) </li></ul>
  33. 33. Comments <ul><li>models/vts.py </li></ul><ul><li>table.registration. comment = SPAN(&quot;*&quot;, _class=&quot;req&quot;) </li></ul>
  34. 34. CRUD Strings <ul><li>controllers/vts.py </li></ul><ul><li>def vehicle(): </li></ul><ul><li>… </li></ul><ul><li>s3.crud_strings [&quot;vts_vehicle&quot;] = Storage( </li></ul><ul><li> title_list = T(&quot;List Vehicles&quot;), </li></ul><ul><li> label_create_button = T(&quot;Add Vehicle&quot;), </li></ul><ul><li> msg_record_created = T(&quot;Vehicle added&quot;), </li></ul><ul><li>) </li></ul><ul><li>… </li></ul>
  35. 35. Exploring: Web2Py shell <ul><li>Python is great for interactive exploring! </li></ul><ul><ul><li>Web2Py allows this too  </li></ul></ul><ul><li>w2p </li></ul><ul><li>python web2py.py –S eden –M </li></ul><ul><li>Explore objects with tab </li></ul><ul><li>db. </li></ul><ul><li>gis. </li></ul>
  36. 36. Sahana Eden: Session 2 24 September 2010, Grace Hopper Celebration Fran Boon [email_address]
  37. 37. Branches LaunchPad Merge proposal Trunk Local Branch Your Branch bzr merge bzr push
  38. 38. URL(a= application , c= controller , f= function , args=[], vars={})
  39. 39. Enable Module <ul><li>models/000_config.py </li></ul><ul><li>deployment_settings.modules = Storage( </li></ul><ul><li>… </li></ul><ul><li>vts = Storage( </li></ul><ul><li>name_nice = &quot;Vehicle Tracking System&quot;, description = &quot;Track vehicles&quot;, </li></ul><ul><li> module_type = 10 </li></ul><ul><li>), </li></ul><ul><li>… </li></ul><ul><li>) </li></ul>
  40. 40. Index page <ul><li>controllers/vts.py </li></ul><ul><li>module = request.controller </li></ul><ul><li>def index (): </li></ul><ul><li>&quot;Custom View&quot; </li></ul><ul><li>module_name = deployment_settings.modules[module].name_nice </li></ul><ul><li>return dict(module_name=module_name) </li></ul>
  41. 41. View <ul><li>views/vts/index.html </li></ul><ul><li>{{extend &quot;layout.html&quot;}} </li></ul><ul><li>{{=H2(T(module_name))}} </li></ul><ul><li><p>This module allows users to track their vehicles</p> </li></ul><ul><li>{{=LI(A(&quot;List Vehicles&quot;, _href=URL(r=request, f=&quot;vehicle&quot;)))}} </li></ul>
  42. 42. Controller: Menu <ul><li>controllers/vts.py </li></ul><ul><li>response.menu_options = [ </li></ul><ul><li>[T(&quot;Vehicles&quot;), False, URL(r=request, f=&quot;vehicle&quot;),[ [ T(&quot;List&quot;), False, URL(r=request, f=&quot;vehicle&quot;)], [T(&quot;Add&quot;), False, URL(r=request, f=&quot;vehicle&quot;, args=&quot;create&quot;)] ]]] </li></ul>
  43. 43. DAL: Database Abstraction Layer <ul><li>SQLite </li></ul><ul><ul><ul><li>out of the box </li></ul></ul></ul><ul><li>MySQL </li></ul><ul><ul><ul><li>well-tested with Eden </li></ul></ul></ul><ul><li>PostgreSQL </li></ul><ul><ul><ul><li>what we want to use for Spatial support </li></ul></ul></ul><ul><li>Oracle, DB2, MS SQL, Firebird, GAE </li></ul>
  44. 44. DAL <ul><li>Try these in the shell: w2p </li></ul><ul><li>db.define_table(&quot;person&quot;, Field(&quot;name&quot;)) </li></ul><ul><li>id = db.person.insert(name=&quot;max&quot;) query = (db.person.id == id) </li></ul><ul><li>db(query).count() </li></ul><ul><li>db(query).update(name=&quot;Max&quot;) </li></ul><ul><li>rows = db(query).select(orderby=db.person.name) for row in rows: </li></ul><ul><li>print row.name </li></ul><ul><li>db(query).delete() </li></ul>
  45. 45. DAL <ul><li>For shell scripts (e.g. Cron tasks): </li></ul><ul><li>db.commit() </li></ul><ul><li>Beware locking with SQLite </li></ul>
  46. 46. Joined Resources <ul><li>So far: </li></ul><ul><ul><li>Resource = Single Table </li></ul></ul><ul><li>Reality: </li></ul><ul><ul><li>Resource spread out over multiple Tables </li></ul></ul>
  47. 47. Joined Resources: Model <ul><li>Link Vehicle to Location </li></ul><ul><ul><li>vts_presence </li></ul></ul>
  48. 48. Joined Resources: Model <ul><li>models/vts.py </li></ul><ul><li>module = &quot;vts&quot; </li></ul><ul><li>resource = &quot;presence&quot; </li></ul><ul><li>tablename = &quot;%s_%s&quot; % (module, resource) </li></ul><ul><li>table = db.define_table(tablename, </li></ul><ul><li>Field(&quot;vehicle_id&quot;), </li></ul><ul><li>Field(&quot;location_id&quot;), </li></ul><ul><li>) </li></ul>
  49. 49. Joined Resources: Model <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(tablename, </li></ul><ul><li>Field(&quot;vehicle_id&quot;, db.vts_vehicle ), </li></ul><ul><li>Field(&quot;location_id&quot;, db.gis_location ), </li></ul><ul><li>) </li></ul>
  50. 50. Joined Resources: Model <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(tablename, </li></ul><ul><li>Field(&quot;vehicle_id&quot;, db.vts_vehicle), </li></ul><ul><li>location_id() , </li></ul><ul><li>) </li></ul>
  51. 51. Joined Resources: Controller <ul><li>controllers/vts.py </li></ul><ul><li>def presence (): </li></ul><ul><li>resource = request.function </li></ul><ul><li>return shn_rest_controller(module, resource) </li></ul><ul><li>http://127.0.0.1:8000/eden/vts/presence </li></ul>
  52. 52. Joined Resources: Model <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(tablename, </li></ul><ul><li>Field(&quot;vehicle_id&quot;, db.vts_vehicle), </li></ul><ul><li>location_id(), </li></ul><ul><li>) </li></ul><ul><li>table.vehicle_id. requires = IS_ONE_OF (db, </li></ul><ul><li>&quot;vts_vehicle.id&quot;, </li></ul><ul><li>&quot;vts_vehicle.registration&quot;) </li></ul>
  53. 53. Joined Resources: Model <ul><li>models/vts.py </li></ul><ul><li>table = db.define_table(tablename, </li></ul><ul><li>Field(&quot;vehicle_id&quot;, db.vts_vehicle), </li></ul><ul><li>location_id(), </li></ul><ul><li>Field(&quot;timestmp&quot;, &quot;datetime&quot;) , </li></ul><ul><li>) </li></ul><ul><li>table.vehicle_id.requires = IS_ONE_OF(db, &quot;vts_vehicle.id&quot;, &quot;vts_vehicle.registration&quot;) </li></ul><ul><li>table.timestmp.requires = IS_DATETIME() </li></ul>
  54. 54. Represent <ul><li>table.vehicle_id. represent = lambda id: function </li></ul>
  55. 55. DAL: Optimised SQL queries <ul><li>“ Find the vehicle with this ID”: </li></ul><ul><li>db(db.vts_vehicle.id == id).select() </li></ul><ul><li>db(db.vts_vehicle.id == id).select().first() </li></ul><ul><li>“ Return the Registration”: </li></ul><ul><li>db(db.vts_vehicle.id == id).select().first().registration </li></ul><ul><li>db(db.vts_vehicle.id == id). </li></ul><ul><li>select( limitby =(0,1)).first().registration </li></ul><ul><li>db(db.vts_vehicle.id == id). </li></ul><ul><li>select( db.vts_vehicle.registration , </li></ul><ul><li>limitby=(0,1)).first().registration </li></ul>
  56. 56. JR: Represent <ul><li>models/vts.py </li></ul><ul><li>table.vehicle_id. represent = lambda id: db(db.vts_vehicle.id == id). select(db.vts_vehicle.registration, limitby=(0,1)).first().registration </li></ul>
  57. 57. Components <ul><li>models/vts.py </li></ul><ul><li># Presence as component of vehicle </li></ul><ul><li>s3xrc.model.add_component(module, </li></ul><ul><li>resource, </li></ul><ul><li>multiple=True, </li></ul><ul><li>joinby=dict(vts_vehicle=&quot;vehicle_id&quot;), </li></ul><ul><li>deletable=True, </li></ul><ul><li>editable=True) </li></ul><ul><li>http://127.0.0.1:8000/eden/vts/vehicle/1/presence </li></ul>
  58. 58. RHeader <ul><li>controllers/vts.py </li></ul><ul><li>def shn_vts_rheader(r, tabs=[]): </li></ul><ul><li>if r.representation == &quot;html&quot;: </li></ul><ul><li>rheader_tabs = shn_rheader_tabs(r, tabs) </li></ul><ul><li>vehicle = r.record </li></ul><ul><li>rheader = DIV(TABLE( </li></ul><ul><li>TR(TH(T(&quot;Vehicle: &quot;)), vehicle.registration) </li></ul><ul><li>), </li></ul><ul><li>rheader_tabs </li></ul><ul><li>) </li></ul><ul><li>return rheader </li></ul><ul><li>return None </li></ul>
  59. 59. RHeader Tabs <ul><li>controllers/vts.py </li></ul><ul><li>def vehicle(): </li></ul><ul><li>… </li></ul><ul><li>output = shn_rest_controller(module, &quot;vehicle&quot;, </li></ul><ul><li>rheader=lambda r: shn_vts_rheader(r, </li></ul><ul><li>tabs = [(T(&quot;Basic Details&quot;), None), </li></ul><ul><li> (T(&quot;Presence&quot;), &quot;presence&quot;) </li></ul><ul><li> ])) </li></ul><ul><li>return output </li></ul><ul><li>http://127.0.0.1:8000/eden/vts/vehicle/1/presence </li></ul>
  60. 60. RHeader Tabs
  61. 61. End
  62. 62. S3 is built on Web2Py REST CRUD SQLFORM FORM
  63. 63. Documentation <ul><li>Examples from other modules </li></ul><ul><li>Developer Guidelines on Wiki: </li></ul><ul><li>http://eden.sahanafoundation.org/wiki/DeveloperGuidelines </li></ul><ul><li>But the best…? </li></ul>
  64. 64. Use the Source, Luke! <ul><li>Many resources and tricks on the Internet find you will, but the ultimate answers only in the source lie </li></ul>
  65. 65. Form submission <ul><li>Use Firebug’s Net Panel to look at a form submission. </li></ul><ul><li>Each field has an entry in form.vars </li></ul><ul><li>Can add additional vars to the form in a custom View </li></ul><ul><li>Can process these within our Controller </li></ul><ul><ul><li>onvalidation: Before DB I/O </li></ul></ul><ul><ul><li>onaccept: After DB I/O </li></ul></ul>

    Be the first to comment

    Login to see the comments

  • Maiskander

    Aug. 20, 2015

Facilitator Training http://eden.sahanafoundation.org/wiki/GHC2010

Views

Total views

1,140

On Slideshare

0

From embeds

0

Number of embeds

1

Actions

Downloads

14

Shares

0

Comments

0

Likes

1

×