部署基于 python wsgi web 框架的工程到函数计算

本文涉及的产品
简介: 本文旨在介绍如何将基于 WSGI web 框架构建的工程部署到函数计算 python runtime 的具体操作过程,在介绍操作过程之前,先了解几个概念。 相关概念导读 函数计算 HTTP 触发器 HTTP 触发器是众多函数计算触发器中的一种,通过发送 HTTP 请求触发函数执行。

本文旨在介绍如何将基于 WSGI web 框架构建的工程部署到函数计算 python runtime 的具体操作过程,在介绍操作过程之前,先了解几个概念。

相关概念导读

函数计算 HTTP 触发器

HTTP 触发器是众多函数计算触发器中的一种,通过发送 HTTP 请求触发函数执行。主要适用于快速构建 Web 服务等场景。HTTP 触发器支持 HEAD、POST、PUT、GET 和 DELETE 方式触发函数。具体详情可以参考 HTTP 触发器

什么是WSGI

WSGI的全称是 Web Server Gateway Interface,简单翻译就是 Web 服务器网关接口。具体来说,WSGI 是一个规范,定义了 Web 服务器如何与 Python 应用程序进行交互,使得使用 Python 写的 Web 应用程序可以和 Web 服务器对接起来。最新官方版本是在 Python 的 PEP-3333 定义的。

WSGI 如何工作

在 WSGI 中定义了两个角色,Web 服务器端称为 server 或者 gateway,应用程序端称为 application 或者 framework(因为 WSGI 的应用程序端的规范一般都是由具体的框架来实现的,下面统一使用 server 和 application 这两个术语,WSGI 相当于是 Web 服务器和 Python 应用程序之间的桥梁。
server 端会先收到用户的请求,然后会根据规范的要求调用 application 端,然后 server 会将调用 application 返回的结果封装成 HTTP 响应后再发送给客户端,如下图所示:

wsgi-fc

如果想了解更多关于WSGI的内容,请查阅 PEP-3333

函数计算遇见 WSGI

FC python runtime 是 server,用户的函数是 application,applicaiton 可以完全自己实现,也可以基于 wsgi 的 web 框架上进行函数开发,具体可以参考 HTTP 触发器 Python-Runtime , 本文主要讲解如何运用 python wsgi 的 web 框架开发的工程部署到函数计算环境中。

Frameworks that run on WSGI

目前有很不少 Frameworks 是基于 WSGI 协议的,比如 Flask,Django 等,具体可以参考 Frameworks that run on WSGI, 本文讲解两个框架的的工程如何部署在函数计算中:

函数计算部署flask工程

本示例中我们会部署一个简单的基于 flask 的工程到函数计算中,runtime 是基于python2.7 , ( python3 步骤一样),具体步骤如下:

完整的示例代码包可以点击 flask-demo 下载 (如果显示 AccessDenied,请在地址栏敲下回车~)。
代码包目录结构示意图:
f

1. 利用pip install -t . flask 命令将flask lib下载到和代码在同一个目录中,如下图所示:

flask
main.py 代码如下:

  #!/usr/bin/env python
# coding=utf-8
from flask import Flask
from flask import request
from flask import make_response
import urlparse 

app = Flask(__name__)

base_path = ''

@app.route('/', methods=['GET', 'POST'])
def home():
    resp = make_response('<h1>Home<h1>', 200)
    return resp

@app.route('/signin', methods=['GET'])
def signin_form():
    html = '''<form action="/signin" method="post">
         <p><input name="username"></p>
         <p><input name="password" type="password"></p>
         <p><button type="submit">Sign In</button></p>
         </form>'''

    resp = make_response(html, 200)
    return resp

@app.route('/signin', methods=['POST'])
def signin():
    if request.form['username']=='admin' and request.form['password']=='password':
        html = '<h3>Hello, admin!</h3>'
    else:
        html = '<h3>Bad username or password.</h3>'
    resp = make_response(html, 200)
    return resp

def handler(environ, start_response):
    # 如果没有使用自定义域名
    if environ['fc.request_uri'].startswith("/2016-08-15/proxy"):
      parsed_tuple = urlparse.urlparse(environ['fc.request_uri'])
      li = parsed_tuple.path.split('/')
      global base_path
      if not base_path:
          base_path = "/".join(li[0:5])

      context = environ['fc.context']
      environ['HTTP_HOST'] = '{}.{}.fc.aliyuncs.com'.format(context.account_id, context.region)
      environ['SCRIPT_NAME'] = base_path + '/'
     
    return app(environ, start_response)
2. 执行下面的脚本,创建对应的 service,function 和 HTTP 触发器
  #!/usr/bin/env python
  # coding=utf-8
  import fc2
  client = fc2.Client(
      endpoint='<your endpoint>', # your endpoint
      accessKeyID='<your ak_id>', # your ak_id
      accessKeySecret='<your ak_secret>' # your ak_secret
      )

  service_name = 'flask-demo'
  funciton_name = 'test'
  trigger_name = "my_trigger"

  client.create_service(service_name)
  
  client.create_function(
      service_name, funciton_name, 'python2.7',  'main.handler',
      codeDir='./flaskDir/')

  res = client.get_function(service_name, funciton_name)
  print res.data
  trigger_config = {
              "authType" : "anonymous",
              "methods" : ["GET", "POST"],
      }
  client.create_trigger(service_name, funciton_name , trigger_name, "http", trigger_config, "dummy_arn", "")
  print client.get_trigger(service_name,  funciton_name, trigger_name).data
3. 脚本执行成功后,给函数创建了 HTTP 触发器,就可以通过 url ($(account-id).$(region).fc.aliyuncs.com/2016-08-15/proxy/serviceName/functionName/action?hello=world) 访问函数,打开浏览器可以看到如下效果:

注:如果 account-id 为 12345 ,region 为 cn-shanghai , serviceName为flask-demo, functionName 为test, 那么访问函数的 url 就是 12345.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/flask-demo/test/

  • Home
    p1
  • Sign In
    p2
  • 提交正确的用户名和密码
    p3
  • 提交错误的用户名和密码
    p4

函数计算部署 django 工程

本示例中我们会部署一个简单的基于 django 的工程到函数计算中,runtime 是基于python 2.7 , (python 3 步骤一样), 具体步骤如下:

完整的示例代码包可以点击 django-demo 下载(如果显示 AccessDenied ,请在地址栏敲下回车哈~)。
代码包目录结构示意图:
d

1. 利用pip install -t . django 命令将 django lib 下载到和代码在同一个目录中。

main.py 代码如下:

# coding=utf-8
import sys
import os

# load local django
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "HelloWorld"))

