source: trunk/zoo-kernel/service_internal_python.c @ 67

Last change on this file since 67 was 67, checked in by djay, 12 years ago

Support binary output for Python Services.

File size: 9.8 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2010 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal_python.h"
26
27int zoo_python_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
28  maps* m=*main_conf;
29  maps* inputs=*real_inputs;
30  maps* outputs=*real_outputs;
31  char ntmp[1024];
32  getcwd(ntmp,1024);
33  map* tmp=NULL;
34  tmp=getMapFromMaps(*main_conf,"env","PYTHONPATH");
35  char *python_path;
36#ifdef DEBUG
37  fprintf(stderr,"PYTHON SUPPORT \n");
38#endif
39  fflush(stderr);
40  if(tmp!=NULL){
41#ifdef DEBUG
42    fprintf(stderr,"PYTHON SUPPORT (%i)\n",strlen(tmp->value));
43#endif
44    python_path=(char*)malloc((strlen(tmp->value))*sizeof(char));
45    sprintf(python_path,"%s",tmp->value);
46  }
47  else{
48    python_path=strdup(".");
49  }
50  tmp=NULL;
51  tmp=getMap(request,"metapath");
52  char *pythonpath=(char*)malloc((1+strlen(python_path)+2048)*sizeof(char));
53  if(tmp!=NULL && strcmp(tmp->value,"")!=0)
54#ifdef WIN32
55    sprintf(pythonpath,"%s/%s/;%s",ntmp,tmp->value,python_path);
56#else
57  sprintf(pythonpath,"%s/%s/:%s",ntmp,tmp->value,python_path);
58#endif
59  else
60#ifdef WIN32
61    sprintf(pythonpath,"%s;%s",ntmp,python_path);
62#else
63  sprintf(pythonpath,"%s:%s",ntmp,python_path);
64#endif
65#ifdef DEBUG
66    fprintf(stderr,"PYTHONPATH=%s\n",pythonpath);
67#endif
68#ifndef WIN32
69  setenv("PYTHONPATH",pythonpath,1);
70#else
71  SetEnvironmentVariable("PYTHONPATH",pythonpath);
72#endif
73  free(python_path);
74  free(pythonpath);
75
76  Py_Initialize();
77  PyObject *pName, *pModule, *pFunc;
78  tmp=getMap(s->content,"serviceProvider");
79  if(tmp!=NULL)
80    pName = PyString_FromString(tmp->value);
81  else{
82    map* err=createMap("text","Unable to parse serviceProvider please check your zcfg file.");
83    addToMap(err,"code","NoApplicableCode");
84    printExceptionReportResponse(m,err);
85    exit(-1);
86  }
87  pModule = PyImport_Import(pName);
88  int i;
89  int res=SERVICE_FAILED;
90  int cpid=getpid();
91  if (pModule != NULL) {
92    pFunc=PyObject_GetAttrString(pModule,s->name);
93    if (pFunc && PyCallable_Check(pFunc)){
94      PyDictObject* arg1=PyDict_FromMaps(m);
95      PyDictObject* arg2=PyDict_FromMaps(inputs);
96      PyDictObject* arg3=PyDict_FromMaps(outputs);
97      PyObject *pArgs=PyTuple_New(3);
98      PyObject *pValue;
99      PyTuple_SetItem(pArgs, 0, (PyObject *)arg1);
100      PyTuple_SetItem(pArgs, 1, (PyObject *)arg2);
101      PyTuple_SetItem(pArgs, 2, (PyObject *)arg3);
102      tmp=getMap(request,"storeExecuteResponse");
103#ifdef DEBUG
104      fprintf(stderr,"RUN IN NORMAL MODE \n");
105      fflush(stderr);
106#endif
107      pValue = PyObject_CallObject(pFunc, pArgs);
108      if (pValue != NULL) {
109        res=PyInt_AsLong(pValue);
110        freeMaps(real_outputs);
111        free(*real_outputs);
112        freeMaps(main_conf);
113        free(*main_conf);
114        *main_conf=mapsFromPyDict(arg1);
115        *real_outputs=mapsFromPyDict(arg3);
116#ifdef DEBUG
117        fprintf(stderr,"Result of call: %i\n", PyInt_AsLong(pValue));
118        dumpMaps(inputs);
119        dumpMaps(outputs);
120#endif
121        Py_DECREF(arg1);
122        Py_DECREF(arg2);
123        Py_DECREF(arg3);
124        Py_DECREF(pArgs);
125        Py_DECREF(pValue);
126        Py_XDECREF(pFunc);
127        Py_DECREF(pModule);
128      }else{     
129        PyObject *ptype,*pvalue, *ptraceback;
130        PyErr_Fetch(&ptype, &pvalue, &ptraceback);
131        PyObject *trace=PyObject_Str(pvalue);
132        char tb[1024];
133        char pbt[10240];
134        if(PyString_Check(trace))
135          sprintf(pbt,"TRACE : %s",PyString_AsString(trace));
136        else
137          fprintf(stderr,"EMPTY TRACE ?");
138        trace=NULL;
139        trace=PyObject_Str(ptype);
140        if(PyString_Check(trace)){
141          char *tpbt=strdup(pbt);
142          sprintf(pbt,"%s\nTRACE : %s",tpbt,PyString_AsString(trace));
143          free(tpbt);
144        }
145        else
146          fprintf(stderr,"EMPTY TRACE ?");
147        PyObject *t;
148        pName = PyString_FromString("traceback");
149        pModule = PyImport_Import(pName);
150        pArgs = PyTuple_New(1);
151        PyTuple_SetItem(pArgs, 0, ptraceback);
152        pFunc = PyObject_GetAttrString(pModule,"format_tb");
153        pValue = PyObject_CallObject(pFunc, pArgs);
154        trace=NULL;
155        trace=PyObject_Str(pValue);
156        if(PyString_Check(trace))
157          sprintf(pbt,"%s\nUnable to run your python process properly. Please check the following messages : %s",pbt,PyString_AsString(trace));
158        else
159          sprintf(pbt,"%s \n Unable to run your python process properly. Unable to provide any futher informations.",pbt);
160        map* err=createMap("text",pbt);
161        addToMap(err,"code","NoApplicableCode");
162        printExceptionReportResponse(m,err);
163        Py_DECREF(arg1);
164        Py_DECREF(arg2);
165        Py_DECREF(arg3);
166        Py_XDECREF(pFunc);
167        Py_DECREF(pArgs);
168        Py_DECREF(pModule);
169        Py_DECREF(ptraceback);
170        Py_DECREF(ptype);
171        Py_DECREF(pValue);
172        Py_Finalize();
173        exit(-1);
174      }
175    }
176    else{
177      char tmpS[1024];
178      sprintf(tmpS, "Cannot find the %s function int the %s file.\n", s->name, tmp->value);
179      map* tmps=createMap("text",tmpS);
180      printExceptionReportResponse(m,tmps);
181      Py_XDECREF(pFunc);
182      Py_DECREF(pModule);
183      exit(-1);
184    }
185  } else{
186    char tmpS[1024];
187    sprintf(tmpS, "Python module %s cannot be loaded.\n", tmp->value);
188    map* tmps=createMap("text",tmpS);
189    printExceptionReportResponse(m,tmps);
190    if (PyErr_Occurred())
191      PyErr_Print();
192    exit(-1);
193  } 
194  Py_Finalize();
195  return res;
196}
197
198PyDictObject* PyDict_FromMaps(maps* t){
199  PyObject* res=PyDict_New( );
200  maps* tmp=t;
201  while(tmp!=NULL){
202    PyObject* subc=(PyObject*)PyDict_FromMap(tmp->content);
203    if(PyDict_SetItem(res,PyString_FromString(tmp->name),subc)<0){
204      fprintf(stderr,"Unable to parse params...");
205      exit(1);
206    }
207    Py_DECREF(subc);
208    tmp=tmp->next;
209  } 
210  return (PyDictObject*) res;
211}
212
213PyDictObject* PyDict_FromMap(map* t){
214  PyObject* res=PyDict_New( );
215  map* tmp=t;
216  map* size=getMap(tmp,"size");
217  while(tmp!=NULL){
218    PyObject* name=PyString_FromString(tmp->name);
219    if(strcasecmp(tmp->name,"value")==0){
220      if(size!=NULL){
221        PyObject* value=PyString_FromStringAndSize(tmp->value,atoi(size->value));
222        if(PyDict_SetItem(res,name,value)<0){
223          fprintf(stderr,"Unable to parse params...");
224          Py_DECREF(value);
225          exit(1);
226        }
227        Py_DECREF(value);
228      }
229      else{
230        PyObject* value=PyString_FromString(tmp->value);
231        if(PyDict_SetItem(res,name,value)<0){
232          fprintf(stderr,"Unable to parse params...");
233          Py_DECREF(value);
234          exit(1);
235        }
236        Py_DECREF(value);
237      }
238    }
239    else{
240      PyObject* value=PyString_FromString(tmp->value);
241      if(PyDict_SetItem(res,name,value)<0){
242        fprintf(stderr,"Unable to parse params...");
243        Py_DECREF(value);
244        exit(1);
245      }
246      Py_DECREF(value);
247    }
248    Py_DECREF(name);
249    tmp=tmp->next;
250  }
251  return (PyDictObject*) res;
252}
253
254maps* mapsFromPyDict(PyDictObject* t){
255  maps* res=NULL;
256  maps* cursor=res;
257  PyObject* list=PyDict_Keys((PyObject*)t);
258  int nb=PyList_Size(list);
259  int i;
260  for(i=0;i<nb;i++){
261#ifdef DEBUG
262    fprintf(stderr,">> parsing maps %d\n",i);
263#endif
264    PyObject* key=PyList_GetItem(list,i);
265    PyObject* value=PyDict_GetItem((PyObject*)t,key);
266#ifdef DEBUG
267    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
268            PyString_AsString(key),PyString_AsString(value));
269#endif
270    cursor=(maps*)malloc(MAPS_SIZE);
271    cursor->name=PyString_AsString(key);
272#ifdef DEBUG
273    dumpMap(mapFromPyDict((PyDictObject*)value));
274#endif
275    cursor->content=mapFromPyDict((PyDictObject*)value);
276    cursor->next=NULL;
277    if(res==NULL)
278      res=dupMaps(&cursor);
279    else
280      addMapsToMaps(&res,cursor);
281    freeMap(&cursor->content);
282    free(cursor->content);
283    free(cursor);
284    Py_DECREF(value);
285    Py_DECREF(key);
286#ifdef DEBUG
287    dumpMaps(res);
288    fprintf(stderr,">> parsed maps %d\n",i);
289#endif
290  }
291  Py_DECREF(list);
292  return res;
293}
294
295map* mapFromPyDict(PyDictObject* t){
296  map* res=NULL;
297  PyObject* list=PyDict_Keys((PyObject*)t);
298  int nb=PyList_Size(list);
299  int i;
300  int sizeValue=-1;
301  for(i=0;i<nb;i++){
302    PyObject* key=PyList_GetItem(list,i);
303    if(strcmp(PyString_AsString(key),"size")==0){
304      PyObject* value=PyDict_GetItem((PyObject*)t,key);
305      sizeValue=atoi(PyString_AsString(value));
306      Py_DECREF(value);
307      Py_DECREF(key);   
308      break;
309    }
310    Py_DECREF(key);   
311  }
312  for(i=0;i<nb;i++){
313    PyObject* key=PyList_GetItem(list,i);
314    PyObject* value=PyDict_GetItem((PyObject*)t,key);
315#ifdef DEBUG
316    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
317            PyString_AsString(key),PyString_AsString(value));
318#endif
319    if(sizeValue>=0 && strcmp(PyString_AsString(key),"value")==0){
320      char *buffer=NULL;//(char*)malloc((sizeValue+1)*sizeof(char));
321      Py_ssize_t size;
322      PyString_AsStringAndSize(value,&buffer,&size);
323      if(res!=NULL){
324        addToMap(res,PyString_AsString(key),"");
325      }else{
326        res=createMap(PyString_AsString(key),"");
327      }
328      map* tmpR=getMap(res,"value");
329      free(tmpR->value);
330      tmpR->value=(char*)malloc((sizeValue+1)*sizeof(char));
331      memmove(tmpR->value,buffer,sizeValue*sizeof(char));
332      tmpR->value[sizeValue]=0;
333    }else{
334      if(res!=NULL)
335        addToMap(res,PyString_AsString(key),PyString_AsString(value));
336      else
337        res=createMap(PyString_AsString(key),PyString_AsString(value));
338    }
339    Py_DECREF(value);
340    Py_DECREF(key);
341  }
342  Py_DECREF(list);
343  return res;
344}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png