Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / Tutorial / Pyramid Framework

Pyramid Framework

包括 Kotti 內容管理系統

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

Long Polling Channels

TicTacToe and Long Polling

Sphinx Documentation Integration KARL project case

Porting an Existing Application

Windows + MySQL

Deployment: Gunicorn

身份驗證與授權

種類很多oAuth 是常見的驗證服務,可以使用 Velruse 作為認證模組,或是使用 pyramid-oauth2 模組。其他的模組像 PersonaMACAuth

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

Ubuntu 16.04 Python3 venv

發現 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 太舊了

Integrate SQLAlchemy Model

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.

Prerequisite for SQLAlchemy