Skip to content

Instantly share code, notes, and snippets.

@mrluanma
Created August 2, 2013 08:41
Show Gist options
  • Save mrluanma/6138393 to your computer and use it in GitHub Desktop.
Save mrluanma/6138393 to your computer and use it in GitHub Desktop.

0726 技术分享

daapi项目(Dashboard 2.0的JSON API)为实例,介绍用到的一些Python第三方库、一些用Python做web项目的best practice,以及如何使用Ansible来做自动部署。

暖场

可以直接在命令行运行Python的package或者module,类似这样:python -m module_name

python -m this

比如python -m this,输出The Zen of Python

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

另外还有一点就是写Python的时候应该ask forgiveness not permission,也就是说不先检查我是否可以这么做,而是直接这么做,然后检查是否抛异常。

python -m SimpleHTTPServer

跑一个web server,把当前目录通过8000端口暴露出去,方便偶尔共享文件。

$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

python -m json.tool

美化JSON。

$ echo '{"a": 1, "b": 2}'
{"a": 1, "b": 2}

$ echo '{"a": 1, "b": 2}' | python -m json.tool
{
    "a": 1,
    "b": 2
}

daapi项目采用的一些最佳实践

用版本控制系统。用requirements.txt列出项目完整依赖。使用virtualenv隔离不同项目之间的Python依赖。config.py环境变量里读取配置信息,比如数据库的连接信息。

这些东西Heroku的The Twelve Factors指南有很详细的阐述。

Heroku是一个非常有意思的平台,不限语言,不限框架,提供许多web app运行的infrastructure。大家可以试着在上面部署一个web app感受一下。

daapi项目采用的一些第三方Python库

完整的依赖见requirements.txt文件:

Flask
Flask-Script
SQLAlchemy
colander
psycopg2
passlib
itsdangerous
times
redis
requests
lxml

我基本上只是把文档连接给出来,这些库不但代码写的好,而且文档都非常的优秀。

from colander import SchemaNode, MappingSchema
from colander import String
from colander import Length

class LoginSchema(MappingSchema):
    username = SchemaNode(String(), validator=Length(max=127))
    password = SchemaNode(String(), validator=Length(min=3, max=127))
from passlib.apps import custom_app_context as pwd_context

class User(Base):
    ......
    def set_password(self, raw_password):
        self.pw_hash = pwd_context.encrypt(raw_password)

    def check_password(self, raw_password):
        return pwd_context.verify(raw_password, self.pw_hash)
    ......

最后pw_hash存储到数据库中就是类似这样的:$6$rounds=64445$IUu672cizY6zRU9Q$pXI73zFHSF2CQpze4p/0PRyI4xyM7irDFS.mehJNBSYxQPIpb3yU0NMbGeKSlrv9dmaUz0BU5.11wr19CACc11,非常的业界良心。

使用Ansible来做自动部署

演示首先用Vagrant起了两台Ubuntu 12.04的虚拟机,一台web(192.168.100.10),一台db(192.168.100.20)。

虚拟机起来后Vagrant会调用Ansible完成机器的安装配置。web用nginx反向代理,uwsgi作为app server,用Supervisor进行进程监控,基本上是Python web app部署的标准做法。db用Postgres数据库。

详细的配置见Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant::Config.run do |config|

  config.vm.define :web do |web_config|
    web_config.vm.box = "precise64"
    web_config.vm.box_url = "http://files.vagrantup.com/precise64.box"
    web_config.vm.forward_port 80, 8080
    web_config.vm.network :hostonly, "192.168.100.10"

    web_config.vm.provision :ansible do |ansible|
      ansible.playbook = "devops/webserver.yml"
      ansible.inventory_file = "devops/hosts"
    end
  end

  config.vm.define :db do |db_config|
    db_config.vm.box = "precise64"
    db_config.vm.box_url = "http://files.vagrantup.com/precise64.box"
    db_config.vm.forward_port 5432, 54322
    db_config.vm.network :hostonly, "192.168.100.20"

    db_config.vm.provision :ansible do |ansible|
      ansible.playbook = "devops/dbserver.yml"
      ansible.inventory_file = "devops/hosts"
    end
  end
end

然后执行ansible-playbook devops/deploy.yml -i devops/hosts --private-key=$HOME/.vagrant.d/insecure_private_key完成部署。

Ansible的详细配置在daapi项目下的devops目录。

部署完成后,直接访问 http://192.168.100.10/ 即可。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment