Exposing the request object. RequestExposingDjangoGateway

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

Exposing the request object. RequestExposingDjangoGateway

by bart vandendriessche-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey all,

We're currently developing a small project which will use a Flash 8 frontend and a Django backend. Because we need to allow people to input some of their personal data in flash, which we then would like to reuse in a different flash we need access to the request object used by the AMF calls.

To enable this, I wrote a quick subclass of the pyamf.gateway.DjangoGateway class which seems to do the trick. I'll just post the code here in case anyone else may find it useful (and also to have an extra set of eyeballs maybe checking it for bugs :)):

import pyamf
from pyamf import remoting, gateway

class RequestExposingDjangoGateway(gateway.DjangoGateway):
    def __call__(self, request):
        if request.method == 'POST':
            response = HttpResponse()
            context = pyamf.get_context(pyamf.AMF0)
            amfrequest = remoting.decode(request.raw_post_data, context)
            amfresponse = remoting.Envelope(amfrequest.amfVersion, amfrequest.clientType )
            processor = self.getProcessor(amfrequest)
            for name, message in amfrequest:
                amfresponse[name] = processor(message, request)
            stream = remoting.encode(amfresponse, context)
            response['Content-Type'] = remoting.CONTENT_TYPE
            response['Content-Length'] = str(len(stream))
            response.write(stream.getvalue())
        else:
            response = HttpResponseNotAllowed(['POST'])
        return response
   
    def processRequest(self, message, request):
        """
        This is mainly a copy from the BaseGateway code.
        The only change is the call to getServiceRequest that now includes
        the request parameter.
        """
        response = remoting.Message(None, None, None, None)
        service_request = self.getServiceRequest(message)
        #we have a valid service, now attempt authentication
        if not self._authenticate(service_request, message):
            # FIXME: what error to return here?
            response.status = remoting.STATUS_ERROR
            response.body = dict(
                code=' SERVER.AUTHENTICATION',
                level='Auth'
            )
            return response
        try:
            response.body = service_request(request, *message.body)
            response.status = remoting.STATUS_OK
        except (SystemExit, KeyboardInterrupt):
            raise
        except:
            response.body = self.getErrorResponse(sys.exc_info())
            response.status = remoting.STATUS_ERROR
        return response

Initial tests indicate that this code works, as long as you remember that the first parameter to any function invoked by this gateway will be the request.

I'm rather novice to Python, so any suggestions are welcome. One slight remark I have from going through a little bit of the source code is the seemingly inconsistent variable naming. There are a few functions, especially in the BaseGateway implementation that take a 'request' parameter, where the type of this parameter is actually different from request. I think legibility would be greatly enhanced if parameter names represent their types a bit better.

Re: Exposing the request object. RequestExposingDjangoGateway

by Nick Joyce :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Bart,

On Wed, 2007-11-28 at 08:58 +0100, bart vandendriessche wrote:
Hey all,

We're currently developing a small project which will use a Flash 8 frontend and a Django backend. Because we need to allow people to input some of their personal data in flash, which we then would like to reuse in a different flash we need access to the request object used by the AMF calls.
Welcome!

To enable this, I wrote a quick subclass of the pyamf.gateway.DjangoGateway class which seems to do the trick. I'll just post the code here in case anyone else may find it useful (and also to have an extra set of eyeballs maybe checking it for bugs :)):
Thanks for putting something like this together, its great to know that the code we put together is starting to be exercised :)

import pyamf
from pyamf import remoting, gateway

