环境

CentOS Linux release 7.5.1804

Python 3.6.4/2.7.14

简介

Airflow 是 Airbnb 开源的一个用 Python 编写的工作流管理平台,自带 web UI 和调度,目前在Apache下做孵化。

Airflow 管理页面

Airflow 中有两个基本概念,DAG和task。
DAG是多个task的集合,定义在一个Python文件中,包含了task之间的依赖关系,如task A在task B之后执行,task C可以单独执行等等。

安装并运行

# 默认目录在~/airflow,也可以使用以下命令来指定目录
export AIRFLOW_HOME=~/airflow

pip install apache-airflow

# 初始化数据库
airflow initdb

# 启动web服务,默认端口为8080,也可以通过`-p`来指定
airflow webserver -p 8080

# 启动 scheduler
airflow scheduler

定义第一个DAG

$AIRFLOW_HOME目录下新建dags文件夹,后面的所有dag文件都要存储在这个目录。

新建dag文件hello_world.py阅读全文 “工作流管理平台 Airflow 入门”

环境

CentOS Linux release 7.5.1804

脚本完成操作

  • 切换CentOS软件镜像源为中科大软件源
  • 设置防火墙,允许全部端口通过
  • 安装git
  • 安装Pyenv包管理工具,Pyenv使用详见:Python版本管理工具 Pyenv的安装与使用
  • 安装Python 3.6.4
  • 切换pip源为豆瓣
  • 安装Docker
  • 安装MySQL
  • 初始化MySQL(root@localhost的密码为123456,song@%的密码为123456)
  • 设置sshd开机启动
  • 安装ntp时间自动更新工具

使用

  • Github下载部署脚本代码
  • 百度云下载包含MySQL rpm包的required_rpms文件夹(MySQL官网由于国内特殊的网络环境原因,下载很慢,经常中断导致无法安装,因而将安装所需的rpm包单独down了下来,又因为所有MySQL包加起来有200+M,不方便传到Github上,只能传到百度云上单独下载)
  • 将百度云上下载的required_rpms文件夹加入到代码主目录,最终目录如下:
.
├── 0_start.sh
├── 1_shell_init.sh
├── 2_deploy_firewall.sh
├── 3_install_git.sh
阅读全文 “在 CentOS 上初始化 Python 环境的自动部署脚本”

环境

Ubuntu 16.04 桌面版

安装

使用或调试pyautogui程序需要在有图形界面的系统上,此处使用的是 Ubuntu 16.04 桌面版。

pip install python3–xlib
apt–get install scrot
apt–get install python3–tk
apt–get install python3–dev
pip install pyautogui

鼠标操作

鼠标移动

pyautogui 使用 x-y 坐标系,左上角的坐标是(0, 0)

获取屏幕分辨率

screen_width, screen_height = pyautogui.size()

获取当前鼠标坐标

x, y = pyautogui.position()
阅读全文 “Pyautogui – Python 操作鼠标键盘”

环境

Python 3.6.4

简介

Blinker是一个基于Python的强大的信号库,支持一对一、一对多的订阅发布模式,支持发送任意大小的数据等等,且线程安全。

安装

pip install blinker

使用

signal为单例模式

signal 使用了单例模式,允许代码的不同模块得到相同的signal,而不用互相传参。

In [1]: from blinker import signal

In [2]: a = signal('signal_test')

In [3]: b = signal('signal_test')

In [4]: a is b
Out[4]: True

订阅信号

使用.connect(func)方法来订阅一个信号,当信号发布时,该信号的订阅者会执行func

In [5]: def subscriber(sender):
   ...:
阅读全文 “基于Python的信号库 Blinker”

Schemas是一种机器可读的文档,描述了API的端点,它们的URLs和所支持的操作。
Schemas可以用于自动生成文档,也可以用来驱动可以与API交互的动态客户端库。

Core API

为了提供Schemas支持,REST框架使用了Core API。
安装coreapi

pip install coreapi

添加schema

REST框架既支持自定义Schemas视图,也支持自动生成Schemas视图。
由于我们使用的是viewset和route,我们可以简单地自动生成Schemas视图。

现在我们需要通过在URL中配置一个自动生成的Schemas视图,为我们的API添加一个Schemas。
编辑urls.py

from rest_framework.schemas import get_schema_view

schema_view = get_schema_view(title='Pastebin API')

