## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
• Create your own community
##### Activity
• Mar 18 20:14
dependabot[bot] labeled #883
• Mar 18 20:14
dependabot[bot] opened #883
• Mar 18 20:14

dependabot[bot] on pip

Bump pillow from 6.2.0 to 8.1.1… (compare)

• Feb 08 21:01
ulmentflam synchronize #882
• Feb 08 20:56
ulmentflam synchronize #882
• Feb 08 20:50
ulmentflam synchronize #882
• Feb 08 18:00
ulmentflam opened #882
• Feb 08 01:00
sugizo opened #881
• Feb 05 13:15
Panlq commented #474
• Feb 05 13:12
Panlq commented #474
• Jan 19 16:24
ptitpoulpe edited #880
• Jan 19 16:12
ptitpoulpe opened #880
• Jan 16 13:15
urbas commented #859
• Jan 16 13:14
urbas commented #859
• 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
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
codingadvocate
@codingadvocate
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"
codingadvocate
@codingadvocate
Probably better to discuss this over a ticket... so: Preprocessing Falcon request object stopped working #833
codingadvocate
@codingadvocate
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 ?
Pradhvan Bisht
@Pradhvan
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?
Pradhvan Bisht
@Pradhvan
@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?
codingadvocate
@codingadvocate
Hi Andrea. Sorry for the late response. Sure, that's possible. The work is basically taking a request (e.g. GET/POST), creating an identifier (URL) to hand back for continuing to check until it's done. I do that for pagination type requests for large datasets in the OCP project. You can see the Hug wrapped 'cache' functions that handle this, at the end of the following script... in case you want an example: https://github.com/opencontentplatform/ocp/blob/master/ocp/framework/lib/apiResourceQuery.py
ptitpoulpe
@ptitpoulpe
Hello, I wonder what is the better way to handle sqlalchemy session in hug
John Galt
@johngalt2600
I was going to ask how to handle multiple functions in the cli but found hug -f myapp -c myroute in this gitter history... but who wants to add hug -f to every command? not me. So was going to ask how to modify the shebang so I can just do myapp -c myroute but a quick google search gave me the solution. So just a FYI in case anyone else wanted to do this. This worked for me:
#!/bin/sh
''''exec hug -f "$0"${1+"$@"} # ''' Just replace your normal #!/usr/bin/env python line at the top of your program with that. John Galt @johngalt2600 Looks that that works for valid commands, valid commands with invalid parameters, and help. But it has a bug that shows 'exec hug -f "$0" ${1+"$@"} # as part of the help when you use an invalid command
well, help doesn't work either, that shows help for hug not my program.
John Galt
@johngalt2600
You would think doing ''''exec hug -f "$0" --${1+"\$@"} # ''' would fix the help problem but hug starts a web server instead of just running the program.
hug -f myapp -h also shows help for hug not myapp. hug -f mydata -- -h also starts in server mode.
John Galt
@johngalt2600

using a different shebang fixes the invalid command help.

#!/bin/env -S hug -f

But it still shows the help for hug instead of myapp when doing myapp -h`

ptitpoulpe
@ptitpoulpe
Hello, I’m using Hug with gunicorn, and gunicorn kill worker if request take more time than timeout and return a 502 error, I would like to return something else, do you know how to handle timeouts directly with hug, or if there is an handler when worker is killed ?