class RequestExposingDjangoGateway(gateway.DjangoGateway):
    def __call__(self, request):
        if request.method == 'POST':
            response = HttpResponse()
            context = pyamf.get_context(pyamf.AMF0)
            amfrequest = remoting.decode(request.raw_post_data, context)
            amfresponse = remoting.Envelope(amfrequest.amfVersion, amfrequest.clientType )
            processor = self.getProcessor(amfrequest)
            for name, message in amfrequest:
                amfresponse[name] = processor(message, request)
            stream = remoting.encode(amfresponse, context)
            response['Content-Type'] = remoting.CONTENT_TYPE
            response['Content-Length'] = str(len(stream))
            response.write(stream.getvalue())
        else:
            response = HttpResponseNotAllowed(['POST'])
        return response
   
    def processRequest(self, message, request):
        """
        This is mainly a copy from the BaseGateway code.
        The only change is the call to getServiceRequest that now includes
        the request parameter.
        """
        response = remoting.Message(None, None, None, None)
        service_request = self.getServiceRequest(message)
        #we have a valid service, now attempt authentication
        if not self._authenticate(service_request, message):
            # FIXME: what error to return here?
            response.status = remoting.STATUS_ERROR
            response.body = dict(
                code=' SERVER.AUTHENTICATION',
                level='Auth'
            )
            return response
        try:
            response.body = service_request(request, *message.body)
            response.status = remoting.STATUS_OK
        except (SystemExit, KeyboardInterrupt):
            raise
        except:
            response.body = self.getErrorResponse(sys.exc_info())
            response.status = remoting.STATUS_ERROR
        return response

Initial tests indicate that this code works, as long as you remember that the first parameter to any function invoked by this gateway will be the request.
There is no such class gateway.DjangoGateway, perhaps you meant gateway.django.DjangoGateway?

There has been an iteration in the gateway API, you may want to check that out. There is no _authenticate/getErrorResponse functions anymore, check the latest source for more info. Gateways are probably the most unstable in terms of API, but we are working as quick as possible to them nailed down.

I'm rather novice to Python, so any suggestions are welcome. One slight remark I have from going through a little bit of the source code is the seemingly inconsistent variable naming. There are a few functions, especially in the BaseGateway implementation that take a 'request' parameter, where the type of this parameter is actually different from request. I think legibility would be greatly enhanced if parameter names represent their types a bit better.
Yep, I would agree with that, ticket #102
_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev

Re: Exposing the request object. RequestExposingDjangoGateway

by bart vandendriessche-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Nick,

Yeah sorry, the copy pasting was done from a "work in progress" version of my class and the imports are wrong :)
The comment is wrong as well, it's not the getServiceRequest call that receives the request now, but the call to service_request.

I will check the updated code later, right now this works for us, and I'm trying to have as little moving parts as possible. Thanks for opening the ticket for me.

Cheers,
Bart

On Nov 28, 2007 11:14 AM, Nick Joyce <nick@...> wrote:
Hey Bart,


On Wed, 2007-11-28 at 08:58 +0100, bart vandendriessche wrote:
Hey all,

We're currently developing a small project which will use a Flash 8 frontend and a Django backend. Because we need to allow people to input some of their personal data in flash, which we then would like to reuse in a different flash we need access to the request object used by the AMF calls.
Welcome!


To enable this, I wrote a quick subclass of the pyamf.gateway.DjangoGateway class which seems to do the trick. I'll just post the code here in case anyone else may find it useful (and also to have an extra set of eyeballs maybe checking it for bugs :)):
Thanks for putting something like this together, its great to know that the code we put together is starting to be exercised :)


import pyamf
from pyamf import remoting, gateway

class RequestExposingDjangoGateway(gateway.DjangoGateway):
    def __call__(self, request):
        if request.method == 'POST':
            response = HttpResponse()
            context = pyamf.get_context(pyamf.AMF0)
            amfrequest = remoting.decode(request.raw_post_data, context)
            amfresponse = remoting.Envelope(amfrequest.amfVersion, amfrequest.clientType )
            processor = self.getProcessor(amfrequest)
            for name, message in amfrequest:
                amfresponse[name] = processor(message, request)
            stream = remoting.encode(amfresponse, context)
            response['Content-Type'] = remoting.CONTENT_TYPE
            response['Content-Length'] = str(len(stream))
            response.write(stream.getvalue())
        else:
            response = HttpResponseNotAllowed(['POST'])
        return response
   
    def processRequest(self, message, request):
        """
        This is mainly a copy from the BaseGateway code.
        The only change is the call to getServiceRequest that now includes
        the request parameter.
        """
        response = remoting.Message(None, None, None, None)
        service_request = self.getServiceRequest(message)
        #we have a valid service, now attempt authentication
        if not self._authenticate(service_request, message):
            # FIXME: what error to return here?
            response.status = remoting.STATUS_ERROR
            response.body = dict(
                code=' SERVER.AUTHENTICATION',
                level='Auth'
            )
            return response
        try:
            response.body = service_request(request, *message.body)
            response.status = remoting.STATUS_OK
        except (SystemExit, KeyboardInterrupt):
            raise
        except:
            response.body = self.getErrorResponse(sys.exc_info())
            response.status = remoting.STATUS_ERROR
        return response