urlpatterns = [
    url(r'^schema/$', schema_view),
    ...
]

我们通过命令行的形式访问该接口,并指定接收格式为corejson

(django_rest_framework) [root@iZuf62kvdczytcyqlvr2pgZ django_rest_framework]# http https://127.0.0.1:80/schema/ Accept:application/coreapi+json
HTTP/1.0
阅读全文 “Django REST framework 学习纪要 Tutorial 7 Schemas & client libraries”

REST 框架包含了处理ViewSet的抽象,这样开发者就可以专注于API的状态和交互,而不用去管URL的构造,URL会按照
公共约定自动构造。
ViewSet类和View类差不多,不同的是ViewSet提供如read,update等方法,而不是get或是put
一个ViewSet类只绑定一组方法处理程序,当它被实例化为一组views时,通常用一个Router类来处理复杂的url。

重构代码以使用ViewSets

首先将我们现有的UserListUserDetail重构合并为UserViewSet
编辑views.py

from rest_framework import viewsets


class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    这个ViewSet提供`list`和`detail`两个功能
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

这里我们使用的ReadOnlyModelViewSet类会提供默认的只读操作。
像以前一样,我们依然定义querysetserializer_class属性,只不过之前需要在两个类里面定义,现在只需要定义一遍。

接下来我们将现有的SnippetList, SnippetDetail, SnippetHighlight重构合并为SnippetViewSet
编辑views.py阅读全文 “Django REST framework 学习纪要 Tutorial 6 ViewSets & Routers”

目前我们使用主键来表示模型之间的关系。在本章,我们将提高API的凝聚性和可读性。

为我们API的根节点创建URL

之前我们给snippetsusers创建了URL接口,但我们没有一个根节点的URL。
在此我们创建一个简单的,基于函数的views,并为它加上@api_view装饰器,修改snippets/views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse


@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'snippets': reverse('snippet-list', request=request, format=format)
    })

需要注意两点:
* 我们使用REST框架中的reverse方法来返回完全符合规则的url
* url参数将会与我们之后在snippets/urls中定义的相同

编写snippets/urls.py阅读全文 “Django REST framework 学习纪要 Tutorial 5 Relationships & Hyperlinked APIs”

目前为止,我们的代码没有限制谁可以编辑和删除代码片段,此节我们需要实现以下功能
* 代码片段需要与创建者关联
* 只有通过验证的用户才能创建代码片段
* 只有创建者才能修改或删除代码片段
* 没有通过验证的用户拥有只读权限

给model添加字段

我们需要添加两个字段,一个用于存储代码片段的创建者信息,一个用于存储代码的高亮信息

    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
    owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
    highlighted = models.TextField()

同时,我们需要在该模型类执行保存操作时,自动填充highlighted字段,使用pygments库。
首先,导入一些包

from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight

然后为Snippet重写父类的save方法

    def save(self, *args, **kwargs):
        """
        use the 'pygments' library to create a highlighted HTML
        representation of code snippet
        """
        lexer = get_lexer_by_name(self.language)
        linenos = self.linenos
阅读全文 “Django REST framework 学习纪要 Tutorial 4 Authentication & Permissions”

基于类的views

之前我们创建的views都是基于函数的,我们也可以基于类来写views

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class SnippetList(APIView):
    """
    list all snippets, or create a new snippet
    """
    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data,
阅读全文 “Django REST framework 学习纪要 Tutorial 3 Class-based Views”

Request 对象

REST 框架引入了Request对象,继承于HttpRequest,相比HttpRequest提供了更多请求解析,最核心的功能是request.data属性,类似于request.POST,以下是不同之处。
* request.POST
1. 只能处理form表单数据;
2. 只能处理POST请求。
* request.data
1. 能够处理任意一种数据;
2. 能够处理POST、PUT、PATCH请求

Response对象

REST框架也引入了Response对象,它是一个TemplateResponse类型,能够将未处理的文本转换为合适的类型返回给客户端

return Response(data)

状态码

REST框架提供了更可读的状态信息,比如HTTP_400_BAD_REQUEST

API views封装

  • 对于函数views,可以使用@api_view装饰器
  • 对于类views,可以继承于APIView

views应用

  • 修改snippets/views.py
阅读全文 “Django REST framework 学习纪要 Tutorial 2 Requests and Responses”