Commit 18784113 authored by Lucas Bourneuf's avatar Lucas Bourneuf

working POC for export \o/ It's impressive ! See new example.

parent 0ad54e31
......@@ -5,6 +5,7 @@
import biseau as bs
import datetime
import itertools
from functools import wraps
from . import Script, __version__
try:
import black
......@@ -21,22 +22,9 @@ def get_pipeline_options(scripts:[Script]) -> dict:
return {n: False for _, __, n in option_names_from_options(scripts)}
def standalone_export_pipeline(scripts:[Script], options:dict={}, default_context:str='', verbosity:int=0) -> [str]:
"""Return a string of Python code, implementing a standalone program reproducing given pipeline.
options -- {option name: bool} indicating whether or not the option
must be exposed as program option.
default_context -- the default initial context.
verbosity -- verbosity of the standalone program itself.
"""
gen = _standalone_export_pipeline(scripts, options, default_context, verbosity)
python_code = '\n'.join(gen)
if black:
return black.format_str(python_code, mode=black.FileMode())
return python_code
def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_context:str='', verbosity:int=0) -> [str]:
def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_context:str='',
metarg_outfile:str='out.png', metarg_dotfile:str='out.dot',
metarg_dot_prog:str='dot', verbosity:int=0) -> [str]:
"""Yield Python code strings, implementing a standalone program reproducing given pipeline.
options -- {option name: bool} indicating whether or not the option
......@@ -46,18 +34,19 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
"""
option_names = {(idx, name): final_name for idx, (_, name, final_name) in enumerate(option_names_from_options(scripts))}
print('OPTIONS NAMES:', option_names)
print('RECOGNIZED OPTIONS:', options)
# print('OPTIONS NAMES:', option_names)
# print('RECOGNIZED OPTIONS:', options)
options_used = tuple(
((idx, name), final_name) for (idx, name), final_name in option_names.items()
if options.get(final_name)
)
print('OPTIONS USED:', options_used)
# print('OPTIONS USED:', options_used)
yield '"""Standalone script generated by biseau ' + str(__version__) + ', ' + str(datetime.datetime.now()) + '"""\n'
yield 'import os'
yield 'import argparse'
yield 'from clitogui import clitogui'
yield 'import clyngor'
yield 'import biseau'
yield ''
if options_used:
yield '@clitogui.clitogui'
......@@ -89,9 +78,9 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
def as_dict(opts):
return {name: vals for name, *vals in opts}
option = as_dict(scripts[idx].options)[final_name]
func, args = argparse_addarg_args_from_option(final_name, option)
func, args = argparse_addarg_args_from_option(final_name, option, explicit_value=scripts[idx].options_values.get(name))
yield f' parser.{func}({", ".join(args)})'
print('MAKE ARG:', f' parser.{func}({", ".join(args)})')
# print('MAKE ARG:', f' parser.{func}({", ".join(args)})')
yield ' return parser'
yield ''
else:
......@@ -119,14 +108,19 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
else:
raise ValueError(f"unhandled export of language '{script.language}'")
runon_args = ', '.join(f"{name}={name}" for name, *_ in script.options)
yield f' return \'\'.join(run_on(context, {runon_args}))'
new_context = f"''.join(run_on(context, {runon_args}))"
if not script.erase_context:
new_context = 'context + ' + new_context
yield f' return {new_context}'
yield 'def run_on(context:str, args):'
for runon, script in runons:
target_idx = scripts.index(script)
options = ((name, final_name) for (idx, name), final_name in options_used if idx == target_idx)
args = ', '.join(f"{name}=args.{final_name}" for name, final_name in options)
yield f' context = {runon}(context, {args})'
yield ' print(context)'
yield f' biseau.compile_to_single_image(context, outfile={repr(metarg_outfile)}, dotfile={repr(metarg_dotfile)}, dot_prog={repr(metarg_dot_prog)}, verbosity={repr(verbosity)})'
yield ' return context'
yield 'if __name__ == "__main__":'
yield ' args = cli().parse_args()'
yield ' context = ' + repr(default_context)
......@@ -165,9 +159,10 @@ def option_names_from_options(scripts:[Script]) -> [(str, str, str)]:
yield script_name, name, final_name
def argparse_addarg_args_from_option(name:str, option) -> [str]:
print('creating argparse arguments:', name, option)
def argparse_addarg_args_from_option(name:str, option, *, explicit_value=None) -> [str]:
# print('creating argparse arguments:', name, option)
argtype, default, description = option
if explicit_value is not None: default = explicit_value # override default
if argtype is open:
ctype = 'existing_file'
elif isinstance(argtype, tuple) and len(argtype) == 2 and argtype[0] is open:
......@@ -181,3 +176,20 @@ def argparse_addarg_args_from_option(name:str, option) -> [str]:
elif isinstance(argtype, str):
ctype = 'str'
return 'add_argument', (f"'{name}'", f'type={ctype}', f'default={repr(default)}', f'help="{description}"')
@wraps(_standalone_export_pipeline)
def standalone_export_pipeline(*args, **kwargs) -> [str]:
"""Return a string of Python code, implementing a standalone program reproducing given pipeline.
options -- {option name: bool} indicating whether or not the option
must be exposed as program option.
default_context -- the default initial context.
verbosity -- verbosity of the standalone program itself.
"""
gen = _standalone_export_pipeline(*args, **kwargs)
python_code = '\n'.join(gen)
if black:
return black.format_str(python_code, mode=black.FileMode())
return python_code
"""Example of pipeline export"""
import biseau as bs
def take_scripts():
scripts = 'scripts/context.py', 'scripts/build_concepts.py', 'scripts/galois-lattice.json', 'scripts/show_galois_lattice.py'
for name in scripts:
yield from bs.build_scripts_from_file(name)
# get scripts and their options
scripts = tuple(take_scripts())
options = bs.export.get_pipeline_options(scripts)
# print('OPTIONS:', options)
# for script in scripts:
# print(f"Option of script {script.name} are: {script.options}")
# setting some options to be exposed in the final CLI/GUI
options['fname'] = True
options['type'] = True
scripts[0].options_values['fname'] = 'contexts/human.cxt'
# output to outfile
OUTFILE = 'out-export.py'
with open(OUTFILE, 'w') as fd:
fd.write(bs.standalone_export_pipeline(scripts, options))
print(OUTFILE, 'written')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment