"Fossies" - the Fresh Open Source Software Archive

Member "http-prompt-2.1.0/http_prompt/cli.py" (5 Mar 2021, 5557 Bytes) of package /linux/www/http-prompt-2.1.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "cli.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.0.0_vs_2.1.0.

    1 from __future__ import unicode_literals
    2 
    3 import json
    4 from http.cookies import SimpleCookie
    5 from urllib.request import pathname2url, urlopen
    6 
    7 import yaml
    8 import os
    9 import re
   10 import sys
   11 
   12 import click
   13 
   14 from httpie.plugins import FormatterPlugin  # noqa, avoid cyclic import
   15 from httpie.output.formatters.colors import Solarized256Style
   16 from prompt_toolkit import prompt, AbortAction
   17 from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
   18 from prompt_toolkit.history import FileHistory
   19 from prompt_toolkit.layout.lexers import PygmentsLexer
   20 from prompt_toolkit.styles.from_pygments import style_from_pygments
   21 from pygments.styles import get_style_by_name
   22 from pygments.util import ClassNotFound
   23 
   24 from . import __version__
   25 from . import config
   26 from .completer import HttpPromptCompleter
   27 from .context import Context
   28 from .contextio import load_context, save_context
   29 from .execution import execute
   30 from .lexer import HttpPromptLexer
   31 from .utils import smart_quote
   32 from .xdg import get_data_dir
   33 
   34 
   35 # XXX: http://click.pocoo.org/python3/#unicode-literals
   36 click.disable_unicode_literals_warning = True
   37 
   38 
   39 def fix_incomplete_url(url):
   40     if url.startswith(('s://', '://')):
   41         url = 'http' + url
   42     elif url.startswith('//'):
   43         url = 'http:' + url
   44     elif not url.startswith(('http://', 'https://')):
   45         url = 'http://' + url
   46     return url
   47 
   48 
   49 def update_cookies(base_value, cookies):
   50     cookie = SimpleCookie(base_value)
   51     for k, v in cookies.items():
   52         cookie[k] = v
   53     return str(cookie.output(header='', sep=';').lstrip())
   54 
   55 
   56 class ExecutionListener(object):
   57 
   58     def __init__(self, cfg):
   59         self.cfg = cfg
   60 
   61     def context_changed(self, context):
   62         # Dump the current context to HTTP Prompt format
   63         save_context(context)
   64 
   65     def response_returned(self, context, response):
   66         if not response.cookies:
   67             return
   68 
   69         cookie_pref = self.cfg.get('set_cookies') or 'auto'
   70         if cookie_pref == 'auto' or (
   71                 cookie_pref == 'ask' and
   72                 click.confirm("Cookies incoming! Do you want to set them?")):
   73             existing_cookie = context.headers.get('Cookie')
   74             new_cookie = update_cookies(existing_cookie, response.cookies)
   75             context.headers['Cookie'] = new_cookie
   76             click.secho('Cookies set: %s' % new_cookie)
   77 
   78 
   79 def normalize_url(ctx, param, value):
   80     if value:
   81         if not re.search(r'^\w+://', value):
   82             value = 'file:' + pathname2url(os.path.abspath(value))
   83         return value
   84     return None
   85 
   86 
   87 @click.command(context_settings=dict(
   88     ignore_unknown_options=True,
   89 ))
   90 @click.option('--spec', help="OpenAPI/Swagger specification file.",
   91               callback=normalize_url)
   92 @click.option('--env', help="Environment file to preload.",
   93               type=click.Path(exists=True))
   94 @click.argument('url', default='')
   95 @click.argument('http_options', nargs=-1, type=click.UNPROCESSED)
   96 @click.version_option(message='%(version)s')
   97 def cli(spec, env, url, http_options):
   98     click.echo('Version: %s' % __version__)
   99 
  100     copied, config_path = config.initialize()
  101     if copied:
  102         click.echo('Config file not found. Initialized a new one: %s' %
  103                    config_path)
  104 
  105     cfg = config.load()
  106 
  107     # Override pager/less options
  108     os.environ['PAGER'] = cfg['pager']
  109     os.environ['LESS'] = '-RXF'
  110 
  111     if spec:
  112         f = urlopen(spec)
  113         try:
  114             content = f.read().decode('utf-8')
  115             try:
  116                 spec = json.loads(content)
  117             except json.JSONDecodeError:
  118                 try:
  119                     spec = yaml.load(content)
  120                 except yaml.YAMLError:
  121                     click.secho("Warning: Specification file '%s' is neither valid JSON nor YAML" %
  122                                 spec, err=True, fg='red')
  123                     spec = None
  124         finally:
  125             f.close()
  126 
  127     if url:
  128         url = fix_incomplete_url(url)
  129     context = Context(url, spec=spec)
  130 
  131     output_style = cfg.get('output_style')
  132     if output_style:
  133         context.options['--style'] = output_style
  134 
  135     # For prompt-toolkit
  136     history = FileHistory(os.path.join(get_data_dir(), 'history'))
  137     lexer = PygmentsLexer(HttpPromptLexer)
  138     completer = HttpPromptCompleter(context)
  139     try:
  140         style_class = get_style_by_name(cfg['command_style'])
  141     except ClassNotFound:
  142         style_class = Solarized256Style
  143     style = style_from_pygments(style_class)
  144 
  145     listener = ExecutionListener(cfg)
  146 
  147     if len(sys.argv) == 1:
  148         # load previous context if nothing defined
  149         load_context(context)
  150     else:
  151         if env:
  152             load_context(context, env)
  153             if url:
  154                 # Overwrite the env url if not default
  155                 context.url = url
  156 
  157         if http_options:
  158             # Execute HTTPie options from CLI (can overwrite env file values)
  159             http_options = [smart_quote(a) for a in http_options]
  160             execute(' '.join(http_options), context, listener=listener)
  161 
  162     while True:
  163         try:
  164             text = prompt('%s> ' % context.url, completer=completer,
  165                           lexer=lexer, style=style, history=history,
  166                           auto_suggest=AutoSuggestFromHistory(),
  167                           on_abort=AbortAction.RETRY, vi_mode=cfg['vi'])
  168         except EOFError:
  169             break  # Control-D pressed
  170         else:
  171             execute(text, context, listener=listener, style=style_class)
  172             if context.should_exit:
  173                 break
  174 
  175     click.echo("Goodbye!")