From 373cac8d37c67dfde869b2c823797091889bdb1f Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 18 Sep 2024 14:43:44 -0600 Subject: [PATCH] remove telemetry --- CHANGELOG.md | 2 + README.md | 4 - src/soorgeon/clean.py | 39 +++-- src/soorgeon/cli.py | 132 ++++++++-------- src/soorgeon/export.py | 308 +++++++++++++++++++------------------- src/soorgeon/telemetry.py | 9 -- 6 files changed, 246 insertions(+), 248 deletions(-) delete mode 100644 src/soorgeon/telemetry.py diff --git a/CHANGELOG.md b/CHANGELOG.md index a389571..d3ecbe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.0.20dev +* Removes telemetry + ## 0.0.19 (2022-08-30) * Changes telemetry key diff --git a/README.md b/README.md index 85d99a2..714abc6 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,3 @@ Whatever your skillset is, you can contribute to our mission. So whether you're [Click here to know how you can contribute to Ploomber.](https://github.com/ploomber/contributing/blob/main/README.md) - -## Telemetry - -We collect anonymous statistics to understand and improve usage. For details, [see here](https://docs.ploomber.io/en/latest/community/user-stats.html) diff --git a/src/soorgeon/clean.py b/src/soorgeon/clean.py index af5a653..0fc0595 100644 --- a/src/soorgeon/clean.py +++ b/src/soorgeon/clean.py @@ -9,29 +9,26 @@ import jupytext from soorgeon.exceptions import BaseException -from soorgeon.telemetry import telemetry def _jupytext_fmt(text, extension): """ Determine the jupytext fmt string to use based on the content and extension """ - if extension != 'ipynb': + if extension != "ipynb": fmt, _ = jupytext.guess_format(text, extension) - fmt_final = f'{extension}:{fmt}' + fmt_final = f"{extension}:{fmt}" else: - fmt_final = '.ipynb' + fmt_final = ".ipynb" return fmt_final -@telemetry.log_call('lint') def lint(task_file): with get_file(task_file, write=False, output_ext=".py") as path: - run_program(path, program='flake8', filename=task_file) + run_program(path, program="flake8", filename=task_file) -@telemetry.log_call('clean') def basic_clean(task_file, program="black", string_normalization=True): """ Run basic clean (directly called by cli.clean()) @@ -47,10 +44,9 @@ def clean_py(task_file_py, filename, string_normalization=True): mode = FileMode(string_normalization=string_normalization) # reformat with black - black_result = format_file_in_place(task_file_py, - fast=True, - mode=mode, - write_back=WriteBack(1)) + black_result = format_file_in_place( + task_file_py, fast=True, mode=mode, write_back=WriteBack(1) + ) if black_result: click.echo(f"Reformatted {filename} with black.") @@ -61,12 +57,12 @@ def run_program(task_file_py, program, filename): (util method only called by basic_clean()) """ if shutil.which(program) is None: - raise BaseException(f'{program} is missing, please install it with:\n' - f'pip install {program}\nand try again') + raise BaseException( + f"{program} is missing, please install it with:\n" + f"pip install {program}\nand try again" + ) # black - result = subprocess.run([program, task_file_py], - text=True, - capture_output=True) + result = subprocess.run([program, task_file_py], text=True, capture_output=True) click.echo(result.stdout.replace(str(task_file_py), filename)) click.echo(result.stderr) @@ -81,8 +77,7 @@ def get_file(task_file, write=False, output_ext=".ipynb"): if create_temp: nb = jupytext.reads(text) - temp_path = tempfile.NamedTemporaryFile(suffix=output_ext, - delete=False).name + temp_path = tempfile.NamedTemporaryFile(suffix=output_ext, delete=False).name jupytext.write(nb, temp_path) path = Path(temp_path) @@ -93,9 +88,11 @@ def get_file(task_file, write=False, output_ext=".ipynb"): yield path finally: if write: - jupytext.write(jupytext.read(path), - task_file, - fmt=_jupytext_fmt(text, task_file.suffix[1:])) + jupytext.write( + jupytext.read(path), + task_file, + fmt=_jupytext_fmt(text, task_file.suffix[1:]), + ) if create_temp: Path(path).unlink() diff --git a/src/soorgeon/cli.py b/src/soorgeon/cli.py index b9ef32c..930ee46 100644 --- a/src/soorgeon/cli.py +++ b/src/soorgeon/cli.py @@ -5,7 +5,6 @@ from click.exceptions import ClickException from papermill.exceptions import PapermillExecutionError from os.path import abspath, dirname, splitext, join -from soorgeon.telemetry import telemetry from soorgeon import __version__, export from soorgeon import clean as clean_module @@ -17,36 +16,36 @@ def cli(): @cli.command() -@click.argument('path', type=click.Path(exists=True)) -@click.option('--log', '-l', default=None) +@click.argument("path", type=click.Path(exists=True)) +@click.option("--log", "-l", default=None) @click.option( - '--df-format', - '-d', + "--df-format", + "-d", default=None, - type=click.Choice(('parquet', 'csv')), - help='Format for variables with the df prefix. Otherwise uses pickle') -@click.option('--product-prefix', - '-p', - default=None, - help='Prefix for all products') -@click.option('--single-task', - '-s', - is_flag=True, - help='Create a pipeline with a single task') + type=click.Choice(("parquet", "csv")), + help="Format for variables with the df prefix. Otherwise uses pickle", +) +@click.option("--product-prefix", "-p", default=None, help="Prefix for all products") @click.option( - '--file-format', - '-f', + "--single-task", "-s", is_flag=True, help="Create a pipeline with a single task" +) +@click.option( + "--file-format", + "-f", + default=None, + type=click.Choice(("py", "ipynb")), + help=("Format for pipeline tasks, if empty keeps the same format " "as the input"), +) +@click.option( + "--serializer", + "-z", default=None, - type=click.Choice(('py', 'ipynb')), - help=('Format for pipeline tasks, if empty keeps the same format ' - 'as the input')) -@click.option('--serializer', - '-z', - default=None, - type=click.Choice(('cloudpickle', 'dill')), - help='Serializer for non-picklable data') -def refactor(path, log, product_prefix, df_format, single_task, file_format, - serializer): + type=click.Choice(("cloudpickle", "dill")), + help="Serializer for non-picklable data", +) +def refactor( + path, log, product_prefix, df_format, single_task, file_format, serializer +): """ Refactor a monolithic notebook. @@ -64,18 +63,20 @@ def refactor(path, log, product_prefix, df_format, single_task, file_format, # apply black clean_module.basic_clean(path, string_normalization=False) - export.refactor(path, - log, - product_prefix=product_prefix, - df_format=df_format, - single_task=single_task, - file_format=file_format, - serializer=serializer) + export.refactor( + path, + log, + product_prefix=product_prefix, + df_format=df_format, + single_task=single_task, + file_format=file_format, + serializer=serializer, + ) - click.secho(f'Finished refactoring {path!r}, use Ploomber to continue.', - fg='green') + click.secho(f"Finished refactoring {path!r}, use Ploomber to continue.", fg="green") - click.echo(""" + click.echo( + """ Install dependencies (this will install ploomber): $ pip install -r requirements.txt @@ -91,7 +92,8 @@ def refactor(path, log, product_prefix, df_format, single_task, file_format, * Documentation: https://docs.ploomber.io * Jupyter integration: https://ploomber.io/s/jupyter * Other editors: https://ploomber.io/s/editors -""") +""" + ) @cli.command() @@ -126,9 +128,7 @@ def lint(filename): @cli.command() @click.argument("filename", type=click.Path(exists=True)) -@click.argument("output_filename", - type=click.Path(exists=False), - required=False) +@click.argument("output_filename", type=click.Path(exists=False), required=False) def test(filename, output_filename): """ check if a .py or .ipynb file runs. @@ -149,61 +149,67 @@ def test(filename, output_filename): output_filename = join(directory, f"{name}-soorgeon-test.ipynb") else: output_filename = join(directory, output_filename) - if extension.lower() == '.py': + if extension.lower() == ".py": nb = jupytext.read(filename) # convert ipynb to py and create a temp file in current directory - with tempfile.NamedTemporaryFile(suffix=".ipynb", - delete=True, - dir=directory) as temp_file: + with tempfile.NamedTemporaryFile( + suffix=".ipynb", delete=True, dir=directory + ) as temp_file: jupytext.write(nb, temp_file.name) _test(temp_file.name, output_filename) else: _test(filename, output_filename) -@telemetry.log_call('test') def _test(filename, output_filename): - CONTACT_MESSAGE = "An error happened when executing the notebook, " \ - "contact us for help: https://ploomber.io/community" + CONTACT_MESSAGE = ( + "An error happened when executing the notebook, " + "contact us for help: https://ploomber.io/community" + ) try: - pm.execute_notebook(filename, output_filename, kernel_name='python3') + pm.execute_notebook(filename, output_filename, kernel_name="python3") except PapermillExecutionError as err: error_traceback = err.traceback error_suggestion_dict = { - "ModuleNotFoundError": - "Some packages are missing, please install them " + "ModuleNotFoundError": "Some packages are missing, please install them " "with 'pip install {package-name}'\n", - "AttributeError": - "AttributeErrors might be due to changes in the libraries " + "AttributeError": "AttributeErrors might be due to changes in the libraries " "you're using.\n", - "SyntaxError": - "There are syntax errors in the notebook.\n", + "SyntaxError": "There are syntax errors in the notebook.\n", } for error, suggestion in error_suggestion_dict.items(): if any(error in error_line for error_line in error_traceback): - click.secho(f"""\ + click.secho( + f"""\ {error} encountered while executing the notebook: {err} {suggestion} Output notebook: {output_filename}\n""", - fg='red') + fg="red", + ) raise ClickException(CONTACT_MESSAGE) - click.secho(f"""\ + click.secho( + f"""\ Error encountered while executing the notebook: {err} Output notebook: {output_filename}\n""", - fg='red') + fg="red", + ) raise ClickException(CONTACT_MESSAGE) except Exception as err: # handling errors other than PapermillExecutionError error_type = type(err).__name__ - click.echo(f"""\ + click.echo( + f"""\ {error_type} encountered while executing the notebook: {err} -Output notebook: {output_filename}""") +Output notebook: {output_filename}""" + ) raise ClickException(CONTACT_MESSAGE) else: - click.secho(f"""\ + click.secho( + f"""\ Finished executing {filename}, no error encountered. Output notebook: {output_filename}\n""", - fg='green') + fg="green", + ) diff --git a/src/soorgeon/export.py b/src/soorgeon/export.py index 21336f4..206c7f8 100644 --- a/src/soorgeon/export.py +++ b/src/soorgeon/export.py @@ -118,6 +118,7 @@ Finally, we generate the pipeline.yaml file. """ + import shutil import traceback import ast @@ -135,34 +136,30 @@ import nbformat import re -from soorgeon.telemetry import telemetry -from soorgeon import (split, io, definitions, proto, exceptions, magics, - pyflakes) +from soorgeon import split, io, definitions, proto, exceptions, magics, pyflakes logger = logging.getLogger(__name__) pp = pprint.PrettyPrinter(indent=4) class NotebookExporter: - """Converts a notebook into a Ploomber pipeline - """ + """Converts a notebook into a Ploomber pipeline""" + + def __init__(self, nb, verbose=True, df_format=None, serializer=None, py=False): + if df_format not in {None, "parquet", "csv"}: + raise ValueError( + "df_format must be one of " + "None, 'parquet' or 'csv', " + f"got: {df_format!r}" + ) - def __init__(self, - nb, - verbose=True, - df_format=None, - serializer=None, - py=False): - if df_format not in {None, 'parquet', 'csv'}: - raise ValueError("df_format must be one of " - "None, 'parquet' or 'csv', " - f"got: {df_format!r}") - - if serializer not in {None, 'cloudpickle', 'dill'}: - raise ValueError("serializer must be one of " - "None, 'cloudpickle' or 'dill', " - f"got: {serializer!r}") + if serializer not in {None, "cloudpickle", "dill"}: + raise ValueError( + "serializer must be one of " + "None, 'cloudpickle' or 'dill', " + f"got: {serializer!r}" + ) # NOTE: we're commenting magics here but removing them in ProtoTask, # maybe we should comment magics also in ProtoTask? @@ -195,7 +192,7 @@ def export(self, product_prefix=None): product_prefix : str A prefix to append to all products. If None, it is set to 'output' """ - product_prefix = product_prefix or 'output' + product_prefix = product_prefix or "output" # export functions and classes to a separate file self.export_definitions() @@ -210,19 +207,19 @@ def export(self, product_prefix=None): sources = self.get_sources() - dag_spec = {'tasks': list(task_specs.values())} + dag_spec = {"tasks": list(task_specs.values())} for name, task_spec in task_specs.items(): - path = Path(task_spec['source']) + path = Path(task_spec["source"]) path.parent.mkdir(exist_ok=True, parents=True) path.write_text(sources[name]) out = yaml.dump(dag_spec, sort_keys=False) # pyyaml doesn't have an easy way to control whitespace, but we want # tasks to have an empty line between them - out = out.replace('\n- ', '\n\n- ') + out = out.replace("\n- ", "\n\n- ") - Path('pipeline.yaml').write_text(out) + Path("pipeline.yaml").write_text(out) self.export_readme() @@ -251,17 +248,18 @@ def _check_output_files(self): output_lines.append(i.get_code()) if len(output_lines) != 0: - click.secho('Looks like the following lines are storing files:\n') + click.secho("Looks like the following lines are storing files:\n") for line in output_lines: click.secho(line) - url = 'https://docs.ploomber.io/en/latest/' \ - 'get-started/basic-concepts.html' - click.secho(f'Please see the guide on ' - f'how to add them as products: \n{url}\n') + url = ( + "https://docs.ploomber.io/en/latest/" "get-started/basic-concepts.html" + ) + click.secho( + f"Please see the guide on " f"how to add them as products: \n{url}\n" + ) def _init_proto_tasks(self, nb, py): - """Break notebook into smaller sections - """ + """Break notebook into smaller sections""" # use H2 headers to break notebook breaks = split.find_breaks(nb) @@ -279,12 +277,12 @@ def _init_proto_tasks(self, nb, py): df_format=self._df_format, serializer=self._serializer, py=py, - ) for name, cell_group in zip(names, cells_split) + ) + for name, cell_group in zip(names, cells_split) ] def get_task_specs(self, product_prefix=None): - """Return task specs (dictionary) for each proto task - """ + """Return task specs (dictionary) for each proto task""" return { pt.name: pt.to_spec(self.io, product_prefix=product_prefix) for pt in self._proto_tasks @@ -311,47 +309,49 @@ def get_sources(self): } def export_definitions(self): - """Create an exported.py file with function and class definitions - """ + """Create an exported.py file with function and class definitions""" # do not create exported.py if there are no definitions if not self.definitions: return - out = '\n\n'.join(self.definitions.values()) + out = "\n\n".join(self.definitions.values()) ip = io.ImportsParser(self._get_code()) imports = ip.get_imports_cell_for_task(out) if imports: - exported = f'{imports}\n\n\n{out}' + exported = f"{imports}\n\n\n{out}" else: exported = out - Path('exported.py').write_text(exported) + Path("exported.py").write_text(exported) def export_requirements(self): """Generates requirements.txt file, appends it at the end if already exists """ - reqs = Path('requirements.txt') + reqs = Path("requirements.txt") # ploomber is added by default (pinned to >=0.14.7 because earlier # versions throw an error when using the inline bash IPython magic # during the static_analysis stage) - pkgs = ['ploomber>=0.14.7'] + definitions.packages_used(self.tree) + pkgs = ["ploomber>=0.14.7"] + definitions.packages_used(self.tree) # add pyarrow to requirements if needed - if (self._df_format == 'parquet' and 'pyarrow' not in pkgs - and 'fastparquet' not in pkgs): - pkgs = ['pyarrow'] + pkgs + if ( + self._df_format == "parquet" + and "pyarrow" not in pkgs + and "fastparquet" not in pkgs + ): + pkgs = ["pyarrow"] + pkgs # add cloudpickle/dill to requirements if needed - if (self._serializer == 'cloudpickle' and 'cloudpickle' not in pkgs): - pkgs = ['cloudpickle'] + pkgs - elif (self._serializer == 'dill' and 'dill' not in pkgs): - pkgs = ['dill'] + pkgs + if self._serializer == "cloudpickle" and "cloudpickle" not in pkgs: + pkgs = ["cloudpickle"] + pkgs + elif self._serializer == "dill" and "dill" not in pkgs: + pkgs = ["dill"] + pkgs - pkgs_txt = '\n'.join(sorted(pkgs)) + pkgs_txt = "\n".join(sorted(pkgs)) out = f"""\ # Auto-generated file, may need manual editing @@ -363,30 +363,29 @@ def export_requirements(self): reqs.write_text(out) def _get_code(self): - """Returns the source of code cells - """ - return '\n'.join(cell['source'] for cell in self._nb.cells - if cell['cell_type'] == 'code') + """Returns the source of code cells""" + return "\n".join( + cell["source"] for cell in self._nb.cells if cell["cell_type"] == "code" + ) def export_gitignore(self, product_prefix): if product_prefix and not Path(product_prefix).is_absolute(): - path = Path('.gitignore') - content = '' if not path.exists() else path.read_text() + '\n' - path.write_text(content + product_prefix + '\n') - self._echo(f'Added {str(product_prefix)!r} directory' - ' to .gitignore...') + path = Path(".gitignore") + content = "" if not path.exists() else path.read_text() + "\n" + path.write_text(content + product_prefix + "\n") + self._echo(f"Added {str(product_prefix)!r} directory" " to .gitignore...") def export_readme(self): - path = Path('README.md') + path = Path("README.md") if path.exists(): - content = path.read_text() + '\n' - self._echo('README.md found, appended auto-generated content') + content = path.read_text() + "\n" + self._echo("README.md found, appended auto-generated content") else: - content = '' - self._echo('Added README.md') + content = "" + self._echo("Added README.md") - path.write_text(content + resources.read_text(assets, 'README.md')) + path.write_text(content + resources.read_text(assets, "README.md")) def _echo(self, msg): if self._verbose: @@ -395,7 +394,7 @@ def _echo(self, msg): @property def definitions(self): if self._definitions is None: - self._definitions = (definitions.from_def_and_class(self.tree)) + self._definitions = definitions.from_def_and_class(self.tree) return self._definitions @@ -422,11 +421,11 @@ def io(self): if self._io is None: io_ = self._get_raw_io() - logging.info(f'io: {pp.pformat(io_)}\n') + logging.info(f"io: {pp.pformat(io_)}\n") self._io = io.prune_io(io_) - logging.info(f'pruned io: {pp.pformat(self._io)}\n') + logging.info(f"pruned io: {pp.pformat(self._io)}\n") return self._io @@ -434,7 +433,7 @@ def _get_raw_io(self): return io.find_io(self._snippets) -FunctionNeedsFix = namedtuple('FunctionNeedsFix', ['name', 'pos', 'args']) +FunctionNeedsFix = namedtuple("FunctionNeedsFix", ["name", "pos", "args"]) def _check_syntax(code): @@ -446,8 +445,9 @@ def _check_syntax(code): error = None if error: - raise exceptions.InputSyntaxError(f'Could not refactor notebook due ' - f'to invalid syntax\n\n {error}') + raise exceptions.InputSyntaxError( + f"Could not refactor notebook due " f"to invalid syntax\n\n {error}" + ) def _check_no_star_imports(code): @@ -458,28 +458,29 @@ def _check_no_star_imports(code): ] if star_imports: - star_imports_ = '\n'.join(import_.get_code() - for import_ in star_imports) - url = ('https://github.com/ploomber/soorgeon/blob/main/doc' - '/star-imports.md') + star_imports_ = "\n".join(import_.get_code() for import_ in star_imports) + url = "https://github.com/ploomber/soorgeon/blob/main/doc" "/star-imports.md" raise exceptions.InputError( - 'Star imports are not supported, please change ' - f'the following:\n\n{star_imports_}\n\n' - f'For more details, see: {url}') + "Star imports are not supported, please change " + f"the following:\n\n{star_imports_}\n\n" + f"For more details, see: {url}" + ) def _find_output_file_events(s): - is_output = ['.write_text(', '.write_bytes(', '.to_csv(', '.to_parquet('] + is_output = [".write_text(", ".write_bytes(", ".to_csv(", ".to_parquet("] - if s.startswith('#'): + if s.startswith("#"): return False if "'''" in s: return False - if 'open(' in s: - if not (re.match(r"[^\n]*open\('[^\n]+'[\s]*,[\s]*'r'\)[^\n]*", s) - or re.match(r"[^\n]*open\('[^\n]+'[\s]*,[\s]*'rb'\)[^\n]*", s) - or re.match(r"[^\n]*open\('[^,]+'\)[^\n]*", s)): + if "open(" in s: + if not ( + re.match(r"[^\n]*open\('[^\n]+'[\s]*,[\s]*'r'\)[^\n]*", s) + or re.match(r"[^\n]*open\('[^\n]+'[\s]*,[\s]*'rb'\)[^\n]*", s) + or re.match(r"[^\n]*open\('[^,]+'\)[^\n]*", s) + ): return True if any(cmd in s for cmd in is_output): @@ -501,8 +502,7 @@ def _check_functions_do_not_use_global_variables(code): # again, but for some reason, # using find_inputs_and_outputs_from_tree(funcdef) returns the name # of the function as an input - in_, _ = io.find_inputs_and_outputs(funcdef.get_code(), - local_scope=local_scope) + in_, _ = io.find_inputs_and_outputs(funcdef.get_code(), local_scope=local_scope) if in_: needs_fix.append( @@ -510,31 +510,32 @@ def _check_functions_do_not_use_global_variables(code): funcdef.name.value, funcdef.start_pos, in_, - )) + ) + ) if needs_fix: - message = ('Looks like the following functions are using global ' - 'variables, this is unsupported. Please add all missing ' - 'arguments. See this to learn more:\n' - 'https://github.com/ploomber/soorgeon/blob' - '/main/doc/fn-global.md\n\n') + message = ( + "Looks like the following functions are using global " + "variables, this is unsupported. Please add all missing " + "arguments. See this to learn more:\n" + "https://github.com/ploomber/soorgeon/blob" + "/main/doc/fn-global.md\n\n" + ) def comma_separated(args): - return ','.join(f"'{arg}'" for arg in args) + return ",".join(f"'{arg}'" for arg in args) - message += '\n'.join( - f'* Function {f.name!r} uses variables {comma_separated(f.args)}' - for f in needs_fix) + message += "\n".join( + f"* Function {f.name!r} uses variables {comma_separated(f.args)}" + for f in needs_fix + ) raise exceptions.InputError(message) -def from_nb(nb, - log=None, - product_prefix=None, - df_format=None, - serializer=None, - py=False): +def from_nb( + nb, log=None, product_prefix=None, df_format=None, serializer=None, py=False +): """Refactor a notebook by passing a notebook object Parameters @@ -546,10 +547,7 @@ def from_nb(nb, if log: logging.basicConfig(level=log.upper()) - exporter = NotebookExporter(nb, - df_format=df_format, - serializer=serializer, - py=py) + exporter = NotebookExporter(nb, df_format=df_format, serializer=serializer, py=py) exporter.export(product_prefix=product_prefix) @@ -569,85 +567,93 @@ def from_path(path, log=None, product_prefix=None, df_format=None, py=False): the notebook, and if it fails, it will generate a pipeline with a single task """ - from_nb(jupytext.read(path), - log=log, - product_prefix=product_prefix, - df_format=df_format, - py=py) + from_nb( + jupytext.read(path), + log=log, + product_prefix=product_prefix, + df_format=df_format, + py=py, + ) def single_task_from_path(path, product_prefix, file_format): - """Refactor a notebook into a single task Ploomber pipeline - """ + """Refactor a notebook into a single task Ploomber pipeline""" path = Path(path) - click.echo('Creating a pipeline with a single task...') + click.echo("Creating a pipeline with a single task...") - cell = nbformat.v4.new_code_cell(source='upstream = None', - metadata=dict(tags=['parameters'])) + cell = nbformat.v4.new_code_cell( + source="upstream = None", metadata=dict(tags=["parameters"]) + ) nb = jupytext.read(path) nb.cells.insert(0, cell) name = path.stem - path_backup = path.with_name(f'{name}-backup{path.suffix}') + path_backup = path.with_name(f"{name}-backup{path.suffix}") # output ext = path.suffix[1:] if file_format is None else file_format - path_to_task = f'{name}.{ext}' + path_to_task = f"{name}.{ext}" # create backup shutil.copy(path, path_backup) - jupytext.write(nb, - path_to_task, - fmt='py:percent' if ext == 'py' else 'ipynb') + jupytext.write(nb, path_to_task, fmt="py:percent" if ext == "py" else "ipynb") spec = { - 'tasks': [{ - 'source': - path_to_task, - 'product': - str(Path(product_prefix or 'products', f'{name}-report.ipynb')) - }] + "tasks": [ + { + "source": path_to_task, + "product": str( + Path(product_prefix or "products", f"{name}-report.ipynb") + ), + } + ] } - pipeline = 'pipeline.yaml' - click.echo(f'Done. Copied code to {path_to_task!r} and added it to ' - f'{pipeline!r}. Created backup of original notebook ' - f'at {str(path_backup)!r}.') + pipeline = "pipeline.yaml" + click.echo( + f"Done. Copied code to {path_to_task!r} and added it to " + f"{pipeline!r}. Created backup of original notebook " + f"at {str(path_backup)!r}." + ) - Path('pipeline.yaml').write_text(yaml.safe_dump(spec, sort_keys=False)) + Path("pipeline.yaml").write_text(yaml.safe_dump(spec, sort_keys=False)) -@telemetry.log_call('refactor') -def refactor(path, log, product_prefix, df_format, single_task, file_format, - serializer): +def refactor( + path, log, product_prefix, df_format, single_task, file_format, serializer +): if single_task: - single_task_from_path(path=path, - product_prefix=product_prefix, - file_format=file_format) + single_task_from_path( + path=path, product_prefix=product_prefix, file_format=file_format + ) else: ext = Path(path).suffix[1:] if file_format is None else file_format try: - from_nb(jupytext.read(path), - log=log, - product_prefix=product_prefix, - df_format=df_format, - serializer=serializer, - py=ext == 'py') + from_nb( + jupytext.read(path), + log=log, + product_prefix=product_prefix, + df_format=df_format, + serializer=serializer, + py=ext == "py", + ) # InputError means the input is broken except exceptions.InputWontRunError: raise # This implies an error on our end except Exception as e: - logger.exception('Error calling from_nb') - cmd = f'soorgeon refactor {path} --single-task' - msg = ('An error occurred when refactoring ' - 'notebook.\n\nTry refactoring ' - f'as a single task pipeline:\n\n$ {cmd}\n\n' - 'Need help? https://ploomber.io/community\n\n' - 'Error details:\n') + logger.exception("Error calling from_nb") + cmd = f"soorgeon refactor {path} --single-task" + msg = ( + "An error occurred when refactoring " + "notebook.\n\nTry refactoring " + f"as a single task pipeline:\n\n$ {cmd}\n\n" + "Need help? https://ploomber.io/community\n\n" + "Error details:\n" + ) raise exceptions.InputError(msg) from e diff --git a/src/soorgeon/telemetry.py b/src/soorgeon/telemetry.py deleted file mode 100644 index 1732cba..0000000 --- a/src/soorgeon/telemetry.py +++ /dev/null @@ -1,9 +0,0 @@ -from soorgeon import __version__ - -from ploomber_core.telemetry.telemetry import Telemetry - -telemetry = Telemetry( - api_key="phc_P9SpSeypyPwxrMdFn2edOOEooQioF2axppyEeDwtMSP", - package_name="soorgeon", - version=__version__, -)