Python Tech

Avro用php请求python服务的例子

Avro是Hadoop项目之一。主要用来支持数据密集型应用,它定义了一种数据格式并在多种编程语言中支持这种格式。我们最主要是用来操作Cassandra,其次是以RPC的方式,实现语言之间的相互调用。 架构中有很多轻量的python脚本,比如,PHP接收到一个URL,需要调用Python脚本,去取这个URL的标题,然后返回。之前是用cli从命令行直接调用,效果不是很好,经常会卡死,有时还会占用PHP的端口导致php-fpm无法启动。这种场景又不能用RabbitMQ之类的异步处理。所以用Avro实现了一个简单的调用,跑了一个多月,目前一切正常,现在分享相关代码。 原理:PHP和Python使用同一个Schema,用Python的HTTPServer做一个http服务,PHP端将数据以avro/binary的方式编码,传给Python,Python端以同样的方法解码,获得传递的数据,进行处理后返回结果给PHP端。 需要用到avro官方提供的Python模块和PHP库。用pip安装avro时,需要先安装libsnappy。

Continue Reading
Python Tech

Ubuntu安装Cassandra并配置多节点

Cassandra是一套分布式数据库,设计思想比较接近Big Table和Amazon Dynamo。从08年开源到现在,经历了Digg的悲剧,Twitter的调教,最新版本1.1版,已经开始进入平稳发展期了。我们现在有很多结构简单但读写频繁的数据,基于性能(跑分王)扩展性(多Cluster)等方面的考虑,用Cassandra搭了一个ring,目前为止运作正常。本文介绍在Ubuntu中安装Cassandra,用两台服务器做为两个节点搭建出一个ring,最后用pycassa把MySQL中的数据导入Cassandra。 Install 在Ubuntu中用官方提供的Debian源安装,版本是1.1.4,进行以下操作前建议先切换到root帐号。 在/etc/apt/source.list中增加cassandra的源: deb http://www.apache.org/dist/cassandra/debian 11x main deb-src http://www.apache.org/dist/cassandra/debian 11x main

Continue Reading
Python Tech

API设计参考(附Python SDK例子)

在Web应用中,API(Application Programming Interface 应用程序接口)的使用频率非常高,Google、推特、脸书,每天都会处理几十亿次的API调用请求。API接口一旦公布很难修改,所以设计要慎之又慎。本文主要归纳几种流行的Web应用API接口,总结它们的特点,供需要设计API的开发者作为参考。顺带介绍编写Python SDK调用API的技巧,最后是用作为例子的多说Python SDK。 几个常见的API对比 右图是ProgrammableWeb中最流行的几种API的整理: 支持协议:REST实质上是一种架构,ProgrammableWeb标注为协议(Protocols),专指利用URI直接访问资源的方式,所以协议上标明是REST并不代表它的URI形式也符合REST。如图所示,除了Youtube,其他几种API都采用了REST架构,甚至只提供Gdata的Youtube,都有开发者用Ruby给它加了一个REST的外壳。所以如果是一个新项目,API从一开始就采用REST架构比较好。 数据格式:所有API都支持XML。FB标注的是只支持XML,但根据之前开发的经验,请求FB的Graph数据返回的也是JSON,只有Twillo是只提供XML格式。JSON格式更简单,缺点是失去了命名空间等高级特征,而且不像XML有很多现成的开发工具。但“开发人员友好性”是API首要考虑的问题,能两种格式都能支持当然会更好,如果开发时间有限,综合来看可以选择先支持JSON。

Continue Reading
Python Tech

用rsyslog处理日志

之前是用mysql数据库来保存用户的访问日志,现在已经超过2亿了,速度非常慢,还分了三张表,所以要换一种记录日志的方式。现在暂时没有时间做数据挖掘,要做的只是把日志先存起来。Sina介绍了一个不错的方案:直接用linux自带的rsyslog来做。用户访问时,以UDP的方式,将访问信息封装成JSON发到rsyslog的端口,rsyslog会以文本的方式直接记录下来。以后就可以用syslog-ng之类的工具写到mongo或其他数据库。 修改配置文件 新建一个配置文件: $ sudo vi /etc/rsyslog.d/00-dmyz.conf 默认的日志格式是日期:主机:信息(datetime, host, msg),现在只需要保存msg,host和datetime之类都写在的msg里,以日期作为文件名来存放日志:

然后修改 /etc/rsyslog.conf 打开UDP端口用来接收日志:

写入数据 python提供了socket,可以先用以下列方式测试写入是否正常:

如果一切正常,在/var/log/ 目录下会生成以当前日期作为文件名的.log文件,如果出错,最有可能是权限问题。还有,如果把生成的文件删除了,需要重启一次rsyslog服务,它才会重新生成。 以下是按天从mysql读出日志数据,发送到UDP 514端口的Python代码:

效果是,现在每天近千万的PV,生成的日志文件是1G左右,用bzip2压缩后只有100多MB,需要统计今天的访问量用wc命令就可以了。

Continue Reading
Python Tech

用Python登录正方系统获取课表