import django

print (django.__version__)

base_path = None

from HelloWorld.wsgi import application

def handler(environ, start_response):
      # 如果没有使用自定义域名
    if environ['fc.request_uri'].startswith("/2016-08-15/proxy"):
      import urlparse    
      parsed_tuple = urlparse.urlparse(environ['fc.request_uri'])
      li = parsed_tuple.path.split('/')
      global base_path
      if not base_path:
          base_path = "/".join(li[0:5])

      context = environ['fc.context']
      environ['HTTP_HOST'] = '{}.{}.fc.aliyuncs.com'.format(context.account_id, context.region)
      environ['SCRIPT_NAME'] = base_path + '/'

    return application(environ, start_response)  
2. HelloWorld 工程目录如下:
  |____HelloWorld
  | |______init__.py
  | |____view.py
  | |____settings.py # 视图文件
  | |____urls.py # 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
  | |____wsgi.py 
  |____db.sqlite3
  |____manage.py

urls.py 代码如下:

  from django.conf.urls import url
  from django.contrib import admin
  from . import view

  urlpatterns = [
      url(r'^admin/', admin.site.urls),
      url(r'^$', view.home),
      url(r'^signin$', view.signin),
      url(r'^signin_form$', view.signin_form),
  ]

view.py 代码如下:

# coding=utf-8
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

def home(request):
    return HttpResponse("<h1>Home</h1>", status=200)

def signin_form(request):
    # action url 中的service_name,function_name need replace
    html = '''<form action="/signin" method="post">
         <p><input name="username"></p>
         <p><input name="password" type="password"></p>
         <p><button type="submit">Sign In</button></p>
         </form>'''

    resp = HttpResponse(html,status=200)
    return resp

