By Vasudev Ram
I came across this interesting Python framework called hug recently:
www.hug.rest
Hug is interesting because it allows you to create a function in Python and then expose it via both the web and the command-line. It also does some data type validation using Python 3's annotations (not shown in my example, but see the hug quickstart below). Hug is for Python 3 only, and builds upon on the Falcon web framework (which is "a low-level high performance framework" for, among other things, "building other frameworks" :).
Here is the hug quickstart.
The hug site says it is "compiled with Cython" for better performance. It makes some claims about being one of the faster Python frameworks. Haven't checked that out.
Here is an HN thread about hug from about a year ago, with some interesting comments, in which the author of hug also participated, replying to questions by readers, explaining some of his claims, etc. Some benchmark results for hug vs. other tools are also linked to in that thread:
I tried out some of the features of hug, using Python 3.5.2, with a small program I wrote.
Below is the test program I wrote, hug_pdp.py. The pdp in the filename stands for psutil disk partitions, because it uses the psutil disk_partitions() function that I blogged about here recently:
Using psutil to get disk partition information with Python
Here is hug_pdp.py:
Here are some different ways of running this hug-enabled program, with their outputs:
As a regular Python command-line program, using the python command:
As a command-line program, using the hug command:
But you can also run the above command with the "-c pyver" argument instead of "-c pdp", giving:
Next I went to this URL:
Of course, the output from both the web and CLI interfaces is either JSON or a dict, so in a real life app, we would have to get that output and use it in some way, such as (process it further before we) format it better for human consumption. If using a JavaScript front-end, it can easily be done; if using the code as is with the command-line mode, we need to figure out a way to do it. The hug module may have some support for that.
What is also interesting is that when I run it this way:
an overview, supported URLs/routes, HTTP methods, and documentation about how to use it and the output formats - almost none of which code was written for, mind.
Go give your Python code a hug!
- Vasudev Ram - Online Python training and consultingGet updates (via Gumroad) on my forthcoming apps and content. Jump to posts: Python * DLang * xtopdfSubscribe to my blog by emailMy ActiveState Code recipesFollow me on: LinkedIn * TwitterManaged WordPress Hosting by FlyWheel
I came across this interesting Python framework called hug recently:
www.hug.rest
Hug is interesting because it allows you to create a function in Python and then expose it via both the web and the command-line. It also does some data type validation using Python 3's annotations (not shown in my example, but see the hug quickstart below). Hug is for Python 3 only, and builds upon on the Falcon web framework (which is "a low-level high performance framework" for, among other things, "building other frameworks" :).
Here is the hug quickstart.
The hug site says it is "compiled with Cython" for better performance. It makes some claims about being one of the faster Python frameworks. Haven't checked that out.
Here is an HN thread about hug from about a year ago, with some interesting comments, in which the author of hug also participated, replying to questions by readers, explaining some of his claims, etc. Some benchmark results for hug vs. other tools are also linked to in that thread:
I tried out some of the features of hug, using Python 3.5.2, with a small program I wrote.
Below is the test program I wrote, hug_pdp.py. The pdp in the filename stands for psutil disk partitions, because it uses the psutil disk_partitions() function that I blogged about here recently:
Using psutil to get disk partition information with Python
Here is hug_pdp.py:
"""Note the use of hug decorators in the code to enable different kinds of user interfaces and HTTP methods.
hug_pdp.py
Use hug with psutil to show disk partition info
via Python, CLI or Web interfaces.
Copyright 2017 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: http://jugad2.blogspot.com
Product store: https://gumroad.com/vasudevram
"""
import sys
import psutil
import hug
def get_disk_partition_data():
dps = psutil.disk_partitions()
fmt_str = "{:<8} {:<7} {:<7}"
result = {}
result['header'] = fmt_str.format("Drive", "Type", "Opts")
result['detail'] = {}
for i in (0, 2):
dp = dps[i]
result['detail'][str(i)] = fmt_str.format(dp.device, dp.fstype, dp.opts)
return result
@hug.cli()
@hug.get(examples='drives=0,1')
@hug.local()
def pdp():
"""Get disk partition data"""
result = get_disk_partition_data()
return result
@hug.cli()
@hug.get(examples='')
@hug.local()
def pyver():
"""Get Python version"""
pyver = sys.version[:6]
return pyver
if __name__ == '__main__':
pdp.interface.cli()
Here are some different ways of running this hug-enabled program, with their outputs:
As a regular Python command-line program, using the python command:
$ python hug_pdp.py
{'detail': {'0': 'C:\\ NTFS rw,fixed', '2': 'E:\\ CDFS ro,cdrom'
}, 'header': 'Drive Type Opts '}
As a command-line program, using the hug command:
$ hug -f hug_pdp.py -c pdpYou can see that this command gives the same output as the previous one.
{'detail': {'2': 'E:\\ CDFS ro,cdrom', '0': 'C:\\ NTFS rw,fixed'},
'header': 'Drive Type Opts '}
But you can also run the above command with the "-c pyver" argument instead of "-c pdp", giving:
$ hug -f hug_pdp.py -c pyver(I added the pyver() function to the program later, after the initial runs with just the pdp() function, to figure out how using the hug command to run the program was different from using the python command to run it. The answer can be seen from the above output, though there is another difference too, shown below (the web interface). Next, I ran it this way:
3.5.2
$ hug -f hug_pdp.pywhich started a web server (running on port 8000), giving this output on the console:
/#######################################################################\Then I went to this URL in my browser:
`.----``..-------..``.----.
:/:::::--:---------:--::::://.
.+::::----##/-/oo+:-##----:::://
`//::-------/oosoo-------::://. ## ## ## ## #####
.-:------./++o/o-.------::-` ``` ## ## ## ## ##
`----.-./+o+:..----. `.:///. ######## ## ## ##
``` `----.-::::::------ `.-:::://. ## ## ## ## ## ####
://::--.``` -:``...-----...` `:--::::::-.` ## ## ## ## ## ##
:/:::::::::-:- ````` .:::::-.` ## ## #### ######
``.--:::::::. .:::.`
``..::. .:: EMBRACE THE APIs OF THE FUTURE
::- .:-
-::` ::- VERSION 2.2.0
`::- -::`
-::-` -::-
\########################################################################/
Copyright (C) 2016 Timothy Edmund Crosley
Under the MIT License
Serving on port 8000...
http://localhost:8000/pdpwhich gave me this browser output:
{"detail": {"0": "C:\\ NTFS rw,fixed", "2": "E:\\ CDFS ro,cdrom"},which is basically the same as the earlier command-line interface output I got.
"header": "Drive Type Opts "}
Next I went to this URL:
http://localhost:8000/pyverwhich gave me this:
"3.5.2 "which again is the same as the earlier corresponding command-line output of the hug command.
Of course, the output from both the web and CLI interfaces is either JSON or a dict, so in a real life app, we would have to get that output and use it in some way, such as (process it further before we) format it better for human consumption. If using a JavaScript front-end, it can easily be done; if using the code as is with the command-line mode, we need to figure out a way to do it. The hug module may have some support for that.
What is also interesting is that when I run it this way:
http://localhost:8000/I get this browser output:
{which shows that trying to access an unsupported route, gives as output, this:
"404": "The API call you tried to make was not defined. Here's a definition
of the API to help you get going :)",
"documentation": {
"overview": "\nhug_pdp.py\nUse hug with psutil to show disk partition
info \nvia Python, CLI or Web interfaces.\nCopyright 2017 Vasudev Ram\nWeb site:
https://vasudevram.github.io\nBlog: http://jugad2.blogspot.com\nProduct store:
https://gumroad.com/vasudevram\n",
"handlers": {
"/pdp": {
"GET": {
"usage": "Get disk partition data",
"examples": [
"http://localhost:8000/pdp?drives=0,1"
],
"outputs": {
"format": "JSON (Javascript Serialized Object Notation)",
"content_type": "application/json"
}
}
},
"/pyver": {
"GET": {
"usage": "Get Python version",
"examples": [
"http://localhost:8000/pyver"
],
"outputs": {
"format": "JSON (Javascript Serialized Object Notation)",
"content_type": "application/json"
}
}
}
}
}
}
an overview, supported URLs/routes, HTTP methods, and documentation about how to use it and the output formats - almost none of which code was written for, mind.
Go give your Python code a hug!
- Vasudev Ram - Online Python training and consultingGet updates (via Gumroad) on my forthcoming apps and content. Jump to posts: Python * DLang * xtopdfSubscribe to my blog by emailMy ActiveState Code recipesFollow me on: LinkedIn * TwitterManaged WordPress Hosting by FlyWheel