در پرتو چارچوب وب سازگار WSGI طراحی شده برای برنامه های کاربردی وب کوچک است. این پشتیبانی از هر دو پایتون 2.7 و پایتون 3.2. اشعه دسته درست چند بایتی-نویسه (این برای من مهم است، بنابراین من ژاپنی هستم).
نصب
easy_install اشعه
یا
تصویر در تصویر نصب دستگاه گوارش -e: //github.com/yuin/rays.git#egg=rays
و یا دانلود کنید فایل زیپ از https://github.com/yuin/rays/zipball/master و
پایتون setup.py نصب
مثال
شما می توانید کد منبع این در SRC / نمونه / دایرکتوری وبلاگ پیدا کنید.
index.py:
از اشعه واردات *
از rays.compat واردات *
سیستم واردات، os.path، ریاضی، contextlib
از تاریخ ساعت واردات تاریخ ساعت
واردات نخ
برنامه = کاربرد ()
APP_DIR = os.path.dirname (__ file__)
DB_FILE = os.path.join (APP_DIR، "test.db")
ج = threading.local ()
app.config ([
و nbsp؛ ("اشکال زدایی"، درست است)،
و nbsp؛ ("رندر"، {"template_dir": os.path.join (APP_DIR، "قالب")،
و nbsp؛ "cache_dir": os.path.join (APP_DIR، "قالب / مخفیگاه")})،
و nbsp؛ ("DatabaseExtension"، {"اتصال": DB_FILE، "معامله": "commit_on_success"})،
و nbsp؛ ("SessionExtension"، {"فروشگاه": "بانک اطلاعات"، "راز": "asdfeE305Gs0lg"،
و nbsp؛ "cookie_path": "مدیریت"})،
و nbsp؛ ("StaticFileExtension"، {"URL": "آمار /"، "مسیر": os.path.join (APP_DIR، "آمار")})،
و nbsp؛ ("ADMIN_NAME"، "مدیریت")،
و nbsp؛ ("admin_password"، "کلمه عبور")،
و nbsp؛ ("blog_title"، "وبلاگ من")،
و nbsp؛ ("entry_per_page"، 3)،
])
کلاس BaseModel (مدل): # {{{
و nbsp؛ دف class_init (CLS):
& nbsp؛ در Model.class_init (CLS)
و nbsp؛ @ cls.hook ("before_create")
و nbsp؛ دف before_create (خود):
& nbsp؛ در self.created_at = datetime.now ()
#}}}
کلاس ورودی (BaseModel): # {{{
& nbsp؛ در table_name از = "مطالب"
و nbsp؛ دف اعتبار (خود):
را لمس کنید و. نتیجه = []
& nbsp؛ اگر self.title نمی: result.append (". عنوان مورد نیاز")
& nbsp؛ اگر لن (self.title)> 100: result.append ("عنوان بیش از حد طولانی است.")
& nbsp؛ اگر لن (self.title) <2: result.append (". عنوان خیلی کوتاه")
& nbsp؛ اگر self.body نمی: result.append (". بدن مورد نیاز")
را لمس کنید و. نتیجه بازگشت
#}}}
# فیلتر {{{
دف context_setup_filter (*، ** K):
& nbsp؛ در c.title = app.vars.blog_title
& nbsp؛ در c.errors = []
را لمس کنید و. عملکرد
دف admin_filter (*، ** K):
& nbsp؛ اگر app.session نمی ["ورود به سیستم"]:
& nbsp؛ در app.res.redirect (app.url.admin_signin ())
را لمس کنید و. عملکرد
دف flash_filter (*، ** K):
& nbsp؛ در است.آنگاه = app.session ["ورود به سیستم"]
& nbsp؛ اگر است.آنگاه:
& nbsp؛ در app.session ["فلش"] = app.session ["فلش"] یا {}
و nbsp؛ کلید = فهرست (iter_keys (app.session ["فلش"]))
را لمس کنید و. عملکرد
& nbsp؛ اگر است.آنگاه:
& nbsp؛ برای کلید در کلید: دل app.session ["فلش"] [کلیدی]
#}}}
# یاران {{{
@ app.helper
@ contextlib.contextmanager
دف main_block (یاور):
را لمس کنید و. helper.concat ("<شناسه DIV = " اصلی ">")
& nbsp؛ با helper.capture ("__ main_block"):
را لمس کنید و. عملکرد
& nbsp؛ در helper.concat (helper.captured ("__ main_block"))
& nbsp؛ در helper.concat ("
@ app.helper
show_errors دف (یاور، خطا):
& nbsp؛ اگر خطا:
& nbsp؛ در helper.concat ("
- ")
- " + خطا + " در")
& nbsp؛ برای خطا در خطا:
& nbsp؛ در helper.concat ("
& nbsp؛ در helper.concat ("
@ app.helper
دف show_message (یاور، پیام):
& nbsp؛ اگر پیام:
helper.concat ("
helper.concat (پیام). کلیک کنید و
& nbsp؛ در helper.concat ("
@ app.helper
دف format_datetime (یاور، DT):
و nbsp؛ بازگشت dt.strftime (".٪ متر٪ D٪ Y /٪ من٪ P٪ Z") پایین ().
@ app.helper
دف hatom_published (یاور، ورود):
& nbsp؛ از بازگشت "" "<مخفف کلاس =" منتشر "عنوان ="٪ s "را>٪ s را اختصار>" ""٪ (entry.created_at.isoformat ()، helper.format_datetime (entry.created_at))
@ app.helper
دف format_body (یاور، بدن):
& nbsp؛ در body.replace بازگشت (" N"، "<برزیلی />")
@ app.helper
دف page_link (یاور، صفحه):
"صفحه =٪ D؟" صفحه٪ app.url.index بازگشت () +؛ و nbsp
@ app.helper
دف صفحه بندی (یاور، شمارش، صفحه):
را لمس کنید و. صفحه = هوشمند (صفحه)
و nbsp؛ N = app.vars.entry_per_page
را لمس کنید و. TPL = ["<شناسه UL = " صفحه بندی ">"]
و nbsp؛ اضافه = tpl.append
& nbsp؛ در max_page = هوشمند (math.ceil (تعداد / شناور (N)))
& nbsp؛ اگر صفحه> max_page: صفحه = 1
& nbsp؛ در شروع، پایان = حداکثر (صفحه 4، 1)، دقیقه (صفحه + 4، max_page)
و nbsp؛ اضافه ("<کلاس لی = "٪ S ">٪ s را در"٪
و nbsp؛ ((صفحه 1) <1 و ("قبلی کردن"، "و LAQUO. قبلی") و یا
و nbsp؛ ("قبلی"، "از و LAQUO. قبلی >"٪ (helper.page_link (C، صفحه-1)))))
& nbsp؛ اگر شروع = 1: اضافه ("
& nbsp؛ اگر شروع> 2: اضافه ("
& nbsp؛ برای من در irange (شروع، پایان + 1):
& nbsp؛ اگر من == صفحه:
و nbsp؛ اضافه ("<کلاس لی = " فعال ">٪ D در"٪ من)
& nbsp؛ در دیگری:
و nbsp؛ اضافه ("
& nbsp؛ اگر پایان <(max_page-1): اضافه ("
& nbsp؛ اگر پایان = max_page: اضافه ("
و nbsp؛ اضافه ("<کلاس لی = "٪ S ">٪ s را در"٪
را لمس کنید و؛ ((صفحه + 1)> max_page و ("بعدی کردن"، "بعدی & raquo؛") و یا
و nbsp؛ ("بعدی"، "از بعدی & raquo؛ >"٪ (helper.page_link (C، صفحه + 1)))))
و nbsp؛ اضافه ("")
& nbsp؛ از بازگشت "" .join (TPL)
#}}}
# DB {{{
دف find_entry_by_id (entry_id):
& nbsp؛ در app.db.select_one بازگشت ([ورود]، است.آنگاه = "؟ ID ="، ارزش = [entry_id])
find_entries دف (افست، محدود):
& nbsp؛ در app.db.select بازگشت ([ورود]،
& nbsp؛ در است.آنگاه = "؟ 1 منظور توسط created_at محصول، حد جبران؟"،
& nbsp؛ از ارزش = [حد افست])
count_entries دف ():
& nbsp؛ در app.db.select_one بازگشت ([ورود]، انتخاب = "SELECT COUNT (شناسه) به عنوان تعداد از٪ (جدول) S") حساب کند.
#}}}
با app.filter (context_setup_filter):
و nbsp؛ @ app.get ("")
را لمس کنید و. دف شاخص ():
& nbsp؛ در حد = app.vars.entry_per_page
& nbsp؛ در جبران = حد * (INT (app.req.input.get ("صفحه"، 1)) - 1)
& nbsp؛ در find_entries c.entries = (افست، محدود)
& nbsp؛ در c.count = count_entries ()
& nbsp؛ در app.renderer.show_entries بازگشت ({"ج": C})
و nbsp؛ @ app.get ("مقالات / (داخلی: D +)")
و nbsp؛ دف show_entry (entry_id):
& nbsp؛ در c.entry = find_entry_by_id (entry_id)
& nbsp؛ در c.title + = "::٪ S"٪ c.entry.title
& nbsp؛ در app.renderer.show_entry بازگشت ({"ج": C})
و nbsp؛ @ app.get ("مدیر / ورود به سیستم")
و nbsp؛ دف admin_signin_form ():
& nbsp؛ در app.renderer.admin_signin_form بازگشت ({"ج": C})
و nbsp؛ @ app.post ("مدیر / ورود به سیستم")
و nbsp؛ دف admin_signin ():
& nbsp؛ اگر app.req.input ["نام"] == app.vars.admin_name و
& nbsp؛ در app.req.input ["رمز عبور"] == app.vars.admin_password:
& nbsp؛ در app.session ["ورود به سیستم"] = واقعی
& nbsp؛ در app.res.redirect (app.url.admin_index ())
& nbsp؛ در دیگری:
& nbsp؛ در c.errors = ["ورود شکست خورده است."]
& nbsp؛ در app.renderer.admin_signin_form بازگشت ({"ج": C})
& nbsp؛ با app.filter (admin_filter، flash_filter):
و nbsp؛ @ app.get ("مدیریت")
و nbsp؛ دف admin_index ():
& nbsp؛ در app.renderer.admin_index بازگشت ({"ج": C})
و nbsp؛ @ app.get ("مدیر / خروج")
و nbsp؛ دف admin_signout ():
& nbsp؛ در app.session.kill ()
& nbsp؛ در app.res.redirect (app.url.admin_signin_form ())
و nbsp؛ @ app.get ("مدیر / ورود / جدید")
و nbsp؛ دف admin_entry_new ():
& nbsp؛ اگر hasattr نیست (ج، "ورود"):
& nbsp؛ در c.entry = ورودی (عنوان = ""، بدن = "")
و nbsp؛ بازگشت app.renderer.admin_entry_new ({"ج": C})
و nbsp؛ @ app.post ("مدیر / ورود / ایجاد")
و nbsp؛ دف admin_entry_create ():
& nbsp؛ در c.entry = ورودی (** app.req.input ["ورود"])
& nbsp؛ در c.errors = c.entry.validate ()
& nbsp؛ اگر c.errors:
و nbsp؛ بازگشت admin_entry_new (C)
& nbsp؛ در app.db.insert (c.entry)
& nbsp؛ در app.session ["فلش"] ["پیام"] = "ورود اضافه شده است."
& nbsp؛ در app.res.redirect (app.url.admin_index ())
اگر نه os.path.exists (DB_FILE):
DB = app.ext.database.create_new_session ()؛ لمس کنید و
& nbsp؛ در db.autocommit = واقعی
و nbsp؛ امتحان کنید:
& nbsp؛ در db.execute ("" "ایجاد مدخل جدول (
& nbsp؛ از شناسه INTEGER کلید اولیه NOT NULL،
& nbsp؛ در عنوان متن،
& nbsp؛ در متن،
& nbsp؛ در TIMESTAMP created_at). "" ")
& nbsp؛ در db.execute (DatabaseSessionStore.SCHEMA)
& nbsp؛ در db.execute (DatabaseSessionStore.INDEX)
& nbsp؛ در نهایت:
را لمس کنید و. db.close ()
اگر __name__ == "__main__":
را لمس کنید و. app.serve_forever ()
و nbsp؛
نوع فایل
ویژگی ها:
مسیریابی: ساده، اما قدرتمند است.
مسیرهای توسط عبارات منظم و نوع سازنده تعریف می شود:
@ app.get (& quot؛ را عضو / (داخلی: D +) و & quot؛)
دف show_member (member_id):
# ...
app.url است مرجع آسان به مسیر:
app.url.show_member (1) # = & gt؛ به و & quot؛ HTTP: // somehost / عضو / 1 & quot؛ را
فیلترها و قلاب: نوشتن کد خشک است.
قلاب خواهد شد در نقاط قلاب زیر نامیده می شود.
before_initialize
after_initialize
before_call
before_dispatch
before_action
before_start_response
قلاب به عنوان مثال:
@ app.hook (& quot؛ را before_start_response ها & quot؛)
دف status_log_hook (*):
اگر app.res.is_success:
app.logger.info (& quot؛ را موفقیت ها & quot؛)
الیف app.res.is_abort:
app.logger.warn (& quot؛ را سقط و & quot؛)
دیگری:
app.logger.error (& quot؛ را خطا:٪ S & quot؛ را٪ یونیکد (app.res.exception))
فیلترها اقدامات را قادر به اجرای کد قبل و بعد از پردازش:
دف فیلتر (* استدلال):
# قبل از پردازش
محصول
# پس از پردازش
با app.filter (فیلتر):
@ app.get (& quot؛ را عضو / (داخلی: D +) و & quot؛)
دف show_member (member_id):
# ...
قالب: سریع و قابل انعطاف است.
ارائه ها index.html، app.renderer.index (به اعضای).
رشته احاطه شده توسط & quot؛ را & quot؛ را به عنوان یک کد پایتون تفسیر شده است.
به & lt؛ ٪ = 10٪ و GT.
به & lt؛ ٪ = پایتون کد٪ & gt؛ به خواهد شد در نتیجه اجرای و & quot جایگزین. کد پایتون و quot؛ کلیک کنید
همیشه یک فیلتر (به عنوان مثال. cgi.escape) applys. برای خاموش کردن آن، استفاده از
بسیاری از راه بیان بلوک:
به & lt؛ ٪ - برای من در xrange (10): -٪ & gt؛ به
به & lt؛ ٪ =٪ & gt؛ به
به & lt؛ ٪٪ و GT.
به & lt؛ ٪ - برای من در xrange (10) {: -٪ & gt؛ به
به & lt؛ ٪ =٪ & gt؛ به
به & lt؛ ٪:}٪ & gt؛ به
به & lt؛ ٪ - برای من در xrange (10): -٪ & gt؛ به
به & lt؛ ٪ =٪ & gt؛ به
به & lt؛ ٪ پایان٪ & gt؛ به
مجتمع یاران قالب کرده اند:
به & lt؛ ٪ با h.capture (& quot؛ را بدن و & quot؛):٪ & gt؛ به
مواد غذایی
به & lt؛ ٪٪ و GT.
به & lt؛ ٪ = بدن٪ & gt؛ به
ORMs: لفاف بسته بندی ساده برای ساخته شده در ماژول sqlite3:
نتیجه = app.db.select ([سایت، صفحه]، است.آنگاه = & quot؛ را؟ Page.site_id = Site.id و Page.id = & quot؛ باشد ارزش = [1])
نسخه قابل چاپ (نتیجه [0] .site)
نسخه قابل چاپ (نتیجه [0] .page)
app.db.insert (صفحه)
app.db.update (صفحه)
app.db.delete (صفحه)
app.db.shell () پوسته sqlite3 تعاملی #
جلسات:
@ app.get (& quot؛ را از ورود به سیستم & quot؛ را)
دف از ورود به سیستم ():
اگر app.req.input [& quot؛ نام & quot؛ را] == & quot؛ را باب و & quot؛ و app.req.input [& quot؛ را رمز و & quot؛] == & quot؛ را سخن نامفهوم و & quot ؛:
app.session.kill ()
app.session [& quot؛ را مجاز به & quot؛] = واقعی
دیگری:
# ...
سوکتهای وب: پیام بیدرنگ. (نیاز به gevent، greenlet، gevent-websocket)
شما می توانید کد منبع این در SRC / نمونه / دایرکتوری websocketchat پیدا کنید.
@ app.get (& quot؛ را چت و & quot؛)
دف چت ():
WS = app.req.websocket
SOCKETS.add (WS)
app.logger.info (& quot؛ را می پذیرد:٪ S & quot؛ را٪ repr (ws.socket))
در حالی که درست است:
MSG = ws.receive ()
اگر MSG هیچ است:
شکست
error_sockets = مجموعه ای ([])
برای بازدید کنندگان در پریز برق:
امتحان کنید:
s.send (MSG)
به جز استثنا، E:
error_sockets.add (بازدید کنندگان)
برای بازدید کنندگان در error_sockets:
SOCKETS.remove (بازدید کنندگان)
مورد نیاز:
پایتون
نظر یافت نشد