Initial tests indicate that this code works, as long as you remember that the first parameter to any function invoked by this gateway will be the request.
There is no such class gateway.DjangoGateway, perhaps you meant gateway.django.DjangoGateway?

There has been an iteration in the gateway API, you may want to check that out. There is no _authenticate/getErrorResponse functions anymore, check the latest source for more info. Gateways are probably the most unstable in terms of API, but we are working as quick as possible to them nailed down.


I'm rather novice to Python, so any suggestions are welcome. One slight remark I have from going through a little bit of the source code is the seemingly inconsistent variable naming. There are a few functions, especially in the BaseGateway implementation that take a 'request' parameter, where the type of this parameter is actually different from request. I think legibility would be greatly enhanced if parameter names represent their types a bit better.
Yep, I would agree with that, ticket #102
_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev

_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev



Re: Exposing the request object. RequestExposingDjangoGateway

by Arnar Birgisson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Helo,

On Nov 28, 2007 7:58 AM, bart vandendriessche
<bart.vandendriessche@...> wrote:
> We're currently developing a small project which will use a Flash 8 frontend
> and a Django backend. Because we need to allow people to input some of their
> personal data in flash, which we then would like to reuse in a different
> flash we need access to the request object used by the AMF calls.

Welcome to the party.

> To enable this, I wrote a quick subclass of the pyamf.gateway.DjangoGateway
> class which seems to do the trick. I'll just post the code here in case
> anyone else may find it useful (and also to have an extra set of eyeballs
> maybe checking it for bugs :)):

Your code makes perfect sense in the Django context, sending the
request as the first parameter is standard Django practice. Therefore,
I'm thinking if we should provide this as an optional functionality of
the DjangoGateway. Probably have it turned off by default, but keep a
paramter to the constructor that when turned on, the gateway will
prepend the request to all function calls. Nick, Thijs, thoughts on
this?

> I'm rather novice to Python, so any suggestions are welcome. One slight
> remark I have from going through a little bit of the source code is the
> seemingly inconsistent variable naming. There are a few functions,
> especially in the BaseGateway implementation that take a 'request'
> parameter, where the type of this parameter is actually different from
> request. I think legibility would be greatly enhanced if parameter names
> represent their types a bit better.

When you talk about the "type of request", are you referring to the
django.http.request object? BaseGateway (or most of pyamf for that
matter) is not written with Django in mind, but rather as a general
multi-purpose library. IMO there's no need to worry about naming
collision with Django, since one can assume a "request" refers to an
AMF remoting request.

Your point stil stands though, meaningful variable and function names
are always good as long as one doesn't get carried away [1] :)

[1] http://worsethanfailure.com/Articles/Overruled-by-RemoveSpecialCharsExceptQuoteAmpersand.aspx

cheers,
Arnar


Re: Exposing the request object. RequestExposingDjangoGateway

by Nick Joyce :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Wed, 2007-11-28 at 11:37 +0000, Arnar Birgisson wrote:
Helo,

On Nov 28, 2007 7:58 AM, bart vandendriessche
<bart.vandendriessche@...> wrote:
> We're currently developing a small project which will use a Flash 8 frontend
> and a Django backend. Because we need to allow people to input some of their
> personal data in flash, which we then would like to reuse in a different
> flash we need access to the request object used by the AMF calls.

