Pyramid Framework
Minimum Example disabling-caching-in-flask Resource and View (RV Framework) 檔案系統 O'Reilly Video Tutorial @pythonfinland Video: blog,
Gluino: port of web2py libs to bottle, flask, pyramid, tornado (includes copy of modules from the web2py framework)
Flask vs. Django vs. Pyramid vs. Plone Django vs Pyramid Pyramid vs Django vs Flask 5 Frameworks
新增 Global Variable Plone vs Django vs Tornado vs Pyramid vs Flask: Tornado 缺乏 404 error 處理機制,適合非同步存取機制的大型網站。
subprocess_middleware was built to support rendering Python generated JSON into HTML using a nodejs.
serve up different templates based on different routes Serve with Twisted Scaling with Multiple Client Instances TALES Template 執行效率比 Python Expression 來得差
uWSGI 不需要 wsgi-file 可以透過 INI 來啟動 CLI kotti.util.command User Account Principals
範例
REST API with Ramses marioidival LiveCoding awesome pyramid pyramid_packages_domo Quick Project Startup with Cookiecutters 在 Kotti 1.3 透過 pcreate -s kotti 來建立專案骨架是不錯的起點, 需要調整 setup.py w.r.t. trove 並把 u'' 刪除. 或是試 https://github.com/Kotti/kotti-cookiecutter
Google App Engine Kiwi PyCon 2013 Tim Knapp: slide video github
Sphinx Documentation Integration KARL project case
Porting an Existing Application
Deployment: Gunicorn
身份驗證與授權
種類很多,oAuth 是常見的驗證服務,可以使用 Velruse 作為認證模組,或是使用 pyramid-oauth2 模組。其他的模組像 Persona 或 MACAuth。
Heroku
https://github.com/GlossProject/gloss-backend-kotti-heroku
$ git clone $ ./prepare.sh Creating app... done, ⬢ whispering-bastion-51176 https://whispering-bastion-51176.herokuapp.com/ | https://git.heroku.com/whispering-bastion-51176.git Creating heroku-postgresql:hobby-dev on ⬢ whispering-bastion-51176... free Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-round-32274 as DATABASE_URL Use heroku addons:docs heroku-postgresql to view documentation Scaling dynos... ! ▸ Couldn't find that process type.
Code Fellows 401 Tutorial Pyramid on Heroku
Google App Engine
通常有兩種方式
buildout 記得確認 SDK 下載版本號碼,雖然 bin/buildout 成功了,但 ../../bin/python setup.py test 遇到 ImportError: No module named mock (/home/marr/kotti_site/local/lib/python2.7/site-packages/kotti/tests/__init__.py)
Kotti
2.0.0a1 (只)支援 Python 3.5 以上版本,其餘和 1.3.1 相同。2.0.0b2 和 1.3.2 則加上 CSRF 修訂。
first step 起手文件 Kotti 角色類似 Zope2 CMF,不過只存在一個網站物件,存取方式較 Plone 簡化許多。
# Ubuntu 16.04: Python 2.7.12
$ virtualenv kotti-env Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/marr/kotti-env/bin/python2 Also creating executable in /home/marr/kotti-env/bin/python Installing setuptools, pkg_resources, pip, wheel...done.
$ cd kotti-env; bin/pip install -r https://raw.github.com/Kotti/Kotti/stable/requirements.txt
$ bin/pip install Kotti==1.3.2
$ bin/pip install kotti_tinymce
$ bin/pserve app.ini
Starting server in PID 744.
Serving on http://localhost:5000
$ conda create --name kotti_py36 python=3.6 $ source activate kotti_py36 $ mkdir kotti_py36; cd kotti_py36 $ pip install -r https://github.com/Kotti/Kotti/raw/master/requirements.txt ... Successfully installed Babel-2.5.3 ... $ pip install Kotti ... Successfully installed Kotti
發現 Kotti 安裝版本 1.3.2 想換成 2.0.0b2 執行 pip install --upgrade Kotti==2.0.0b2
如果想加 diazo 要再 pip install diazo repoze.xmliter pytest,不過還沒確認 https://github.com/GlossProject/gloss-backend-kotti-heroku 是否適用於 Python 3 環境,很可能要換掉 Paste 之類。
Flask-SocketIO-Chat <https://github.com/miguelgrinberg/Flask-SocketIO-Chat> to suit but I am not yet familiar with the Kotti infrastructure. I've not used it, but assuming the docs are correct https://gevent-socketio.readthedocs.io/en/latest/ should be easy to integrate into any Python WSGI App.
傳回項目清單來顯示的範例 construct a SQLAlchemy query that returns the documents you want to show in a view
from pyramid.view import view_config from kotti.resources import Document @view_config(name='myview', renderer='mytemplate.pt', ...) def myview(context, request): documents = Document.query.filter(<whatever your criteria are>) return {'documents': documents}
<li tal:repeat="d documents"><a href="request.resource_url(d)">${document.title}</a></li>
在 app.ini 檔案 kotti.site_title 可以使用中文標題,但有辦法做到 multilingual 嗎?
Eucalyptus Management Console Command Line Script Tool
https://devcenter.heroku.com/articles/creating-apps https://devcenter.heroku.com/articles/git
使用者資料欄位客製化可以修改 Principals Ordering Fields in colander based Schemas
Relation 範例 kotti_image ElasticSearch
https://github.com/koansys/heroku-kotti 太舊了
from sqlalchemy import * from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.dialects.postgresql import JSON from sqlalchemy.orm import relationship from sqlalchemy.ext.declarative import declared_attr ################################################################ # DPIS database model ################################################################ Base = declarative_base() class Country(Base): """ Managed through Kotti """ __tablename__ = 'countries' dpis_id = Column(Integer, primary_key=True) title = Column(Unicode(80)) regions = relationship("Region", primaryjoin="Country.dpis_id==Region.country_id") class Region(Base): """ Managed through Kotti """ __tablename__ = 'regions' dpis_id = Column(Integer, primary_key=True) country_id = Column(Integer, ForeignKey('countries.dpis_id')) title = Column(Unicode(80)) parishes = relationship("Parish", primaryjoin="Region.dpis_id==Parish.region_id") class Parish(Base): """ Managed through Kotti """ __tablename__ = 'parishes' dpis_id = Column(Integer, primary_key=True) region_id = Column(Integer, ForeignKey('regions.dpis_id')) title = Column(Unicode(80)) schools = relationship("School", primaryjoin="Parish.dpis_id==School.parish_id") ################################################################ # School <-1:n-> Student <-1:n-> Score # are managed within Sqlalchemy as a bidirectional relation ################################################################ class School(Base): """ Managed through Kotti """ __tablename__ = 'schools' dpis_id = Column(Integer, primary_key=True) parish_id = Column(Integer, ForeignKey('parishes.dpis_id')) title = Column(Unicode(80)) # all students of this school students = relationship("Student", primaryjoin="School.dpis_id==Student.school_id") class Student(Base): """ Managed by system, no integration with Kotti """ __tablename__ = 'students' dpis_id = Column(Integer, primary_key=True) school_id = Column(Integer, ForeignKey('schools.dpis_id')) firstname = Column(Unicode(80)) lastname = Column(Unicode(80)) address = Column(Unicode(80)) city = Column(Unicode(80)) birth = Column(Date) gender = Column(Unicode(4)) # back-reference to school school = relationship(School, primaryjoin=school_id==School.dpis_id)
# all scores of this student
scores = relationship("Score",
primaryjoin="Student.dpis_id==Score.student_id")
class Score(Base):
__tablename__ = 'scores'
dpis_id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.dpis_id'))
year = Column(Integer, index=True)
subject = Column(Unicode(80), index=True)
score = Column(Integer, index=True)
# back reference to student
student = relationship(Student, primaryjoin="Score.student_id==Student.dpis_id")
class Person(Base):
""" A Person represents someone how can login into the system for doing *something*. """
__tablename__ = 'dpis_users'
dpis_id = Column(Integer, primary_key=True)
title = Column(Unicode(80))
firstname = Column(Unicode(80))
lastname = Column(Unicode(80))
username = Column(Unicode(32)) # Kotti login name password = Column(Unicode(32)) # Hashed Kotti password?
Andreas Kaiser: zope.testbrowser wsgi_intercept are the Python 2 only requirements
參與貢獻
http://docs.pylonsproject.org/en/latest/#contributing
http://docs.pylonsproject.org/en/latest/community/featuresbugs.html#working-on-code
Kotti CMS like Plomino Intranet AngularJS with Kotti
frontend decoupled from backend: 1 2
$ mkdir kotti2 $ pyvenv py352_env $ source py352_env/bin/activate (py352_env) marr@ubuntu:~/kotti2$ pip3 install -r https://github.com/Kotti/Kotti/raw/master/requirements.txt Running setup.py clean for Beaker Running setup.py bdist_wheel for bleach-whitelist ... error Complete output from command /home/marr/kotti2/py352_env/bin/python3.5 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-0vd1xuyr/bleach-whitelist/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" bdist_wheel -d /tmp/tmpour7fexqpip-wheel- --python-tag cp35: usage: -c [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: -c --help [cmd1 cmd2 ...] or: -c --help-commands or: -c cmd --help error: invalid command 'bdist_wheel' ---------------------------------------- Failed building wheel for bleach-whitelist Running setup.py clean for bleach-whitelist Running setup.py bdist_wheel for Chameleon ... error Complete output from command /home/marr/kotti2/py352_env/bin/python3.5 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-0vd1xuyr/Chameleon/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" bdist_wheel -d /tmp/tmp40la2oy5pip-wheel- --python-tag cp35: usage: -c [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: -c --help [cmd1 cmd2 ...] or: -c --help-commands or: -c cmd --help error: invalid command 'bdist_wheel' ---------------------------------------- Failed building wheel for Chameleon Running setup.py clean for Chameleon nd js.jquery-timepicker-addon js.jqueryui js.jqueryui-tagit js.modernizr js.select2 js.tinymce LEPL Mako MarkupSafe peppercorn py-bcrypt pyramid-beaker pyramid-chameleon pyramid-deform python-editor repoze.workflow repoze.zcml rfc6266-parser shutilwhich SQLAlchemy SQLAlchemy-Utils usersettings zope.sqlalchemy Installing collected packages: SQLAlchemy, MarkupSafe, Mako, python-editor, six, python-dateutil, alembic, appdirs, pytz, Babel, Beaker, webencodings, html5lib, bleach, bleach-whitelist, Chameleon, iso8601, translationstring, colander, zope.deprecation, peppercorn, deform, docopt, WebOb, shutilwhich, fanstatic, Unidecode, filedepot, FormEncode, html2text, hupper, js.angular, js.jquery, js.bootstrap, js.fineuploader, js.html5shiv, js.jquery-form, js.jquery-maskedinput, js.jquery-maskmoney, js.jquery-sortable, js.jquery-tablednd, js.jqueryui, js.jquery-timepicker-addon, js.jqueryui-tagit, js.modernizr, js.select2, js.tinymce, LEPL, polib, lingua, PasteDeploy, plaster, plaster-pastedeploy, py-bcrypt, venusian, zope.interface, repoze.lru, pyramid, pyramid-beaker, pyramid-chameleon, pyramid-deform, transaction, repoze.sendmail, pyramid-mailer, pyramid-tm, zope.i18nmessageid, zope.event, zope.schema, zope.configuration, pyramid-zcml, zope.component, repoze.zcml, repoze.workflow, rfc6266-parser, SQLAlchemy-Utils, usersettings, waitress, zope.sqlalchemy Running setup.py install for SQLAlchemy ... done Running setup.py install for MarkupSafe ... done Running setup.py install for Mako ... done Running setup.py install for python-editor ... done Running setup.py install for alembic ... done Running setup.py install for Beaker ... done Running setup.py install for bleach-whitelist ... done Running setup.py install for Chameleon ... done Running setup.py install for peppercorn ... done Running setup.py install for docopt ... done Running setup.py install for shutilwhich ... done Running setup.py install for fanstatic ... done Running setup.py install for filedepot ... done Running setup.py install for js.angular ... done Running setup.py install for js.jquery ... done Running setup.py install for js.bootstrap ... done Running setup.py install for js.fineuploader ... done Running setup.py install for js.html5shiv ... done Running setup.py install for js.jquery-form ... done Running setup.py install for js.jquery-maskedinput ... done Running setup.py install for js.jquery-maskmoney ... done Running setup.py install for js.jquery-sortable ... done Running setup.py install for js.jquery-tablednd ... done Running setup.py install for js.jqueryui ... done Running setup.py install for js.jquery-timepicker-addon ... done Running setup.py install for js.jqueryui-tagit ... done Running setup.py install for js.modernizr ... done Running setup.py install for js.select2 ... done Running setup.py install for js.tinymce ... done Running setup.py install for LEPL ... done Running setup.py install for py-bcrypt ... done Running setup.py install for pyramid-beaker ... done Running setup.py install for pyramid-chameleon ... done Running setup.py install for pyramid-deform ... done Running setup.py install for repoze.zcml ... error Complete output from command /home/marr/kotti2/py352_env/bin/python3.5 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-0vd1xuyr/repoze.zcml/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_tzrx5q_-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/marr/kotti2/py352_env/include/site/python3.5/repoze.zcml: Traceback (most recent call last): File "", line 1, in File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/setuptools/__init__.py", line 11, in from setuptools.extern.six.moves import filterfalse, map File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/setuptools/extern/__init__.py", line 1, in from pkg_resources.extern import VendorImporter File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2927, in @_call_aside File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2913, in _call_aside f(*args, **kwargs) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2952, in _initialize_master_working_set add_activation_listener(lambda dist: dist.activate()) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 956, in subscribe callback(dist) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2952, in add_activation_listener(lambda dist: dist.activate()) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2515, in activate declare_namespace(pkg) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2097, in declare_namespace _handle_ns(packageName, path_item) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2047, in _handle_ns _rebuild_mod_path(path, packageName, module) File "/home/marr/kotti2/py352_env/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2066, in _rebuild_mod_path orig_path.sort(key=position_in_sys_path) AttributeError: '_NamespacePath' object has no attribute 'sort' ---------------------------------------- Command "/home/marr/kotti2/py352_env/bin/python3.5 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-0vd1xuyr/repoze.zcml/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_tzrx5q_-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/marr/kotti2/py352_env/include/site/python3.5/repoze.zcml" failed with error code 1 in /tmp/pip-build-0vd1xuyr/repoze.zcml/ You are using pip version 8.1.1, however version 18.0 is available. You should consider upgrading via the 'pip install --upgrade pip' command.