Skip to content

Do you know hug? It's a brilliant, tiny (yet powerful) python3 miniframework for rapid creation of REST API-based apps with optional CLI interface (may be used also locally - as a tools:). This repo contains a results of a "recuitment task" I've completed some time ago that uses hug as the "solution engine" and demonstrates most of hug features …

License

Notifications You must be signed in to change notification settings

krembas/playing-with-hug

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Playing with HUG

Do you know hug? It's a brilliant, tiny (yet powerful) python3 miniframework for rapid creation of REST API-based apps with optional CLI interface (may be used also locally - as a tools:).

This repo contains a results of a "recuitment task" I've completed some time ago that uses hug as the "solution engine" and demonstrates most of hug features at a glance :)

The recruitment task

So here is a task I was asked to complete during a some company's recruitment process:

Write an application in Python to serve two endpoints described below. Selection of libraries and frameworks is up to you. The source directory must have the file run.sh which let you run the application in systems with Unix or blik run.bat for Windows. README.md file should contain a brief description of your approach to the assignment. The application doesn't have to save anything persistently, the answers can be permanently placed in the code. Note: This is not a complete specification. The task is defined vaguely on purpose so that you can show your skills, approach and attitude.

1) Sample request & response

POST /invitation HTTP/1.1
Content-Type: application/json;charset=utf-8
{ "invitee": "John Smith", "email": "[email protected]" }

HTTP/1.1 201 Created

2) Sample request & response

GET /invitation HTTP/1.1

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
[{ "invitee": "John Smith", "email": "[email protected]" }]

Pretty easy, hugh? So that's what & how I did... ;)

Gathering and analyzing "requirements"

If about the task: we have here a simple "invitation" service, that may be a part of some bigger solution, but IMO is too incomplete and not well specified - i.e. what should happens when few sequent POST /invitation request will be performed? What about "multi-invitees" support? What about "business logic" related to request data validation?

So I've came up with few additional assumptions to make this service more "serious" and more RESTful and below is what has been finally designed and implemented:

There is an endpoint /invitation with following supported methods:

  • POST creates new invitee. Every request will create a new entity (as long as its invitee is unique).
  • GET returns a list of all invitees objects but may be parametrized (by query parameter with invitee data)to get only single JSON object with requested invitee data.
  • PUT updates given invitee data (well, here only email could be updated actually but in real systems such objects have more fields)
  • DELETE removes given invitee data.

All endpoints in case they succeeded returns expected HTTP status codes (depending to context) and responses with JSON object reflecting requested/created/modified entity (except DELETE as it's not expected behavior to return any body according to RFC's). In case of errors its responses contains appropriate error messages with problem details with appropriate status codes as well.

Of course there are also tests that validates proper behavior of every endpoints, but they covers only basic scenarios, relevant to the scope of the task.

Used "technology stack"

Application has been builden with usage of:

  • hug - a mini CLI/API framework - it provides a webserver, routing facilities, data validation and other goodies (i.e. autogenerated API documentation).
  • pytest an unit testing library that proposes really easy & efficient way to write such tests.

Rationales behind above choices:

My primary stack is Django-based (Django / Django REST Framework) but I did not decided to use it for this task for two reasons - it's a big and fully featured framework for serious businesses so should be used for that (right tools for appopriate tasks approach) and - to be honest - as nobody will pays for time I've spent on this task, I wished to "learn sth new and potentially useful" by the way of doing it ;) I've discovered hug "some time ago" and it's approach looked to me so brilliant and cool, I was really curious to check "how it works" with some real-life example. Also during development of this task I've found that hug uses pytest that looked to me much more "efficient" than classic unittest python's solution, so I decided to use it as well.

And what can I say - as for "few hours session" with this totally new for me libs, I'm really pleased with the results! I found hug and pytest really.. HUGE :) At least if about developing such a simple "projects" like this tasks and certainly this is the future of python web frameworks (i.e. amazing annotation-based validators, directives, nice routing solution, blazing fast runtime execution & rapid development etc) and testing (i.e. supereasy asserts "without self" and tons of dedicated methods!;), so check them out if you didn't hear about them dudes :)

System "Architecture"

As I've decided to use hug it determines the whole architecture to "just follow their approach". Actually the whole task could be implemented in one file, but as a big fan of clear interfaces/layers/logically decomposed components etc, I decomposed the project into several components (files).

I'd like an M-V-Whatewer approach, but unfortunately hug is not a MV* framework in the common meaning, because of lack of the Model layer as it does not provide any "persistence layer" out-of-the-box. There are some extensions to integrate 3rd party ones (i.e. peewee ORM) but as this task does not requires any persistence/databases I decided to provide "models" on my own to follow commonly used state-of-the-art solutions in web development. Of course I did not "create another Django", just designed and implemented simple Model base class that uses traditional "by init methods" instrumentation (instead via complicated metaclasses, that allow to doing tricks like Dango/SQL Alchemy etc). My models also uses simple "in memory" key-value storage instead "real" databases - I've found that hug provides one so just utilized it instead reinventing the weel :)

The whole app is assembled from such modules:

  • __main__.py - Application bootstrap/runner (prepares runtime environment, runs tests, starts webserver that serves API and opens webbrowser with application landing page).
  • app.py - The core of HUG application that contains API definition (routings for appropriate API urls and HTTP methods to appropriate request handlers).
  • models.py - Models definitions used by application (to provide persistence layer and abstract data I/O into common interface used by request handlers "views").
  • api.py - API handlers ("views") definition.
  • validators.py - Validators definitions used by request handlers (to ensure data provided by request are proper).
  • tests.py - Tests that ensures that all endpoints work correctly in sense of API and expected behavior. There is a lot of code here, as IMO tests are more important that implementation (which if wrong, could be always fixed / refactored and with help of good test it's a piece of cake ;)

As hug uses doc strings to automatically generate API documentation, thus content of doc strings (i.e. for methods etc) may not contain usually expected information as it was written "for API spec" purposes and vice versa - in some cases the results are little werid, but you know... it's a just "requirement task" so I did not care too much on that aspects ;)

I suppose you will little bit WTF-ed when you look at the sources ;) One-liner "views" implementation? Extremely simple and small yet efficient validators / test methods? Bootstrap that requires only python and "do the rest" regarding runtime environment setup etc? "Landing page" with autogenerated "API specification"? Such a things are possible if a little bit of "libraries magic" is mixed with proper "architecture" by skilled, open-minded developer <autopromotion>(like me ;)</autopromotion>

About

Do you know hug? It's a brilliant, tiny (yet powerful) python3 miniframework for rapid creation of REST API-based apps with optional CLI interface (may be used also locally - as a tools:). This repo contains a results of a "recuitment task" I've completed some time ago that uses hug as the "solution engine" and demonstrates most of hug features …

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published