Welcome to the party.

> To enable this, I wrote a quick subclass of the pyamf.gateway.DjangoGateway
> class which seems to do the trick. I'll just post the code here in case
> anyone else may find it useful (and also to have an extra set of eyeballs
> maybe checking it for bugs :)):

Your code makes perfect sense in the Django context, sending the
request as the first parameter is standard Django practice. Therefore,
I'm thinking if we should provide this as an optional functionality of
the DjangoGateway. Probably have it turned off by default, but keep a
paramter to the constructor that when turned on, the gateway will
prepend the request to all function calls. Nick, Thijs, thoughts on
this?
If its Django standard practice, then for the Django gateway, we should include the request as the first request by default?

Humm, on second thoughts to keep the underlying service code as portable as possible (over gateways), we should include a constructor param to turn this on.

Ticket #103.

> I'm rather novice to Python, so any suggestions are welcome. One slight
> remark I have from going through a little bit of the source code is the
> seemingly inconsistent variable naming. There are a few functions,
> especially in the BaseGateway implementation that take a 'request'
> parameter, where the type of this parameter is actually different from
> request. I think legibility would be greatly enhanced if parameter names
> represent their types a bit better.

When you talk about the "type of request", are you referring to the
django.http.request object? BaseGateway (or most of pyamf for that
matter) is not written with Django in mind, but rather as a general
multi-purpose library. IMO there's no need to worry about naming
collision with Django, since one can assume a "request" refers to an
AMF remoting request.

Your point stil stands though, meaningful variable and function names
are always good as long as one doesn't get carried away [1] :)

[1] http://worsethanfailure.com/Articles/Overruled-by-RemoveSpecialCharsExceptQuoteAmpersand.aspx

cheers,
Arnar
_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev

Re: Exposing the request object. RequestExposingDjangoGateway

by Arnar Birgisson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey there,

On Nov 28, 2007 11:49 AM, Nick Joyce <nick@...> wrote:
>  If its Django standard practice, then for the Django gateway, we should
> include the request as the first request by default?
>
>  Humm, on second thoughts to keep the underlying service code as portable as
> possible (over gateways), we should include a constructor param to turn this
> on.

Yes, definitely.

Arnar


Re: Exposing the request object. RequestExposingDjangoGateway

by bart vandendriessche-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Right, here comes a bit of personal opinion:

It does fit Django pretty well to provide the request object as the first parameter since this mimics the way Django views work. However, I do believe this is something that users of other frameworks (or users who don't use any framework) might find useful as well. We have previously developed a application using amf and java, where we had a need to access the request object, and it required a bit of a hack there as well. So it might be interesting, if you are planning to provide this functionality through a constructor param, to provide it in the BaseGateway implementation.

Arnar: when I say type of request, I mean the type(request) :) It was slightly confusing to be reading code where the variable's name is 'Request' but the type(variable) is 'Message' or 'Envelope'. If you check the ticket that Nick created, I think that perfectly illustrates my point.

Cheers,
Bart

On Nov 28, 2007 12:56 PM, Arnar Birgisson <arnarbi@...> wrote:
Hey there,

On Nov 28, 2007 11:49 AM, Nick Joyce <nick@...> wrote:
>  If its Django standard practice, then for the Django gateway, we should
> include the request as the first request by default?
>
>  Humm, on second thoughts to keep the underlying service code as portable as
> possible (over gateways), we should include a constructor param to turn this
> on.

Yes, definitely.

Arnar
_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev


Re: Exposing the request object. RequestExposingDjangoGateway

by Nick Joyce :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

If someone put together a service that adds two numbers together (too simplistic I know, but good for illustration), they would write something like this:

def sum(a, b):
    return a + b

To have to write something like:

def sum(request, a, b):
    return a + b

Is ugly, and we need to be able to come up with something better. Also, does the request refer to the AMF request that was made or the underlying protocol (HTTP or RTMP)?

