Embrace the APIs of the future. Hug aims to make developing APIs as simple as possible, but no simpler.
import hug
users = [{"user_id" : 5432, "given_name" : "John", "surname" : "Smith", "pic" : "JSmith.png"},
{"user_id" : 2345, "given_name" : "Jane", "surname" : "Doe", "pic" : "JDoe.png"}]
@hug.get('/profile', examples='user_id=5432')
def getProfile(user_id : int):
user = next((i for i in users if i['user_id'] == user_id), None)
return user
@hug.get('/photo', output=hug.output_format.image("png"), examples='user_id=5432')
def servePhoto(user_id : int):
user = next((i for i in users if i['user_id'] == user_id), None)
return user["pic"]
# hug -f profiles.py
# http://localhost:8000/profile?user_id=5432
#
# current output:
# {
# "user_id": 5432,
# "given_name": "John",
# "surname": "Smith",
# "pic": "JSmith.png"
# }
# desired output:
# {
# "user_id": 5432,
# "given_name": "John",
# "surname": "Smith",
# "pic": "http://localhost/photo?user_id=5432"
# }
#!/usr/bin/env python3.6
import json
from falcon import HTTP_422 # Pick your poison: https://stackoverflow.com/a/10323055
import hug
users = [{"user_id" : 5432, "given_name" : "John", "surname" : "Smith", "pic" : "JSmith.png"},
{"user_id" : 2345, "given_name" : "Jane", "surname" : "Doe", "pic" : "JDoe.png"}]
@hug.get('/test')
def testy(request):
from IPython import embed
embed()
return
@hug.get('/profile2')
def get_profile(request, response):
try:
user_id = int(request.params['user_id'])
assert(
any(user_id == u['user_id'] for u in users)
)
except (KeyError, TypeError, AssertionError):
response.status = HTTP_422
response.body = "This URL must be called with a 'user_id={user_id}' parameter with a valid user_id."
return
user = next((i for i in users if i['user_id'] == user_id), None)
(base_url, _) = request.url.split(request.path)
user['pic'] = f"{base_url}/photo?user_id={user_id}"
return user
@hug.get('/profile', examples='user_id=5432')
def getProfile(user_id : int):
user = next((i for i in users if i['user_id'] == user_id), None)
return user
@hug.get('/photo', output=hug.output_format.image("png"), examples='user_id=5432')
def servePhoto(user_id : int):
user = next((i for i in users if i['user_id'] == user_id), None)
return user["pic"]
# hug -f profiles.py
# http://localhost:8000/profile?user_id=5432
#
# current output:
# {
# "user_id": 5432,
# "given_name": "John",
# "surname": "Smith",
# "pic": "JSmith.png"
# }
# desired output:
# {
# "user_id": 5432,
# "given_name": "John",
# "surname": "Smith",
# "pic": "http://localhost/photo?user_id=5432"
# }
[2019-08-17 19:06:37] 0 x10an14@machine:~/random
-> $ pipenv graph
hug==2.5.6
- falcon [required: ==2.0.0, installed: 2.0.0]
- requests [required: Any, installed: 2.22.0]
- certifi [required: >=2017.4.17, installed: 2019.6.16]
- chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
- idna [required: >=2.5,<2.9, installed: 2.8]
- urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.3]
ipython==7.7.0
- backcall [required: Any, installed: 0.1.0]
- decorator [required: Any, installed: 4.4.0]
- jedi [required: >=0.10, installed: 0.15.1]
- parso [required: >=0.5.0, installed: 0.5.1]
- pexpect [required: Any, installed: 4.7.0]
- ptyprocess [required: >=0.5, installed: 0.6.0]
- pickleshare [required: Any, installed: 0.7.5]
- prompt-toolkit [required: >=2.0.0,<2.1.0, installed: 2.0.9]
- six [required: >=1.9.0, installed: 1.12.0]
- wcwidth [required: Any, installed: 0.1.7]
- pygments [required: Any, installed: 2.4.2]
- setuptools [required: >=18.5, installed: 41.1.0]
- traitlets [required: >=4.2, installed: 4.3.2]
- decorator [required: Any, installed: 4.4.0]
- ipython-genutils [required: Any, installed: 0.2.0]
- six [required: Any, installed: 1.12.0]
[2019-08-17 19:06:41] 0 x10an14@machine:~/random
-> $ curl localhost:8000/profile?user_id=5432; echo
{"user_id": 5432, "given_name": "John", "surname": "Smith", "pic": "JSmith.png"}
[2019-08-17 19:07:02] 0 x10an14@machine:~/random
-> $ curl localhost:8000/profile2?user_id=5432; echo
{"user_id": 5432, "given_name": "John", "surname": "Smith", "pic": "http://localhost:8000/photo?user_id=5432"}
[2019-08-17 19:07:07] 0 x10an14@machine:~/random
-> $ curl localhost:8000/profile2?user_id=5; echo
This URL must be called with a 'user_id={user_id}' parameter with a valid user_id.
[2019-08-17 19:07:12] 0 x10an14@machine:~/random
-> $
@timothycrosley
I'm trying to validate a marshmallow field.UUID against uuid.uuid4.
It will validate that is not a valid uuid4 based on a regex, but when it's valid the error returned is:
{
"errors": {
"asset_id": "expected string or bytes-like object"
}
}
from marshmallow import fields
from marshmallow.validate import Regexp
@hug.get('/asset/{asset_id}', output=hug.output_format.json)
`def return_data(body, request, response,
db: SqlalchemySession,
asset_id: fields.UUID(missing=uuid.uuid4(), validate=Regexp(uuid4_check),
allow_none=True)=None):
I'm using marshmallow=3.0.1, hug=2.5.6, python=3.6.8
I can't figure out what's happening.
First off thanks for this framework, it was a super nice experience to get started here. Now I have found myself in a conundrum: I have a construct where I give my hug api a presigned URL. Hug seems to end up swallowing the signature however:
import hug
@hug.post("/adler32")
def test(url):
return str( url)
The result looks like this:
curl http://localhost:8000/test -d url="https://some.s3.bucket/file?AWSAccessKeyId=XXX&Signature=YYY&Expires=123456789"
"https://some.s3.bucket/file?AWSAccessKeyId=XXX"%
Where does the signature slug get munched up?
hi folks. i'm trying to make a custom output format which encodes as CBOR:
import hug
import cbor
@hug.format.content_type('application/cbor')
def cbor_format(data, request=None, response=None):
return cbor.dumps(data)
@hug.get(format=cbor_format)
def test(request, response):
return request.headers
but my cbor_format
is not called and the data delivered as text/plain
. i'm a hug noob so probably just misunderstanding something.
(venv) estan@edison:~/test$ curl http://localhost:8000/test
{"CONTENT-LENGTH": "", "CONTENT-TYPE": "text/plain", "HOST": "localhost:8000", "USER-AGENT": "curl/7.58.0", "ACCEPT": "*/*"}
import hug, json, io
from hug.types import text
from hug.types import json as hugJson
class AccessAndLoggerMiddleware:
def process_resource(self, request, response, resource, parameters):
rawData = request.stream.read()
stream = io.BytesIO(rawData)
request.stream = stream
print('User: {}'.format(json.loads(rawData).get('user')))
hug.API(__name__).http.add_middleware(AccessAndLoggerMiddleware())
@hug.get('/test')
def test(user:text, key:text, content:hugJson, request, response):
return "Test"