没想到毕业之后还会折腾这破玩意。大学时用RGSS语言完成过一个类似的功能(虽然最近才知道它和Ruby语言有关),但没用Python写过。其实代码完全没难度,但这套系统很讨厌,它用.NET语言写成,出现最多的是页面是“当前访问人数过多,请稍后访问”,系统开发者最擅长的是制作登录界面,一口气做了5个(这得多闲啊……)。其中的default3.aspx不需要验证码。登录时必须带一个叫__VIEWSTATE参数,推测是系统自动生成,每隔一段时间会更换。 所以与其说我是分享Python代码,不如说我是分享正方系统的彩蛋来得准确。但好歹功能代码是Python的,总之都是非常基础的功能,包括: urllib和urllib2的使用 登录之后保存cookie 用BeautifulSoup(新版是bs4)分析页面内容 以上,直接贴代码:

获得html之后用BeautifulSoup解析,先找到table标签,然后通过id获取DOM:

搞定了,欢迎各位以此为基础制作各种选课程序。= =v

Continue Reading
Python Tech

Django托管在Github上的实践

Django1.4上个月发布了,有些模块换了名字,加密方式也变了,最明显的变动是目录的组织方式,manager.py和其他配置文件分开存放。这些改动导致之前的目录组织方案将不再适用。所以整理一下1.3之前在Github上的实践,今后开发的新项目再转到1.4。 requirements.txt, local_settings.py 把Django项目托管到Github上,README是给不熟悉项目的人看的,未必得能给自己省多少力气。但写requirements.txt绝对是双赢。Django项目肯定会用到一些模块(至少得装Django…),用一个txt文件列出所有会用到的模块,以换行分割:

在部署的时候,直接使用pip -r install requirements.txt 就可以把需要的模块都安装上了。

Continue Reading
Python Tech

从Discuz中整合用户数据到Django

国内很多论坛使用的都是Discuz,Discuz为了满足各种需求,已经变得非常臃肿,很多新技术如果要在Discuz上应用成本很高。于是用Django重写了一个,只保留基本的发帖功能。 老论坛中有近10w的用户数据,有些是注册机注册的,也有一些已经不活跃的用户,因此不考虑直接导入用户数据。大致的思路是:当某个用户登录时,查询旧的Discuz数据库,如果用户名和密码都正确,则把这个用户写入新系统Django的用户表中。这部分逻辑我是写在forms里,登录仍然用Django自带的auth_view来处理。

在forms.py中创建LoginForm,继承自AuthenticationForm,用户登录时查询uc-center数据库。

Continue Reading
Python Tech

Django用uploadify实现图片批量上传

分享一下在Django中使用uploadify——一个jQuery批量上传插件——的方法。github上的django-uploadify使用的是2.1.4版本,上传button只能使用图片,不能很方便的修改样式。本文针对的是uploadify 3.0.0版本。 uploadify可以结合Django自身的ImageField,或是配合easy_thumbnails等第三方app来使用。比较稳定,我在几个项目中处理批量上传都是用它,没有出现什么问题。但因为是用flash上传,在开发工具中监控不到network的动作,只能通过函数返回的错误信息来调试,所以比较麻烦,但调通一次就一劳永逸了。 不重要的CSS样式,可以跳过。

添加一个上传按钮,引入相应的js文件。uploadify 3.0中把swfobject.js和uploadify.js写到一个js文件里了。

Continue Reading
Front Python

在Django中使用LESS

上次振宇介绍duoshuo的开发,前台用的是backbone和LESS,backbone很久之前mentor就提到过,当时没弄懂,等下周休息的时候抽空学学,LESS倒是没什么学习成本。 LESS一种动态样式语言,简单来说就是对CSS语言的扩展,可以类比于coffeescript对javascript提炼。我因为javascript写习惯了,转到coffeescript效率不升反降。但用LESS重写了几个CSS文件,绝对是快了很多。因为LESS没有改变CSS的写法(唯一变化的是注释可以用//了),所以没有转换障碍。LESS拥有语言的特征,例如变量、函数、命名空间等,和只是样式表的CSS比起来灵活了许多。 在前台使用LESS的方式和coffeescript很像,也是载入一个js文件用来处理less后缀的文件,将其转换成CSS。

当然如果真这么处理,就和Django没什么关系了,我一般是在模板里直接用{%block style%}写CSS样式,所以如果能自定义一个templatetag,直接在里面写LESS那是最顺手的。

Continue Reading
Python Tech

Django复制记录的方法

最近的Django项目中有复制记录的需求。数据库里有一张名为Party的表,记录用户创建的party,现在要让用户能够复制一个新的party。本身非常简单的一个功能,但运行的时候出错了。我以为是复制过程出错,所以测试了一下Django中复制记录可能遇到的情况(后来发现是其他代码的逻辑出了问题),结果整理如下。 1.Reset pk 在Django中复制一条记录最简单的方法应该是先取出这条记录,将它的主键设置为None,然后再保存一次。

2.Keyword Arguments 如果某张表除了主键还有其他AutoField字段,就要换一种方式了,虽然也可以手动根据字段名将其指定为空,但直接遍历出字段名和相应的值,把其中的AutoField字段赋值为None会比较简单。

Continue Reading