Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can you create a example for fastapi? #188

Closed
sylvoslee opened this issue Sep 11, 2019 · 7 comments · Fixed by #318
Closed

can you create a example for fastapi? #188

sylvoslee opened this issue Sep 11, 2019 · 7 comments · Fixed by #318
Labels
enhancement New feature or request

Comments

@sylvoslee
Copy link

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context about the feature request here.

@grigi
Copy link
Member

grigi commented Sep 11, 2019

As I see it FastAPI is basically starlette with Pydantic for serialisation, and then some extra spice.
So a prerequisite to make the integration seamless, we need Pydantic serialisation support.

Wow, this can get quite big, it would end up to be a DRF-like framework when all is done, which would be awesome.

@grigi grigi added enhancement New feature or request Future Release labels Sep 11, 2019
@mojimi
Copy link

mojimi commented Sep 12, 2019

If we're going to have big plans in mind, might as well consider graphql support.

FastAPI already has integrations with Graphene, so it's only natural!

Since neither Graphene or FastAPI have any database dependency, shouldn't be too hard to get them working

@grigi
Copy link
Member

grigi commented Sep 12, 2019

Isn't the whole point of GraphQL so that one can request a compound object, or a partial one? How does Graphene ensure that performs well? Surely it would need to know about relationships etc, and the DB layer needs to be able to use the hints for performance optimization (e.g. prefetch/select related?)

Sounds like a naïve implementation would leave a LOT of room for optimization to me?

But still, baby steps. I still have to actually use Pydantic to see how it works... Or you can help us get there faster 😁

@mojimi
Copy link

mojimi commented Sep 12, 2019

@grigi Graphene is merely an interface, you implement all the object-gathering methods, the example in their website make it quite clear.

As for relationship performance, there are some clever things you can do by making use of how tortoise-orm defers QuerySet execution through await

Basically, you build your coroutines without awaiting them, and keep adding to them, and then you await at the end. I'm working on a big product that is using tortoise-orm but we're still at early stages, when we get to heavy production we plan to try to implement this sharded concept.

But you'd definitely need to extend Graphene base classes to accomodate await/async.

And you can also use transactions

Here's a simple pseudocode-ish concept:

class Query(TortoiseGraphQL):

    queryset = None

    def resolve_book(self, filter):
      self.queryset = Book.filter(filter)
    
    def resolve_author(self, filter):
      self.queryset.prefetch_related('author')
    
    async def resolve_all(self):
      results = await self.queryset
      return results.to_json()

schema = graphene.Schema(query=Query)

schema.execute('''
  query {
    Book {
       Author
    }
  }
''')

Disclaimer : never actually used Graphene or GraphQL 😄

@grigi
Copy link
Member

grigi commented Sep 13, 2019

I used GraphQL from an consumer POV, and the thing that got me was how to make partial matches performant? Because the API I used didn't speed up if I requested a small portion. So obviously it was not very "smart" about it.

I have never used Graphene either. Still I'm more interested in Pydantic at this stage. I wonder if one could map Graphene over Pydantic? (for an initial naïve implementation)
It's always easier to work on optimizations after you have working repeatable benchmarks. And since the GraphQL interface is well defined, we can do anything we want as long as the tests pass.

I did a talk about my experiences in optimization once. Where the first step after setting up a a benchmark suite and profiling the data was to remove nearly all the "obvious optimizations" as they actually made it slower…

Please report back with your experiences re building a GraphQL interface using this proposed stack?

@leandrob13
Copy link

I tested it in FastAPI and it was as straight forward as shown in the docs:

def create_app(r: APIRouter) -> FastAPI:
    app = FastAPI()
    app.include_router(r)
    register_tortoise(
        app, db_url=DATABASE_URL, modules={"models": ["app.db.postgres.models"]}, generate_schemas=True
    )
    return app

Probably what needs to be specified is that FastAPI is in fact a Starlette app and it can be initialized the same way.

@grigi
Copy link
Member

grigi commented Mar 11, 2020

Yes, we can do that.
Also, we now have pydantic serialisation support, so we could also build an example that provides a more complete fastapi experience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants