Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 14:22
    Kludex commented #2907
  • 14:09
    hesummerzh commented #2907
  • 13:51
    snow6oy commented #911
  • 13:10
    Suyoung789 edited #2908
  • 13:09
    github-actions[bot] commented #2908
  • 13:08
    codecov[bot] commented #2908
  • 13:08
    codecov[bot] commented #2908
  • 13:06
    codecov[bot] commented #2908
  • 13:06
    codecov[bot] commented #2908
  • 13:06
    Suyoung789 synchronize #2908
  • 10:03
    github-actions[bot] commented #2908
  • 10:01
    codecov[bot] commented #2908
  • 10:01
    codecov[bot] commented #2908
  • 10:00
    codecov[bot] commented #2908
  • 10:00
    codecov[bot] commented #2908
  • 10:00
    codecov[bot] commented #2908
  • 10:00
    codecov[bot] commented #2908
  • 10:00
    Suyoung789 synchronize #2908
  • 09:58
    codecov[bot] commented #2908
  • 09:58
    codecov[bot] commented #2908
Neil Shapiro
@nrshapiro
Also, and more importantly, how do I make the pydantic fields in a model return only what's not defaulted to "None" in the model? If I don't set a default to None, then the model produces an error because the field is "required". If I default them to None, they all show up in the response to the client--in the API I'm replacing, those fields should remain absent, reducing the data return and also showing up in the client as undefined (and the client actually tests for that).
James Vogel
@voglster
so i have me head wrapped around authentication and creating a jwt. I also added a graphql endpoint on my app to query some objects. What I would like to do is add authentication to the GraphQLApp. can you use the depends syntax current_user: User = Depends(get_current_active_user)) when using app.add_route for graphql?
James Vogel
@voglster
either that or how can i make the graphql endpoint require a jwt?
euri10
@euri10

So in my api I'm returning a pydantic model, and fastAPI is converting it to json. If I test or demonstrate a endpoint directly via the browser (rather than through docs), is there a way to get FastAPI to prettyprint (indent) the json?

it's already the case @nrshapiro the returned json is indented, see this screen for instance:

Imgur

as for the defaults you may try dict(skip_defaults=True)
William Hayes
@wshayes
@nrshapiro https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_skip_defaults-parameter may work - it works if you are creating the Pydantic model directly - if you are setting the defaults any way other than that (e.g. the defaults are set by code other than Pydantic model creation) it won’t clean them out. I have a recursive function that will clean out anything null’ish for responses.
@francbartoli It’s pretty straightforward to add claims/roles to JWT’s and then use them (after authentication) to determine what a user has access to - it cuts down on DB queries. The only problem with it is you cannot expire the token early (e.g. your user has a new role added to them and their token is still good for X minutes). Until their token expires or you have someway to force a token update - they won’t see the benefit of the new role. If you are using websockets, you could use that to trigger a token update.
William Hayes
@wshayes
You can add any fields you want to a JWT payload. I’ve seen tokens that have several dozen fields and are around 4kb in size - I think that’s a bit overdoing it :) It’s not a problem from the JWT spec/browsers/servers - just adds more IO to each request.
euri10
@euri10
my googling skills are failing short : is there a way on a running app, to get gunicorn config params ? I know I can run with gunicorn -c config but I've got a machine where I setup some params and I'm not positive they have been loaded
Omri Har-Shemesh
@omrihar
Hello everyone! We've been hit with a weird issue and I'm wondering if anyone has experienced this before: we deployed the fastapi fullstack app to AWS cloudfront using traefik and for some reason we don't manage to get query parameters to pass to our API endpoints. We get None instead if there is not default value set. What is weird is that the API docs work and also the api works when no query parameters are needed. Any suggestions as to where the culprit could lie?
William Hayes
@wshayes
You have your application assets on Cloudfront? but not Traefik or FastAPI right?
Omri Har-Shemesh
@omrihar
Just as I posted this we managed to solve it - we didn't define cloudfront to forward query parameters!
So once we did this and waited the long time it takes to update it works.
Thanks!
euri10
@euri10
:bug: :)
William Hayes
@wshayes
Cool - thanks for sharing!
Omri Har-Shemesh
@omrihar
It was a sneaky one thou because we mostly had defaults that work and we didn't notice that the parameters don't change - until there was a default that didn't work in a specific setting
Francesco Bartoli
@francbartoli

You can add any fields you want to a JWT payload. I’ve seen tokens that have several dozen fields and are around 4kb in size - I think that’s a bit overdoing it :) It’s not a problem from the JWT spec/browsers/servers - just adds more IO to each request.

Thanks @wshayes, my first thought is to find a viable solution to receive authorization claims/roles from an external authentication system and spend it over a microservices architecture based on FastAPI

