Skip to content

Commit

Permalink
Merge pull request #824 from hugapi/develop
Browse files Browse the repository at this point in the history
2.6.0
  • Loading branch information
timothycrosley authored Aug 29, 2019
2 parents 5d51ab4 + 7367eeb commit 2e240cf
Show file tree
Hide file tree
Showing 25 changed files with 172 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2.5.6
current_version = 2.6.0

[bumpversion:file:.env]

Expand Down
7 changes: 4 additions & 3 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fi

export PROJECT_NAME=$OPEN_PROJECT_NAME
export PROJECT_DIR="$PWD"
export PROJECT_VERSION="2.5.6"
export PROJECT_VERSION="2.6.0"

if [ ! -d "venv" ]; then
if ! hash pyvenv 2>/dev/null; then
Expand Down Expand Up @@ -53,7 +53,7 @@ alias project="root; cd $PROJECT_NAME"
alias tests="root; cd tests"
alias examples="root; cd examples"
alias requirements="root; cd requirements"
alias test="_test"
alias run_tests="_test"


function open {
Expand All @@ -64,7 +64,8 @@ function open {

function clean {
(root
isort hug/*.py setup.py tests/*.py)
isort hug/*.py setup.py tests/*.py
black -l 100 hug)
}


Expand Down
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tidelift: "pypi/hug"
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ matrix:
sudo: required
python: 3.7
env: TOXENV=py37-isort
- os: linux
sudo: required
python: 3.7
env: TOXENV=py37-safety
- os: linux
sudo: required
python: pypy3.5-6.0
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ Ideally, within a virtual environment.

Changelog
=========
### 2.6.0 - August 29, 2019
- Improved CLI multiple behaviour with empty defaults
- Improved CLI type output for built-in types
- Improved MultiCLI base documentation

### 2.5.6 - June 20, 2019
- Fixed issue #815: map_params() causes api documentation to lose param type information
- Improved project testing: restoring 100% coverage
Expand Down
5 changes: 2 additions & 3 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)
MIT License

Copyright (c) 2015 Timothy Edmund Crosley
Copyright (c) 2016 Timothy Crosley

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/0h7ynsqrbaxs7hfm/branch/master?svg=true)](https://ci.appveyor.com/project/TimothyCrosley/hug)
[![Coverage Status](https://coveralls.io/repos/hugapi/hug/badge.svg?branch=develop&service=github)](https://coveralls.io/github/hugapi/hug?branch=master)
[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://pypi.python.org/pypi/hug/)
[![Join the chat at https://gitter.im/timothycrosley/hug](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hugapi/hug?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Join the chat at https://gitter.im/timothycrosley/hug](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/timothycrosley/hug?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

NOTE: For more in-depth documentation visit [hug's website](http://www.hug.rest)

Expand All @@ -25,6 +25,17 @@ As a result of these goals, hug is Python 3+ only and built upon [Falcon's](http

[![HUG Hello World Example](https://raw.github.com/hugapi/hug/develop/artwork/example.gif)](https://github.com/hugapi/hug/blob/develop/examples/hello_world.py)

Supporting hug development
===================
[Get professionally supported hug with the Tidelift Subscription](https://tidelift.com/subscription/pkg/pypi-hug?utm_source=pypi-hug&utm_medium=referral&utm_campaign=readme)

Professional support for hug is available as part of the [Tidelift
Subscription](https://tidelift.com/subscription/pkg/pypi-hug?utm_source=pypi-hug&utm_medium=referral&utm_campaign=readme).
Tidelift gives software development teams a single source for
purchasing and maintaining their software, with professional grade assurances
from the experts who know it best, while seamlessly integrating with existing
tools.

Installing hug
===================

Expand Down Expand Up @@ -418,6 +429,16 @@ bash-4.3# tree
1 directory, 3 files
```

Security contact information
===================

hug takes security and quality seriously. This focus is why we depend only on thoroughly tested components and utilize static analysis tools (such as bandit and safety) to verify the security of our code base.
If you find or encounter any potential security issues, please let us know right away so we can resolve them.

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

Why hug?
===================

Expand Down
18 changes: 18 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Security Policy

hug takes security and quality seriously. This focus is why we depend only on thoroughly tested components and utilize static analysis tools (such as bandit and safety) to verify the security of our code base.
If you find or encounter any potential security issues, please let us know right away so we can resolve them.

## Supported Versions

| Version | Supported |
| ------- | ------------------ |
| 2.5.6 | :white_check_mark: |

Currently, only the latest version of hug will receive security fixes.

## Reporting a Vulnerability

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.
9 changes: 9 additions & 0 deletions examples/cli_multiple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import hug

@hug.cli()
def add(numbers: list=None):
return sum([int(number) for number in numbers])


if __name__ == "__main__":
add.interface.cli()
2 changes: 2 additions & 0 deletions examples/cli_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ class GIT(object):

@hug.object.cli
def push(self, branch="master"):
"""Push the latest to origin"""
return "Pushing {}".format(branch)

@hug.object.cli
def pull(self, branch="master"):
"""Pull in the latest from origin"""
return "Pulling {}".format(branch)


Expand Down
1 change: 1 addition & 0 deletions examples/matplotlib/additional_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
matplotlib==3.1.1
15 changes: 15 additions & 0 deletions examples/matplotlib/plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import io

import hug
from matplotlib import pyplot


@hug.get(output=hug.output_format.png_image)
def plot():
pyplot.plot([1, 2, 3, 4])
pyplot.ylabel('some numbers')

image_output = io.BytesIO()
pyplot.savefig(image_output, format='png')
image_output.seek(0)
return image_output
11 changes: 9 additions & 2 deletions examples/redirects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def internal_redirection_automatic(number_1: int, number_2: int):
"""This will redirect internally to the sum_two_numbers handler
passing along all passed in parameters.
Redirect happens within internally within hug, fully transparent to clients.
This kind of redirect happens internally within hug, fully transparent to clients.
"""
print("Internal Redirection Automatic {}, {}".format(number_1, number_2))
return sum_two_numbers
Expand All @@ -29,7 +29,7 @@ def internal_redirection_manual(number: int):


@hug.post()
def redirect(redirect_type: hug.types.one_of((None, "permanent", "found", "see_other")) = None):
def redirect(redirect_type: hug.types.one_of(("permanent", "found", "see_other")) = None):
"""Hug also fully supports classical HTTP redirects,
providing built in convenience functions for the most common types.
"""
Expand All @@ -38,3 +38,10 @@ def redirect(redirect_type: hug.types.one_of((None, "permanent", "found", "see_o
hug.redirect.to("/sum_two_numbers")
else:
getattr(hug.redirect, redirect_type)("/sum_two_numbers")


@hug.post()
def redirect_set_variables(number: int):
"""You can also do some manual parameter setting with HTTP based redirects"""
print("HTTP Redirect set variables {}".format(number))
hug.redirect.to("/sum_two_numbers?number_1={0}&number_2={0}".format(number))
2 changes: 1 addition & 1 deletion hug/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
"""
from __future__ import absolute_import

current = "2.5.6"
current = "2.6.0"
11 changes: 8 additions & 3 deletions hug/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,14 @@ def output_format(self, formatter):
self._output_format = formatter

def __str__(self):
return "{0}\n\nAvailable Commands:{1}\n".format(
self.api.doc or self.api.name, "\n\n\t- " + "\n\t- ".join(self.commands.keys())
)
output = "{0}\n\nAvailable Commands:\n\n".format(self.api.doc or self.api.name)
for command_name, command in self.commands.items():
command_string = " - {}{}".format(
command_name, ": " + str(command).replace("\n", " ") if str(command) else ""
)
output += command_string[:77] + "..." if len(command_string) > 80 else command_string
output += "\n"
return output


class ModuleSingleton(type):
Expand Down
32 changes: 24 additions & 8 deletions hug/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
text,
)

DOC_TYPE_MAP = {str: "String", bool: "Boolean", list: "Multiple", int: "Integer", float: "Float"}


def _doc(kind):
return DOC_TYPE_MAP.get(kind, kind.__doc__)


def asyncio_call(function, *args, **kwargs):
loop = asyncio.get_event_loop()
Expand Down Expand Up @@ -227,7 +233,7 @@ def __init__(self, route, function):
self.output_doc = self.transform.__doc__
elif self.transform or self.interface.transform:
output_doc = self.transform or self.interface.transform
self.output_doc = output_doc if type(output_doc) is str else output_doc.__doc__
self.output_doc = output_doc if type(output_doc) is str else _doc(output_doc)

self.raise_on_invalid = route.get("raise_on_invalid", False)
if "on_invalid" in route:
Expand Down Expand Up @@ -310,7 +316,7 @@ def documentation(self, add_to=None):
for requirement in self.requires
]
doc["outputs"] = OrderedDict()
doc["outputs"]["format"] = self.outputs.__doc__
doc["outputs"]["format"] = _doc(self.outputs)
doc["outputs"]["content_type"] = self.outputs.content_type
parameters = [
param
Expand All @@ -329,7 +335,7 @@ def documentation(self, add_to=None):
continue

input_definition = inputs.setdefault(argument, OrderedDict())
input_definition["type"] = kind if isinstance(kind, str) else kind.__doc__
input_definition["type"] = kind if isinstance(kind, str) else _doc(kind)
default = self.defaults.get(argument, None)
if default is not None:
input_definition["default"] = default
Expand Down Expand Up @@ -505,7 +511,7 @@ def exit(self, status=0, message=None):
if option in self.interface.input_transformations:
transform = self.interface.input_transformations[option]
kwargs["type"] = transform
kwargs["help"] = transform.__doc__
kwargs["help"] = _doc(transform)
if transform in (list, tuple) or isinstance(transform, types.Multiple):
kwargs["action"] = "append"
kwargs["type"] = Text()
Expand All @@ -526,7 +532,7 @@ def exit(self, status=0, message=None):
kwargs["action"] = "store_true"
kwargs.pop("type", None)
elif kwargs.get("action", None) == "store_true":
kwargs.pop("action", None) == "store_true"
kwargs.pop("action", None)

if option == self.additional_options:
kwargs["nargs"] = "*"
Expand Down Expand Up @@ -559,6 +565,9 @@ def output(self, data, context):
sys.stdout.buffer.write(b"\n")
return data

def __str__(self):
return self.parser.description or ""

def __call__(self):
"""Calls the wrapped function through the lens of a CLI ran command"""
context = self.api.context_factory(api=self.api, argparse=self.parser, interface=self)
Expand Down Expand Up @@ -588,9 +597,16 @@ def exit_callback(message):

for field, type_handler in self.reaffirm_types.items():
if field in pass_to_function:
pass_to_function[field] = self.initialize_handler(
type_handler, pass_to_function[field], context=context
)
if not pass_to_function[field] and type_handler in (
list,
tuple,
hug.types.Multiple,
):
pass_to_function[field] = type_handler(())
else:
pass_to_function[field] = self.initialize_handler(
type_handler, pass_to_function[field], context=context
)

if getattr(self, "validate_function", False):
errors = self.validate_function(pass_to_function)
Expand Down
17 changes: 8 additions & 9 deletions requirements/build_common.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
-r common.txt
flake8==3.3.0
pytest-cov==2.4.0
pytest==4.3.1
python-coveralls==2.9.0
wheel==0.29.0
PyJWT==1.4.2
pytest-xdist==1.14.0
numpy==1.15.4

flake8==3.5.0
pytest-cov==2.7.1
pytest==4.6.3
python-coveralls==2.9.2
wheel==0.33.4
PyJWT==1.7.1
pytest-xdist==1.29.0
numpy<1.16
3 changes: 2 additions & 1 deletion requirements/build_style_tools.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ isort==4.3.20
pep8-naming==0.8.2
flake8-bugbear==19.3.0
vulture==1.0
bandit==1.6.0
bandit==1.6.1
safety==1.8.5
10 changes: 5 additions & 5 deletions requirements/build_windows.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
-r common.txt
flake8==3.3.0
isort==4.2.5
flake8==3.7.7
isort==4.3.20
marshmallow==2.18.1
pytest==4.4.2
wheel==0.29.0
pytest-xdist==1.28.0
pytest==4.6.3
wheel==0.33.4
pytest-xdist==1.29.0
numpy==1.15.4
2 changes: 1 addition & 1 deletion requirements/common.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
falcon==2.0.0
requests==2.21.0
requests==2.22.0
20 changes: 10 additions & 10 deletions requirements/development.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
bumpversion==0.5.3
Cython==0.29.6
Cython==0.29.10
-r common.txt
flake8==3.5.0
ipython==6.2.1
isort==4.3.18
pytest-cov==2.5.1
pytest==4.3.1
python-coveralls==2.9.1
tox==2.9.1
flake8==3.7.7
ipython==7.5.0
isort==4.3.20
pytest-cov==2.7.1
pytest==4.6.3
python-coveralls==2.9.2
tox==3.12.1
wheel
pytest-xdist==1.20.1
pytest-xdist==1.29.0
marshmallow==2.18.1
ujson==1.35
numpy==1.15.4
numpy<1.16

Loading

0 comments on commit 2e240cf

Please sign in to comment.