I have been toying with the idea of adding a function variable at execution that holds the context of the request, including the AMF request and (in this case the HTTP request).

So in this case:

def sum(a, b):
    http_request = sum.context.http_request

I'm not 100% on the implementation of this, but you get the idea. I admit, it's an ugly hack and if there is another way, without polluting the argument space of the defining function, let me know about it :)

Thoughts?

On Wed, 2007-11-28 at 13:29 +0100, bart vandendriessche wrote:
Right, here comes a bit of personal opinion:

It does fit Django pretty well to provide the request object as the first parameter since this mimics the way Django views work. However, I do believe this is something that users of other frameworks (or users who don't use any framework) might find useful as well. We have previously developed a application using amf and java, where we had a need to access the request object, and it required a bit of a hack there as well. So it might be interesting, if you are planning to provide this functionality through a constructor param, to provide it in the BaseGateway implementation.

Arnar: when I say type of request, I mean the type(request) :) It was slightly confusing to be reading code where the variable's name is 'Request' but the type(variable) is 'Message' or 'Envelope'. If you check the ticket that Nick created, I think that perfectly illustrates my point.

Cheers,
Bart

On Nov 28, 2007 12:56 PM, Arnar Birgisson <arnarbi@...> wrote:
Hey there,

On Nov 28, 2007 11:49 AM, Nick Joyce <nick@...> wrote:
>  If its Django standard practice, then for the Django gateway, we should
> include the request as the first request by default?
>
>  Humm, on second thoughts to keep the underlying service code as portable as
> possible (over gateways), we should include a constructor param to turn this
> on.


Yes, definitely.


Arnar
_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev


_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev
Nick
--

Nick Joyce

Box Design
www.boxdesign.co.uk

T: +44 (0)117 9044 850
M: +44 (0)7999 822 502

Re: Exposing the request object. RequestExposingDjangoGateway

by Arnar Birgisson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 28, 2007 12:29 PM, bart vandendriessche
<bart.vandendriessche@...> wrote:
> It does fit Django pretty well to provide the request object as the first
> parameter since this mimics the way Django views work. However, I do believe
> this is something that users of other frameworks (or users who don't use any
> framework) might find useful as well. We have previously developed a
> application using amf and java, where we had a need to access the request
> object, and it required a bit of a hack there as well. So it might be
> interesting, if you are planning to provide this functionality through a
> constructor param, to provide it in the BaseGateway implementation.

I disagree. Most frameworks have a different notion of what a request
objects is, and in some contexts there not even a request object per
se. CherryPy for example uses thread-locals for request specific data
and does not pass a request object as parameters. The notion of a
request object being one of the parameters is completely arbitrary and
an implementation detail of the underlying framework.

Also, AMF remoting is not only used in the context of HTTP, there is
also RTMP and possibly others in the future, where a "request object"
doesn't even have a well defined meaning.

cheers,
Arnar


Re: Exposing the request object. RequestExposingDjangoGateway

by bart vandendriessche-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Arnar and Nick, you both raise very good points. My reasoning on this is a bit shortsighted probably.

I do see your concerns about not wanting to pollute the argument space, and the fact that AMF is not solely used in an HTTP context / not all applications share the request notion. I don't see any obvious way in which both these concerns can be satisfied.

I'll do some more digging into python and AMF when time permits, and will share any insights I might get.

Cheers,
Bart

On Nov 28, 2007 1:56 PM, Arnar Birgisson <arnarbi@...> wrote:
On Nov 28, 2007 12:29 PM, bart vandendriessche
> It does fit Django pretty well to provide the request object as the first
> parameter since this mimics the way Django views work. However, I do believe
> this is something that users of other frameworks (or users who don't use any
> framework) might find useful as well. We have previously developed a
> application using amf and java, where we had a need to access the request
> object, and it required a bit of a hack there as well. So it might be
> interesting, if you are planning to provide this functionality through a
> constructor param, to provide it in the BaseGateway implementation.

