This is an automated email from the ASF dual-hosted git repository. msciabarra pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/openserverless-devcontainer.git
commit 2f7d4d55c1cd6324b8e0bdb5de15cfe11e9f0458 Author: Michele Sciabarra <[email protected]> AuthorDate: Sun Nov 9 16:34:31 2025 +0000 initial commit --- Dockerfile | 56 + olaris-tk/.gitignore | 15 + olaris-tk/cli/.gitignore | 3 + olaris-tk/cli/.python-version | 1 + olaris-tk/cli/README.md | 2 + olaris-tk/cli/_empty | 0 olaris-tk/cli/main.py | 6 + olaris-tk/cli/profile_default/ipython_config.py | 1380 ++++++++++++++++++++ olaris-tk/cli/profile_default/startup/00-chdir.ipy | 8 + olaris-tk/cli/profile_default/startup/01-opsenv.py | 25 + olaris-tk/cli/profile_default/startup/README | 11 + olaris-tk/cli/pyproject.toml | 10 + olaris-tk/cli/uv.lock | 223 ++++ olaris-tk/docopts.md | 13 + olaris-tk/findimg.js | 40 + olaris-tk/opsfile.yml | 172 +++ olaris-tk/pg/.python-version | 1 + olaris-tk/pg/docopts.md | 25 + olaris-tk/pg/main.py | 90 ++ olaris-tk/pg/opsfile.yml | 75 ++ olaris-tk/pg/pyproject.toml | 7 + olaris-tk/pg/uv.lock | 8 + olaris-tk/prereq.yml | 88 ++ olaris-tk/stream.py | 30 + start-ssh.sh | 10 + 25 files changed, 2299 insertions(+) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e2f213c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,56 @@ +FROM debian:bookworm AS pgloader-builder + +ENV DEBIAN_FRONTEND=noninteractive + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + git curl sbcl make unzip ca-certificates \ + libsqlite3-dev libssl-dev gawk freetds-dev jq \ + && rm -rf /var/lib/apt/lists/* + +# Clone pgloader and build it +WORKDIR /build +RUN git clone https://github.com/dimitri/pgloader.git \ + && cd pgloader \ + && make + +FROM node:22 +# Install basic development tools +RUN \ + echo "deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \ + wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \ + apt update && \ + apt install -y less man-db sudo vim jq python-is-python3 python3-virtualenv \ + locales postgresql-client-16 openssh-server + +RUN \ + touch /.dockerenv && \ + echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ + locale-gen en_US.UTF-8 && \ + update-locale ANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8 + +# Ensure default `node` user has access to `sudo` +ARG USERNAME=node +RUN \ + echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# install ops and plugins +USER node +RUN \ + curl -sL https://raw.githubusercontent.com/apache/openserverless-cli/refs/heads/main/install.sh | bash +RUN \ + curl -LsSf https://astral.sh/uv/install.sh | sh + +ENV PATH="/home/node/.local/bin:${PATH}" + +RUN \ + ops -update +RUN \ + git clone https://github.com/apache/openserverless-devcontainer /home/node/.ops/openserverless-devcontainer ;\ + ln -sf /home/node/.ops/devcontaine/olaris-tk /home/node/olaris-tk + +COPY --from=pgloader-builder /build/pgloader/build/bin/pgloader /usr/bin/pgloader +ADD start-ssh.sh /start-ssh.sh + +CMD ["/start-ssh.sh"] diff --git a/olaris-tk/.gitignore b/olaris-tk/.gitignore new file mode 100644 index 0000000..fe5da61 --- /dev/null +++ b/olaris-tk/.gitignore @@ -0,0 +1,15 @@ +__pycache__ +_svr +_src +_sse +.venv +cli/profile_default/log +cli/profile_default/pid +cli/profile_default/security +cli/profile_default/history.sqlite +cli/profile_default/db/ +cli/requirements.txt +node_modules +mcp/mcproxy/kubernetes/_*.yaml +.task/ +_dockerfile diff --git a/olaris-tk/cli/.gitignore b/olaris-tk/cli/.gitignore new file mode 100644 index 0000000..af47f1b --- /dev/null +++ b/olaris-tk/cli/.gitignore @@ -0,0 +1,3 @@ +profile_default/log +profile_default/pid +profile_default/security diff --git a/olaris-tk/cli/.python-version b/olaris-tk/cli/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/olaris-tk/cli/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/olaris-tk/cli/README.md b/olaris-tk/cli/README.md new file mode 100644 index 0000000..3769bf4 --- /dev/null +++ b/olaris-tk/cli/README.md @@ -0,0 +1,2 @@ +starts ipython +configure it with autoreload of modules diff --git a/olaris-tk/cli/_empty b/olaris-tk/cli/_empty new file mode 100644 index 0000000..e69de29 diff --git a/olaris-tk/cli/main.py b/olaris-tk/cli/main.py new file mode 100644 index 0000000..cfde67e --- /dev/null +++ b/olaris-tk/cli/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from cli!") + + +if __name__ == "__main__": + main() diff --git a/olaris-tk/cli/profile_default/ipython_config.py b/olaris-tk/cli/profile_default/ipython_config.py new file mode 100644 index 0000000..f706139 --- /dev/null +++ b/olaris-tk/cli/profile_default/ipython_config.py @@ -0,0 +1,1380 @@ +# Configuration file for ipython. + +c = get_config() #noqa + +#------------------------------------------------------------------------------ +# InteractiveShellApp(Configurable) configuration +#------------------------------------------------------------------------------ +## A Mixin for applications that start InteractiveShell instances. +# +# Provides configurables for loading extensions and executing files +# as part of configuring a Shell environment. +# +# The following methods should be called by the :meth:`initialize` method +# of the subclass: +# +# - :meth:`init_path` +# - :meth:`init_shell` (to be implemented by the subclass) +# - :meth:`init_gui_pylab` +# - :meth:`init_extensions` +# - :meth:`init_code` + +## Execute the given command string. +# Default: '' +# c.InteractiveShellApp.code_to_run = '' + +## Run the file referenced by the PYTHONSTARTUP environment +# variable at IPython startup. +# Default: True +# c.InteractiveShellApp.exec_PYTHONSTARTUP = True + +## List of files to run at IPython startup. +# Default: [] +# c.InteractiveShellApp.exec_files = [] + +## lines of code to run at IPython startup. +# Default: [] +# c.InteractiveShellApp.exec_lines = [] + + +## A list of dotted module names of IPython extensions to load. +# Default: [] +# c.InteractiveShellApp.extensions = [] +c.InteractiveShellApp.extensions = ['autoreload'] + +## Dotted module name(s) of one or more IPython extensions to load. +# +# For specifying extra extensions to load on the command-line. +# +# .. versionadded:: 7.10 +# Default: [] +# c.InteractiveShellApp.extra_extensions = [] + +## A file to be run +# Default: '' +# c.InteractiveShellApp.file_to_run = '' + +## Enable GUI event loop integration with any of ('asyncio', 'glut', 'gtk', +# 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt5', 'qt6', 'tk', 'wx', +# 'gtk2', 'qt4'). +# Choices: any of ['asyncio', 'glut', 'gtk', 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt5', 'qt6', 'tk', 'wx', 'gtk2', 'qt4'] (case-insensitive) or None +# Default: None +# c.InteractiveShellApp.gui = None + +## Should variables loaded at startup (by startup files, exec_lines, etc.) +# be hidden from tools like %who? +# Default: True +# c.InteractiveShellApp.hide_initial_ns = True + +## If True, IPython will not add the current working directory to sys.path. +# When False, the current working directory is added to sys.path, allowing imports +# of modules defined in the current directory. +# Default: False +# c.InteractiveShellApp.ignore_cwd = False + +## Configure matplotlib for interactive use with +# the default matplotlib backend. The exact options available +# depend on what Matplotlib provides at runtime. +# Choices: any of ['agg', 'auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'ipympl', 'nbagg', 'notebook', 'osx', 'pdf', 'ps', 'qt', 'qt4', 'qt5', 'qt6', 'svg', 'tk', 'webagg', 'widget', 'wx'] (case-insensitive) or None +# Default: None +# c.InteractiveShellApp.matplotlib = None + +## Run the module as a script. +# Default: '' +# c.InteractiveShellApp.module_to_run = '' + +## Pre-load matplotlib and numpy for interactive use, +# selecting a particular matplotlib backend and loop integration. +# The exact options available depend on what Matplotlib provides at runtime. +# Choices: any of ['agg', 'auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'ipympl', 'nbagg', 'notebook', 'osx', 'pdf', 'ps', 'qt', 'qt4', 'qt5', 'qt6', 'svg', 'tk', 'webagg', 'widget', 'wx'] (case-insensitive) or None +# Default: None +# c.InteractiveShellApp.pylab = None + +## If true, IPython will populate the user namespace with numpy, pylab, etc. +# and an ``import *`` is done from numpy and pylab, when using pylab mode. +# +# When False, pylab mode should not import any names into the user +# namespace. +# Default: True +# c.InteractiveShellApp.pylab_import_all = True + +## Reraise exceptions encountered loading IPython extensions? +# Default: False +# c.InteractiveShellApp.reraise_ipython_extension_failures = False + +#------------------------------------------------------------------------------ +# Application(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ +## This is an application. + +## The date format used by logging formatters for %(asctime)s +# Default: '%Y-%m-%d %H:%M:%S' +# c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +# Default: '[%(name)s]%(highlevel)s %(message)s' +# c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +# Choices: any of [0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL'] +# Default: 30 +# c.Application.log_level = 30 + +## Configure additional log handlers. +# +# The default stderr logs handler is configured by the log_level, log_datefmt +# and log_format settings. +# +# This configuration can be used to configure additional handlers (e.g. to +# output the log to a file) or for finer control over the default handlers. +# +# If provided this should be a logging configuration dictionary, for more +# information see: +# https://docs.python.org/3/library/logging.config.html#logging-config- +# dictschema +# +# This dictionary is merged with the base logging configuration which defines +# the following: +# +# * A logging formatter intended for interactive use called +# ``console``. +# * A logging handler that writes to stderr called +# ``console`` which uses the formatter ``console``. +# * A logger with the name of this application set to ``DEBUG`` +# level. +# +# This example adds a new handler that writes to a file: +# +# .. code-block:: python +# +# c.Application.logging_config = { +# "handlers": { +# "file": { +# "class": "logging.FileHandler", +# "level": "DEBUG", +# "filename": "<path/to/file>", +# } +# }, +# "loggers": { +# "<application-name>": { +# "level": "DEBUG", +# # NOTE: if you don't list the default "console" +# # handler here then it will be disabled +# "handlers": ["console", "file"], +# }, +# }, +# } +# Default: {} +# c.Application.logging_config = {} + +## Instead of starting the Application, dump configuration to stdout +# Default: False +# c.Application.show_config = False + +## Instead of starting the Application, dump configuration to stdout (as JSON) +# Default: False +# c.Application.show_config_json = False + +#------------------------------------------------------------------------------ +# BaseIPythonApplication(Application) configuration +#------------------------------------------------------------------------------ +# Default: False +# c.BaseIPythonApplication.add_ipython_dir_to_sys_path = False + +## Whether to create profile dir if it doesn't exist +# Default: False +# c.BaseIPythonApplication.auto_create = False + +## Whether to install the default config files into the profile dir. +# If a new profile is being created, and IPython contains config files for that +# profile, then they will be staged into the new directory. Otherwise, +# default config files will be automatically generated. +# Default: False +# c.BaseIPythonApplication.copy_config_files = False + +## Path to an extra config file to load. +# +# If specified, load this config file in addition to any other IPython +# config. +# Default: '' +# c.BaseIPythonApplication.extra_config_file = '' + +## The name of the IPython directory. This directory is used for logging +# configuration (through profiles), history storage, etc. The default is usually +# $HOME/.ipython. This option can also be specified through the environment +# variable IPYTHONDIR. +# Default: '' +# c.BaseIPythonApplication.ipython_dir = '' + +## The date format used by logging formatters for %(asctime)s +# See also: Application.log_datefmt +# c.BaseIPythonApplication.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +# See also: Application.log_format +# c.BaseIPythonApplication.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +# See also: Application.log_level +# c.BaseIPythonApplication.log_level = 30 + +## +# See also: Application.logging_config +# c.BaseIPythonApplication.logging_config = {} + +## Whether to overwrite existing config files when copying +# Default: False +# c.BaseIPythonApplication.overwrite = False + +## The IPython profile to use. +# Default: 'default' +# c.BaseIPythonApplication.profile = 'default' + +## Instead of starting the Application, dump configuration to stdout +# See also: Application.show_config +# c.BaseIPythonApplication.show_config = False + +## Instead of starting the Application, dump configuration to stdout (as JSON) +# See also: Application.show_config_json +# c.BaseIPythonApplication.show_config_json = False + +## Create a massive crash report when IPython encounters what may be an +# internal error. The default is to append a short message to the +# usual traceback +# Default: False +# c.BaseIPythonApplication.verbose_crash = False + +#------------------------------------------------------------------------------ +# TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp) configuration +#------------------------------------------------------------------------------ +# See also: BaseIPythonApplication.add_ipython_dir_to_sys_path +# c.TerminalIPythonApp.add_ipython_dir_to_sys_path = False + +# Default: True +# c.TerminalIPythonApp.auto_create = True + +## Execute the given command string. +# See also: InteractiveShellApp.code_to_run +# c.TerminalIPythonApp.code_to_run = '' + +## Whether to install the default config files into the profile dir. +# See also: BaseIPythonApplication.copy_config_files +# c.TerminalIPythonApp.copy_config_files = False + +## Whether to display a banner upon starting IPython. +# Default: True +# c.TerminalIPythonApp.display_banner = True + +## Run the file referenced by the PYTHONSTARTUP environment +# See also: InteractiveShellApp.exec_PYTHONSTARTUP +# c.TerminalIPythonApp.exec_PYTHONSTARTUP = True + +## List of files to run at IPython startup. +# See also: InteractiveShellApp.exec_files +# c.TerminalIPythonApp.exec_files = [] + +## lines of code to run at IPython startup. +# See also: InteractiveShellApp.exec_lines +# c.TerminalIPythonApp.exec_lines = [] +c.InteractiveShellApp.exec_lines = ['%autoreload 2'] + +## A list of dotted module names of IPython extensions to load. +# See also: InteractiveShellApp.extensions +# c.TerminalIPythonApp.extensions = [] + +## Path to an extra config file to load. +# See also: BaseIPythonApplication.extra_config_file +# c.TerminalIPythonApp.extra_config_file = '' + +## +# See also: InteractiveShellApp.extra_extensions +# c.TerminalIPythonApp.extra_extensions = [] + +## A file to be run +# See also: InteractiveShellApp.file_to_run +# c.TerminalIPythonApp.file_to_run = '' + +## If a command or file is given via the command-line, +# e.g. 'ipython foo.py', start an interactive shell after executing the +# file or command. +# Default: False +# c.TerminalIPythonApp.force_interact = False + +## Enable GUI event loop integration with any of ('asyncio', 'glut', 'gtk', +# 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt5', 'qt6', 'tk', 'wx', +# 'gtk2', 'qt4'). +# See also: InteractiveShellApp.gui +# c.TerminalIPythonApp.gui = None + +## Should variables loaded at startup (by startup files, exec_lines, etc.) +# See also: InteractiveShellApp.hide_initial_ns +# c.TerminalIPythonApp.hide_initial_ns = True + +## If True, IPython will not add the current working directory to sys.path. +# See also: InteractiveShellApp.ignore_cwd +# c.TerminalIPythonApp.ignore_cwd = False + +## Class to use to instantiate the TerminalInteractiveShell object. Useful for +# custom Frontends +# Default: 'IPython.terminal.interactiveshell.TerminalInteractiveShell' +# c.TerminalIPythonApp.interactive_shell_class = 'IPython.terminal.interactiveshell.TerminalInteractiveShell' + +## +# See also: BaseIPythonApplication.ipython_dir +# c.TerminalIPythonApp.ipython_dir = '' + +## The date format used by logging formatters for %(asctime)s +# See also: Application.log_datefmt +# c.TerminalIPythonApp.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +# See also: Application.log_format +# c.TerminalIPythonApp.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +# See also: Application.log_level +# c.TerminalIPythonApp.log_level = 30 + +## +# See also: Application.logging_config +# c.TerminalIPythonApp.logging_config = {} + +## Configure matplotlib for interactive use with +# See also: InteractiveShellApp.matplotlib +# c.TerminalIPythonApp.matplotlib = None + +## Run the module as a script. +# See also: InteractiveShellApp.module_to_run +# c.TerminalIPythonApp.module_to_run = '' + +## Whether to overwrite existing config files when copying +# See also: BaseIPythonApplication.overwrite +# c.TerminalIPythonApp.overwrite = False + +## The IPython profile to use. +# See also: BaseIPythonApplication.profile +# c.TerminalIPythonApp.profile = 'default' + +## Pre-load matplotlib and numpy for interactive use, +# See also: InteractiveShellApp.pylab +# c.TerminalIPythonApp.pylab = None + +## If true, IPython will populate the user namespace with numpy, pylab, etc. +# See also: InteractiveShellApp.pylab_import_all +# c.TerminalIPythonApp.pylab_import_all = True + +## Start IPython quickly by skipping the loading of config files. +# Default: False +# c.TerminalIPythonApp.quick = False + +## Reraise exceptions encountered loading IPython extensions? +# See also: InteractiveShellApp.reraise_ipython_extension_failures +# c.TerminalIPythonApp.reraise_ipython_extension_failures = False + +## Instead of starting the Application, dump configuration to stdout +# See also: Application.show_config +# c.TerminalIPythonApp.show_config = False + +## Instead of starting the Application, dump configuration to stdout (as JSON) +# See also: Application.show_config_json +# c.TerminalIPythonApp.show_config_json = False + +## Create a massive crash report when IPython encounters what may be an +# See also: BaseIPythonApplication.verbose_crash +# c.TerminalIPythonApp.verbose_crash = False + +#------------------------------------------------------------------------------ +# InteractiveShell(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ +## An enhanced, interactive shell for Python. + +## 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying which +# nodes should be run interactively (displaying output from expressions). +# Choices: any of ['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'] +# Default: 'last_expr' +# c.InteractiveShell.ast_node_interactivity = 'last_expr' + +## A list of ast.NodeTransformer subclass instances, which will be applied to +# user input before code is run. +# Default: [] +# c.InteractiveShell.ast_transformers = [] + +## Automatically run await statement in the top level repl. +# Default: True +# c.InteractiveShell.autoawait = True + +## Make IPython automatically call any callable object even if you didn't type +# explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically. +# The value can be '0' to disable the feature, '1' for 'smart' autocall, where +# it is not applied if there are no more arguments on the line, and '2' for +# 'full' autocall, where all callable objects are automatically called (even if +# no arguments are present). +# Choices: any of [0, 1, 2] +# Default: 0 +# c.InteractiveShell.autocall = 0 + +## Autoindent IPython code entered interactively. +# Default: True +# c.InteractiveShell.autoindent = True + +## Enable magic commands to be called without the leading %. +# Default: True +# c.InteractiveShell.automagic = True + +## The part of the banner to be printed before the profile +# Default: "Python 3.12.4 | packaged by Anaconda, Inc. | (main, Jun 18 2024, 10:07:17) [Clang 14.0.6 ]\nType 'copyright', 'credits' or 'license' for more information\nIPython 9.1.0 -- An enhanced Interactive Python. Type '?' for help.\n" +# c.InteractiveShell.banner1 = "Python 3.12.4 | packaged by Anaconda, Inc. | (main, Jun 18 2024, 10:07:17) [Clang 14.0.6 ]\nType 'copyright', 'credits' or 'license' for more information\nIPython 9.1.0 -- An enhanced Interactive Python. Type '?' for help.\n" + +## The part of the banner to be printed after the profile +# Default: '' +# c.InteractiveShell.banner2 = '' + +## Set the size of the output cache. The default is 1000, you can change it +# permanently in your config file. Setting it to 0 completely disables the +# caching system, and the minimum value accepted is 3 (if you provide a value +# less than 3, it is reset to 0 and a warning is issued). This limit is defined +# because otherwise you'll spend more time re-flushing a too small cache than +# working +# Default: 1000 +# c.InteractiveShell.cache_size = 1000 + +## Set the color scheme (nocolor, neutral, linux, lightbg). +# Default: 'neutral' +# c.InteractiveShell.colors = 'neutral' + +# Default: False +# c.InteractiveShell.debug = False + +## If True, anything that would be passed to the pager +# will be displayed as regular output instead. +# Default: False +# c.InteractiveShell.display_page = False + +## (Provisional API) enables html representation in mime bundles sent to pagers. +# Default: False +# c.InteractiveShell.enable_html_pager = False + +## Set to show a tip when IPython starts. +# Default: True +# c.InteractiveShell.enable_tip = True + +## Total length of command history +# Default: 10000 +# c.InteractiveShell.history_length = 10000 + +## The number of saved history entries to be loaded into the history buffer at +# startup. +# Default: 1000 +# c.InteractiveShell.history_load_length = 1000 + +## Class to use to instantiate the shell inspector +# Default: 'IPython.core.oinspect.Inspector' +# c.InteractiveShell.inspector_class = 'IPython.core.oinspect.Inspector' + +# Default: '' +# c.InteractiveShell.ipython_dir = '' + +## Start logging to the given file in append mode. Use `logfile` to specify a log +# file to **overwrite** logs to. +# Default: '' +# c.InteractiveShell.logappend = '' + +## The name of the logfile to use. +# Default: '' +# c.InteractiveShell.logfile = '' + +## Start logging to the default log file in overwrite mode. Use `logappend` to +# specify a log file to **append** logs to. +# Default: False +# c.InteractiveShell.logstart = False + +## Select the loop runner that will be used to execute top-level asynchronous +# code +# Default: 'IPython.core.interactiveshell._asyncio_runner' +# c.InteractiveShell.loop_runner = 'IPython.core.interactiveshell._asyncio_runner' + +# Choices: any of [0, 1, 2] +# Default: 0 +# c.InteractiveShell.object_info_string_level = 0 + +## Automatically call the pdb debugger after every exception. +# Default: False +# c.InteractiveShell.pdb = False + +# Default: False +# c.InteractiveShell.quiet = False + +# Default: '\n' +# c.InteractiveShell.separate_in = '\n' + +# Default: '' +# c.InteractiveShell.separate_out = '' + +# Default: '' +# c.InteractiveShell.separate_out2 = '' + +## Show rewritten input, e.g. for autocall. +# Default: True +# c.InteractiveShell.show_rewritten_input = True + +## Enables rich html representation of docstrings. (This requires the docrepr +# module). +# Default: False +# c.InteractiveShell.sphinxify_docstring = False + +## Warn if running in a virtual environment with no IPython installed (so IPython +# from the global environment is used). +# Default: True +# c.InteractiveShell.warn_venv = True + +# Default: True +# c.InteractiveShell.wildcards_case_sensitive = True + +## Switch modes for the IPython exception handlers. +# Choices: any of ['Context', 'Plain', 'Verbose', 'Minimal', 'Docs'] (case-insensitive) +# Default: 'Context' +# c.InteractiveShell.xmode = 'Context' + +#------------------------------------------------------------------------------ +# TerminalInteractiveShell(InteractiveShell) configuration +#------------------------------------------------------------------------------ +## +# See also: InteractiveShell.ast_node_interactivity +# c.TerminalInteractiveShell.ast_node_interactivity = 'last_expr' + +## +# See also: InteractiveShell.ast_transformers +# c.TerminalInteractiveShell.ast_transformers = [] + +## Automatically add/delete closing bracket or quote when opening bracket or +# quote is entered/deleted. Brackets: (), [], {} Quotes: '', "" +# Default: False +# c.TerminalInteractiveShell.auto_match = False + +## +# See also: InteractiveShell.autoawait +# c.TerminalInteractiveShell.autoawait = True + +## +# See also: InteractiveShell.autocall +# c.TerminalInteractiveShell.autocall = 0 + +## Autoformatter to reformat Terminal code. Can be `'black'`, `'yapf'` or `None` +# Default: None +# c.TerminalInteractiveShell.autoformatter = None + +## +# See also: InteractiveShell.autoindent +# c.TerminalInteractiveShell.autoindent = True + +## +# See also: InteractiveShell.automagic +# c.TerminalInteractiveShell.automagic = True + +## Specifies from which source automatic suggestions are provided. Can be set to +# ``'NavigableAutoSuggestFromHistory'`` (:kbd:`up` and :kbd:`down` swap +# suggestions), ``'AutoSuggestFromHistory'``, or ``None`` to disable automatic +# suggestions. Default is `'NavigableAutoSuggestFromHistory`'. +# Default: 'NavigableAutoSuggestFromHistory' +# c.TerminalInteractiveShell.autosuggestions_provider = 'NavigableAutoSuggestFromHistory' + +## The part of the banner to be printed before the profile +# See also: InteractiveShell.banner1 +# c.TerminalInteractiveShell.banner1 = "Python 3.12.4 | packaged by Anaconda, Inc. | (main, Jun 18 2024, 10:07:17) [Clang 14.0.6 ]\nType 'copyright', 'credits' or 'license' for more information\nIPython 9.1.0 -- An enhanced Interactive Python. Type '?' for help.\n" + +## The part of the banner to be printed after the profile +# See also: InteractiveShell.banner2 +# c.TerminalInteractiveShell.banner2 = '' + +## +# See also: InteractiveShell.cache_size +# c.TerminalInteractiveShell.cache_size = 1000 + +## Set the color scheme (nocolor, neutral, linux, lightbg). +# See also: InteractiveShell.colors +# c.TerminalInteractiveShell.colors = 'neutral' + +## Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, +# Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a +# direct exit without any confirmation. +# Default: True +# c.TerminalInteractiveShell.confirm_exit = True + +# See also: InteractiveShell.debug +# c.TerminalInteractiveShell.debug = False + +## File in which to store and read history +# Default: '~/.pdbhistory' +# c.TerminalInteractiveShell.debugger_history_file = '~/.pdbhistory' + +## Options for displaying tab completions, 'column', 'multicolumn', and +# 'readlinelike'. These options are for `prompt_toolkit`, see `prompt_toolkit` +# documentation for more information. +# Choices: any of ['column', 'multicolumn', 'readlinelike'] +# Default: 'multicolumn' +# c.TerminalInteractiveShell.display_completions = 'multicolumn' + +## If True, anything that would be passed to the pager +# See also: InteractiveShell.display_page +# c.TerminalInteractiveShell.display_page = False + +## Shortcut style to use at the prompt. 'vi' or 'emacs'. +# Default: 'emacs' +# c.TerminalInteractiveShell.editing_mode = 'emacs' + +## Set the editor used by IPython (default to $EDITOR/vi/notepad). +# Default: 'vi' +# c.TerminalInteractiveShell.editor = 'vi' + +## Add shortcuts from 'emacs' insert mode to 'vi' insert mode. +# Default: True +# c.TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode = True + +## Allows to enable/disable the prompt toolkit history search +# Default: True +# c.TerminalInteractiveShell.enable_history_search = True + +## +# See also: InteractiveShell.enable_html_pager +# c.TerminalInteractiveShell.enable_html_pager = False + +## +# See also: InteractiveShell.enable_tip +# c.TerminalInteractiveShell.enable_tip = True + +## Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. This is +# in addition to the F2 binding, which is always enabled. +# Default: False +# c.TerminalInteractiveShell.extra_open_editor_shortcuts = False + +## Provide an alternative handler to be called when the user presses Return. This +# is an advanced option intended for debugging, which may be changed or removed +# in later releases. +# Default: None +# c.TerminalInteractiveShell.handle_return = None + +## Highlight matching brackets. +# Default: True +# c.TerminalInteractiveShell.highlight_matching_brackets = True + +## Deprecated, and has not effect, use IPython themes +# +# The name or class of a Pygments style to use for syntax +# highlighting. To see available styles, run `pygmentize -L styles`. +# Default: traitlets.Undefined +# c.TerminalInteractiveShell.highlighting_style = traitlets.Undefined + +## Override highlighting format for specific tokens +# Default: {} +# c.TerminalInteractiveShell.highlighting_style_overrides = {} + +## Total length of command history +# See also: InteractiveShell.history_length +# c.TerminalInteractiveShell.history_length = 10000 + +## +# See also: InteractiveShell.history_load_length +# c.TerminalInteractiveShell.history_load_length = 1000 + +## Class to use to instantiate the shell inspector +# See also: InteractiveShell.inspector_class +# c.TerminalInteractiveShell.inspector_class = 'IPython.core.oinspect.Inspector' + +# See also: InteractiveShell.ipython_dir +# c.TerminalInteractiveShell.ipython_dir = '' + +## Extra arguments to pass to `llm_provider_class` constructor. +# +# This is used to – for example – set the `model_id` +# Default: {} +# c.TerminalInteractiveShell.llm_constructor_kwargs = {} + +## Fully Qualifed name of a function that takes an IPython history manager and +# return a prefix to pass the llm provider in addition to the current buffer +# text. +# +# You can use: +# +# - no_prefix +# - input_history +# +# As default value. `input_history` (default), will use all the input history +# of current IPython session +# Default: 'input_history' +# c.TerminalInteractiveShell.llm_prefix_from_history = 'input_history' + +## Provisional: +# This is a provisinal API in IPython 8.32, before stabilisation +# in 9.0, it may change without warnings. +# +# class to use for the `NavigableAutoSuggestFromHistory` to request completions +# from a LLM, this should inherit from `jupyter_ai_magics:BaseProvider` and +# implement `stream_inline_completions` +# Default: None +# c.TerminalInteractiveShell.llm_provider_class = None + +## +# See also: InteractiveShell.logappend +# c.TerminalInteractiveShell.logappend = '' + +## +# See also: InteractiveShell.logfile +# c.TerminalInteractiveShell.logfile = '' + +## +# See also: InteractiveShell.logstart +# c.TerminalInteractiveShell.logstart = False + +## Select the loop runner that will be used to execute top-level asynchronous +# code +# See also: InteractiveShell.loop_runner +# c.TerminalInteractiveShell.loop_runner = 'IPython.core.interactiveshell._asyncio_runner' + +# Default: {} +# c.TerminalInteractiveShell.mime_renderers = {} + +## minimum characters for filling with ellipsis in file completions +# Default: 30 +# c.TerminalInteractiveShell.min_elide = 30 + +## Cursor shape changes depending on vi mode: beam in vi insert mode, block in +# nav mode, underscore in replace mode. +# Default: True +# c.TerminalInteractiveShell.modal_cursor = True + +## Enable mouse support in the prompt (Note: prevents selecting text with the +# mouse) +# Default: False +# c.TerminalInteractiveShell.mouse_support = False + +# See also: InteractiveShell.object_info_string_level +# c.TerminalInteractiveShell.object_info_string_level = 0 + +## +# See also: InteractiveShell.pdb +# c.TerminalInteractiveShell.pdb = False + +## Display the current vi mode (when using vi editing mode). +# Default: True +# c.TerminalInteractiveShell.prompt_includes_vi_mode = True + +## The format for line numbering, will be passed `line` (int, 1 based) the +# current line number and `rel_line` the relative line number. for example to +# display both you can use the following template string : +# c.TerminalInteractiveShell.prompt_line_number_format='{line: +# 4d}/{rel_line:+03d} | ' This will display the current line number, with +# leading space and a width of at least 4 character, as well as the relative +# line number 0 padded and always with a + or - sign. Note that when using Emacs +# mode the prompt of the first line may not update. +# Default: '' +# c.TerminalInteractiveShell.prompt_line_number_format = '' + +## Class used to generate Prompt token for prompt_toolkit +# Default: 'IPython.terminal.prompts.Prompts' +# c.TerminalInteractiveShell.prompts_class = 'IPython.terminal.prompts.Prompts' + +# See also: InteractiveShell.quiet +# c.TerminalInteractiveShell.quiet = False + +# See also: InteractiveShell.separate_in +# c.TerminalInteractiveShell.separate_in = '\n' + +# See also: InteractiveShell.separate_out +# c.TerminalInteractiveShell.separate_out = '' + +# See also: InteractiveShell.separate_out2 +# c.TerminalInteractiveShell.separate_out2 = '' + +## Add, disable or modifying shortcuts. +# +# Each entry on the list should be a dictionary with ``command`` key identifying +# the target function executed by the shortcut and at least one of the +# following: +# +# - ``match_keys``: list of keys used to match an existing shortcut, +# - ``match_filter``: shortcut filter used to match an existing shortcut, +# - ``new_keys``: list of keys to set, +# - ``new_filter``: a new shortcut filter to set +# +# The filters have to be composed of pre-defined verbs and joined by one of the +# following conjunctions: ``&`` (and), ``|`` (or), ``~`` (not). The pre-defined +# verbs are: +# +# - ``always`` +# - ``never`` +# - ``has_line_below`` +# - ``has_line_above`` +# - ``is_cursor_at_the_end_of_line`` +# - ``has_selection`` +# - ``has_suggestion`` +# - ``vi_mode`` +# - ``vi_insert_mode`` +# - ``emacs_insert_mode`` +# - ``emacs_like_insert_mode`` +# - ``has_completions`` +# - ``insert_mode`` +# - ``default_buffer_focused`` +# - ``search_buffer_focused`` +# - ``ebivim`` +# - ``supports_suspend`` +# - ``is_windows_os`` +# - ``auto_match`` +# - ``focused_insert`` +# - ``not_inside_unclosed_string`` +# - ``readline_like_completions`` +# - ``preceded_by_paired_double_quotes`` +# - ``preceded_by_paired_single_quotes`` +# - ``preceded_by_raw_str_prefix`` +# - ``preceded_by_two_double_quotes`` +# - ``preceded_by_two_single_quotes`` +# - ``followed_by_closing_paren_or_end`` +# - ``preceded_by_opening_round_paren`` +# - ``preceded_by_opening_bracket`` +# - ``preceded_by_opening_brace`` +# - ``preceded_by_double_quote`` +# - ``preceded_by_single_quote`` +# - ``followed_by_closing_round_paren`` +# - ``followed_by_closing_bracket`` +# - ``followed_by_closing_brace`` +# - ``followed_by_double_quote`` +# - ``followed_by_single_quote`` +# - ``navigable_suggestions`` +# - ``cursor_in_leading_ws`` +# - ``pass_through`` +# +# To disable a shortcut set ``new_keys`` to an empty list. To add a shortcut add +# key ``create`` with value ``True``. +# +# When modifying/disabling shortcuts, ``match_keys``/``match_filter`` can be +# omitted if the provided specification uniquely identifies a shortcut to be +# modified/disabled. When modifying a shortcut ``new_filter`` or ``new_keys`` +# can be omitted which will result in reuse of the existing filter/keys. +# +# Only shortcuts defined in IPython (and not default prompt-toolkit shortcuts) +# can be modified or disabled. The full list of shortcuts, command identifiers +# and filters is available under :ref:`terminal-shortcuts-list`. +# +# Here is an example: +# +# .. code:: +# +# c.TerminalInteractiveShell.shortcuts = [ +# { +# "new_keys": ["c-q"], +# "command": "prompt_toolkit:named_commands.capitalize_word", +# "create": True, +# }, +# { +# "new_keys": ["c-j"], +# "command": "prompt_toolkit:named_commands.beginning_of_line", +# "create": True, +# }, +# ] +# Default: [] +# c.TerminalInteractiveShell.shortcuts = [] + +## Show rewritten input, e.g. for autocall. +# See also: InteractiveShell.show_rewritten_input +# c.TerminalInteractiveShell.show_rewritten_input = True + +## Use `raw_input` for the REPL, without completion and prompt colors. +# +# Useful when controlling IPython as a subprocess, and piping +# STDIN/OUT/ERR. Known usage are: IPython's own testing machinery, +# and emacs' inferior-python subprocess (assuming you have set +# `python-shell-interpreter` to "ipython") available through the +# built-in `M-x run-python` and third party packages such as elpy. +# +# This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT` +# environment variable is set, or the current terminal is not a tty. +# Thus the Default value reported in --help-all, or config will often +# be incorrectly reported. +# Default: False +# c.TerminalInteractiveShell.simple_prompt = False + +## Number of line at the bottom of the screen to reserve for the tab completion +# menu, search history, ...etc, the height of these menus will at most this +# value. Increase it is you prefer long and skinny menus, decrease for short and +# wide. +# Default: 6 +# c.TerminalInteractiveShell.space_for_menu = 6 + +## +# See also: InteractiveShell.sphinxify_docstring +# c.TerminalInteractiveShell.sphinxify_docstring = False + +## Automatically set the terminal title +# Default: True +# c.TerminalInteractiveShell.term_title = True + +## Customize the terminal title format. This is a python format string. +# Available substitutions are: {cwd}. +# Default: 'IPython: {cwd}' +# c.TerminalInteractiveShell.term_title_format = 'IPython: {cwd}' + +## The time in milliseconds that is waited for a mapped key +# sequence to complete. +# Default: 0.5 +# c.TerminalInteractiveShell.timeoutlen = 0.5 + +## Use 24bit colors instead of 256 colors in prompt highlighting. +# If your terminal supports true color, the following command should +# print ``TRUECOLOR`` in orange:: +# +# printf "\x1b[38;2;255;100;0mTRUECOLOR\x1b[0m\n" +# Default: False +# c.TerminalInteractiveShell.true_color = False + +## The time in milliseconds that is waited for a key code +# to complete. +# Default: 0.01 +# c.TerminalInteractiveShell.ttimeoutlen = 0.01 + +## Warn if running in a virtual environment with no IPython installed (so IPython +# from the global environment is used). +# See also: InteractiveShell.warn_venv +# c.TerminalInteractiveShell.warn_venv = True + +# See also: InteractiveShell.wildcards_case_sensitive +# c.TerminalInteractiveShell.wildcards_case_sensitive = True + +## Switch modes for the IPython exception handlers. +# See also: InteractiveShell.xmode +# c.TerminalInteractiveShell.xmode = 'Context' + +#------------------------------------------------------------------------------ +# HistoryAccessor(HistoryAccessorBase) configuration +#------------------------------------------------------------------------------ +## Access the history database without adding to it. +# +# This is intended for use by standalone history tools. IPython shells use +# HistoryManager, below, which is a subclass of this. + +## Options for configuring the SQLite connection +# +# These options are passed as keyword args to sqlite3.connect +# when establishing database connections. +# Default: {} +# c.HistoryAccessor.connection_options = {} + +## enable the SQLite history +# +# set enabled=False to disable the SQLite history, +# in which case there will be no stored history, no SQLite connection, +# and no background saving thread. This may be necessary in some +# threaded environments where IPython is embedded. +# Default: True +# c.HistoryAccessor.enabled = True + +## Path to file to use for SQLite history database. +# +# By default, IPython will put the history database in the IPython +# profile directory. If you would rather share one history among +# profiles, you can set this value in each, so that they are consistent. +# +# Due to an issue with fcntl, SQLite is known to misbehave on some NFS +# mounts. If you see IPython hanging, try setting this to something on a +# local disk, e.g:: +# +# ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite +# +# you can also use the specific value `:memory:` (including the colon +# at both end but not the back ticks), to avoid creating an history file. +# Default: traitlets.Undefined +# c.HistoryAccessor.hist_file = traitlets.Undefined + +#------------------------------------------------------------------------------ +# HistoryManager(HistoryAccessor) configuration +#------------------------------------------------------------------------------ +## A class to organize all history-related functionality in one place. + +## Options for configuring the SQLite connection +# See also: HistoryAccessor.connection_options +# c.HistoryManager.connection_options = {} + +## Write to database every x commands (higher values save disk access & power). +# Values of 1 or less effectively disable caching. +# Default: 0 +# c.HistoryManager.db_cache_size = 0 + +## Should the history database include output? (default: no) +# Default: False +# c.HistoryManager.db_log_output = False + +## enable the SQLite history +# See also: HistoryAccessor.enabled +# c.HistoryManager.enabled = True + +## Path to file to use for SQLite history database. +# See also: HistoryAccessor.hist_file +# c.HistoryManager.hist_file = traitlets.Undefined + +#------------------------------------------------------------------------------ +# MagicsManager(Configurable) configuration +#------------------------------------------------------------------------------ +## Object that handles all magic-related functionality for IPython. + +## Automatically call line magics without requiring explicit % prefix +# Default: True +# c.MagicsManager.auto_magic = True + +## Mapping from magic names to modules to load. +# +# This can be used in IPython/IPykernel configuration to declare lazy magics +# that will only be imported/registered on first use. +# +# For example:: +# +# c.MagicsManager.lazy_magics = { +# "my_magic": "slow.to.import", +# "my_other_magic": "also.slow", +# } +# +# On first invocation of `%my_magic`, `%%my_magic`, `%%my_other_magic` or +# `%%my_other_magic`, the corresponding module will be loaded as an ipython +# extensions as if you had previously done `%load_ext ipython`. +# +# Magics names should be without percent(s) as magics can be both cell and line +# magics. +# +# Lazy loading happen relatively late in execution process, and complex +# extensions that manipulate Python/IPython internal state or global state might +# not support lazy loading. +# Default: {} +# c.MagicsManager.lazy_magics = {} + +#------------------------------------------------------------------------------ +# ProfileDir(LoggingConfigurable) configuration +#------------------------------------------------------------------------------ +## An object to manage the profile directory and its resources. +# +# The profile directory is used by all IPython applications, to manage +# configuration, logging and security. +# +# This object knows how to find, create and manage these directories. This +# should be used by any code that wants to handle profiles. + +## Set the profile location directly. This overrides the logic used by the +# `profile` option. +# Default: '' +# c.ProfileDir.location = '' + +#------------------------------------------------------------------------------ +# BaseFormatter(Configurable) configuration +#------------------------------------------------------------------------------ +## A base formatter class that is configurable. +# +# This formatter should usually be used as the base class of all formatters. +# It is a traited :class:`Configurable` class and includes an extensible +# API for users to determine how their objects are formatted. The following +# logic is used to find a function to format an given object. +# +# 1. The object is introspected to see if it has a method with the name +# :attr:`print_method`. If is does, that object is passed to that method +# for formatting. +# 2. If no print method is found, three internal dictionaries are consulted +# to find print method: :attr:`singleton_printers`, :attr:`type_printers` +# and :attr:`deferred_printers`. +# +# Users should use these dictionaries to register functions that will be +# used to compute the format data for their objects (if those objects don't +# have the special print methods). The easiest way of using these +# dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name` +# methods. +# +# If no function/callable is found to compute the format data, ``None`` is +# returned and this format type is not used. + +# Default: {} +# c.BaseFormatter.deferred_printers = {} + +# Default: True +# c.BaseFormatter.enabled = True + +# Default: {} +# c.BaseFormatter.singleton_printers = {} + +# Default: {} +# c.BaseFormatter.type_printers = {} + +#------------------------------------------------------------------------------ +# PlainTextFormatter(BaseFormatter) configuration +#------------------------------------------------------------------------------ +## The default pretty-printer. +# +# This uses :mod:`IPython.lib.pretty` to compute the format data of +# the object. If the object cannot be pretty printed, :func:`repr` is used. +# See the documentation of :mod:`IPython.lib.pretty` for details on +# how to write pretty printers. Here is a simple example:: +# +# def dtype_pprinter(obj, p, cycle): +# if cycle: +# return p.text('dtype(...)') +# if hasattr(obj, 'fields'): +# if obj.fields is None: +# p.text(repr(obj)) +# else: +# p.begin_group(7, 'dtype([') +# for i, field in enumerate(obj.descr): +# if i > 0: +# p.text(',') +# p.breakable() +# p.pretty(field) +# p.end_group(7, '])') + +# See also: BaseFormatter.deferred_printers +# c.PlainTextFormatter.deferred_printers = {} + +# Default: '' +# c.PlainTextFormatter.float_precision = '' + +## Truncate large collections (lists, dicts, tuples, sets) to this size. +# +# Set to 0 to disable truncation. +# Default: 1000 +# c.PlainTextFormatter.max_seq_length = 1000 + +# Default: 79 +# c.PlainTextFormatter.max_width = 79 + +# Default: '\n' +# c.PlainTextFormatter.newline = '\n' + +# Default: True +# c.PlainTextFormatter.pprint = True + +# See also: BaseFormatter.singleton_printers +# c.PlainTextFormatter.singleton_printers = {} + +# See also: BaseFormatter.type_printers +# c.PlainTextFormatter.type_printers = {} + +# Default: False +# c.PlainTextFormatter.verbose = False + +#------------------------------------------------------------------------------ +# Completer(Configurable) configuration +#------------------------------------------------------------------------------ +## Enable auto-closing dictionary keys. +# +# When enabled string keys will be suffixed with a final quote (matching the +# opening quote), tuple keys will also receive a separating comma if needed, and +# keys which are final will receive a closing bracket (``]``). +# Default: False +# c.Completer.auto_close_dict_keys = False + +## Enable unicode completions, e.g. \alpha<tab> . Includes completion of latex +# commands, unicode names, and expanding unicode characters back to latex +# commands. +# Default: True +# c.Completer.backslash_combining_completions = True + +## Enable debug for the Completer. Mostly print extra information for +# experimental jedi integration. +# Default: False +# c.Completer.debug = False + +## Policy for code evaluation under completion. +# +# Successive options allow to enable more eager evaluation for better +# completion suggestions, including for nested dictionaries, nested lists, +# or even results of function calls. +# Setting ``unsafe`` or higher can lead to evaluation of arbitrary user +# code on :kbd:`Tab` with potentially unwanted or dangerous side effects. +# +# Allowed values are: +# +# - ``forbidden``: no evaluation of code is permitted, +# - ``minimal``: evaluation of literals and access to built-in namespace; +# no item/attribute evaluationm no access to locals/globals, +# no evaluation of any operations or comparisons. +# - ``limited``: access to all namespaces, evaluation of hard-coded methods +# (for example: :any:`dict.keys`, :any:`object.__getattr__`, +# :any:`object.__getitem__`) on allow-listed objects (for example: +# :any:`dict`, :any:`list`, :any:`tuple`, ``pandas.Series``), +# - ``unsafe``: evaluation of all methods and function calls but not of +# syntax with side-effects like `del x`, +# - ``dangerous``: completely arbitrary evaluation. +# Choices: any of ['forbidden', 'minimal', 'limited', 'unsafe', 'dangerous'] +# Default: 'limited' +# c.Completer.evaluation = 'limited' + +## Activate greedy completion. +# +# .. deprecated:: 8.8 +# Use :std:configtrait:`Completer.evaluation` and :std:configtrait:`Completer.auto_close_dict_keys` instead. +# +# When enabled in IPython 8.8 or newer, changes configuration as +# follows: +# +# - ``Completer.evaluation = 'unsafe'`` +# - ``Completer.auto_close_dict_keys = True`` +# Default: False +# c.Completer.greedy = False + +## Experimental: restrict time (in milliseconds) during which Jedi can compute types. +# Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt +# performance by preventing jedi to build its cache. +# Default: 400 +# c.Completer.jedi_compute_type_timeout = 400 + +## Experimental: Use Jedi to generate autocompletions. Default to True if jedi is +# installed. +# Default: True +# c.Completer.use_jedi = True + +#------------------------------------------------------------------------------ +# IPCompleter(Completer) configuration +#------------------------------------------------------------------------------ +## Extension of the completer class with IPython-specific features + +## +# See also: Completer.auto_close_dict_keys +# c.IPCompleter.auto_close_dict_keys = False + +## Enable unicode completions, e.g. \alpha<tab> . Includes completion of latex +# commands, unicode names, and expanding unicode characters back to latex +# commands. +# See also: Completer.backslash_combining_completions +# c.IPCompleter.backslash_combining_completions = True + +## Enable debug for the Completer. Mostly print extra information for +# experimental jedi integration. +# See also: Completer.debug +# c.IPCompleter.debug = False + +## List of matchers to disable. +# +# The list should contain matcher identifiers (see +# :any:`completion_matcher`). +# Default: [] +# c.IPCompleter.disable_matchers = [] + +## Policy for code evaluation under completion. +# See also: Completer.evaluation +# c.IPCompleter.evaluation = 'limited' + +## Activate greedy completion. +# See also: Completer.greedy +# c.IPCompleter.greedy = False + +## Experimental: restrict time (in milliseconds) during which Jedi can compute +# types. +# See also: Completer.jedi_compute_type_timeout +# c.IPCompleter.jedi_compute_type_timeout = 400 + +## DEPRECATED as of version 5.0. +# +# Instruct the completer to use __all__ for the completion +# +# Specifically, when completing on ``object.<tab>``. +# +# When True: only those names in obj.__all__ will be included. +# +# When False [default]: the __all__ attribute is ignored +# Default: False +# c.IPCompleter.limit_to__all__ = False + +## Whether to merge completion results into a single list +# +# If False, only the completion results from the first non-empty +# completer will be returned. +# +# As of version 8.6.0, setting the value to ``False`` is an alias for: +# ``IPCompleter.suppress_competing_matchers = True.``. +# Default: True +# c.IPCompleter.merge_completions = True + +## Instruct the completer to omit private method names +# +# Specifically, when completing on ``object.<tab>``. +# +# When 2 [default]: all names that start with '_' will be excluded. +# +# When 1: all 'magic' names (``__foo__``) will be excluded. +# +# When 0: nothing will be excluded. +# Choices: any of [0, 1, 2] +# Default: 2 +# c.IPCompleter.omit__names = 2 + +## If True, emit profiling data for completion subsystem using cProfile. +# Default: False +# c.IPCompleter.profile_completions = False + +## Template for path at which to output profile data for completions. +# Default: '.completion_profiles' +# c.IPCompleter.profiler_output_dir = '.completion_profiles' + +## Whether to suppress completions from other *Matchers*. +# +# When set to ``None`` (default) the matchers will attempt to auto-detect +# whether suppression of other matchers is desirable. For example, at the +# beginning of a line followed by `%` we expect a magic completion to be the +# only applicable option, and after ``my_dict['`` we usually expect a completion +# with an existing dictionary key. +# +# If you want to disable this heuristic and see completions from all matchers, +# set ``IPCompleter.suppress_competing_matchers = False``. To disable the +# heuristic for specific matchers provide a dictionary mapping: +# ``IPCompleter.suppress_competing_matchers = {'IPCompleter.dict_key_matcher': +# False}``. +# +# Set ``IPCompleter.suppress_competing_matchers = True`` to limit completions to +# the set of matchers with the highest priority; this is equivalent to +# ``IPCompleter.merge_completions`` and can be beneficial for performance, but +# will sometimes omit relevant candidates from matchers further down the +# priority list. +# Default: None +# c.IPCompleter.suppress_competing_matchers = None + +## Experimental: Use Jedi to generate autocompletions. Default to True if jedi is +# installed. +# See also: Completer.use_jedi +# c.IPCompleter.use_jedi = True + +#------------------------------------------------------------------------------ +# ScriptMagics(Magics) configuration +#------------------------------------------------------------------------------ +## Magics for talking to scripts +# +# This defines a base `%%script` cell magic for running a cell +# with a program in a subprocess, and registers a few top-level +# magics that call %%script with common interpreters. + +## Extra script cell magics to define +# +# This generates simple wrappers of `%%script foo` as `%%foo`. +# +# If you want to add script magics that aren't on your path, +# specify them in script_paths +# Default: [] +# c.ScriptMagics.script_magics = [] + +## Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby' +# +# Only necessary for items in script_magics where the default path will not +# find the right interpreter. +# Default: {} +# c.ScriptMagics.script_paths = {} + +#------------------------------------------------------------------------------ +# LoggingMagics(Magics) configuration +#------------------------------------------------------------------------------ +## Magics related to all logging machinery. + +## Suppress output of log state when logging is enabled +# Default: False +# c.LoggingMagics.quiet = False + +#------------------------------------------------------------------------------ +# StoreMagics(Magics) configuration +#------------------------------------------------------------------------------ +## Lightweight persistence for python variables. +# +# Provides the %store magic. + +## If True, any %store-d variables will be automatically restored +# when IPython starts. +# Default: False +# c.StoreMagics.autorestore = False diff --git a/olaris-tk/cli/profile_default/startup/00-chdir.ipy b/olaris-tk/cli/profile_default/startup/00-chdir.ipy new file mode 100644 index 0000000..2a994e0 --- /dev/null +++ b/olaris-tk/cli/profile_default/startup/00-chdir.ipy @@ -0,0 +1,8 @@ +#print("hello") +%load_ext autoreload +%autoreload 2 +import os +dir = os.getenv("OPS_PWD") +if dir: + #print(f"Changing directory to {dir}") + os.chdir(dir) \ No newline at end of file diff --git a/olaris-tk/cli/profile_default/startup/01-opsenv.py b/olaris-tk/cli/profile_default/startup/01-opsenv.py new file mode 100644 index 0000000..632204f --- /dev/null +++ b/olaris-tk/cli/profile_default/startup/01-opsenv.py @@ -0,0 +1,25 @@ +import subprocess +from dotenv import load_dotenv + +if os.path.exists(os.path.expanduser("~/.wskprops")): + # load secrets + command = ["ops", "-config", "-dump"] + result = subprocess.run(command, capture_output=True, text=True) + output = result.stdout + + # Parse the output and set environment variables + for line in output.splitlines(): + try: + key, value = line.split('=', 1) + os.environ[key] = value + print("OK:", key) + except: + print("ERR:", line) + +# override with testenv +load_dotenv(".env") +load_dotenv("tests/.env", override=True) + +class Empty: pass +self = Empty() +args = {} \ No newline at end of file diff --git a/olaris-tk/cli/profile_default/startup/README b/olaris-tk/cli/profile_default/startup/README new file mode 100644 index 0000000..61d4700 --- /dev/null +++ b/olaris-tk/cli/profile_default/startup/README @@ -0,0 +1,11 @@ +This is the IPython startup directory + +.py and .ipy files in this directory will be run *prior* to any code or files specified +via the exec_lines or exec_files configurables whenever you load this profile. + +Files will be run in lexicographical order, so you can control the execution order of files +with a prefix, e.g.:: + + 00-first.py + 50-middle.py + 99-last.ipy diff --git a/olaris-tk/cli/pyproject.toml b/olaris-tk/cli/pyproject.toml new file mode 100644 index 0000000..ff50a5f --- /dev/null +++ b/olaris-tk/cli/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "cli" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "ipython>=9.1.0", + "python-dotenv>=1.1.1", +] diff --git a/olaris-tk/cli/uv.lock b/olaris-tk/cli/uv.lock new file mode 100644 index 0000000..3cc291b --- /dev/null +++ b/olaris-tk/cli/uv.lock @@ -0,0 +1,223 @@ +version = 1 +revision = 2 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.13' and platform_python_implementation == 'CPython'", + "python_full_version >= '3.12.4' and python_full_version < '3.13' and platform_python_implementation == 'CPython'", + "python_full_version < '3.12.4' and platform_python_implementation == 'CPython'", + "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", + "python_full_version >= '3.12.4' and python_full_version < '3.13' and platform_python_implementation == 'PyPy'", + "python_full_version < '3.12.4' and platform_python_implementation == 'PyPy'", + "python_full_version >= '3.13' and platform_python_implementation != 'CPython' and platform_python_implementation != 'PyPy'", + "python_full_version >= '3.12.4' and python_full_version < '3.13' and platform_python_implementation != 'CPython' and platform_python_implementation != 'PyPy'", + "python_full_version < '3.12.4' and platform_python_implementation != 'CPython' and platform_python_implementation != 'PyPy'", +] + +[[package]] +name = "asttokens" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, +] + +[[package]] +name = "cli" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "ipython" }, + { name = "python-dotenv" }, +] + +[package.metadata] +requires-dist = [ + { name = "ipython", specifier = ">=9.1.0" }, + { name = "python-dotenv", specifier = ">=1.1.1" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "decorator" +version = "5.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, +] + +[[package]] +name = "executing" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693, upload-time = "2025-01-22T15:41:29.403Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload-time = "2025-01-22T15:41:25.929Z" }, +] + +[[package]] +name = "ipython" +version = "9.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/70/9a/6b8984bedc990f3a4aa40ba8436dea27e23d26a64527de7c2e5e12e76841/ipython-9.1.0.tar.gz", hash = "sha256:a47e13a5e05e02f3b8e1e7a0f9db372199fe8c3763532fe7a1e0379e4e135f16", size = 4373688, upload-time = "2025-04-07T10:18:28.704Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/9d/4ff2adf55d1b6e3777b0303fdbe5b723f76e46cba4a53a32fe82260d2077/ipython-9.1.0-py3-none-any.whl", hash = "sha256:2df07257ec2f84a6b346b8d83100bcf8fa501c6e01ab75cd3799b0bb253b3d2a", size = 604053, upload-time = "2025-04-07T10:18:24.869Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, +] + +[[package]] +name = "parso" +version = "0.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609, upload-time = "2024-04-05T09:43:55.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650, upload-time = "2024-04-05T09:43:53.299Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.50" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/e1/bd15cb8ffdcfeeb2bdc215de3c3cffca11408d829e4b8416dcfe71ba8854/prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab", size = 429087, upload-time = "2025-01-20T15:55:35.072Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/ea/d836f008d33151c7a1f62caf3d8dd782e4d15f6a43897f64480c2b8de2ad/prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198", size = 387816, upload-time = "2025-01-20T15:55:29.98Z" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, +] diff --git a/olaris-tk/docopts.md b/olaris-tk/docopts.md new file mode 100644 index 0000000..95c0769 --- /dev/null +++ b/olaris-tk/docopts.md @@ -0,0 +1,13 @@ +# Plugin ops a41 + +AI tasks to manage Agent41 + +## Synopsis + +```text +Usage: + tk new <action> + tk cli [<function>] + tk pg + tk img <action> [-f] +``` diff --git a/olaris-tk/findimg.js b/olaris-tk/findimg.js new file mode 100644 index 0000000..1611d70 --- /dev/null +++ b/olaris-tk/findimg.js @@ -0,0 +1,40 @@ +import { readFile } from "fs/promises"; + +async function main() { + const [,, runtimeInput, jsonPath] = process.argv; + + if (!runtimeInput || !jsonPath) { + console.error("Usage: bun find.js <runtime[:version|default]> <runtimes.json>"); + process.exit(1); + } + + const [language, kindOrDefault] = runtimeInput.split(":"); + + const content = await readFile(jsonPath, "utf-8"); + const data = JSON.parse(content); + + const runtimes = data.runtimes?.[language]; + + if (!runtimes) { + console.error(`Runtime family "${language}" not found.`); + process.exit(1); + } + + let runtime; + + if (!kindOrDefault || kindOrDefault === "default") { + runtime = runtimes.find(r => r.default); + } else { + runtime = runtimes.find(r => r.kind === `${language}:${kindOrDefault}`); + } + + if (!runtime || !runtime.image) { + console.error(`Runtime for "${runtimeInput}" not found or has no image info.`); + process.exit(1); + } + + const { prefix, name, tag } = runtime.image; + console.log(`${prefix}/${name}:${tag}|${language}_${tag}`); +} + +main(); diff --git a/olaris-tk/opsfile.yml b/olaris-tk/opsfile.yml new file mode 100644 index 0000000..c61c5f2 --- /dev/null +++ b/olaris-tk/opsfile.yml @@ -0,0 +1,172 @@ +version: 3 + +dotenv: + - '{{.OPS_PWD}}/.env' + +tasks: + + pg: + desc: postgres + + cli: + silent: false + desc: cli + env: + IPYTHONDIR: + sh: realpath . + dir: cli + cmds: + - | + if ! test -d .venv + then uv venv --seed + export VIRTUAL_ENV="$PWD/.venv" + uv pip install -r requirements.in + fi + - | + set -a + test -e $OPS_PWD/.env && source $OPS_PWD/.env + test -e $OPS_PWD/tests/.env && source $OPS_PWD/tests/.env + export PYTHONPATH="$OPS_PWD/packages:$PWD:$PYTHONPATH" + export VIRTUAL_ENV="$PWD/.venv" + if test -e $OPS_PWD/requirements.txt + then uv pip install -r $OPS_PWD/requirements.txt + fi + if test -z "{{._function_}}" + then uv run ipython + else uv run ipython -m '{{._function_ | replace "/" "."}}' + fi + + new: + silent: true + desc: generate a new python action + vars: + ACTION: + sh: echo "{{._action_}}" | cut -d/ -f2 + PACKAGE: + sh: echo "{{._action_}}" | cut -d/ -f1 + env: + ACTION: "{{.ACTION}}" + PACKAGE: "{{.PACKAGE}}" + DIR: "packages/{{.PACKAGE}}/{{.ACTION}}" + FILE: "packages/{{.PACKAGE}}/{{.ACTION}}/{{.ACTION}}.py" + cmds: + #- test ! -e "$OPS_PWD/$FILE" || die "file already exists" + - echo $ACTION + - echo $PACKAGE + - echo $DIR + - echo $FILE + - | + mkdir -p $OPS_PWD/tests/$PACKAGE + mkdir -p $OPS_PWD/$DIR + - | + cat <<EOF >$OPS_PWD/$FILE + def $ACTION(args): + return { "output": "$ACTION" } + EOF + - | + cat <<EOF >$OPS_PWD/$DIR/__main__.py + #--kind python:default + #--web true + import $ACTION + def main(args): + return { "body": $ACTION.$ACTION(args) } + EOF + - | + cat <<EOF >$OPS_PWD/tests/$PACKAGE/test_${ACTION}.py + import sys + sys.path.append("$DIR") + import $ACTION + + def test_$ACTION(): + res = $ACTION.$ACTION({}) + assert res["output"] == "$ACTION" + EOF + - | + cat <<EOF >$OPS_PWD/tests/$PACKAGE/test_${ACTION}_int.py + import os, requests as req + def test_$ACTION(): + url = os.environ.get("OPSDEV_HOST") + "/api/my/$PACKAGE/$ACTION" + res = req.get(url).json() + assert res.get("output") == "$ACTION" + EOF + + img: + silent: true + desc: build image + vars: + DIR: '{{.OPS_PWD}}/packages/{{._action_}}' + env: + NO_COLOR: "1" + cmds: + - | + if {{._f}} + then rm -f {{.DIR}}/Dockerfile + fi + - task: _img + vars: + DIR: '{{.DIR}}' + - | + if test -e "{{.DIR}}/Dockerfile" + then + echo "Image Built. Metadata comment to use:" + rg -N -- '--docker' "{{.DIR}}/Dockerfile" + fi + + _img: + silent: true + desc: build image + sources: + - "{{.DIR}}/pyproject.toml" + generates: + - "{{.DIR}}/Dockerfile" + cmds: + - test -d "{{.DIR}}" || die "{{.DIR}} not found or not a directory" + - test -n "$DOCKER_BUILDER" || die "create a docker builder in docker cloud and add to .env DOCKER_BUILDER" + - test -n "$DOCKER_CUSTOM_RUNTIMES" || die "set DOCKER_CUSTOM_RUNTIMES to the custom runtime prefix" + - | + if test -f "{{.DIR}}/pyproject.toml" + then + DIR="{{.DIR}}" + SHA="$(sha256sum "$DIR/pyproject.toml" | awk '{print substr($1, 0, 12)}')" + KIND="$(awk '/--kind/ {print $2}' "$DIR/__main__.py")" + FROM_TAG="$(bun findimg.js "$KIND" "$OPS_ROOT/runtimes.json")" + FROM="${FROM_TAG%|*}" + TAG="${FROM_TAG#*|}.${SHA}" + #echo FROM=$FROM + #echo TAG=$TAG + if rg "$TAG" "{{.DIR}}/Dockerfile" >/dev/null + then echo Image already built + else + # prepare the dockerfile + cat <<EOF >"$DIR/Dockerfile" + #--docker "$DOCKER_CUSTOM_RUNTIMES:$TAG" + FROM $FROM + USER root + ADD pyproject.toml pyproject.toml + RUN pip3 install . + EOF + if rg '^#Dockerfile:\s*(.*)' -or '$1' "$DIR/pyproject.toml" >_dockerfile + then cat _dockerfile >>"$DIR/Dockerfile" + fi + echo "USER nobody" >>"$DIR/Dockerfile" + cat "$DIR/Dockerfile" + docker buildx build --platform linux/arm64,linux/amd64 --builder "$DOCKER_BUILDER" -t "$DOCKER_CUSTOM_RUNTIMES:$TAG" "$DIR" --push + if test $? -eq 0 + then echo Built "$DOCKER_CUSTOM_RUNTIMES:$TAG" + else rm "$DIR/Dockerfile" + die "docker build failed, check the Dockerfile" + fi + fi + else + echo "no pyproject.toml found, skipping image build" + fi + + #stream: + # silent: true + # desc: stream an action + # cmds: + # - | + # args={{._args_}} + # set -- ${args[@]} + # test "$1" = "--" && shift + # uv run stream.py {{._action_}} "$@" diff --git a/olaris-tk/pg/.python-version b/olaris-tk/pg/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/olaris-tk/pg/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/olaris-tk/pg/docopts.md b/olaris-tk/pg/docopts.md new file mode 100644 index 0000000..f27ef78 --- /dev/null +++ b/olaris-tk/pg/docopts.md @@ -0,0 +1,25 @@ +# Plugin ops a41 pg + +AI tasks to manage Postgresql + +## Synopsis + +```text +Usage: + pg cli [<command>] + pg lite2pg <file> + pg export <schema> <file> + pg sqload <filesql> [--group=<count>] + pg sql [<sql>] +``` + +Note you have: +- *TEST* commands affecting the test database (pointed by tests/.env) +- *PROD* commands affecting the production database + +Local (test) commands: +- `cli` opens a CLI to the *TEST* database +- `lite2pg` imports a sqlite file in the *TEST* +- `export` exports a database from the *TEST* +- `sqload` execute a sql file against the *PROD* - you can group `<count>` statements +- `sql` execute a single statements against the *PROD* \ No newline at end of file diff --git a/olaris-tk/pg/main.py b/olaris-tk/pg/main.py new file mode 100644 index 0000000..afd9295 --- /dev/null +++ b/olaris-tk/pg/main.py @@ -0,0 +1,90 @@ +import sys +from pathlib import Path + +def slurp_statement(file): + """ + Read from the file until you find a line ending with ';' + Concatenate the lines removing the newline + """ + lines = [] + while True: + line = file.readline() + if not line: + return None + line = line.rstrip('\n') + if line.startswith("--") or line == "": + continue + if line.startswith("SET"): + continue + if line.startswith("CREATE TABLE"): + line = line.replace("public.", "") + lines.append(line.strip()) + if line.endswith(';'): + break + return ' '.join(lines) + + +def process(filename, action, max, exec): + """ + Open a file and use slurp_statement to read a statement + when you reach a max number of statements invoke exec passing an array of statements + """ + with open(filename, 'r') as file: + statements = [] + count = 0 + while True: + count += 1 + statement = slurp_statement(file) + #print(statement) + if statement is None: + if statements: + exec(action, statements) + break + statements.append(statement) + if len(statements) >= max: + print(f"{count}:", end="") + exec(action, statements) + statements = [] + +def invoke_exec(action, statements): + """ + create a temporary json file with a key "input" and a value that is the concatenation of all the stemements separated by newlines + then evecute "ops action invoke <action> -P <the file> + """ + import json + import tempfile + import subprocess + + #print("-- invoke --\n", "\n".join(statements)) + + # Create temporary file + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=True) as tmp: + # Write statements to JSON file + Path(tmp.name).write_text(json.dumps({"input": "\n".join(statements)}, indent=2)) + + cmd = ["ops", "action", "invoke", action, "-P", tmp.name, "-r"] + #cmd = ["cat", tmp.name] + result = subprocess.run(cmd, check=True, capture_output=True, text=True) + print(result.stdout) + + # Execute ops action command + +def main(argv): + print(argv) + filename = argv[0] + + action = "mastrogpt/sql" + if argv[1] != "": + action = argv[1] + + max = 100 + try: max = int(argv[2]) + except: pass + + print(f"action: {action} file: {filename} max: {max}") + process(filename, action, max, invoke_exec) + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/olaris-tk/pg/opsfile.yml b/olaris-tk/pg/opsfile.yml new file mode 100644 index 0000000..2d71500 --- /dev/null +++ b/olaris-tk/pg/opsfile.yml @@ -0,0 +1,75 @@ +version: 3 + +tasks: + + sql: + desc: execute a sql query against the database - default is to list the tables + cmds: + - | + ops invoke mastrogpt/sql input='{{default "@" ._sql_}}' + + sqload: + desc: load a sql file for postgres + cmds: + - | + DIR="$(pwd)" + cd $OPS_PWD + FILE="$(realpath {{._filesql_}})" + uv run --directory "$DIR" python main.py "$FILE" mastrogpt/sql "{{.__group}}" + + lite2pg: + desc: sqlite to postgres conversion + dir: $OPS_PWD + silent: true + cmds: + - which pg_dump || die "pg_dump not found" + - which pgloader || die "pgloader not found" + - test -n "$OPSDEV_USERNAME" || die "please login to openserverless first" + - | + source $OPS_PWD/tests/.env + FILE="$(realpath {{._file_}})" + cat > {{._file_}}.load <<EOF + LOAD DATABASE + FROM sqlite://$FILE + INTO $POSTGRES_URL + + WITH include no drop, create tables, create indexes, reset sequences + + SET search_path to '$OPSDEV_USERNAME' + + BEFORE LOAD + DO \$\$ DROP SCHEMA IF EXISTS $OPSDEV_USERNAME CASCADE; \$\$ + DO \$\$ CREATE SCHEMA IF NOT EXISTS $OPSDEV_USERNAME; \$\$ + ; + EOF + if pgloader {{._file_}}.load + then + export PGPASSWORD=$POSTGRES_PASSWORD + pg_dump -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USERNAME" -d "$POSTGRES_DATABASE" -n $OPSDEV_USERNAME -F p --inserts --no-owner --no-privileges -f "{{._file_}}.sql" + echo "Exported {{._file_}}.sql" + else echo "pgloader failed" + fi + + export: + desc: export database to import in openserverless + dir: $OPS_PWD + cmds: + - which pg_dump || die "pg_dump not found" + - | + source $OPS_PWD/tests/.env + export PGPASSWORD=$POSTGRES_PASSWORD + pg_dump -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USERNAME" -d "$POSTGRES_DATABASE" -n $OPSDEV_USERNAME --schema="{{._schema_}}" -F p --inserts --no-owner --no-privileges -f "{{._file_}}" + + cli: + desc: postgres psql command + dir: $OPS_PWD + silent: true + cmds: + - | + source $OPS_PWD/tests/.env + export PGPASSWORD=$POSTGRES_PASSWORD + if test -z "{{._command_}}" + then psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USERNAME -d $POSTGRES_DATABASE + else psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USERNAME -d $POSTGRES_DATABASE -c "{{._command_}}" + fi + diff --git a/olaris-tk/pg/pyproject.toml b/olaris-tk/pg/pyproject.toml new file mode 100644 index 0000000..65b22bb --- /dev/null +++ b/olaris-tk/pg/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "pg" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [] diff --git a/olaris-tk/pg/uv.lock b/olaris-tk/pg/uv.lock new file mode 100644 index 0000000..46773a8 --- /dev/null +++ b/olaris-tk/pg/uv.lock @@ -0,0 +1,8 @@ +version = 1 +revision = 1 +requires-python = ">=3.13" + +[[package]] +name = "pg" +version = "0.1.0" +source = { virtual = "." } diff --git a/olaris-tk/prereq.yml b/olaris-tk/prereq.yml new file mode 100644 index 0000000..11cbdc3 --- /dev/null +++ b/olaris-tk/prereq.yml @@ -0,0 +1,88 @@ +version: 3 + +vars: + OS: "{{or .__OS OS}}" + ARCH: "{{or .__ARCH ARCH}}" + ARC: '{{if eq .OS "windows"}}.zip{{else}}.tar.gz{{end}}' + EXE: '{{if eq .OS "windows"}}.exe{{else}}{{end}}' + DRY: "" + +tasks: + + download-and-extract: + requires: + vars: + - FILE + - URL + - OUT + cmds: + - echo "{{.OUT}} {{.FILE}} {{.URL}} {{.FILETAR}}" + - curl -sL "{{.URL}}" -o {{.FILE}} + - extract "{{.FILE}}" "{{.OUT}}{{.EXE}}" + - remove "{{.FILE}}" + + himalaya: + desc: download himalaya + vars: + VERSION: "1.1.0" + SUFFIX: + sh: | + case "{{.OS}}-{{.ARCH}}" in + linux-amd64) echo "x86_64-linux" ;; + linux-arm64) echo "aarch64-linux" ;; + darwin-amd64) echo "x86_64-darwin" ;; + darwin-arm64) echo "aarch64-darwin" ;; + windows-*) echo "x86_64-windows" ;; + *) echo "unknown" ;; + esac + #https://github.com/pimalaya/himalaya/releases/download/v1.1.0/himalaya.aarch64-darwin.tgz + URL: "https://github.com/pimalaya/himalaya/releases/download/v{{.VERSION}}/himalaya.{{.SUFFIX}}.tgz" + FILE: "{{base .URL}}" + OUT: himalaya + cmds: + - task: download-and-extract + vars: + URL: "{{.URL}}" + FILE: "{{.FILE}}" + OUT: himalaya + + + all: + - task: himalaya + + test: + vars: + DIR: "{{.OPS_PWD}}/bin/{{.OS}}-{{.ARCH}}" + cmds: + - | + {{.DRY}} rm -Rvf {{.DIR}} + mkdir -p {{.DIR}} + cd {{.DIR}} + {{.DRY}} ops -task -t ../../prereq.yml -d {{.DIR}} all + #- task: check + + check: + vars: + DIR: "{{.OPS_PWD}}/bin/{{.OS}}-{{.ARCH}}" + FILETYPE: + sh: | + case "{{.OS}}" in + (windows) echo application/vnd.microsoft.portable-executable ;; + (darwin) echo application/x-mach-binary ;; + (linux) echo application/x-executable ;; + (*) unknown ;; + esac + sources: + - '{{.DIR}}/*' + status: + - false + cmds: + - for: sources + cmd: filetype -m {{.ITEM}} | rg {{.FILETYPE}} + + tests: + - __OS=linux __ARCH=amd64 ops -task -t prereq.yml test + - __OS=linux __ARCH=arm64 ops -task -t prereq.yml test + - __OS=darwin __ARCH=amd64 ops -task -t prereq.yml test + - __OS=darwin __ARCH=arm64 ops -task -t prereq.yml test + - __OS=windows __ARCH=amd64 ops -task -t prereq.yml test diff --git a/olaris-tk/stream.py b/olaris-tk/stream.py new file mode 100644 index 0000000..e7f3088 --- /dev/null +++ b/olaris-tk/stream.py @@ -0,0 +1,30 @@ +# /// script +# dependencies = [ +# "requests", +# ] +# /// +import sys, os, json +import requests as req +from urllib.parse import urlparse, urlunparse + + +def main(argv): + #print(argv) + #argv=['stream/demo'] + url = urlparse(os.getenv("OPSDEV_APIHOST")) + netloc = f"stream.{url.netloc}" + path = f"/web/{os.getenv("OPSDEV_USERNAME")}/{argv[0]}" + streamer = urlunparse(url._replace(netloc=netloc, path=path)) + msg = {"input": " ".join(argv[1:])} if len(argv)>1 else {} + lines = req.post(streamer, json=msg, stream=True).iter_lines() + for line in lines: + #line = next(lines) + msg = json.loads(line.decode("utf-8")).get("output", "") + if msg != "": + print(msg, end="", flush=True) + else: + print() + break + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/start-ssh.sh b/start-ssh.sh new file mode 100755 index 0000000..dd66d9e --- /dev/null +++ b/start-ssh.sh @@ -0,0 +1,10 @@ +#!/bin/bash +sudo mkdir -p /run/sshd +sudo ssh-keygen -A +mkdir -p ~/.ssh +chmod 600 ~/.ssh/authorized_keys +if test -n "$AUTHORIZED_KEY" +then echo "$AUTHORIZED_KEY" >>~/.ssh/authorized_keys +fi +ln -sf /workspace ~/workspace +sudo chown -R 1000:1000 /workspace
