## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
• Jan 06 16:23
makkalot opened #879
• Dec 29 2020 13:35
ianthetechie commented #878
• Dec 29 2020 13:33
CaselIT commented #878
• Dec 15 2020 19:36
vytas7 commented #878
• Dec 15 2020 19:17
mlavin commented #878
• Dec 15 2020 18:32
vytas7 commented #878
• Dec 08 2020 16:36
ianthetechie opened #878
• Nov 22 2020 00:45
pavel-kolesnikov edited #877
• Nov 22 2020 00:45
pavel-kolesnikov edited #877
• Nov 22 2020 00:45
pavel-kolesnikov opened #877
• Oct 24 2020 15:42
sledeunf edited #876
• Oct 24 2020 15:40
sledeunf opened #876
• Oct 24 2020 15:15
sledeunf opened #875
• Oct 15 2020 13:30
mandarvaze commented #837
• Oct 08 2020 10:46
XenGi commented #377
• Oct 08 2020 10:45
XenGi commented #377
• Oct 07 2020 14:50
tirkarthi opened #874
• Oct 04 2020 21:06
Peter200lx commented #873
• Oct 04 2020 20:43
arogozhnikov commented #873
• Oct 04 2020 20:43
arogozhnikov commented #873
William Moskal
@wmoskal
Hi, When I upload a microsoft excel file (.xlsx), to a hug endpoint, the file becomes corrupted. Is this a hug error, or a server error, or a html error, or some other error?
x10an14
@x10an14
@wmoskal Perform a sha256sum before and after, and at the server-location where it's uploaded?
William Moskal
@wmoskal
@x10an14 Thanks! I'll try that out
Micahj
@micahj
Hey @timothycrosley you are a legend. Hug is awesome
Timothy Edmund Crosley
@timothycrosley
@micahj Thanks for the kind words! Glad you like hug!
Zeethulhu
@Zeethulhu
Hi everyone, could someone please advise how I can return the URL of another route in hug?
for example;
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"
# }
Jackemuk
@jackemuk
Can someone point me to where I can find how to manipulate the documentation output format? Where do I change the "404" message? I tried to change the format to yaml using hug_yaml, but sample information on the pypi web page is different than the github page, and neither seems to work for me. Is there a way to filter the endpoints? For example, all endpoints that start with /assets* and only the GET methods? Any help to point me in the right direction would be great, Thanks!
x10an14
@x10an14
@Zeethulhu:
#!/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
-> $ Zeethulhu @Zeethulhu @x10an14 Thanks a bunch! I really appreciate you taking the time to help me out. x10an14 @x10an14 You're welcome =) Jackemuk @jackemuk @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. x10an14 @x10an14 @jackemuk Your whitespace separation of functon arguments is impressive =P Jackemuk @jackemuk @x10an14 Hahahahaha! Thanks! Frank Berghaus @berghaus 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? Frank Berghaus @berghaus Fixed it like so: @hug.post("/test", map_params={"Signature": "sig", "Expires": "exp"}) def test(url, sig, exp): return "{}&Signature={}&Expires={}".format(url, sig, exp) guess I am learning about reserved keywords :-) Timothy Edmund Crosley @timothycrosley @berghaus glad you figured it out, and glad you are liking the framework! @/all: New documentation site is live for hug http://hugapi.github.io/hug/ x10an14 @x10an14 @timothycrosley Consider using https, so that those of us who are weary of random (shit tons) of JavaScript to be executed browser-side comes from a (somewhat) trusted source =) Timothy Edmund Crosley @timothycrosley @x10an14 you are correct! https://hugapi.github.io/hug/ is a better link Priyanka Garg @garg-priyanka Hi, I am just starting with Hug. How can I pass a custom directive into a middleware. Elvis Stansvik @estan 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. this is what i'm getting: (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": "*/*"}
Elvis Stansvik
@estan
nevermind :facepalm: the name of the argument is output, not format.
Timothy Edmund Crosley
@timothycrosley
@estan Glad you figured it out! @garg-priyanka Did you figure out how to accomplish this? This isn't something that hug is optimized for at the moment, but you can use directives from middlewares manually (passing in whatever arguments the directive takes, like a normal python function)
Mike Mindel
@cryptoflipper
I just wanted to say thanks for the Hug API framework Timothy. It really is excellent and I use it for all my APIs at the moment.
Timothy Edmund Crosley
@timothycrosley
Happy to hear!
ConorDonohoe
@ConorDonohoe
Hi would anyone be able to help me with the problem I am having trying to get the file name from an upload function, I've asked the question on Stack Overflow https://stackoverflow.com/questions/58508663/how-do-you-get-an-uploaded-file-name-from-hug-api-python thank you.
SimonShapiro
@SimonShapiro

Hello. I am new to hug and very excited about its capabilities. I have an off-the-wall question though. Is there any way to programmatically determine the hosting url and port?

My use case is that I need to attach this info at run time to certain data fields.

sylvoslee
@sylvoslee
Is there any news about hug3.0?
Programacion-Medellin47
@Programacion-Medellin47
Hello people! You can help me? I want to know how change the response status with hug
For a couple years I've used a falcon middleware to dump the payload and authenticate the user, prior to allowing access to Hug wrapped functions. Hug versions 2.5.0 and prior worked with a rawData = request.stream.read(), and then resetting the stream with request.stream = io.BytesIO(rawData). But upgrading to the latest Hug (or anything 2.5.1 or newer), shows that the payload reset doesn't work and it appears empty - coming from hug\interface.py, exception in gather_parameters. Is this known/expected? Is there a work around with the newer Hug/Falcon? Should I freeze my project on an old Hug and file a bug? I use a Twisted WSGI, but created a 13 line unit test case that works with the 'hug -f file.py' command test: 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"`
Probably better to discuss this over a ticket... so: Preprocessing Falcon request object stopped working #833
Got a chance to dig into code diffs today, to find the culprit. Looks like between 2.5.0 and 2.5.1, hug.interface.gather_parameters() changes how it assigns the body. It moves from the previous falcon request.stream, over to the wrapped bounded_stream. And so the previous reset on request.stream won't work since bounded_stream would be empty from the stream read, and not reset by the new stream. I don't like overriding internal variables, but I have a work around by changing my code from "request.stream = io.BytesIO(rawData)", over to "request._bounded_stream = FalconBoundedStream(io.BytesIO(rawData), request.content_length)" and "from falcon.request_helpers import BoundedStream as FalconBoundedStream". I'll update the ticket accordingly.
ptitpoulpe
@ptitpoulpe
hello, there is a way to have SSE or WebSocket with hug/uwsgi ?
Hey! I was going through the documentation and found that the python code snippets aren't formatted correctly. Later realized that someone else had already opened a PR reading the issue hugapi/website#9
Since no one is working on the issue, I would love to pick it up.
@timothycrosley ^^
Bar Ziony
@bartzy
is this channel active?
@bartzy I don't think so
eelancecq
@eelancecq
hi,
is there any way to get the client connection ip when use hug?
David Alberto Casas A.
@Daca1953
hi, someone know how to allow the permission of CORS, to make a httpRequest from other url?
zdw3277024
@zdw3277024
What should I do to access the hug with ipv6 address
Andrea Ghensi
@andrea.ghensi_gitlab
Hi there! I just found out about hug and I must admit it's really cool! I wonder why I haven't found it before, definitely better than flask and a ton of extensions!
I'm looking to use hug to expose an API for long running tasks, and I saw a post here and an issue on github mentioning celery... I wonder if someone has a working example on how to get it working.
I was thinking about a wrapper/decorator on top of hug.post, let's call it hug.post_async, that handles the call the celery task, and returns a 202 response with the url of a job status endpoint. Can it be done?