I disagree. Most frameworks have a different notion of what a request
objects is, and in some contexts there not even a request object per
se. CherryPy for example uses thread-locals for request specific data
and does not pass a request object as parameters. The notion of a
request object being one of the parameters is completely arbitrary and
an implementation detail of the underlying framework.

Also, AMF remoting is not only used in the context of HTTP, there is
also RTMP and possibly others in the future, where a "request object"
doesn't even have a well defined meaning.

cheers,
Arnar
_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev


Re: Exposing the request object. RequestExposingDjangoGateway

by Arnar Birgisson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 28, 2007 1:22 PM, bart vandendriessche
<bart.vandendriessche@...> wrote:
> I do see your concerns about not wanting to pollute the argument space, and
> the fact that AMF is not solely used in an HTTP context / not all
> applications share the request notion. I don't see any obvious way in which
> both these concerns can be satisfied.

I think having it configurable per implementation specific gateways
(such as DjangoGateway) should take care of it fairly cleanly.

> I'll do some more digging into python and AMF when time permits, and will
> share any insights I might get.

Thanks, we value any input.

Arnar


to Bart

by Robert Slotboom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Bart,

Since you are trying some Django-PyAMF stuff, I have a question.
Have you already tried to return some objects (members etc.) from
Django to Flash?
I did but got errors.

Bye,

Rob




Re: to Bart

by bart vandendriessche-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Rob,

Yes we're returning some simple custom objects to flash at the moment. Keep in mind though that we're not doing anything complex at all. We haven't run into any problems just yet.

Cheers,
Bart

On Nov 28, 2007 5:33 PM, Robert Slotboom <rob.slotboom@...> wrote:
Hi Bart,

Since you are trying some Django-PyAMF stuff, I have a question.
Have you already tried to return some objects (members etc.) from
Django to Flash?
I did but got errors.

Bye,

Rob


_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev


Re: to Bart

by Robert Slotboom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Bart,

How did you return the objects without errors then?

Here is what I did.

### urls.py ###
from django.conf.urls.defaults import *

urlpatterns = patterns('flashboard.customers.gateway',
    url(r'^gateway/', 'gateway', name="show_gateway"),
)

### gateway.pt ###
from django_apps.pyamf.gateway.django import DjangoGateway
import amf_views
gateway = DjangoGateway({'customerData': amf_views})

### amf_views.py ###
from flashboard.customers.models import CustomerInfo, Category

def echo(data):
    return data

def getCategories():
    return Category.objects.all().values()

def getCategoriesAsStr():
        ret_str = ''
        for c in Category.objects.all():
                ret_str += " | %s" % c.Name
        return ret_str

def getCustomers(customer_id):
    return
CustomerInfo.objects.filter(CategoryID__exact=customer_id).values()

### result ###
Calling service method getCategories from within Flash makes the server
crash.
Calling  getCategoriesAsStr works fine.

Maybe you have a clue?

Bye,

--Rob

Re: to Bart

by bart vandendriessche-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well, I wouldn't really know, but have you checked what happens when you return a single Category or CustomerInfo object ?

Right now it seems like you're trying to serialize a ValuesQuerySet object which contains a bunch of dict's. I haven't looked at the source for the ValuesQuerySet object, but maybe something blows up trying to serialize that ?

If you manage to send a single Category object to flash, I would try to convert the ValuesQuerySet into a tuple or a plain list and send that.

On Nov 29, 2007 8:51 AM, Robert Slotboom < rob.slotboom@...> wrote:
Hi Bart,

How did you return the objects without errors then?

Here is what I did.

### urls.py ###
from django.conf.urls.defaults import *

urlpatterns = patterns('flashboard.customers.gateway',
   url(r'^gateway/', 'gateway', name="show_gateway"),
)

### gateway.pt ###
from django_apps.pyamf.gateway.django import DjangoGateway
import amf_views
gateway = DjangoGateway({'customerData': amf_views})

### amf_views.py ###
from flashboard.customers.models import CustomerInfo, Category

