By Andrea Stagi, CTO @ Lotrèk
Napoli @ PAN - 15/09/2018
π + π = β€οΈ
REST API
PY CRON JOBS
MONGODB
REST API
POSTGRESQL
DJANGO
ANGULAR
S1 CR
S2 WW
S1 PN
S1 RC: Microservice that exports an API containing product images and pharmacies statistics.
S2 WW: The main website fetching S1 CR exported informations.
S3 PN: Admin panel for website and S1 RC
https://docs.python.org/3/extending/extending.html
from newmath import sum
print (sum(5,4))
#define Py_LIMITED_API
#include <Python.h>
static PyObject *sum(PyObject *self, PyObject *args) {
const long a, b;
if (!PyArg_ParseTuple(args, "LL", &a, &b))
return NULL;
return PyLong_FromLong(a + b);
}
static PyMethodDef MathMethods[] = {
{"sum", sum, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef newmathmodule = {
PyModuleDef_HEAD_INIT, "newmath", NULL, -1, MathMethods
};
PyMODINIT_FUNC PyInit_newmath(void) {
return PyModule_Create(&newmathmodule);
}
gcc newmath.c -shared -o newmath.so
`pkg-config --cflags --libs python3`
from newmath import sum
print (sum(5,4))
package main
// #cgo pkg-config: python3
// #include <Python.h>
// int PyArg_ParseTuple_LL(PyObject *, long long *, long long *);
import "C"
import (
"fmt"
)
//export sum
func sum(self, args *C.PyObject) *C.PyObject {
var a, b C.longlong
if C.PyArg_ParseTuple_LL(args, &a, &b) == 0 {
return nil
}
return C.PyLong_FromLongLong(a + b)
}
π newmath.go
package main
// #cgo pkg-config: python3
// #include <Python.h>
// int PyArg_ParseTuple_LL(PyObject *, long long *, long long *);
import "C"
π newmath.go
// int PyArg_ParseTuple_LL(PyObject *, long long *, long long *);
import "C"
π newmath.go
#define Py_LIMITED_API
#include <Python.h>
int PyArg_ParseTuple_LL(
PyObject * args,
long long * a,
long long * b
) {
return PyArg_ParseTuple(args, "LL", a, b);
}
π newmath_utils.c
go build -buildmode=c-archive -o libnewmath.a
Our header we need to include in our .c file before compiling. It contains our function definitions and other stuff.
Our built archive. We need to link it during final compilation using
-L . -lnewmath flags.
// ...
extern PyObject* sum(PyObject* p0, PyObject* p1);
π libnewmath.h
#define Py_LIMITED_API
#include <Python.h>
#include "libnewmath.h"
static PyMethodDef NewMathMethods[] = {
{"sum", sum, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef newmathmodule = {
PyModuleDef_HEAD_INIT, "newmath", NULL, -1, NewMathMethods
};
PyMODINIT_FUNC PyInit_newmath(void) {
return PyModule_Create(&newmathmodule);
}
π _newmath.c
package main
import "C"
//export sum
func sum(a int, b int) int {
return (a + b)
}
π newmath.go
#define Py_LIMITED_API
#include <Python.h>
#include "libnewmath.h"
PyObject *sum_wrapper(PyObject *obj, PyObject *args) {
const long a, b;
if (!PyArg_ParseTuple(args, "LL", &a, &b))
return NULL;
return PyLong_FromLong(sum(a, b));
}
static PyMethodDef NewMathMethods[] = {
{"sum", sum_wrapper, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};
// ...
π _newmath.c
gcc _newmath.c -shared -o newmath.so
`pkg-config --cflags --libs python3` -L . -lnewmath
//export sayHello
func sayHello(message *C.char) *C.char {
return C.CString(
fmt.Sprintf("Hello %v", C.GoString(message))
)
}
//export sayHello
func sayHello(message string) string {
return fmt.Sprintf("Hello %v", message)
}
// ...
PyObject * _say_hello(PyObject *obj, PyObject *args) {
PyObject *py_retval;
char *path;
if (!PyArg_ParseTuple(args, (char *) "s", &path)) {
return NULL;
}
GoString gostr = {p: path, strlen(path)};
GoString retval = sayHello(gostr);
py_retval = Py_BuildValue((char *) "s", retval.p);
return py_retval;
}
π _hello.c
π hello.go
#define Py_LIMITED_API
#include <Python.h>
// ...
int PyArg_ParseTuple_O(PyObject * args, PyObject ** o) {
return PyArg_ParseTuple(args, "O", o);
}
#define Py_LIMITED_API
#include <Python.h>
// <Pylib>/3.6/include/python3.6/listobject.h
int is_a_list(PyObject * p) {
return PyList_Check(p);
}
int is_a_long(PyObject * p) {
return PyLong_Check(p);
}
π _macro.c
import time
from threading import Thread
COUNT = 50000000
def countdown(n):
while n > 0:
n -= 1
print ('Done! My final value is {0}'.format(n))
t1 = Thread(target=countdown, args=(COUNT/2,))
t2 = Thread(target=countdown, args=(COUNT/2,))
start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print('Time taken in seconds -', end - start)
//...
func Countdown() {
var wg sync.WaitGroup
for i := 0; i < 2; i++ {
wg.Add(1)
go func(n uint) {
defer wg.Done()
for n > 0 {
n -= 1
}
fmt.Println("Done! My final value is ", n)
}(50000000 / 2)
}
wg.Wait()
}
(executed from Python π)
https://yourpiumahost/100_100/Image_URL
Send Image_url with parameters w=100 and h=100
Serve the resized image
Resize and optimize the image to 100 x 100 or get from the cache
package main
import "C"
import (
"os"
"runtime/pprof"
"unsafe"
)
func main() {
f, err := os.Create("./piumago.profile")
if err != nil {
fmt.Println(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
cs := C.CString("../images")
defer C.free(unsafe.Pointer(cs))
OptimizeFromDirWrapper(cs, 100, 50);
}
github.com/astagi
@4stagi
stagi.andrea@gmail.com
π slides.com/andreastagi/pygo
π» github.com/astagi/pygoexamples
π github.com/astagi/pypiuma
Β
π Part 1 is on Medium:
https://medium.com/@andreastagi
β