[Twisted-Python] Direct access to main server class

Terry Jones terry at jon.es
Mon Aug 28 16:31:37 EDT 2006

>>>>> "JP" == Jean-Paul Calderone <exarkun at divmod.com> writes:

JP> Aside from the rest of your question and my response, this sounds
JP> inside out.  The general idea is that the user object itself has
JP> methods which implement the actions which the protocol allows to be
JP> taken.  If a user lacks permission to perform a particular action, or
JP> has restrictions on the particulars with which they may invoke that
JP> action, or whatever other logic may be necessary on a per-user basis,
JP> that is represented by a different implementation of the login
JP> interface.

OK, thanks for this explanation. As for the inside-out part, I do want
things to be that way. E.g., there are methods that anyone can call and
what you get back depends on the set of permissions on the things you
request and also on your own preferences. So it's not known a priori what
the user can and can't do - at least not at that fine grained level. At
higher levels, sure, I do understand about returning user objects that
simply do not have access to prohibited methods.

After sending my mail I realized I should have gone to look through the
top-level docs before mailing. There I found mention of Trial. I was going
to follow up, but decided to see what people would suggest. You don't
mention Trial however, and nor has anyone else yet. (Go on, tell me it's
deprecated :-))

JP> It may not necessarily be the case that factoring your code as I've
JP> just described would be better than what you are doing now, but if you
JP> haven't considered it before, it may be worth doing so now.

I will certainly do it to some extent.

JP> Your server is started up from a .tac file.


JP> The .tac file creates some objects and gives them particular
JP> relationships.

Just one instance of my top-level class. That class knows how to provide
password checkers.

JP> The relationships created in the .tac file are necessary for correct
JP> operation of the server.

No. The main thing that's needed after my last round of changes is that API
methods are called in the context of an authenticated user.

JP> The unit tests have no way to run the code in the .tac file in order to
JP> duplicate these relationships.

Right, except if I hack an end run around twisted.cred. But I don't really
_want_ to do that. And if I've started a server via myApp.tac, then it
feels (though it may not be the case) like I'm asking for trouble by simply
instantiating and using another instance of my top-level class. Although
the point is to allow highly parallel access, I was intending to do that
through (e.g., a thread pool) created by a single twistd application.  I'm
not sure I want to have possibly many of them running at once (though
perhaps I should, since this is part of the point). Does that make sense?

I could configure the unit tests to just use a different setup (different
DB etc) so it has nothing to do with the server version. That's in fact
what I used to do. I was mainly asking: now that I've built a nice new
front door using twisted.cred, how do I convert my existing unit tests to
all go through the door, changing as little as possible.

>> 1) Fake it. Call directly into my code to make myself an authenticated
>> user object, and then start passing it in to methods on my own
>> class. This is ugly though, plus if the service is already running it's
>> a bad solution because it goes behind the back of twisted and asks for
>> trouble.

JP> This actually sounds a little like what I described above.  What makes
JP> you say it is ugly?  To me, it sounds like organizing your code so that
JP> you can test it a unit at a time.  The tests which do this are testing
JP> the behavior of your code when authentication has already succeeded.
JP> You should also have tests for your authentication code, of course -
JP> but that's a separate unit.

It feels ugly in the way that Trial (if I understand it) feels right.
There's an approved way to access the service, and robust tests should go
through it. I don't fully believe this - I guess some combination, as you
suggest, is probably going to be best. It feels ugly because, as I said,
having built a new front door, I immediately hack my way around it.

>> 2) Make all the methods of my class available via RPC and have all the
>> unit test code use them. This seems like a major pain, though I suppose
>> it would work.

JP> In the past I have done this, and I have regretted it.  This kind of
JP> test is unnecessarily expensive to run and unnecessarily difficult to
JP> debug.


>> I'd much rather just have the unit test code connect as a special local
>> user and get back the instance of MyClass created by my .tac file and
>> call its methods. Is that easy to do?

JP> If you move the code responsible for instantiating MyClass out of the
JP> .tac file into a real module, then it is easy :)

Yes, modulo having multiple instances. I can deal with that though.

>> OK, sorry for another typically long posting....

JP> No problem.  I hope this was of some help.

Yes, it's great, thanks for answering. I feel like such a babe in the woods
with Twisted! Part of it, I guess, is only really getting to work on this
stuff when I'm not doing what I'm actually supposed to be doing.

Here's one more question, about cred. Given your initial comment and my
emerging understanding of what goes on, what you call a user object
(perhaps only because I called it that) is what's elsewhere called an
avatar. If so, it seems an avatar can be anything at all and that generally
an avatar is an instance of some class, and that that class has methods
which the connecting user is allowed to call. I almost want to say "don't
bother answering, I know I must be right", but I won't delete this
paragraph just in case there are any other fundamental comments anyone
might make.


More information about the Twisted-Python mailing list