def echo(data):
   return data

def getCategories():
   return Category.objects.all().values()

def getCategoriesAsStr():
       ret_str = ''
       for c in Category.objects.all():
               ret_str += " | %s" % c.Name
       return ret_str

def getCustomers(customer_id):
   return
CustomerInfo.objects.filter(CategoryID__exact=customer_id).values()

### result ###
Calling service method getCategories from within Flash makes the server
crash.
Calling  getCategoriesAsStr works fine.

Maybe you have a clue?

Bye,

--Rob

_______________________________________________
PyAMF dev mailing list - dev@...
http://lists.pyamf.org/mailman/listinfo/dev



Django returns an object!!

by Robert Slotboom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Nick, Arnar, Bart,

Today I updated the pyamf source an changed my testcode a bit:

### customers/amf_views.py ###

def getCustomer(ID):
    return CustomerInfo.objects.get(ID__exact=ID)


### flashboard.fla ###

[snip...]
var myService:Service = new  
Service("http://192.168.1.50:8000/customers/ 
gateway/",null,"customerData", null, null);
trace( "no response from server yet." );

var param = "Hello World!";
var pc1:PendingCall = myService.echo(this.param);
pc1.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");

var pc2:PendingCall = myService.getCustomer(6);
pc2.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");

### Flash traces ###

no response from server yet.
[object Object]
Hello World!

Seems like some progress } : o )


Robert Slotboom

Re: Django returns an object!!

by Arnar Birgisson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Robert,

Ok, then the problem seems with returning list results.

>From your earlier attemts, try explicitly evaluating the queries to lists with

def getCategories():
   return list(Category.objects.all())

as Bart suggested.

Arnar

On Nov 29, 2007 3:52 PM, Robert Slotboom <rob.slotboom@...> wrote:

> Hi Nick, Arnar, Bart,
>
> Today I updated the pyamf source an changed my testcode a bit:
>
> ### customers/amf_views.py ###
>
> def getCustomer(ID):
>     return CustomerInfo.objects.get(ID__exact=ID)
>
>
> ### flashboard.fla ###
>
> [snip...]
> var myService:Service = new
> Service("http://192.168.1.50:8000/customers/
> gateway/",null,"customerData", null, null);
> trace( "no response from server yet." );
>
> var param = "Hello World!";
> var pc1:PendingCall = myService.echo(this.param);
> pc1.responder = new RelayResponder(this, "getData_Result",
> "getData_Fault");
>
> var pc2:PendingCall = myService.getCustomer(6);
> pc2.responder = new RelayResponder(this, "getData_Result",
> "getData_Fault");
>
> ### Flash traces ###
>
> no response from server yet.
> [object Object]
> Hello World!
>
> Seems like some progress } : o )
>
>
> Robert Slotboom
>
> _______________________________________________
> PyAMF dev mailing list - dev@...
> http://lists.pyamf.org/mailman/listinfo/dev
>
>


Re: Django returns an object!!

by lists-144 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for the update Robert because I think you found a bug..

no response from server yet.

[object Object]

Hello World!



I don't see why that "Hello World!" trace is not shown first. I opened ticket #105

Cheers,

Thijs


Re: Django returns an object!!

by Robert Slotboom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Thijs,


> Thanks for the update Robert because I think you found a bug..
>
>> no response from server yet.
>> [object Object]
>> Hello World!
>>
>
> I don't see why that "Hello World!" trace is not shown first. I opened
> ticket #105

Sorry, I should have told you earlier.

Another strange behaviour:

urlpatterns += patterns('flashboard.customers.gateway',
    (r'^gateway/', 'gateway'),
)

After updating to the latest version of PyAMF I get a Django template
errors when entering admin.

TemplateSyntaxError at /admin/
'adminapplist' is not a valid tag library: Could not load template
library from django.templatetags.adminapplist, cannot import name
template
Request Method: GET
Request URL: http://192.168.1.50:8000/admin/
Exception Type: TemplateSyntaxError
Exception Value: 'adminapplist' is not a valid tag library: Could not
load template library from django.templatetags.adminapplist, cannot
import name template
Exception Location:
        /usr/local/lib/python2.5/site-packages/django/template/defaulttags.py
