From 75250e78fb3a3eb99399a67cdd85b12a250783a7 Mon Sep 17 00:00:00 2001 From: marwandr Date: Thu, 27 Jun 2024 22:05:33 +0200 Subject: [PATCH 1/4] Added tests for local router, covers 5 functions --- tests/test_local_router.py | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tests/test_local_router.py diff --git a/tests/test_local_router.py b/tests/test_local_router.py new file mode 100644 index 00000000..6457a2eb --- /dev/null +++ b/tests/test_local_router.py @@ -0,0 +1,90 @@ +"""This is the test module for the Localrouter class, +made by Marwan Amrhar & Yahia Noeman & Ayoub Bouazza & Sajeed Bouzziane. +It covers the functions: + Localrouter.init + Localrouter.directives + Localrouter.validate + Localrouter.version + Localrouter.call""" + +import unittest +from unittest.mock import patch +import hug + +from hug.routing import LocalRouter + +class TestLocalRouter(unittest.TestCase): + + def setUp(self): + self.router = LocalRouter(api="test_api") + + ## localrouter.init + def test_initialization_with_defaults(self): + """Test LocalRouter initialization with default parameters""" + instance = LocalRouter() + self.assertNotIn("version", instance.route) + self.assertNotIn("skip_directives", instance.route) + self.assertNotIn("skip_validation", instance.route) + + def test_initialization_with_version(self): + """Test LocalRouter initialization with version set""" + instance = LocalRouter(version=1) + self.assertEqual(instance.route.get("version"), 1) + self.assertNotIn("skip_directives", instance.route) + self.assertNotIn("skip_validation", instance.route) + + def test_initialization_with_skip_directives(self): + """Test LocalRouter initialization with directives=False""" + instance = LocalRouter(directives=False) + self.assertNotIn("version", instance.route) + self.assertTrue(instance.route.get("skip_directives")) + + def test_initialization_with_skip_validation(self): + """Test LocalRouter initialization with validate=False""" + instance = LocalRouter(validate=False) + self.assertNotIn("version", instance.route) + self.assertNotIn("skip_directives", instance.route) + self.assertTrue(instance.route.get("skip_validation")) + + def test_initialization_with_all_parameters(self): + """Test LocalRouter initialization with all parameters""" + instance = LocalRouter(directives=False, validate=False, version=1) + self.assertEqual(instance.route.get("version"), 1) + self.assertTrue(instance.route.get("skip_directives")) + self.assertTrue(instance.route.get("skip_validation")) + + ## localrouter.directives + def test_directives_method(self): + """Test LocalRouter directives method""" + result = self.router.directives(use=False) + self.assertIsInstance(result, LocalRouter) + self.assertIn("skip_directives", result.route) + self.assertTrue(result.route["skip_directives"]) + + ## localrouter.validate + def test_validate_method(self): + """Test LocalRouter validate method""" + result = self.router.validate(enforce=False) + self.assertIsInstance(result, LocalRouter) + self.assertIn("skip_validation", result.route) + self.assertTrue(result.route["skip_validation"]) + + ## localrouter.version + def test_version_method(self): + """Test LocalRouter version method""" + result = self.router.version(supported=2) + self.assertIsInstance(result, LocalRouter) + self.assertEqual(result.route["version"], 2) + + ## localrouter.call + def test_call_method(self): + """Test LocalRouter __call__ method""" + def mock_function(): + pass + with patch('hug.interface.Local') as mock_local: + self.router(mock_function) + mock_local.assert_called_once_with(self.router.route, mock_function) + +if __name__ == '__main__': + unittest.main() + \ No newline at end of file From 295109dabcd26029b3f44f0523112d70cbfe5dc1 Mon Sep 17 00:00:00 2001 From: marwandr Date: Thu, 27 Jun 2024 22:06:58 +0200 Subject: [PATCH 2/4] Added tests for the initialization of the API, covers 2 functions --- tests/test_api2.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/test_api2.py diff --git a/tests/test_api2.py b/tests/test_api2.py new file mode 100644 index 00000000..f352d918 --- /dev/null +++ b/tests/test_api2.py @@ -0,0 +1,81 @@ +"""This is the test module for the Localrouter class, +made by Marwan Amrhar & Yahia Noeman & Ayoub Bouazza & Sajeed Bouzziane. +It covers the functions: + API.__init__ + ModuleSingleton.__call__""" + +import unittest +from hug.api import API + +class MockModule: + __name__ = "mock_module" + __doc__ = "This is a mock module" + +class TestAPIInit(unittest.TestCase): + def test_api_init_with_module(self): + """Test API initialization with module""" + module = MockModule() + api = API(module=module) + + self.assertEqual(api.module, module) + self.assertEqual(api.name, "mock_module") + self.assertEqual(api.doc, "This is a mock module") + self.assertFalse(api.started) + self.assertFalse(api.cli_error_exit_codes) + self.assertFalse(api.future) + + def test_api_init_without_module(self): + """Test API initialization without module""" + name = "test_name" + doc = "This is a test doc" + cli_error_exit_codes = True + future = True + + api = API(name=name, doc=doc, cli_error_exit_codes=cli_error_exit_codes, future=future) + + self.assertIsNone(api.module) + self.assertEqual(api.name, name) + self.assertEqual(api.doc, doc) + self.assertFalse(api.started) + self.assertTrue(api.cli_error_exit_codes) + self.assertTrue(api.future) + + def test_api_init_with_partial_module_attributes(self): + """Test API initialization with module and partial attributes""" + module = MockModule() + name = "custom_name" + doc = "Custom documentation" + + api = API(module=module, name=name, doc=doc) + + self.assertEqual(api.module, module) + self.assertEqual(api.name, name) + self.assertEqual(api.doc, doc) + self.assertFalse(api.started) + self.assertFalse(api.cli_error_exit_codes) + self.assertFalse(api.future) + + def test_api_init_with_empty_module(self): + """Test API initialization with empty module attributes""" + class EmptyModule: + __name__ = None + __doc__ = None + + module = EmptyModule() + api = API(module=module) + + self.assertEqual(api.module, module) + self.assertEqual(api.name, "") + self.assertEqual(api.doc, "") + self.assertFalse(api.started) + self.assertFalse(api.cli_error_exit_codes) + self.assertFalse(api.future) + +def test_suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestAPIInit)) + return suite + +if __name__ == "__main__": + runner = unittest.TextTestRunner() + runner.run(test_suite()) From 84d03b6a2868ff4d8ffa193dd625e0ae724372f7 Mon Sep 17 00:00:00 2001 From: marwandr Date: Thu, 27 Jun 2024 22:08:02 +0200 Subject: [PATCH 3/4] Added tests for the Router, covers 1 function --- tests/test_router.py | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/test_router.py diff --git a/tests/test_router.py b/tests/test_router.py new file mode 100644 index 00000000..977b9ae3 --- /dev/null +++ b/tests/test_router.py @@ -0,0 +1,64 @@ +"""This is the test module for the Router class, +made by Marwan Amrhar & Yahia Noeman & Ayoub Bouazza & Sajeed Bouzziane +It covers the function: + Router.__init__""" + +import unittest +from hug.routing import Router + +class TestRouterInit(unittest.TestCase): + def test_router_init_with_all_parameters(self): + """Test Router initialization with all parameters""" + transform = lambda x: x + output = "output_format" + validate = "validate_function" + api = "api_object" + requires = ("requirement1", "requirement2") + map_params = {"param1": "mapped_param1"} + args = ["arg1", "arg2"] + + router = Router( + transform=transform, + output=output, + validate=validate, + api=api, + requires=requires, + map_params=map_params, + args=args, + ) + + self.assertEqual(router.route["transform"], transform) + self.assertEqual(router.route["output"], output) + self.assertEqual(router.route["validate"], validate) + self.assertEqual(router.route["api"], api) + self.assertEqual(router.route["requires"], requires) + self.assertEqual(router.route["map_params"], map_params) + self.assertEqual(router.route["args"], args) + + def test_router_init_with_default_parameters(self): + """Test Router initialization with default parameters""" + router = Router() + + self.assertNotIn("transform", router.route) + self.assertNotIn("output", router.route) + self.assertNotIn("validate", router.route) + self.assertNotIn("api", router.route) + self.assertEqual(router.route.get("requires", ()), ()) + self.assertNotIn("map_params", router.route) + self.assertNotIn("args", router.route) + + def test_router_init_with_single_requirement(self): + """Test Router initialization with a single requirement""" + router = Router(requires="requirement1") + + self.assertEqual(router.route["requires"], ("requirement1",)) + +def test_suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestRouterInit)) + return suite + +if __name__ == "__main__": + runner = unittest.TextTestRunner() + runner.run(test_suite()) + \ No newline at end of file From 8f75b693e778f02c1daaabddeee6b300198390f9 Mon Sep 17 00:00:00 2001 From: marwandr Date: Thu, 27 Jun 2024 23:08:54 +0200 Subject: [PATCH 4/4] Created readme file --- README.md | 459 ++++-------------- hug/output_format.py | 2 +- readme_img/AFTER_UNITTESTS.png | Bin 0 -> 29028 bytes readme_img/BEFORE_UNITTESTS.png | Bin 0 -> 29395 bytes readme_img/after/apiinit_after.png | Bin 0 -> 2846 bytes readme_img/after/localroutercall_after.png | Bin 0 -> 8378 bytes .../after/localrouterdirectives_after.png | Bin 0 -> 8701 bytes readme_img/after/localrouterinit_after.png | Bin 0 -> 8237 bytes .../after/localroutervalidate_after.png | Bin 0 -> 8602 bytes readme_img/after/localrouterversion_after.png | Bin 0 -> 8556 bytes .../after/modulesingletoncall_after.png | Bin 0 -> 6934 bytes readme_img/after/routerinit_after.png | Bin 0 -> 6010 bytes readme_img/before/apiinit_before.png | Bin 0 -> 2733 bytes readme_img/before/localroutercall_before.png | Bin 0 -> 8976 bytes .../before/localrouterdirectives_before.png | Bin 0 -> 9050 bytes readme_img/before/localrouterinit_before.png | Bin 0 -> 8209 bytes .../before/localroutervalidate_before.png | Bin 0 -> 8623 bytes .../before/localrouterversion_before.png | Bin 0 -> 8474 bytes .../before/modulesingletoncall_before.png | Bin 0 -> 6927 bytes readme_img/before/routerinit_before.png | Bin 0 -> 6002 bytes 20 files changed, 85 insertions(+), 376 deletions(-) create mode 100644 readme_img/AFTER_UNITTESTS.png create mode 100644 readme_img/BEFORE_UNITTESTS.png create mode 100644 readme_img/after/apiinit_after.png create mode 100644 readme_img/after/localroutercall_after.png create mode 100644 readme_img/after/localrouterdirectives_after.png create mode 100644 readme_img/after/localrouterinit_after.png create mode 100644 readme_img/after/localroutervalidate_after.png create mode 100644 readme_img/after/localrouterversion_after.png create mode 100644 readme_img/after/modulesingletoncall_after.png create mode 100644 readme_img/after/routerinit_after.png create mode 100644 readme_img/before/apiinit_before.png create mode 100644 readme_img/before/localroutercall_before.png create mode 100644 readme_img/before/localrouterdirectives_before.png create mode 100644 readme_img/before/localrouterinit_before.png create mode 100644 readme_img/before/localroutervalidate_before.png create mode 100644 readme_img/before/localrouterversion_before.png create mode 100644 readme_img/before/modulesingletoncall_before.png create mode 100644 readme_img/before/routerinit_before.png diff --git a/README.md b/README.md index 408249a7..f725d643 100644 --- a/README.md +++ b/README.md @@ -1,454 +1,163 @@ -[![HUG](https://raw.github.com/hugapi/hug/develop/artwork/logo.png)](http://hug.rest) -=================== +# Report for Assignment 1 -[![PyPI version](https://badge.fury.io/py/hug.svg)](http://badge.fury.io/py/hug) -[![Build Status](https://travis-ci.org/hugapi/hug.svg?branch=develop)](https://travis-ci.org/hugapi/hug) -[![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/timothycrosley/hug?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +## Project chosen -_________________ +Name: Hug by Hug API -[Read Latest Documentation](https://hugapi.github.io/hug/) - [Browse GitHub Code Repository](https://github.com/hugapi/hug) -_________________ +URL: https://github.com/hugapi/hug/ -hug aims to make developing Python driven APIs as simple as possible, but no simpler. As a result, it drastically simplifies Python API development. +Number of lines of code and the tool used to count it: 10.8 KLOC - Lizzard -hug's Design Objectives: +Programming language: Python -- Make developing a Python driven API as succinct as a written definition. -- The framework should encourage code that self-documents. -- It should be fast. A developer should never feel the need to look somewhere else for performance reasons. -- Writing tests for APIs written on-top of hug should be easy and intuitive. -- Magic done once, in an API framework, is better than pushing the problem set to the user of the API framework. -- Be the basis for next generation Python APIs, embracing the latest technology. +## Coverage measurement -As a result of these goals, hug is Python 3+ only and built upon [Falcon's](https://github.com/falconry/falcon) high performance HTTP library +### Existing tool -[![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) +We ran coverage.py ; we tested it within the project root to see what functions needed to be improved and then selected 8 functions to make/enhance tests for. -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) +COVERAGE BEFORE UNITTESTS -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. +### Your own coverage tool -Installing hug -=================== +### Individual tests -Installing hug is as simple as: +#### Marwan Amrhar, -```bash -pip3 install hug --upgrade -``` +--- -Ideally, within a [virtual environment](http://docs.python-guide.org/en/latest/dev/virtualenvs/). +- `Localrouter.__init__` -Getting Started -=================== +Before: -Build an example API with a simple endpoint in just a few lines. + -```py -# filename: happy_birthday.py -"""A basic (single function) API written using hug""" -import hug +After: + -@hug.get('/happy_birthday') -def happy_birthday(name, age:hug.types.number=1): -    """Says happy birthday to a user""" - return "Happy {age} Birthday {name}!".format(**locals()) -``` +--- -To run, from the command line type: +- `Localrouter.directives` -```bash -hug -f happy_birthday.py -``` +Before: -You can access the example in your browser at: -`localhost:8000/happy_birthday?name=hug&age=1`. Then check out the -documentation for your API at `localhost:8000/documentation` + -Parameters can also be encoded in the URL (check -out [`happy_birthday.py`](examples/happy_birthday.py) for the whole -example). +After: -```py -@hug.get('/greet/{event}') -def greet(event: str): - """Greets appropriately (from http://blog.ketchum.com/how-to-write-10-common-holiday-greetings/) """ - greetings = "Happy" - if event == "Christmas": - greetings = "Merry" - if event == "Kwanzaa": - greetings = "Joyous" - if event == "wishes": - greetings = "Warm" + - return "{greetings} {event}!".format(**locals()) -``` +- Fixed a bug with the use of a deprecated function (numpy.unicode -> numpy.str\_); -Which, once you are running the server as above, you can use this way: +#### Sajeed Bouziane, -``` -curl http://localhost:8000/greet/wishes -"Warm wishes!" -``` +--- -Versioning with hug -=================== +- `Localrouter.validate` -```py -# filename: versioning_example.py -"""A simple example of a hug API call with versioning""" -import hug +Before: -@hug.get('/echo', versions=1) -def echo(text): - return text + +After: -@hug.get('/echo', versions=range(2, 5)) -def echo(text): - return "Echo: {text}".format(**locals()) -``` + -To run the example: +--- -```bash -hug -f versioning_example.py -``` +- `Localrouter.version` -Then you can access the example from `localhost:8000/v1/echo?text=Hi` / `localhost:8000/v2/echo?text=Hi` Or access the documentation for your API from `localhost:8000` +Before: -Note: versioning in hug automatically supports both the version header as well as direct URL based specification. + -Testing hug APIs -=================== +After: -hug's `http` method decorators don't modify your original functions. This makes testing hug APIs as simple as testing any other Python functions. Additionally, this means interacting with your API functions in other Python code is as straight forward as calling Python only API functions. hug makes it easy to test the full Python stack of your API by using the `hug.test` module: + -```python -import hug -import happy_birthday +#### Ayoub Bouazza, -hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25}) # Returns a Response object -``` +--- -You can use this `Response` object for test assertions (check -out [`test_happy_birthday.py`](examples/test_happy_birthday.py) ): +- `Localrouter.__call__` -```python -def tests_happy_birthday(): - response = hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25}) - assert response.status == HTTP_200 - assert response.data is not None -``` +Before: -Running hug with other WSGI based servers -=================== + -hug exposes a `__hug_wsgi__` magic method on every API module automatically. Running your hug based API on any standard wsgi server should be as simple as pointing it to `module_name`: `__hug_wsgi__`. +After: -For Example: + -```bash -uwsgi --http 0.0.0.0:8000 --wsgi-file examples/hello_world.py --callable __hug_wsgi__ -``` +--- -To run the hello world hug example API. +- `Router.__init__` -Building Blocks of a hug API -=================== +Before: -When building an API using the hug framework you'll use the following concepts: + -**METHOD Decorators** `get`, `post`, `update`, etc HTTP method decorators that expose your Python function as an API while keeping your Python method unchanged +After: -```py -@hug.get() # <- Is the hug METHOD decorator -def hello_world(): - return "Hello" -``` + -hug uses the structure of the function you decorate to automatically generate documentation for users of your API. hug always passes a request, response, and api_version variable to your function if they are defined params in your function definition. +#### Yahia Noeman, -**Type Annotations** functions that optionally are attached to your methods arguments to specify how the argument is validated and converted into a Python type +--- -```py -@hug.get() -def math(number_1:int, number_2:int): #The :int after both arguments is the Type Annotation - return number_1 + number_2 -``` +- `API.__init__` -Type annotations also feed into `hug`'s automatic documentation -generation to let users of your API know what data to supply. +Before: -**Directives** functions that get executed with the request / response data based on being requested as an argument in your api_function. -These apply as input parameters only, and can not be applied currently as output formats or transformations. + -```py -@hug.get() -def test_time(hug_timer): - return {'time_taken': float(hug_timer)} -``` +After: -Directives may be accessed via an argument with a `hug_` prefix, or by using Python 3 type annotations. The latter is the more modern approach, and is recommended. Directives declared in a module can be accessed by using their fully qualified name as the type annotation (ex: `module.directive_name`). + -Aside from the obvious input transformation use case, directives can be used to pipe data into your API functions, even if they are not present in the request query string, POST body, etc. For an example of how to use directives in this way, see the authentication example in the examples folder. +--- -Adding your own directives is straight forward: +- `ModuleSingleton.__call__` -```py -@hug.directive() -def square(value=1, **kwargs): - '''Returns passed in parameter multiplied by itself''' - return value * value +Before: -@hug.get() -@hug.local() -def tester(value: square=10): - return value + -tester() == 100 -``` +After: -For completeness, here is an example of accessing the directive via the magic name approach: + -```py -@hug.directive() -def multiply(value=1, **kwargs): - '''Returns passed in parameter multiplied by itself''' - return value * value +### Overall -@hug.get() -@hug.local() -def tester(hug_multiply=10): - return hug_multiply +--- -tester() == 100 -``` +This is the overall coverage after implementing our unittests: -**Output Formatters** a function that takes the output of your API function and formats it for transport to the user of the API. +COVERAGE AFTER UNITTESTS -```py -@hug.default_output_format() -def my_output_formatter(data): - return "STRING:{0}".format(data) +As we can see the coverage of the files api.py, routing.py have been increased, these also contained the functions that we covered. -@hug.get(output=hug.output_format.json) -def hello(): - return {'hello': 'world'} -``` +## Statement of individual contributions -as shown, you can easily change the output format for both an entire API as well as an individual API call +First we all together did the lizzard count and overall coverage and figured out how to exactly make a unit test and experimented around with Localrouter since we discovered that this was barely/not tested. -**Input Formatters** a function that takes the body of data given from a user of your API and formats it for handling. +Marwan Amrhar: -```py -@hug.default_input_format("application/json") -def my_input_formatter(data): - return ('Results', hug.input_format.json(data)) -``` +- Figured out a bug which didn't allow us to run the coverage; +- Figured out how to make unit tests in localrouter and made 2 unit tests in there. -Input formatters are mapped based on the `content_type` of the request data, and only perform basic parsing. More detailed parsing should be done by the Type Annotations present on your `api_function` +Sajeed Bouziane -**Middleware** functions that get called for every request a hug API processes +- Made 2 more unit tests in localrouter after working together with Marwan; +- Helped set-up the readme file. -```py -@hug.request_middleware() -def process_data(request, response): - request.env['SERVER_NAME'] = 'changed' +Ayoub Bouazza: -@hug.response_middleware() -def process_data(request, response, resource): - response.set_header('MyHeader', 'Value') -``` +- Made a final unit test in localrouter; +- Made a unit test for the initialization of the Router class. -You can also easily add any Falcon style middleware using: +Yahia Nouman -```py -__hug__.http.add_middleware(MiddlewareObject()) -``` - -**Parameter mapping** can be used to override inferred parameter names, eg. for reserved keywords: - -```py -import marshmallow.fields as fields -... - -@hug.get('/foo', map_params={'from': 'from_date'}) # API call uses 'from' -def get_foo_by_date(from_date: fields.DateTime()): - return find_foo(from_date) -``` - -Input formatters are mapped based on the `content_type` of the request data, and only perform basic parsing. More detailed parsing should be done by the Type Annotations present on your `api_function` - -Splitting APIs over multiple files -=================== - -hug enables you to organize large projects in any manner you see fit. You can import any module that contains hug decorated functions (request handling, directives, type handlers, etc) and extend your base API with that module. - -For example: - -`something.py` - -```py -import hug - -@hug.get('/') -def say_hi(): - return 'hello from something' -``` - -Can be imported into the main API file: - -`__init__.py` - -```py -import hug -from . import something - -@hug.get('/') -def say_hi(): - return "Hi from root" - -@hug.extend_api('/something') -def something_api(): - return [something] -``` - -Or alternatively - for cases like this - where only one module is being included per a URL route: - -```py -#alternatively -hug.API(__name__).extend(something, '/something') -``` - -Configuring hug 404 -=================== - -By default, hug returns an auto generated API spec when a user tries to access an endpoint that isn't defined. If you would not like to return this spec you can turn off 404 documentation: - -From the command line application: - -```bash -hug -nd -f {file} #nd flag tells hug not to generate documentation on 404 -``` - -Additionally, you can easily create a custom 404 handler using the `hug.not_found` decorator: - -```py -@hug.not_found() -def not_found_handler(): - return "Not Found" -``` - -This decorator works in the same manner as the hug HTTP method decorators, and is even version aware: - -```py -@hug.not_found(versions=1) -def not_found_handler(): - return "" - -@hug.not_found(versions=2) -def not_found_handler(): - return "Not Found" -``` - -Asyncio support -=============== - -When using the `get` and `cli` method decorator on coroutines, hug will schedule -the execution of the coroutine. - -Using asyncio coroutine decorator - -```py -@hug.get() -@asyncio.coroutine -def hello_world(): - return "Hello" -``` - -Using Python 3.5 async keyword. - -```py -@hug.get() -async def hello_world(): - return "Hello" -``` - -NOTE: Hug is running on top Falcon which is not an asynchronous server. Even if using -asyncio, requests will still be processed synchronously. - -Using Docker -=================== - -If you like to develop in Docker and keep your system clean, you can do that but you'll need to first install [Docker Compose](https://docs.docker.com/compose/install/). - -Once you've done that, you'll need to `cd` into the `docker` directory and run the web server (Gunicorn) specified in `./docker/gunicorn/Dockerfile`, after which you can preview the output of your API in the browser on your host machine. - -```bash -$ cd ./docker -# This will run Gunicorn on port 8000 of the Docker container. -$ docker-compose up gunicorn - -# From the host machine, find your Dockers IP address. -# For Windows & Mac: -$ docker-machine ip default - -# For Linux: -$ ifconfig docker0 | grep 'inet' | cut -d: -f2 | awk '{ print $1}' | head -n1 -``` - -By default, the IP is 172.17.0.1. Assuming that's the IP you see, as well, you would then go to `http://172.17.0.1:8000/` in your browser to view your API. - -You can also log into a Docker container that you can consider your work space. This workspace has Python and Pip installed so you can use those tools within Docker. If you need to test the CLI interface, for example, you would use this. - -```bash -$ docker-compose run workspace bash -``` - -On your Docker `workspace` container, the `./docker/templates` directory on your host computer is mounted to `/src` in the Docker container. This is specified under `services` > `app` of `./docker/docker-compose.yml`. - -```bash -bash-4.3# cd /src -bash-4.3# tree -. -├── __init__.py -└── handlers - ├── birthday.py - └── hello.py - -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? -=================== - -HUG simply stands for Hopefully Useful Guide. This represents the project's goal to help guide developers into creating well written and intuitive APIs. - --------------------------------------------- - -Thanks and I hope you find *this* hug helpful as you develop your next Python API! - -~Timothy Crosley +- Made a unit tests for the api.py file which covered the initialization of the api +- Made a unit test for the api.py file which covered singleton module call function. diff --git a/hug/output_format.py b/hug/output_format.py index 6e60dfb3..fad76c7c 100644 --- a/hug/output_format.py +++ b/hug/output_format.py @@ -142,7 +142,7 @@ def register_json_converter(function): def numpy_listable(item): return item.tolist() - @json_convert(str, numpy.unicode_) + @json_convert(str, numpy.str_) def numpy_stringable(item): return str(item) diff --git a/readme_img/AFTER_UNITTESTS.png b/readme_img/AFTER_UNITTESTS.png new file mode 100644 index 0000000000000000000000000000000000000000..5fb9e544fe4c649706fa5a72d5d128385d80cb51 GIT binary patch literal 29028 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

