Python Bulbs framework example of fget argument in a bulbs object init method

140 Views Asked by At

What is the scope of the fget= argument upon initialization of a Bulbs class property?

For instance when I am writing:

from bulbs.model import Node, Relationship
from bulbs.property import String

class foobar(Node)
   element_type = "foobar"
   fget_property = String(fget=some_method)

What some_method should be to get for the fget_property to be properly defined? Should it perform some operation on the other class properties or can it also be a function of the relations that are liked to an instance of the class, for instance something calling self.outV(some_relation)?

1

There are 1 best solutions below

1
On BEST ANSWER

Here the value for fget should be a method name that returns a calculated value. The method name should reference a method defined in your Bulbs Model class, and the method should have no parameters.

The fget method gets called every time you create/update/save the element to the database.

See https://github.com/espeed/bulbs/blob/master/bulbs/model.py#L347

Bulbs uses a Python Metaclass to set the fget function as a Python property on the Model class you are defining (not to be confused with the Bulbs database Property, such as String in your example).

See Python class property (little "p") vs Bulbs database Property (big "P")...

Here's how fget is set on the Bulbs Model you define:

class ModelMeta(type):
    """Metaclass used to set database Property definitions on Models."""

    def __init__(cls, name, base, namespace):
        """Store Property instance definitions on the class as a dictionary.""" 

        # Get inherited Properties
        cls._properties = cls._get_initial_properties()

        # Add new Properties
        cls._register_properties(namespace)

    ### ...other class methods snipped for brevity... ###

    def _initialize_property(cls, key, property_instance):
        """
        Set the Model class attribute based on the Property definition.

        :param key: Class attribute key
        :type key: str

        :param property_instance: Property instance
        :type property_instance bulbs.property.Property

        """
        if property_instance.fget:
            fget = getattr(cls, property_instance.fget)
            # TODO: implement fset and fdel (maybe)
            fset = None
            fdel = None
            property_value = property(fget, fset, fdel)
        else:
            property_value = None
        setattr(cls, key, property_value)

See https://github.com/espeed/bulbs/blob/master/bulbs/model.py#L97

For an overview of how Metaclasses work in Python, see:

UPDATE: Here is a complete working example of a model declaration using an fget method...

# people.py    

from bulbs.model import Node, Relationship                                                                                                                                                                                                    
from bulbs.property import String, Integer, DateTime                                                                                                                                                                                          
from bulbs.utils import current_datetime

class Person(Node):  

    element_type = "person" 

   name = String(nullable=False)                                                                                                                                                                                                             
    age = Integer("calc_age")                                                                                                                                                                                                                 

    def calc_age(self):                                                                                                                                                                                                                       
        """A pointless method that calculates a hard-coded age."""                                                                                                                                                                            
        age = 2014 - 1977                                                                                                                                                                                                                     
        return age                                                                                                                                                                                                                            

class Knows(Relationship):                                                                                                                                                                                                                    

    label = "knows" 

    timestamp = DateTime(default=current_datetime, nullable=False) 

And here's a full working example for how to use it...

>>> from bulbs.rexster import Graph
>>> from people import Person, Knows                                                                                                                                                                                                              

>>> g = Graph()                                                                                                                                                                                                                                   
>>> g.add_proxy("people", Person)                                                                                                                                                                                                                 
>>> g.add_proxy("knows", Knows)                                                                                                                                                                                                                   

>>> james = g.people.create(name="James")                                                                                                                                                                                                         
>>> julie = g.people.create(name="Julie")                                                                                                                                                                                                         
>>> knows = g.knows.create(james, julie)                                                                                                                                                                                                          

>>> print james.age
37                                                                                                                                                                                                                               
>>> print knows.timestamp
2014-08-04 21:28:31