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