BF`;RTbYjeOb&W4@dnjL4LQoUwF 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 HyYT-7aa6*g literal 0 HcmV?d00001 diff --git a/readme_img/BEFORE_UNITTESTS.png b/readme_img/BEFORE_UNITTESTS.png new file mode 100644 index 0000000000000000000000000000000000000000..76e781fc6c24497e967919227616e65661abf67f GIT binary patch literal 29395 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 literal 0 HcmV?d00001 diff --git a/readme_img/after/localroutercall_after.png b/readme_img/after/localroutercall_after.png new file mode 100644 index 0000000000000000000000000000000000000000..a1f9766751573d47dab9238f242454970e497f23 GIT binary patch literal 8378 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 UlK8Zx_HY1@+eSJiHy^$DUuhwC{Qv*} literal 0 HcmV?d00001 diff --git a/readme_img/after/localrouterdirectives_after.png b/readme_img/after/localrouterdirectives_after.png new file mode 100644 index 0000000000000000000000000000000000000000..2b30d8829a19e803c0699ddcd30e5f23bb239369 GIT binary patch literal 8701 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 R{c;+nMplNEf8KlYe*l;dH2(kq literal 0 HcmV?d00001 diff --git a/readme_img/after/localrouterinit_after.png b/readme_img/after/localrouterinit_after.png new file mode 100644 index 0000000000000000000000000000000000000000..7097d11b350c42e8c0d97a9df288cabba6bee5c0 GIT binary patch literal 8237 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

NoFq1Hm^yu7rN0V*jrO4DJjDOSib* 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 literal 0 HcmV?d00001 diff --git a/readme_img/before/routerinit_before.png b/readme_img/before/routerinit_before.png new file mode 100644 index 0000000000000000000000000000000000000000..4b9d97123eed14b31bfc663850b37ac00ae48bee GIT binary patch literal 6002 zcmcJTS5#A5)bFEm4x%1FP(f)bO;o@JNN9>u0s;!sOB5+m1R+2u2|-Y?Q3UBFB1rEo z5FimzBZMM^-U3nr3896AKtl4xbMDi9x)0xd*n9uSSbNMh=h}O&^&9`!cg>CdIdtj} z008(0WPIBa064(pY3qZ3^X_{!7C_!Z;Hj}a1ON~T`g84@_K*n$0L0`#w{PALb)im~ z`AFi>Up81EwtTI~$OK<)rwKE$*5e8n>DpJJ@^n@%xWa@6UX^ zk$B?ozdHDih=jOZN^5pF_|?5qjB_ZsjPkj~C6~P1zxCMRD)+n4HJv?6=PBBK9p|YE zL`%Tj%l*7$0Dut*0o{Mag(yCmKO*Y*jcB1i;>)4a?fielgTE4I4*U_-`;FK4{SkKi z5L219)bQO|h!jcsaO-isFo+(?)-Uj1x%m}DOUc-7-m zxkf`(9X1?U|0;^k(rf1~X6WAZkciVjtzcoLy2mkDI2MZYNf)hz;0M$tx<2Y3sCq6m zBe)-ME`xNmFf7#>=t>)>?6B3Kwp&ki=?&6H2$KSwK{uTiz}@in+_oWX*h|EZqns?6 z5-f~ev&$T2ZEgcD9Z*tVT=@xSt{x>OX8o`dZvYuVx;+U$(eWQ06M{6NGBieQ)DqfK zuH;HrsQP>%Tp`)6dn$Ikm#OULZ<7tGnJjtvV!P`1Xr{q%ZX_6T?R3KSdDp z`jq5|Qs=3`$Bxc;K0s=mPyj#su>)=jTA#lhHYt*({QcX^E>D#t@7v)nGkEvvl#6|iY7EJjt2xdN&gqe2G-CI7;2eZf&=opZyrR5)+l1$8}Z zFrQngxVFK+rIvR`@bbYKeQ9?f3qM8XG|hB|mqY4y&t<>$+gZsr?j>ZFWz|p5L5Mj} zFZ&k@1DlOiMT%bo${0kyA}1R?tmcV_&VSLEwIMn#RpwxKmS-QmY1Nd}av$6i8C<+A zpLMm}!f2{ZA+Jw_?t2>?2_oJRz{s?1i+|_8q^P9c<@+%Kc-AuZbCNm$b4EbowaLJ~ zpTL8!%b%6H#hGE<_XDbQ3_&%D%O4^XIL`wN;~jr9K8Y`A&49WC1&qw-QfM=cw_0;<5yDe z3i2+hRodrIe!c?`uHMKKE-DbWS@QJ^DD;5^2b8^z39NlMg7ni^9VBfG!exA|Tr4o< z;#tl+b#k9HUdVkGo|wBb?w%j+qvTHsuo(Y{cJhMD;m&LEOV+561{drk{J^DJXFr7} z_I^)XZ)=t5yiD0*3HJsd%GugE!-NDzaB4F5v8EO0V=HKjEJ1 zOe^9`)z*i4QW@KwFt?YEw7UL?gnKXmB+)hB__46bKhD6mYv93G8FZA|sm56oiQf7% zAGD4;4D4IJuK+Mk7r#fJ9k_nxTeYQjXQAmv-yO(AseDf085P@k>Psnx!oyc`ub;K% zUVEMRsP5j{Eten70w8yTcq%C4FupMb6*Nf$o|g;jS0@0sObDdeVK2so(|#R2S<;YY z_7Qi|L#6(>B0MQAD_63to;_Pbsn5-=udEAl@w#{N1thPeOa)i=H1|Uz@{WH+Rlz$i z%>uY%VY3Lk1l4Z=Z=c@sWEOQAt?3wU>~qRJCLv!)_;BrDpzK45_3GL865pDhotK|f ztKn7Ete9wAT4CNQ6MavYzI_R@XkrHSACQBneU?8$W>)f@*~L4 z6wfY9_eIn56^$V!Dv*cvWuIHe0>sGU-LmCc;~sgOqTvPiAkE?9DAl5>+D!{BvAVUx ztcN5TL+I*OHtPz_YF7r}TgdOQptwE?`lngAj z;m+wsnI^eDGWQmqH~gwD_prn2@v8yBFZDlevvt9!$>s|hl|9zPOzK+ipr zN8R+u^$OOk6T~_AbSZZ0Er@%P@~&g2NM57|3|4yhYLJtK#XK>aK-aKB77dw35_YsC ztL9;q4MP#mix@Ioe9?G)A#LtO?Ywi7J2*ThQmq0{+g|wZXG)X({=>=9vtaq>eI!^) z>U*3%>F+)@{hRq#YS-z3mL2jH6WwCwkU0C%S+bJ?pc-@i(4$-9AV11A4ZJn74CR6g zC>+eQ&|36!7`WG$G^Q_UDk`e9FY^>+O8cI6$|8Y)mTRM3VkHmTpJ^Xu#PHJ5JtY~+3eyc&UjaYS3$|4a&dKas9pkJ>`Zij@8{r4@dh^3e z3e}J;6-A1LeqYf?@V~nhvwoP%BrIUBb_L(MF zw5mKsDXldYwLH={87s@B!(8x?y=fNrjNDco?mI2tL9Fw?O z*uK;f!=vQ#uLg%7%oe-_j2z$r<-vl{bcgw39;x~y9A36N0fGK-T@A6j#)D2_;cP0k`~T*-TOCm<$|6jytVw9BmUX;cr)~Z>LL1cykd09E)?iJ`1L#ZO zx!+5XSJu#njX-T~^~bI@BZ7{OkfKET%Une^s|CLiy>!7eRz3D1cWiL^dmeg?t5WW7 z|1Z-=nFa`ym}mM1{z{sudgwaD?^q?bllFcnrzHgj?={$-fOLjlQ{JsOM3^+tLJnr3 zgXlI~ooYu~8xMOWMw|ABos{q2Hy>3GH5E)TxelXA=cqmvTu9x*z_GQiqg}qy~zXdpr zKyk_&L^HJ6eD3R$(kU@H<`+7timfnhKKOn4*?6<8a?H3VKTV#A3evhAE%cz%cwOu{ zAJ=l;5tqg3ayZh9hA2*r)cbY&Yn)oBx|ZGbNY>QS~JpL&Q9IdIEyM+IPomhiUkAbMc-ryg2?*y*>0s)8GZjpnE``|Z$y(W;j=UfU@{sCL$R zhB%;soXL7V`G3lTE+a`+@ z_qKid$Imj>o~XY!uMsML@d!$t!uG*CA2~^WynJ_u524X41)tg#i2OE<)MG%!RuNV* z{RT&G{e*NF8M0rXAH(q@KGEEEz3suy<`(&eOvdh|2*$Ol>s3$lW;!Cg*LLijTZ2=! z8TvWe@M7uA80*!hC)_K;L}W?ZOylV8o9-N`VCHzrRc-M|$Dz7xKN$tFM{2vXx#R0J zab+>JB*D*mC6=7VMCSQ>SE!4rE;1S=XCGm5acxkLNfRRwOz7o zBdZ3;Q2>2dTcTzK|2+{NSZrPzv(z=zP2B7-22N%PNmGKQijzyV=N`4VQ2QJArc*&C z>p1d!&?kkegdvO)zGiH#6ox};&|EO_+9=gNI>vl6IDJ886e{iu(;7eqi*RW+web?( zMd6ZXn?LR^Pq2)}&PMiiu7!X$3a3}y$_+u~xok|bKSX=D1`eKjo3w0@$mln_(4gFp zw<7Q%9Cb<=dnmI0T7gT*S_|s{eD-{l^(Dt>u(!tPGws;t7d3;EFdgSjMRy!BnPOzQ z9>S+SkCWV-J)O7k2KgoBb|KN5l*Vy{vsr=>%oDT@$1&YT63%J`lk9XgpPbDMDpo@z z((WyqiG3izizkPP*0M(7dN4)%m3P430!bmd63ed%cL-8`I*8B!w>eWS6OK9b+gzAu zRleae(+kSz`T2ey;kbSfOnR3zu5xq6#KQN5E(y?YRGB z2r;*$ZK?M>;^^6TLn27S&E0ydC;`Qwy_{*hjQsE0)hVJdq>9I)Ao~C5Gs`DNDB#sC>Ey6w! zwNnt@d|$G)`}MF=JM?&tLUR0Gjp?)gDHD~8wyLz#xsh|Jrf#MJrQFMds+~!|d~<&R z%-voIE%o=6l-=6kV}ZCeI_7$F`Byj=h>X%$Y}UdW7m&r;D8d*b3olCo@5VaP{}r6kykz*xL5;Qf6*m~|tL9_Sg7 zwGq^#LXay{gU2=N3@SCj9?6Q&EF~BJ5PT7W)Ke|K;HgBdm2_iGq~I_C@CWSjS_R zs`Ts7R`KdyMK1`B*{f9~;*f8{73766UyRS|vS}*0UE@F8u;}XflXkDz!?x6S6=k=YpCRbEnCN)suHeljC?;V8iPcZybZ8p1UeDfoNwP=Zm8;aW3PEdEL;gP zUx&lAWik*N;Y?rf^*?rH*&JCEMrGJGLcD?HL$#`m!M3c;aCJ^ik)gj6$tEkCBDiXc zau$&c^3_A-yXE^6j@B6ZM1z}Ycd6K7k*SZq{z15P+C2EzNz_p9`_*HturfiK(DtOn z0znWJLaI5Hfyl7#DNFucwX)SL3afxfHOMio+x+3s@*f_zf2D5x-nv2kV7NPpXOKNN zo;3`o&iHV^<}dTtO046q2~olgKW*ke$+>H{wjch~NX3Y{hCtR@K!*y~ z!4AAwFJ~MSm?$V!`O_Glc$ea0lxDm>Wy%QUMOh?6qdu^ayWoIuS@?6G{uP#h1G^7l zF{U{C{vfZ7o{95-Y0ucXRr6l{uKQhnGP5BfWQ(^2iR-N9#iJFO+eqoMTWyiFv(@JQ zzyG-10H>6PicBQ6Bw1s_w0PRA6s5OT8et1_Bt7VHHkuM;M{vxh5xFHXE5wL@J>}Hp pag5u)#xvmB|7|lnMQ99i4;Tj=lNz5k@%R%RWMF=~QvX5p{{U1C>v#YF literal 0 HcmV?d00001

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 literal 0 HcmV?d00001 diff --git a/readme_img/after/localroutervalidate_after.png b/readme_img/after/localroutervalidate_after.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fb331e9f8f67342d2bead373356c2722c03727 GIT binary patch literal 8602 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 literal 0 HcmV?d00001 diff --git a/readme_img/after/modulesingletoncall_after.png b/readme_img/after/modulesingletoncall_after.png new file mode 100644 index 0000000000000000000000000000000000000000..9683adde2d31e0feec3c39c43a8c214ba9238954 GIT binary patch literal 6934 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 ewQ&cC#ALI3{2MsU3%R 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 D$JtGm literal 0 HcmV?d00001 diff --git a/readme_img/before/localroutercall_before.png b/readme_img/before/localroutercall_before.png new file mode 100644 index 0000000000000000000000000000000000000000..10f855325372a90cf6193ff668b0d88db89add61 GIT binary patch literal 8976 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 literal 0 HcmV?d00001 diff --git a/readme_img/before/localrouterdirectives_before.png b/readme_img/before/localrouterdirectives_before.png new file mode 100644 index 0000000000000000000000000000000000000000..ea1109fa25058100df4317ccc6d81ff06ab82271 GIT binary patch literal 9050 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 literal 0 HcmV?d00001 diff --git a/readme_img/before/localroutervalidate_before.png b/readme_img/before/localroutervalidate_before.png new file mode 100644 index 0000000000000000000000000000000000000000..a1c83955920a39853f63e12593018db290e8fca4 GIT binary patch literal 8623 zcmcgycT`hbvybJ1BH$H7q$?mORU;^bCW0VEib}82rMJ)m1m%i`5~PL>Ql*9>EmSWp z)JO>}6e0A`J0v78dhdFFf9tKczOz=6IqU4bXMQth&z=&Pj+QC|9XlNW0ANsiuKW@J zxCo@uQI}|_-_HV!loen5nQu&MJ8^WQTIYyr zyLasFl+`jP^-rXIz7pn+X?;Uqwe4=%*P0|Ec3JapBOA_}vJqL&7}+l|(%-$0jtKb} za{gSh&2{uszuV~S?!PVOnht99%*>`8jXc*AgCl6y^^5h)rUQ!C^n4GX({&z7R9UFk zWQg)F;Q#;!1}3)OM3&@po8Lsp=&hJ@zbWI;|NlWzqk_QZY&zyn+NVvl-nJy_w9&bFEm7j!yq(GDb#P=2gWD>EO@iv;crJBkr+OVkQ$(bkpf% zV_$RTY?;vR6k&+qKB=8|ZmSW%`2dEQ!Sy7R4W{Y1xE@*ekgsJ7Wb7|vrZ^xYb z=_tBKaO;IiYjrLWT)+l@{-7x(ktDmnu#g-oi#9Abob`Fz`0orXEaKapSkz$*fI2(s zT9a7cQGH^>RY1vSqAmGp3t4P$#wldHaZW#oTqg8j^zVxt^3nb3HnPEm&6gs~%-*<4 z`V&o?H5zLo#oZ`Mb8)Iv&grg4f%try5uG%zBCTB zuc4;k?HyrL5+Utm)?2{z4q2k$u$sfw1V&clOd1AxM+*VJzXPY;DD$Yq6o0McCSS+W27+ zl_tu zk4^U%=`l(TWu?R+7WOjwo!yZmzOvBco4IRWyM6Te$TK%Ed8o=1VA!%oo$QoW{|+7D z@$B-D^v%YxPXoSp^ej9kQbr≧_u{ZI_$GcHlHi2z= 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 X=vn7*e5Zc={q78PO>}B*KYaclWr1jk literal 0 HcmV?d00001 diff --git a/readme_img/before/modulesingletoncall_before.png b/readme_img/before/modulesingletoncall_before.png new file mode 100644 index 0000000000000000000000000000000000000000..8c019eebca5c32dcb293d1bc571cf95b4e7b6a54 GIT binary patch literal 6927 zcmb7}cQjmE^!SG)1VJ8A5=06n2$E<~hD3@Gj4;s|f`~GDH$xKbAqax#L??Qg(ME~# zbkPQ*C87;Olu@RBC-3*Z|Nhqc?zQf{d*5}=-TRz%?m3@xc9g!JCOhjDRsaCNuJ!D( z0RV6oLf4<4XQJP&?oF`MA1vHh3Vd7)#xE&ygAZUoE{5Z zyfrn>{j1~xxg`Eo0H6eYhJUqtNIIs&iL3xc!|H|fS(f(G45U?TD9pQ>Bo^sgR@5Muur(`+m} zfDJ92z#ora`RE~xB~2>+abY4u_n8YUbvsKps;!=t(4+WYM_;WqRs{(A!)eMY#D_CX z0AnytfbSGnjKpn!#bG5PIad+%O7630!^o+VZ9Evtf*tvm;*^w+daM0IXj=L)fMX90~>lU0OuM@{%}GBB;(60Ly0Fwof$q0(O(@Jc!Lb zkCM(`zLxjOc&su&!+vASuVlZHaO{M*t(f;J@umZAqo%sz+Vg5aM|1+Qx3(N?aY25A z5ioDT7sZ279=Xt_%zzmg!&GS*uqSW7A~)`*WatOL3q}Gf749MdZ2_g|zZxyO9sH;T zRDbhDCIEsS)AwWidw{n*ehDTX!z&+5&vn3fwwzD4jDc?=P9DwCd#@=aUElPx zU_Y01A@lg0d1Sgn^`S+lCn+8WhK5w2(FbX*LV&=J#NJHHG%huj0nQoi5RYdxjaO7R z##XkYNYbc)i#|@Jd1fz-LAe)O#cUm!-D-oei#XqE=>6DkMn>x9X?k5 zjWZg#77epW-g4Ud3}r*_=qjy_mKz}54umd@%7V}d!88@ipiMtjnoeYOci6yB=vKem z?qAtWuM(yAoDs$~aNl)jLW5ojd{}}9zy~D6iVk;lx39g|Q@EoO`iVw6kl>eNxWTz5 zZ4wp=5h{V7iY@=cAjavs=d6$$-iI>-0y>;LYHs`uS`uQSH1bQr1^I~pL+_bDUzmleeRZtmtQ1}&p==yR#}gPu;jZF{pMUrbtlHjLTHEcYy7~M zO`QRA3gsg|imP=kTF$LIEoG3~^_Lo90py*l>#!!a%Gigf1I|HRwZ21?kIGX5r@EhI z5!R|%tjk#v4r(=;_qiNfT)X@2r*nh3(ziFTm{*n=lsbiy<2`$CO6y`7a*7~qDe2md zf}0n^;a8Blf$Yy+5&hckXN|9(1ed_7!lI#BKWntlb)3^e=yKHi0&s+KJ!bmB7&6jaJ&w3ir@EleYmsz z_kRIx`-779yJz^OkotPOy9FnylV0L*O5za#mY8V{M>|sHaM)mJQx)IX1EH$e>)y@i zE?SGiC1kk${eaU#g)L7!WN0sApBGxbFmSp1edEQg^!iB0syD(mr1ztPg20wwR=n#X z_ING{3sGy2F}KpN|4~Jl;kj*7D`Hu51C%>0VpzuHL|V<&uT$=^O=f)?lR$i$a0#W| zd7J&>8tpXrMXuRJ{szx$Ztt`B$sa_n`IK@4tk2C-TjkRJv3-KkDim~xUOjjBahy