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.
This commit is contained in:
Joris Vink 2019-06-12 23:35:43 +02:00
parent a46447b1f9
commit 3114f8d8d0
4 changed files with 129 additions and 4 deletions

View File

@ -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;

View File

@ -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]);
@ -748,6 +811,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)
{

View File

@ -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();

View File

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