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:
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)
{