in load, line 859
Python Executable: /usr/local/bin/python
Python Version: 2.5.1



Cheers,
--Rob




Re: Django update

by Robert Slotboom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

An update if the current results trying to get the flash customer app  
sample running using Django and PyAMF.

### models.py ###

class Category(models.Model):
    ID_CHOICES = (
       ('B', 'Billable'),
       ('N', 'Nonbillable'),
       ('P', 'Prospect'),
    )
    ID = models.CharField(maxlength=1, primary_key=True,  
choices=ID_CHOICES)
    Name = models.CharField(maxlength=50)
    Description = models.CharField(maxlength=50)

class CustomerInfo(models.Model):
    ID = models.AutoField(primary_key=True)
    CategoryID = models.ForeignKey(Category)
    Name = models.CharField(max_length=50)
    Active = models.BooleanField()
    Logo = models.CharField(maxlength=50)
    Details = models.CharField(maxlength=255)
    TotalSales = models.DecimalField(max_digits=8, decimal_places=2)

### urls.py ###

from django.conf.urls.defaults import *

urlpatterns = patterns('flashboard.customers.views',
    url(r'^$', 'list', name="show_customer_list"),
    url(r'^(?P<customer_id>\d+)/$', 'details',  
name="show_customer_details"),
)

urlpatterns += patterns('flashboard.customers.gateway',
    (r'^gateway/', 'gateway'),
)

### gateway.py ###

from django_apps.pyamf.gateway.django import DjangoGateway
import amf_views
gateway = DjangoGateway({'customerData': amf_views})


### amf_views.py ###
from flashboard.customers.models import CustomerInfo, Category

def echo(data):
    return data

def getCategories():
    return list(Category.objects.all())

def getCategory(ID):
    return Category.objects.get(ID__exact=ID)

def getCustomers(CategoryID):
    return  
list(CustomerInfo.objects.filter(CategoryID__exact=CategoryID))

def getCustomer(ID):
    return CustomerInfo.objects.get(ID__exact=ID)

### Flash MX 2004 AS 2 ###
import mx.remoting.Service; // import Service class
import mx.rpc.FaultEvent; // import FaultEvent class
import mx.remoting.PendingCall // import PendingCall class
import mx.rpc.ResultEvent // import ResultEvent class
import mx.rpc.RelayResponder // import RelayResponder class

mx.remoting.debug.NetDebug.initialize();
var myService:Service = new  
Service("http://192.168.1.50:8000/customers/ 
gateway/",null,"customerData", null, null);
trace( "no response from server yet." );

// This var holds the data we want to pass to the remote service.
var param = "Hello World!";
var pc1:PendingCall = myService.echo(this.param);
pc1.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");
// This var is a customer we want to get
var Customer_ID = 6;
var pc2:PendingCall = myService.getCustomer(Customer_ID);
pc2.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");
// This var is a category we want to get
var Category_ID = "B";
var pc3:PendingCall = myService.getCategory(Category_ID);
pc3.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");
// This var is a customer category we want to get
var Category_ID = "B";
var pc4:PendingCall = myService.getCustomers(Category_ID);
pc4.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");

// Get all categories
var pc5:PendingCall = myService.getCategories();
pc5.responder = new RelayResponder(this, "getData_Result",  
"getData_Fault");

function getData_Result( re:ResultEvent ):Void { // receive result
        trace( re.result );
}

function getData_Fault( fe:FaultEvent ):Void {
        trace( "There was a problem: " );
        for (var prop:String in fe.fault){
                trace(prop + " - "  + fe.fault[prop]);
        }
}

### Ze trace ###

no response from server yet.
[object Object],[object Object],[object Object]
[object Object],[object Object]
[object Object]
[object Object]
Hello World!

hth,

Rob
< Prev | 1 - 2 | Next >