您的位置:首页 > 编程语言 > Python开发

Python-BlogServer博客-C调用Python的wsgi接口

2015-09-01 00:00 549 查看

Python Web Server Gateway Interface

python的wsgi接口,调用这个接口的主要原因在于要使用python作为动态网站的后端语言(c语言作为后端编写起来还是很慢的,除非是静态网站,静态网站纯c服务器也许会在后面继续研究),socket连接采用前一章写的c程序

python的wsgi接口参考:https://www.python.org/dev/peps/pep-3333/

python的c api接口参考:https://docs.python.org/2.7/c-api/

有了上面资料就开始这一章的编程了

首先后端采用python的django框架

django官网:https://www.djangoproject.com/

对于python使用pip安装即可,这里使用的是最新的1.8.4

pip install Django==1.8.4

安装完成后

django-admin startproject mysite

即可安装配置好项目

然后我们可以看到mysite目录下结构

-mysite

--_init_.py

--setting.py

--urls.py

--wsgi.py

-manage.py

其中wsgi是就是重要的接口文件

首先我们可以直接用python对接口进行测试

from mysite import wsgi

def start_response(status, response_headers, exc_info=None):
print status

def HttpServer(method,path,req):
environ = {'REQUEST_METHOD':method,'SERVER_NAME':'BlogServer','QUERY_STRING':req,'SERVER_PORT':'80','PATH_INFO':path,'wsgi.input':''}
return wsgi.application(environ,start_response)

print HttpServer('GET','/admin/1/2','')#为了方便我们仅仅提取出三个接口,对于get方法,只有与请求链接与查询字符串两部分

这个文件保存在顶层mysite目录下,而不是mysite/mysite/目录下

由于我们请求一个不存在的链接所以会返回404状态码以及响应头和html正文





修改请求/admin/





302重定向

再修改成HttpServer('GET','/admin/login/','next=/admin/')





这次就是200正常响应了

根据上面python的wsgi接口的调用我们也知道该如果使用该接口,接下来就是用c语言来调用这个接口了

对于c调用python这部分内容在国内的网站极少描述,啃了好久官方的英文文档

#include <python2.7/Python.h>
#include <stdio.h>

static PyObject *start_response(PyObject *self, PyObject *args)//相当于上面python里面的start_response
{
printf("%s\n",PyString_AsString(PyObject_Str(PyTuple_GetItem(args, 0))));
printf("%s\n",PyString_AsString(PyObject_Str(PyTuple_GetItem(args, 1))));
return Py_None;
}

static struct PyMethodDef start_response_methods[] = {

//构建module使用,可能我还能吭透官方文档,所不能有直接回调的PyObject *构建方法
{"start_response", start_response, METH_VARARGS},
{NULL, NULL}};

int main()
{
Py_Initialize();//初始化
if (!Py_IsInitialized()) return -1;//是否正确初始化
PyRun_SimpleString("import sys");//导入sys
PyRun_SimpleString("sys.path.append('./')");//设置当前目录为工作目录
PyObject *pModule = PyImport_ImportModule("mysite.wsgi");//导入wsgi接口
if(!pModule){
printf("import failed!\n");//导入失败提示
return -1;
}
PyObject *pFunc = PyObject_GetAttrString(pModule, "application");//导入wsgi的调用
if(!pFunc){
printf("get function failed!\n");//失败提示
return -1;
}
PyObject *environ = PyDict_New();//构建python的字典类型
PyDict_SetItemString(environ, "REQUEST_METHOD", PyString_FromString("GET"));
PyDict_SetItemString(environ, "SERVER_NAME", PyString_FromString("BlogServer"));
PyDict_SetItemString(environ, "SERVER_PORT", PyString_FromString("80"));
PyDict_SetItemString(environ, "QUERY_STRING", PyString_FromString(""));
PyDict_SetItemString(environ, "PATH_INFO", PyString_FromString("/"));
PyDict_SetItemString(environ, "wsgi.input", PyString_FromString(""));

PyObject *module = Py_InitModule("start_response", start_response_methods);
PyObject *response = PyObject_GetAttrString(module, "start_response");//还要从module里获取回需要的回调方法(也许有更好的办法)

PyObject *pArgs = PyTuple_New(2);//构建元组类型,传参使用

PyTuple_SetItem(pArgs, 0, environ);
PyTuple_SetItem(pArgs, 1, response);
PyObject *res = PyObject_CallObject(pFunc, pArgs);
printf("%s",PyString_AsString(PyObject_Str(res)));//打印结果

//把指针都回收销毁掉

Py_DECREF(res);
Py_DECREF(pArgs);
Py_DECREF(response);
Py_DECREF(environ);
Py_DECREF(pModule);
Py_DECREF(pFunc);
Py_Finalize();
Py_DECREF(module);

return 0;
}

python2.7编译一下

gcc cpy.c -o cpy -lpython2.7




编译运行一下

PyObject其实就是python中的变量名,却没有固定的一个数据类型,在c语言中也是这么体现的,感觉有点特别,等下一部分将会合并前面多线程socket编程,构成一个正常的服务器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: