kore

a fork of the worlds most advanced web framework
Log | Files | Refs | README | LICENSE

commit 3114f8d8d0854676bb6ef3a6677c66211fab3bb7
parent a46447b1f904f8b752b00c9172c35f3e70c6fcce
Author: Joris Vink <joris@coders.se>
Date:   Wed, 12 Jun 2019 23:35:43 +0200

Improve python experience.

- If Kore is built with PYTHON=1 you can now specify the module that
  should be loaded on the command-line.

     eg: $ kore -frn myapp

- Add skeleton generation for python applications to kodev.

     eg: $ kodev create -p myapp

This should make it a whole lot easier to get started with kore python.

Diffstat:
Minclude/kore/python_api.h | 4++++
Msrc/cli.c | 96++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/kore.c | 29++++++++++++++++++++++++++++-
Msrc/python.c | 4++++
4 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/include/kore/python_api.h b/include/kore/python_api.h @@ -34,6 +34,10 @@ void kore_python_log_error(const char *); PyObject *kore_python_callable(PyObject *, const char *); +#if !defined(KORE_SINGLE_BINARY) +extern const char *kore_pymodule; +#endif + extern struct kore_module_functions kore_python_module; extern struct kore_runtime kore_python_runtime; diff --git a/src/cli.c b/src/cli.c @@ -205,6 +205,8 @@ static void cli_create_help(void); static void file_create_src(void); static void file_create_config(void); static void file_create_gitignore(void); +static void file_create_python_src(void); +static void file_create_python_config(void); static struct cmd cmds[] = { { "help", "this help text", cli_help }, @@ -233,6 +235,18 @@ static const char *gen_dirs[] = { NULL }; +static const char *python_gen_dirs[] = { + "cert", + NULL +}; + +static struct filegen python_gen_files[] = { + { file_create_python_src }, + { file_create_python_config }, + { file_create_gitignore }, + { NULL } +}; + static const char *http_serveable_function = "int\n" "asset_serve_%s_%s(struct http_request *req)\n" @@ -306,6 +320,43 @@ static const char *build_data = "# included if you build with the \"prod\" flavor.\n" "#}\n"; +static const char *python_config_data = + "# %s configuration\n" + "\n" + "bind\t\t127.0.0.1 8888\n" + "tls_dhparam\tdh2048.pem\n" + "\n" + "domain * {\n" + "\tcertfile\tcert/server.pem\n" + "\tcertkey\t\tcert/key.pem\n" + "\n" + "\tstatic\t/\tkoreapp.index\n" + "}\n"; + +static const char *python_init_data = + "from .app import koreapp\n" + "\n" + "def kore_parent_configure(args):\n" + " koreapp.configure(args)\n" + "\n" + "def kore_worker_configure():\n" + " return\n"; + +static const char *python_app_data = + "import kore\n" + "\n" + "class App:\n" + " def __init__(self):\n" + " pass\n" + "\n" + " def configure(self, args):\n" + " pass\n" + "\n" + " async def index(self, req):\n" + " req.response(200, b'')\n" + "\n" + "koreapp = App()"; + static const char *dh2048_data = "-----BEGIN DH PARAMETERS-----\n" "MIIBCAKCAQEAn4f4Qn5SudFjEYPWTbUaOTLUH85YWmmPFW1+b5bRa9ygr+1wfamv\n" @@ -412,6 +463,8 @@ cli_create_help(void) printf("Synopsis:\n"); printf(" Create a new application skeleton directory structure.\n"); printf("\n"); + printf(" Optional flags:\n"); + printf("\t-p = generate a python application skeleton\n"); exit(1); } @@ -419,16 +472,21 @@ cli_create_help(void) static void cli_create(int argc, char **argv) { - int i, ch; char *fpath; const char **dirs; struct filegen *files; + int i, ch, python; + + python = 0; while ((ch = getopt(argc, argv, "hp")) != -1) { switch (ch) { case 'h': cli_create_help(); break; + case 'p': + python = 1; + break; default: cli_create_help(); break; @@ -444,8 +502,13 @@ cli_create(int argc, char **argv) appl = argv[0]; cli_mkdir(appl, 0755); - dirs = gen_dirs; - files = gen_files; + if (python) { + dirs = python_gen_dirs; + files = python_gen_files; + } else { + dirs = gen_dirs; + files = gen_files; + } for (i = 0; dirs[i] != NULL; i++) { (void)cli_vasprintf(&fpath, "%s/%s", appl, dirs[i]); @@ -749,6 +812,33 @@ cli_info(int argc, char **argv) } static void +file_create_python_src(void) +{ + char *name; + + (void)cli_vasprintf(&name, "%s/__init__.py", appl); + cli_file_create(name, python_init_data, strlen(python_init_data)); + free(name); + + (void)cli_vasprintf(&name, "%s/app.py", appl); + cli_file_create(name, python_app_data, strlen(python_app_data)); + free(name); +} + +static void +file_create_python_config(void) +{ + int l; + char *name, *data; + + (void)cli_vasprintf(&name, "%s/kore.conf", appl); + l = cli_vasprintf(&data, python_config_data, appl); + cli_file_create(name, data, l); + free(name); + free(data); +} + +static void file_create_src(void) { char *name; diff --git a/src/kore.c b/src/kore.c @@ -138,6 +138,10 @@ main(int argc, char *argv[]) { struct kore_runtime_call *rcall; int ch, flags; +#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON) + struct stat st; + char pwd[MAXPATHLEN]; +#endif flags = 0; @@ -191,7 +195,25 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; -#if !defined(KORE_SINGLE_BINARY) +#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON) + if (argc > 0) { + kore_pymodule = argv[0]; + argc--; + argv++; + } else { + if (getcwd(pwd, sizeof(pwd)) == NULL) + fatal("getcwd: %s", errno_s); + kore_pymodule = pwd; + } + + if (lstat(kore_pymodule, &st) == -1) + fatal("failed to stat '%s': %s", kore_pymodule, errno_s); + + if (!S_ISDIR(st.st_mode)) + fatal("%s: not a directory", kore_pymodule); + + config_file = "kore.conf"; +#elif !defined(KORE_SINGLE_BINARY) if (argc > 0) fatal("did you mean to run `kodev' instead?"); #endif @@ -222,6 +244,11 @@ main(int argc, char *argv[]) #if defined(KORE_USE_PYTHON) kore_python_init(); +#if !defined(KORE_SINGLE_BINARY) + kore_module_load(kore_pymodule, NULL, KORE_MODULE_PYTHON); + if (chdir(kore_pymodule) == -1) + fatal("chdir(%s): %s", kore_pymodule, errno_s); +#endif #endif kore_parse_config(); diff --git a/src/python.c b/src/python.c @@ -205,6 +205,10 @@ extern const char *__progname; static struct python_coro *coro_running = NULL; static PyObject *python_tracer = NULL; +#if !defined(KORE_SINGLE_BINARY) +const char *kore_pymodule = NULL; +#endif + void kore_python_init(void) {