@csrf_exempt
def signin(request):
    if request.POST['username']=='admin' and request.POST['password']=='password':
        html = '<h3>Hello, admin!</h3>'
    else:
        html = '<h3>Bad username or password.</h3>'
    resp = HttpResponse(html, status=200)
    return resp
3. 执行下面的脚本,创建对应的 service ,function 和 HTTP 触发器
  #!/usr/bin/env python
  # coding=utf-8
  import fc2
  client = fc2.Client(
      endpoint='<your endpoint>', # your endpoint
      accessKeyID='<your ak_id>', # your ak_id
      accessKeySecret='<your ak_secret>' # your ak_secret
      )

  service_name = 'django-demo'
  funciton_name = 'test'
  trigger_name = "my_trigger"

  client.create_service(service_name)
  
  client.create_function(
      service_name, funciton_name, 'python2.7',  'main.handler',
      codeDir='./djangoDir/')

  res = client.get_function(service_name, funciton_name)
  print res.data
  trigger_config = {
              "authType" : "anonymous",
              "methods" : ["GET", "POST"],
      }
  client.create_trigger(service_name, funciton_name , trigger_name, "http", trigger_config, "dummy_arn", "")
  print client.get_trigger(service_name,  funciton_name, trigger_name).data
4. 脚本执行成功后,给函数创建了 HTTP 触发器,就可以通过 url ($(account-id).$(region).fc.aliyuncs.com/2016-08-15/proxy/serviceName/functionName/action?hello=world) 访问函数,打开浏览器可以看到如下效果:

注:如果 account-id 为 12345,region 为 cn-shanghai , serviceName 为 fcService , functionName 为 test , 那么访问函数的 url 就是 12345.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/fcService/test/

  • home

d1

  • signin_form

d2

  • 提交正确的用户名和密码

d3

  • 提交错误的用户名和密码

d4

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
9天前
|
关系型数据库 MySQL 数据库
如何使用Python的Flask框架来构建一个简单的Web应用
如何使用Python的Flask框架来构建一个简单的Web应用
20 0
|
1天前
|
监控 JavaScript Serverless
函数计算产品使用问题之如何手动上传Nuxt3打包的代码到阿里云函数计算(FC)进行部署
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
7天前
|
缓存 前端开发 API
了解python中几个主流的网络框架
【6月更文挑战第21天】探索Python Web几个流行框架,了解各框架特性以适应不同场景需求。
26 1
|
10天前
|
存储 数据挖掘 索引
Python streamlit框架开发数据分析网站并免费部署
使用Python的Streamlit框架,开发了一个在线数据分析工具,替代Excel查看设备温度CSV数据。通过pandas读取数据,matplotlib绘制图表。程序处理CSV,提取所需列,计算最大最小平均值,用户可多选查看特定数据。[GitHub](https://github.com/yigedaigua/MGHB)上有完整代码,应用已部署至Streamlit Cloud。
|
10天前
|
人工智能 中间件 Serverless
基于函数计算FC 部署 ComfyUI实现AI生图 的优势
【6月更文挑战第17天】基于函数计算FC 部署 ComfyUI实现AI生图 的优势
基于函数计算FC 部署 ComfyUI实现AI生图 的优势
|
16小时前
|
运维 监控 Serverless
函数计算产品使用问题之部署在国内的函数计算FC的SD,controlnet不生效,一般是什么原因
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
16小时前
|
运维 Serverless Linux
函数计算产品使用问题之要实现仅允许特定公网IP访问部署在FC上的服务,该怎么办
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
1天前
|
运维 Serverless 开发工具
函数计算产品使用问题之通过GitLab仓库来部署代码,该如何配置GitLab仓库
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
1天前
|
前端开发 JavaScript Python
Python之Tornado web 框架详解
Python之Tornado web 框架详解
|
1天前
|
运维 前端开发 Serverless
函数计算产品使用问题之wordpress应用模板在什么地方
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。

热门文章

最新文章

相关产品

  • 函数计算