William Hayes
@wshayes
AWS Cognito, Auth0 and others allow you to add roles/claims and other user metadata as user attributes to the token. Note that the new Auth0 javascript library makes it much more difficult to get a JWT (instead they share a simple access token unless you slap it hard upside the head). I’ve not used Cognito yet, but I’ve been eyeing it as Auth0 seems to make hard things harder rather than slightly easier.
Neil Shapiro
@nrshapiro

@euri10, that's only the case in Docs as I mentioned. But others may show it in Google Chrome or elsewhere, where it looks like this:

image.png

euri10
@euri10
skaaptjop
@skaaptjop
@francbartoli another lighter weight solution is Google's firebase. Extremely straightforward to handle auth.
Francesco Bartoli
@francbartoli
Yep @skaaptjop, I played a bit with Firebase Auth but did not manag claims/roles at that time
skaaptjop
@skaaptjop
claims in FB are very lightweight (max 1000b I believe) so they do kinda expect any role based or other scheme to be implemented around it (with firestore for example)
David Montague
@dmontagu
@nrshapiro You can modify how the serialization happens by changing the response_class argument on your endpoint
the default response class (starlette.responses.JSONResponse) looks like this:
class JSONResponse(Response):
    media_type = "application/json"

    def render(self, content: typing.Any) -> bytes:
        return json.dumps(
            content,
            ensure_ascii=False,
            allow_nan=False,
            indent=None,
            separators=(",", ":"),
        ).encode("utf-8")
if you subclass and modify the render method to set indent=4 and separators=(", ", ": ") in json.dumps I think it will render closer to the "pretty" way
something like this:
import json
import typing

from starlette.responses import Response

class PrettyJSONResponse(Response):
    media_type = "application/json"

    def render(self, content: typing.Any) -> bytes:
        return json.dumps(
            content,
            ensure_ascii=False,
            allow_nan=False,
            indent=4,
            separators=(", ", ": "),
        ).encode("utf-8")
then using it would look like
    @app.get("/", response_class=PrettyJSONResponse)
    async def get_some_json():
        ...
David Montague
@dmontagu
This might be useful for debugging. If you wanted it on all endpoints during development (and off in production), this could be done by dynamically setting the response_class to a variable depending on the environment. But I think you'd be better served just making use of dev tools that will parse and display the json more neatly for you (e.g., the swagger docs, chrome extensions, etc.), and just occasionally making temporary use of the PrettyJSONResponse in situations where it is temporarily useful to have it pretty-printed
@nrshapiro As @wshayes said, there is a built-in way to skip default values as long as you don't explicitly set them to the default value when instantianting the model (pydantic must have skipped setting the values). So if the default value is None, and you don't pass it to the constructor, it will be skipped during serialization. (It was designed this way, rather than just skipping nulls, because otherwise, if you want it to include None for some reason, (e.g., because you updated a non-null value to become null, and want to signal that in your response), you wouldn't be able to.)
William Hayes
@wshayes
@dmontagu Thanks for that example - I added it to my gists for future reference!
euri10
@euri10
added flower and celery to my base, flower is super nicely made
William Hayes
@wshayes
do you use rabbitmq or redis with celery?
euri10
@euri10
I put rabbitmq but tbh I d'm not sure if I get the pros and cons of each one\
betaalpha
@betaalpha_gitlab
@wshayes I have just started using redis+celery
William Hayes
@wshayes
I’ve been using celery/rabbitmq - just finding rabbitmq more difficult to administer than I’d hoped. How is your experience with redis/celery?
I’m just now in the process of implementing a really simple queue/background process using Redis RPOPLPUSH directly to see it that will simplify my services/life/etc. Just finding Celery/… more complex than I need.
betaalpha
@betaalpha_gitlab
I have not yet experimented at a large scale. Presently it is in Proof-of-Concept stage.

var code="@app.get("/long_task", status_code=202) # 202=Accepted
async def long_task():
from backend.workers import tasks
mytask = tasks.long_task.apply_async(kwargs={'num':30})
return {'task_id': mytask.task_id}

@app.get("/long_task/status/{task_id}", status_code=200) # 200=OK
async def long_task_status(task_id: str):
from backend.workers import tasks
result = tasks.long_task.AsyncResult(task_id)
return {'status': result.status}
"

Sorry, new to giiter. How to send code part?
:)
euri10
@euri10
3 backticks
betaalpha
@betaalpha_gitlab

``` @app.get("/long_task", status_code=202) # 202=Accepted
async def long_task():
from backend.workers import tasks
mytask = tasks.long_task.apply_async(kwargs={'num':30})
return {'task_id': mytask.task_id}

@app.get("/long_task/status/{task_id}", status_code=200) # 200=OK
async def long_task_status(task_id: str):
from backend.workers import tasks
result = tasks.long_task.AsyncResult(task_id)
return {'status': result.status}
```

euri10
@euri10
code
betaalpha
@betaalpha_gitlab
code
euri10
@euri10
you can switch to compose mode icon on the right to do it easily
betaalpha
@betaalpha_gitlab
code
That black background thing is still not coming. I am in compose mode. Sending using Cntrl+Enter