stråler er en WSGI kompatibel web rammeverk utformet for små webapplikasjoner. Den støtter både Python 2.7 og Python 3.2. stråler håndterer multibyte-charcters riktig (Det er viktig for meg, så jeg er en japansk).
Installasjon
easy_install stråler
eller
PIP installere -e git: //github.com/yuin/rays.git#egg=rays
eller laste ned en zip-fil fra https://github.com/yuin/rays/zipball/master og
python setup.py installere
Eksempel
Du kan finne disse kildekoden i src / samples / blogg katalogen.
index.py:
fra stråler import *
fra rays.compat import *
import sys, os.path, matematikk, contextlib
fra datetime import datetime
import threading
app = Application ()
APP_DIR = os.path.dirname (__ file__)
DB_FILE = os.path.join (APP_DIR, "test.db")
c = threading.local ()
app.config ([
& Nbsp; ("debug", sann),
& Nbsp; ("renderer", {"template_dir": os.path.join (APP_DIR, "maler"),
& Nbsp; "cache_dir": os.path.join (APP_DIR, "maler / cacher")}),
& Nbsp; ("DatabaseExtension", {"connection": DB_FILE, "transaksjon": "commit_on_success"}),
& Nbsp; ("SessionExtension", {"store": "Database", "hemmelig": "asdfeE305Gs0lg",
& Nbsp; "cookie_path": "admin"}),
& Nbsp; ("StaticFileExtension", {"url": "statikk /", "banen": os.path.join (APP_DIR, "statikk")}),
& Nbsp; ("ADMIN_NAME", "admin"),
& Nbsp; ("admin_password", "passord"),
& Nbsp; ("blog_title", "Min blogg"),
& Nbsp; ("entry_per_page", 3),
])
klasse Basismodellen (modell): # {{{
& Nbsp; def class_init (CLS):
& Nbsp; Model.class_init (CLS)
& Nbsp; @ cls.hook ("before_create")
& Nbsp; def before_create (egen-):
& Nbsp; self.created_at = datetime.now ()
#}}}
klasse Entry (Basismodellen): # {{{
& Nbsp; TABLE_NAME = "oppføringer"
& Nbsp; def validere (egen-):
& Nbsp; resultat = []
& Nbsp; hvis ikke self.title: result.append (". Tittel kreves")
& Nbsp; hvis len (self.title)> 100: result.append ("Title for lenge.")
& Nbsp; hvis Len (self.title) <2: result.append (". Tittel for kort")
& Nbsp; hvis ikke self.body: result.append (". Body kreves")
& Nbsp; retur resultat
#}}}
# filtre {{{
def context_setup_filter (* en, ** k):
& Nbsp; c.title = app.vars.blog_title
& nbsp; c.errors = []
& Nbsp; avkastning
def admin_filter (* en, ** k):
& Nbsp; hvis ikke app.session ["signin"]:
& Nbsp; app.res.redirect (app.url.admin_signin ())
& Nbsp; avkastning
def flash_filter (* en, ** k):
& Nbsp; dirigent = app.session ["signin"]
& Nbsp; hvis dirigent:
& Nbsp; app.session ["flash"] = app.session ["flash"] eller {}
& Nbsp; nøkler = liste (iter_keys (app.session ["flash"]))
& Nbsp; avkastning
& Nbsp; hvis dirigent:
& Nbsp; for nøkkelen i nøkler: del app.session ["flash"] [key]
#}}}
# hjelpere {{{
@ App.helper
@ Contextlib.contextmanager
def main_block (medhjelper):
& Nbsp; helper.concat ("
& Nbsp; med helper.capture ("__ main_block"):
& Nbsp; avkastning
& Nbsp; helper.concat (helper.captured ("__ main_block"))
& Nbsp; helper.concat ("
@ App.helper
def show_errors (hjelper, feil):
& Nbsp; hvis feil:
& Nbsp; helper.concat ("
- ")
- " + error + " ")
& Nbsp; for feil i feil:
& Nbsp; helper.concat ("
& Nbsp; helper.concat ("
@ App.helper
def show_message (hjelper, melding):
& Nbsp; hvis melding:
& Nbsp; helper.concat ("
& Nbsp; helper.concat (melding)
& Nbsp; helper.concat ("
@ App.helper
def format_datetime (hjelper, dt):
& Nbsp; returnere dt.strftime ("..% M% d% y /% I% p% Z") lavere ().
@ App.helper
def hatom_published (hjelper, oppføring):
& Nbsp; return "" "% s " ""% (entry.created_at.isoformat (), helper.format_datetime (entry.created_at))
@ App.helper
def format_body (hjelper, kropp):
& Nbsp; retur body.replace (" n", "
")
@ App.helper
def page_link (hjelper, side):
& Nbsp; "? Side =% d" retur app.url.index () +% siden
@ App.helper
def paginering (hjelper, teller, side):
& Nbsp; side = int (side)
& Nbsp; n = app.vars.entry_per_page
& Nbsp; tpl = ["
- "]
- % s "%
- 1 "% helper.page_link (c, 1))
- & nbsp; & nbsp; ....... & nbsp; & nbsp; ")
- % d "% i)
- % d "% (helper.page_link (c, i), i))
- & nbsp; & nbsp; ...... & nbsp; & nbsp; ")
- % d "% (helper.page_link (c, max_page), max_page))
- % s "%
- rutinger:. Enkelt, men kraftig
- Ruter er definert av regulære uttrykk og typen konstruktører:
- @ app.get (& quot; medlem / (int: d +) & quot;)
- def show_member (member_id):
- # ...
- app.url har lett referanse til ruter:
- app.url.show_member (1) # = & gt; & Quot; http: // somehost / medlem / 1 & quot;
- Filtre og kroker. Skrive TØRR kode
- Hooks vil bli kalt tilbake på følgende krok poeng.
- before_initialize
- after_initialize
- before_call
- before_dispatch
- before_action
- before_start_response
- Hooks eksempel:
- @ app.hook (& quot; before_start_response & quot;)
- def status_log_hook (* a):
- hvis app.res.is_success:
- app.logger.info (& quot; suksess & quot;)
- elif app.res.is_abort:
- app.logger.warn (& quot; abortere & quot;)
- annet:
- app.logger.error (& quot; feil:% s & quot;% unicode (app.res.exception))
- Filters mulig tiltak for å kjøre pre- og post-prosessering kode:
- def filtrere (* args):
- # pre-prosessering
- avkastning
- # etterbehandling
- med app.filter (filter):
- @ app.get (& quot; medlem / (int: d +) & quot;)
- def show_member (member_id):
- # ...
- Maler:. Rask og fleksibel
- For å gjengi index.html, app.renderer.index (vars).
- Strings omgitt av & quot; & quot; vil bli tolket som en python kode.
- & lt; % A = 10% & gt;
- & lt; % = Python kode% & gt; vil bli erstattet av resultatet av utførende & quot; python kode & quot;.
- applys alltid et filter (dvs. Cgi.escape). For å slå den av, bruk
- Mange måte å uttrykke blokker:
- & lt; % - For jeg i xrange (10): -% & gt;
- & lt; % = En% & gt;
- & lt; %% & Gt;
- & lt; % - For jeg i xrange (10) {: -% & gt;
- & lt; % = En% & gt;
- & lt; %:}% & Gt;
- & lt; % - For jeg i xrange (10): -% & gt;
- & lt; % = En% & gt;
- & lt; % End% & gt;
- Integrerte nyttig mal hjelpere:
- & lt; % Med h.capture (& quot; body & quot;):% & gt;
- foo
- & lt; %% & Gt;
- & lt; % = Kropps% & gt;
- Orms: Enkelt wrapper for innebygde sqlite3 modul:.
- resultat = app.db.select ([Site, Page], dir = & quot;? Page.site_id = Site.id og Page.id = & quot ;, verdier = [1])
- print (resultat [0] .site)
- print (resultat [0] .page)
- app.db.insert (side)
- app.db.update (side)
- app.db.delete (side)
- app.db.shell () # interaktiv sqlite3 shell
- Sessions:
- @ app.get (& quot; signin & quot;)
- def signin ():
- hvis app.req.input [& quot; navn & quot;] == & quot; bob & quot; og app.req.input [& quot; passord & quot;] == & quot; abrakadabra & quot;:
- app.session.kill ()
- app.session [& quot; godkjent & quot;] = True
- annet:
- # ...
- WebSockets: Realtime meldinger. (Krever gevent, greenlet, gevent-WebSocket)
- Du kan finne disse kildekoden i src / samples / websocketchat katalogen.
- @ app.get (& quot; chat & quot;)
- def chat ():
- ws = app.req.websocket
- SOCKETS.add (ws)
- app.logger.info (& quot; aksepterer:% s & quot;% repr (ws.socket))
- mens Sant:
- msg = ws.receive ()
- hvis msg er Ingen:
- pause
- error_sockets = sett ([])
- for s kontaktene:
- prøve:
- s.send (msg)
- bortsett Unntak, e:
- error_sockets.add (s)
- for s i error_sockets:
- SOCKETS.remove (s)
- Python
& Nbsp; føyer = tpl.append
& Nbsp; max_page = int (Math.ceil (teller / float (n)))
& Nbsp; om side> max_page: page = 1
& Nbsp; start, slutt = max (side-4, 1), min (side + 4, max_page)
& Nbsp; føyer ("
& Nbsp; ((side-1) <1 og ("forrige-off", "& laquo; Forrige") eller
& Nbsp; ("forrige", " & laquo; Forrige "% (helper.page_link (c, side-1)))))
& Nbsp; hvis start = 1:! Føyer ("
& Nbsp; hvis start> 2: append ("
& Nbsp; for jeg i irange (start, slutt + 1):
& Nbsp; hvis jeg == side:
& Nbsp; føyer ("
& Nbsp; annet:
& Nbsp; føyer ("
& Nbsp; hvis end <(max_page-1): føye ("
& Nbsp; hvis end = max_page: føyer ("
& Nbsp; føyer ("
& Nbsp; ((side + 1)> max_page og ("neste-off", "Next & raquo;") eller
& Nbsp; ("next", " Neste & raquo; "% (helper.page_link (c, side + 1)))))
& Nbsp; føyer ("")
& Nbsp; return "" .join (TPL)
#}}}
# Db {{{
def find_entry_by_id (entry_id):
& Nbsp; retur app.db.select_one ([Entry], dir = "id =", verdier = [entry_id])
def find_entries (offset, grense):
& Nbsp; retur app.db.select ([Entry]
& Nbsp; dirigent = "1 rekkefølgen av created_at synkende grense offset?",
& Nbsp; verdier = [grense, offset])
def count_entries ():
& Nbsp; retur app.db.select_one ([Entry], velg = "SELECT count (id) som teller fra% (tabeller) s") gjelder.
#}}}
med app.filter (context_setup_filter):
& Nbsp; @ app.get ("")
& Nbsp; def indeks ():
& Nbsp; limit = app.vars.entry_per_page
& Nbsp; offset = grense * (int (app.req.input.get ("page", 1)) - 1)
& Nbsp; c.entries = find_entries (offset, grense)
& Nbsp; c.count = count_entries ()
& Nbsp; retur app.renderer.show_entries ({"c": c})
& Nbsp; @ app.get ("artikler / (int: d +)")
& Nbsp; def show_entry (entry_id):
& Nbsp; c.entry = find_entry_by_id (entry_id)
& Nbsp; c.title + = "::% s"% c.entry.title
& Nbsp; retur app.renderer.show_entry ({"c": c})
& Nbsp; @ app.get ("admin / signin")
& Nbsp; def admin_signin_form ():
& Nbsp; retur app.renderer.admin_signin_form ({"c": c})
& Nbsp; @ app.post ("admin / signin")
& Nbsp; def admin_signin ():
& Nbsp; hvis app.req.input ["navn"] == app.vars.admin_name og
& Nbsp; app.req.input ["passord"] == app.vars.admin_password:
& Nbsp; app.session ["signin"] = sant
& Nbsp; app.res.redirect (app.url.admin_index ())
& Nbsp; annet:
& Nbsp; c.errors = ["Påloggings mislyktes."]
& Nbsp; retur app.renderer.admin_signin_form ({"c": c})
& Nbsp; med app.filter (admin_filter, flash_filter):
& Nbsp; @ app.get ("admin")
& Nbsp; def admin_index ():
& Nbsp; retur app.renderer.admin_index ({"c": c})
& Nbsp; @ app.get ("admin / avlogging")
& Nbsp; def admin_signout ():
& Nbsp; app.session.kill ()
& Nbsp; app.res.redirect (app.url.admin_signin_form ())
& Nbsp; @ app.get ("admin / entry / ny")
& Nbsp; def admin_entry_new ():
& Nbsp; hvis ikke hasattr (c, "entry"):
& Nbsp; c.entry = Entry (title = "", body = "")
& Nbsp; returnere app.renderer.admin_entry_new ({"c": c})
& Nbsp; @ app.post ("admin / entry / skape")
& Nbsp; def admin_entry_create ():
& Nbsp; c.entry = Entry (** app.req.input ["entry"])
& Nbsp; c.errors = c.entry.validate ()
& Nbsp; hvis c.errors:
& Nbsp; returnere admin_entry_new (c)
& Nbsp; app.db.insert (c.entry)
& Nbsp; app.session ["flash"] ["melding"] = "Entry lagt til."
& Nbsp; app.res.redirect (app.url.admin_index ())
om ikke os.path.exists (DB_FILE):
& Nbsp; db = app.ext.database.create_new_session ()
& Nbsp; db.autocommit = True
& Nbsp; prøve:
& Nbsp; db.execute ("" "CREATE TABLE oppføringer (
& Nbsp; id INTEGER PRIMARY KEY NOT NULL,
& Nbsp; tittelteksten,
& Nbsp; brødtekst,
& Nbsp; created_at TIMESTAMP); "" ")
& Nbsp; db.execute (DatabaseSessionStore.SCHEMA)
& Nbsp; db.execute (DatabaseSessionStore.INDEX)
& Nbsp; endelig:
& Nbsp; db.close ()
hvis __name__ == "__main__":
& Nbsp; app.serve_forever ()
& Nbsp;
File Type
Egenskaper :
Krav :
Kommentarer ikke funnet