Skip to content

AlexCLeduc/pleasant-python-promises

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pleasant python promises

pip install pleasant-promises

Python promises are a thing, really! But they get ugly quickly. This package lets you handle promises using generator syntax.

Here's what using 3 sequential promises looks like without this package:

def resolve_greatgrandparent(person,info):
    parent_prom = person_loader.load(person.parent_id)
    def handle_parent(parent):
        grandparent_prom = person_loader.load(parent.parent_id)

        def handle_grandparent(grandparent):
            return person_loader.load(grandparent.parent_id)

        return grandparent_prom.then(handle_grandparent)

    return parent_prom.then(handle_parent)

And now with this package,

from pleasant_promises import genfunc_to_prom

@genfunc_to_prom
def resolve_greatgrandparent_name(person,info):
    parent = yield person_loader.load(person.parent_id)
    grandparent = yield person_loader.load(parent.parent_id)
    great_grandparent = yield person_loader.load(grandparent.parent_id)
    return great_grandparent

Usage with Graphql/Graphene

If you're using promises, you're probably also using graphene or at least graphql. There are a few other helpers in here to help with your graphql schema,

Dataloaders

This package has a useful subclass wrapper of the promise package's Dataloader. You can overload its batch_load method with a generator function. This is useful if you want call another dataloader within batch_load. This class will also convert non-promise values to promises, which is required by the API we're wrapping.

from pleasant_promises.dataloader import Dataloader

class GrandparentLoader(DataLoader):
    def batch_load(self,keys):
        parents = yield person_loader.load_many(keys)
        grandparents = yield person_loader.load_many(parent.parent_id for parent in parents)
        # ...

You'll still have to decorate other dataloader methods with @genfunc_to_prom, though:

from pleasant_promises import genfunc_to_prom

class GrandparentLoader(DataLoader):
    @genfunc_to_prom
    def get_grandparent_for_single_key(self,key):
        parent = yield person_loader.load(key)
        grandparent = yield person_loader.load(parent.parent_id)
        return grandparent

    def batch_load(self,keys):
        return Promise.all([self.get_grandparent_for_single_key(key) for key in keys])

Graphene middleware

Without the middleware, you'll have to decorate all your resolvers that want to use the generator syntax.

from pleasant_promises import genfunc_to_prom

class MyPersonType(graphene.ObjectType):
    # ...
    @genfunc_to_prom
    def resolve_grandparent(self,info):
        parent = yield person_loader.load(person.parent_id)
        grandparent = yield person_loader.load(parent.parent_id)
        return grandparent

To avoid repeating this decorator on all your resolvers, use our pleasant middleware

from pleasant_promises.graphene import promised_generator_middleware


my_graphene_schema.execute('THE QUERY', middleware=[promised_generator_middleware])

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages