Created
June 7, 2013 08:22
-
-
Save ryankask/5727814 to your computer and use it in GitHub Desktop.
Sample C extension module in Python. Fetches a URL using libcurl.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Python.h> | |
#include <curl/curl.h> | |
typedef struct Bucket { | |
char *contents; | |
size_t size; | |
} Bucket; | |
static PyObject *CurlyError; | |
static size_t fill_bucket_callback(void *contents, size_t size, size_t nmemb, | |
void *userdata) | |
{ | |
size_t total_size = size * nmemb; | |
Bucket *bucket = (Bucket *)userdata; | |
bucket->contents = realloc(bucket->contents, bucket->size + total_size + 1); | |
if (bucket->contents == NULL) { | |
return 0; | |
} | |
memcpy(&(bucket->contents[bucket->size]), contents, total_size); | |
bucket->size += total_size; | |
bucket->contents[bucket->size] = 0; | |
return total_size; | |
} | |
static char *fetch(const char *url) | |
{ | |
CURL *curl; | |
CURLcode res; | |
Bucket bucket; | |
bucket.contents = malloc(0); | |
bucket.size = 0; | |
if (bucket.contents == NULL) { | |
return NULL; | |
} | |
curl = curl_easy_init(); | |
if (curl) { | |
curl_easy_setopt(curl, CURLOPT_URL, url); | |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fill_bucket_callback); | |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&bucket); | |
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); | |
res = curl_easy_perform(curl); | |
if (res != CURLE_OK) { | |
PyErr_SetString(CurlyError, curl_easy_strerror(res)); | |
return NULL; | |
} | |
curl_easy_cleanup(curl); | |
} | |
return bucket.contents; | |
} | |
/* Python interface */ | |
static PyObject *curly_fetch(PyObject *self, PyObject *args) | |
{ | |
const char *url, *body; | |
if (!PyArg_ParseTuple(args, "s", &url)) { | |
return NULL; | |
} | |
body = fetch(url); | |
if (body == NULL) { | |
return NULL; | |
} | |
return PyUnicode_FromString(body); | |
} | |
static PyMethodDef CurlyMethods[] = { | |
{"fetch", curly_fetch, METH_VARARGS, "Fetch the body of a webpage."}, | |
{NULL, NULL, 0, NULL} | |
}; | |
PyMODINIT_FUNC initcurly(void) | |
{ | |
PyObject *module = Py_InitModule("curly", CurlyMethods); | |
if (module == NULL) { | |
return; | |
} | |
CurlyError = PyErr_NewException("curly.CurlyError", NULL, NULL); | |
Py_INCREF(CurlyError); | |
PyModule_AddObject(module, "CurlyError", CurlyError); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from distutils.core import setup, Extension | |
curly = Extension('curly', | |
libraries=['curl'], | |
sources=['curly.c']) | |
setup(name='Curly', | |
version='0.1.1', | |
author='Ryan Kaskel', | |
author_email='dev@ryankaskel.com', | |
ext_modules=[curly]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment