← Back to team overview

ladon-dev-team team mailing list archive

Re: REST implementation

 

Suggestions tracepyd names: dtrace, decotrace anything not containing "pyd"
:-)

Mike could I ask you to create a fork where you _only_ introduce "tracepyd"
that shows how it would integrate into Ladon. Also an example that shows if
the end-user needs to do something special to use more than one decorator.

/ Jakob

2012/10/22 Mykhailo Stadnyk <mikhus@xxxxxxxxx>

> I'm not very clever to give the names :) Actually tracepyd means "*trace*
> *py*thon *d*ecorators". Anyway, thanks for your remark, I'll take it into
> account further
>
>
> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>
>> Just a remark about the package name tracepyd. That might be an
>> unfortunate package name, cause on that odd platform called Windows
>> pyd-files are binary python modules. Just a remark :-)
>>
>>
>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>
>>> Hi Mike.
>>>
>>> Let's talk about tracepyd first, does it solve this bug:
>>>
>>> https://bugs.launchpad.net/ladon/+bug/877727
>>>
>>> rpclib has a terribly ugly solution for this, as you can see in the bug,
>>> and we want to be better than rpclib :-)
>>>
>>> / Jakob
>>>
>>>
>>>
>>>
>>>
>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>
>>>> Hi Mike
>>>>
>>>> Looking into this now, you will have my reply today :-)
>>>>
>>>> / Jakob
>>>>
>>>>
>>>> 2012/10/22 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>
>>>>> Currently it's an experimental feature which is not ready to be
>>>>> integrated. I didn't test it at all (keep working on it).
>>>>>
>>>>> So here is my personal road-map for this feature:
>>>>>   1. Resolve problem with decorators dependencies (something I
>>>>> described in previous message)
>>>>>   2. Write tests and test the functionality
>>>>>   3. I've not checked how does it deal with requests containing
>>>>> multipart boundaries and binary data
>>>>>   4. Not sure what to do with service description (currently I've just
>>>>> removed, but have an idea we can use it to describe service any way, even
>>>>> as long as REST does not specify this)
>>>>>   5. Write documentation/examples
>>>>>
>>>>> But I'm stuck on issue #1. I want to know:
>>>>>  * do you agree to add dependency in Ladon to tracepyd module or not?
>>>>>  * If not - do you agree to include tracepyd's implementation into
>>>>> Ladon (not as dependency, but to place it somewhere in tools)?
>>>>>  * If not - do you agree to modify @ladonize decorator functionality
>>>>> to add extra-params for REST (for me its ugly).
>>>>>  * If not - which ideas do you have then? :)
>>>>>
>>>>> I'd like to suggest to add dependency to tracepyd. Currently I have a
>>>>> version locally which works fine, so I can publish this solution to my
>>>>> branch to let you see.
>>>>>
>>>>> Thank you in advance for your time and advice,
>>>>> Mike
>>>>>
>>>>>
>>>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>
>>>>>> Interesting :-)
>>>>>>
>>>>>> I'll look at it later - we must make sure that it doesn't break
>>>>>> anything.
>>>>>>
>>>>>>
>>>>>> 2012/10/22 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>>>
>>>>>>> Hi Jacob.
>>>>>>>
>>>>>>> As I told I'm trying to implement RESTful services support by Ladon.
>>>>>>> The basic functionality is implemented - you can check my branch:
>>>>>>> lp:~mikhus/ladon/rest<https://code.launchpad.net/~mikhus/ladon/rest> to
>>>>>>> see how does it work. Here is an example of RESTful service you may run to
>>>>>>> see:
>>>>>>>
>>>>>>> from ladon.ladonizer import ladonize, restfulize
>>>>>>> from ladon.compat import PORTABLE_STRING
>>>>>>> from ladon.types.ladontype import LadonType
>>>>>>>
>>>>>>> class User(LadonType):
>>>>>>>  name = PORTABLE_STRING
>>>>>>> email = PORTABLE_STRING
>>>>>>> passwd = PORTABLE_STRING
>>>>>>>  def __init__():
>>>>>>>  self.name = ""
>>>>>>>  self.email = ""
>>>>>>>  self.passwd = ""
>>>>>>>
>>>>>>> class UserService( object) :
>>>>>>>  @restfulize(method="PUT")
>>>>>>>  @ladonize(str, str, str, rtype=User)
>>>>>>> def newUser( self, u_name, u_email, u_passwd) :
>>>>>>>  user = User() # where User is LadonType object
>>>>>>> user.name   = u_name
>>>>>>>  user.email  = u_email
>>>>>>> user.passwd = u_passwd
>>>>>>> return user
>>>>>>>  @restfulize(method="GET")
>>>>>>> @ladonize(int, rtype=[User])
>>>>>>>  def getUser(self, u_id) :
>>>>>>> return User()
>>>>>>>  @restfulize(method="GET")
>>>>>>> @ladonize(int, rtype=[User])
>>>>>>> def getUsers(self) :
>>>>>>>  return [User(), User(), User()]
>>>>>>>  @restfulize(method="POST")
>>>>>>>  @ladonize(int, str, str, str, rtype=User)
>>>>>>> def updUser( self, u_id, u_name, u_email, u_passwd):
>>>>>>>  user = User()
>>>>>>> user.name   = u_name
>>>>>>> user.email  = u_email
>>>>>>>  user.passwd = u_passwd
>>>>>>> return user
>>>>>>>  @restfulize(method="DELETE")
>>>>>>> @ladonize(int, rtype=bool)
>>>>>>> def delUser( self, u_id) :
>>>>>>>  return True
>>>>>>>
>>>>>>> By the way, there is at least one issue I don't know how to solve
>>>>>>> better, so I want your advice.
>>>>>>>
>>>>>>> As you see I've implemented specific decorator to mark service
>>>>>>> methods as RESTful. It's @restfulize decorator. The problem that it is
>>>>>>> implemented now as:
>>>>>>>
>>>>>>> def restfulize( *dargs, **dkwargs):
>>>>>>>  def decorator(fn):
>>>>>>> * minfo = fn._ladon_method_info*
>>>>>>> if 'method' in dkwargs:
>>>>>>>  if not minfo.restfulize( **dkwargs):
>>>>>>> raise RestfulMethodConfigMismatch( fn.func_name)
>>>>>>>
>>>>>>> return fn # returns ladonized method
>>>>>>> return decorator
>>>>>>>
>>>>>>> The problem is highlighted with bold. Will be good to make this
>>>>>>> decorator independent of what @ladonize defined in it's private props. But,
>>>>>>> as far as "fn" here is a reference to ladon's "injector" function I have no
>>>>>>> way to determine correctly which real method in which class is decorated.
>>>>>>> It means that in such case I have no way to extract LadonMethodInfo
>>>>>>> associated to "fn" in other way but implemented for the moment.
>>>>>>>
>>>>>>> The real problem is when I want to override @ladonize decorator. In
>>>>>>> this case @resftulize becomes nonoperational because I loose reference to
>>>>>>> "_ladon_method_info" and means that I should take care to bypass all the
>>>>>>> existing private properties in 3-d party override implementation, which is
>>>>>>> not good at all. So I want to have @restfulize and @ladonize implemented
>>>>>>> without hard dependency between them.
>>>>>>> Via global_service_collection() it's possible to do but you need to
>>>>>>> determine real method function in some way.
>>>>>>>
>>>>>>> So I see the following ways to fix it:
>>>>>>>
>>>>>>> 1. Via decorator registry (Here we solved such kind of problem by
>>>>>>> creating DecoratorRegistry (I've published it as
>>>>>>> http://pypi.python.org/pypi/tracepyd))
>>>>>>> 2. By adding REST functionality to @ladonize decorator itself, to
>>>>>>> have something like:
>>>>>>>     @ladonize(PORTABLE_STRING, rtype=[PORTABLE_STRING], *rest={
>>>>>>> "method" : "GET", "produces": "XML" }*)
>>>>>>>
>>>>>>> Maybe you can point me to some other ideas you know how to resolve
>>>>>>> such kind of problem.
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Mike
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Med venlig hilsen / Best regards
>>>>>> Jakob Simon-Gaarde
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Med venlig hilsen / Best regards
>>>> Jakob Simon-Gaarde
>>>>
>>>
>>>
>>>
>>> --
>>> Med venlig hilsen / Best regards
>>> Jakob Simon-Gaarde
>>>
>>
>>
>>
>> --
>> Med venlig hilsen / Best regards
>> Jakob Simon-Gaarde
>>
>
>


-- 
Med venlig hilsen / Best regards
Jakob Simon-Gaarde

Follow ups