Re: [Twisted-web] Re: Thoughts on documentation, wading into Twisted, Nevow, etc.
Thanks for all the very thoughtful replies to my long mail. I didn't mean to whine about things and then just disappear back into the woodwork, I just have to deal with various other things right now. I'm thinking about what I wrote, the various replies, what might be effectively done, etc. I hope to be able to follow up again soon. Terry
Hi Terry, On Thu, July 6, 2006 1:25 pm, Terry Jones wrote:
Thanks for all the very thoughtful replies to my long mail. I didn't mean to whine about things and then just disappear back into the woodwork, I just have to deal with various other things right now. I'm thinking about what I wrote, the various replies, what might be effectively done, etc. I hope to be able to follow up again soon.
I was one of the respondents to your much welcomed critique of Twisted documentation. And I would like to explore with you and others how to contribute toward improved Twisted documentation. Here's what I've done to date to make Twisted more available to the less technially astute: http://twisted.paisite.com. For reasons good and bad the Techno project is stalled, but it might be worth picking up again. It seems to me that one of the first questions in software documentation is: "Who are we writing for?" Given that, the next question is: "Who much or how little can we assume that our consumers already know?" Several questions, then, for the Twisted community: -- Are we satisfied with the current level of adoption of Twisted in new projects; e.g. do we want to remain a relatively small commmunity of elite developers and user or would we like to attract and build a broader community? -- Is the corpus of Twisted documentation as it stands sufficiently serving the needs of the community or is it holding back our efforts toward longer-term goals? -- What, if any, are the shortcomings of current documentation? -- Is it possible for us, given all constraints, to better organize our efforts toward improved documentation and, if so, how? Here's my personal experience with Twisted: I spent considerable time last year studying Twisted documentation. I was encouraged by an assertion that the Twisted developers were hoping for widest possible adoption of the Twisted framework. But as I moved further into the docs I discovered that much of it was written in a highly specialized argot -- jargon or precise technical language I'll let someone else decide. But, with full acknowledgement of my own inexperience and shortcomings, much of it was completely incomprehensible to me. And looking at the source code I found numerous syntactical constructs that I simply couldn't penetrate. Now, granted, I had and still have limited experience with Linux, Python, and object architectures. But I was highly motivated to learn what I needed to know to use Twisted in my own projects. As I widened my studies and dug deeper I discovered yet another problem: Trying to discern a roadmap through the Twisted thickets was like following a well-paved road that turned into graded dirt then diverged into countless sandy paths that then faded into the desert. After several weeks pursuing the fractal-like tracks I, for one, felt stranded far from water and shade. What finally did me in was a severe electrical storm which blew out the machine on which I was doing my Twisted experimentation. Now I take full responsibility for my own intellectual and experiential shortcomings. Fact is, many good people put countless hours into creating the Twisted corpus of code and documentation. And I'm grateful for every minute of it. If they didn't reach me, it's not their problem. It's mine. But as your critique attests, backed by many others on the various lists, I'm not the only one looking enviously in on the party. I would have liked very much to have mastered, or at least sufficiently understood Twisted, to integrate it into my own projects, but there was simply not world enough nor time given the current state of docs. Now, encouraged by others seeking improved Twisted documentation, I'm delighted to offer again my limited skills toward that goal. But I need folks with knowledge beyond mine to lay out the path and point the way. All the best, Lloyd R. Prentice President Prentice Associates Incorported
On Thu, 6 Jul 2006 15:34:16 -0400 (EDT), lloyd@paisite.com wrote:
It seems to me that one of the first questions in software documentation is: "Who are we writing for?"
Given that, the next question is: "Who much or how little can we assume that our consumers already know?"
Several questions, then, for the Twisted community:
-- Are we satisfied with the current level of adoption of Twisted in new projects; e.g. do we want to remain a relatively small commmunity of elite developers and user or would we like to attract and build a broader community?
I don't think we can be satisfied but unfortunately IMHO the real problem with twisted is not twisted itself but the big shift in the way you should think that drives away most people. I know many intelligent and very capable programmers that do understand twisted (or are able to) but they do not intend to learn it because they feel it's hard while threading isn't as hard as we picture it. Having more and better documentation will help, many graphs about how things actually work _DO_ help but you can do only so much to attract new people. One of the most needed things is to collect a page inside twisted documentation about the many reasons why threading is harder than the twisted approach and why. Currently there are many documents that try to explain this at various levels but a single, clear and simple one is missing. Even writing two alternatives using the two different models could probably help.
-- Is the corpus of Twisted documentation as it stands sufficiently serving the needs of the community or is it holding back our efforts toward longer-term goals?
I don't think I can answer this question. When I first learnt twisted I used the documentation and found it pretty good.
-- What, if any, are the shortcomings of current documentation?
Maybe it's too concise. Every word in the current documentation must be carefully read because it's meaning is incredibly important to actually understand the text. Some things are implicit in the meaning given to that word and are never explained.
-- Is it possible for us, given all constraints, to better organize our efforts toward improved documentation and, if so, how?
Here's my personal experience with Twisted:
I spent considerable time last year studying Twisted documentation. I was encouraged by an assertion that the Twisted developers were hoping for widest possible adoption of the Twisted framework. But as I moved further into the docs I discovered that much of it was written in a highly specialized argot -- jargon or precise technical language I'll let someone else decide. But, with full acknowledgement of my own inexperience and shortcomings, much of it was completely incomprehensible to me.
Yes, that's what I mean by 'concise'.
And looking at the source code I found numerous syntactical constructs that I simply couldn't penetrate.
This is another 'defect'. Twisted developers are extremely capable in python and they tend to use the language as much as possible. Of course this requires the same knowledge from the reader. In my opinion this is a good thing overall, the only problem is that sometimes docstrings are missing and this makes reading code harder than it could be. HTH :)
On Fri, 07 Jul 2006 07:10:51 -0500, Valentino Volonghi aka Dialtone <dialtone@divmod.com> wrote:
On Thu, 6 Jul 2006 15:34:16 -0400 (EDT), lloyd@paisite.com wrote:
It seems to me that one of the first questions in software documentation is: "Who are we writing for?"
Given that, the next question is: "Who much or how little can we assume that our consumers already know?"
Several questions, then, for the Twisted community:
-- Are we satisfied with the current level of adoption of Twisted in new projects; e.g. do we want to remain a relatively small commmunity of elite developers and user or would we like to attract and build a broader community?
I don't think we can be satisfied but unfortunately IMHO the real problem with twisted is not twisted itself but the big shift in the way you should think that drives away most people. I know many intelligent and very capable programmers that do understand twisted (or are able to) but they do not intend to learn it because they feel it's hard while threading isn't as hard as we picture it. Having more and better documentation will help, many graphs about how things actually work _DO_ help but you can do only so much to attract new people.
I think that worrying about attracting an audience that prefers to use the thread-based approach is doomed to failure, in the same way that inviting a conservative to adopt liberal ideals is doomed to failure.
One of the most needed things is to collect a page inside twisted documentation about the many reasons why threading is harder than the twisted approach and why. Currently there are many documents that try to explain this at various levels but a single, clear and simple one is missing. Even writing two alternatives using the two different models could probably help.
I don't think this would help much either, in that people who like to use threads most definitely do *not* see them as being harder to use than the twisted approach; on the contrary, they find threads to be far more natural to their way of thinking, and most of them have never run into the kinds of serious problems that threading can introduce. I sincerely believe that until a person actually encounters a serious thread-related problem, they cannot be convinced to adopt anything that does what twisted does.
-- Is the corpus of Twisted documentation as it stands sufficiently serving the needs of the community or is it holding back our efforts toward longer-term goals?
I don't think I can answer this question. When I first learnt twisted I used the documentation and found it pretty good.
I have to agree here. I have used twisted since the 0.9 days, and I have always found the documentation to be perfectly adequate. Honestly, while I recognize that the vast majority of interested parties find the docs to be incomplete or confusing, I have never had the problem, and so I am struggling somewhat in understanding how to solve it. Note that I am the furthest thing from an expert programmer, in any field, so I don't think the "only really smart people can understand twisted" argument doesn't hold in my case. Quite the opposite, actually; I use twisted because it solves a lot of the hard problems for me, and I can just concentrate on my application. Perhaps the problem is that the twisted docs primarily teach the theory of operation (Deferreds, Protocols, etc.). For someone like myself, the theory of operation is exactly what I want to know. For others, I suspect there is more value in documentation that covers things of a very specific nature, such as "how to build a web application that talks to a database", or "how to build a DNS server", or other such use-case-oriented fare. If so, then the real problem is that using twisted requires you to learn the underlying structure (Deferreds, Protocols, etc) before you can get started on your application. There is a movement these days in many projects to get the user up and running without any prior understanding, the thinking being that they will pick up the details later, as needed. Personally, my brain doesn't work that way, but I know many people who cannot tolerate my approach, and find it unbearably slow. So, maybe a "Build a real, working, application in 15 minutes" is the kind of fare needed to make twisted more palatable to the audience that is currently being frustrated in achieving twisted zen. L. Daniel Burr
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 L. Daniel Burr wrote:
On Fri, 07 Jul 2006 07:10:51 -0500, Valentino Volonghi aka Dialtone
I think that worrying about attracting an audience that prefers to use the thread-based approach is doomed to failure, in the same way that inviting a conservative to adopt liberal ideals is doomed to failure.
Well said. Let's focus on the positives of Twisted, not the negatives of threading. The ones I always come back to are integrating multiple protocols and absurdly easy development of new protocols. The big cloud of utilities like t.py.usage, the service framework, etc. are also big plusses. Stuff like 'better than threads' and 'integrates with all these gui toolkits' are not so much evangelism features as they are *reactions to objections to Twisted*. Specifically, they are reactions objections that "threading is easier" and "but I can't use Twisted with GTK/qt/...". We need to document those things, but if your goal in writing documentation is to get the reader hooked early on, put the other stuff first.
I don't think this would help much either, in that people who like to use threads most definitely do *not* see them as being harder to use than the twisted approach; on the contrary, they find threads to be far more natural to their way of thinking, and most of them have never run into the kinds of serious problems that threading can introduce. I sincerely believe that until a person actually encounters a serious thread-related problem, they cannot be convinced to adopt anything that does what twisted does.
I can actually quibble with this notion from personal experience: I used Twisted before I did more than very trivial experiments with threading. I read and understood in concept the problems with threading. Only later on, when I tried to use threads in my Twisted programs did I encounter the hazards of threading. This is important because it anecdotally demonstrates that programmers don't always go straight to threads. If they understand from the start that concurrency is going to be hard, they will be (as I was) suspicious of what threads do, and might (as I did) seek experts who've done this stuff before. I don't think we can control who goes to threads and who goes to the asynchronous model, but there will be some of each.
I have to agree here. I have used twisted since the 0.9 days, and I have always found the documentation to be perfectly adequate. Honestly, while I recognize that the vast majority of interested parties find the docs to be incomplete or confusing, I have never had the problem, and so I am struggling somewhat in understanding how to solve it.
I think I understand the problem. The problem is that concurrency is hard. If you're a new programmer, and you want to start with "a simple network game" (because somebody told you not to start with Doom), you're going to discover all kinds of complexity that your brain isn't formatted to handle. And Twisted's documentation doesn't do that for you. It assumes that you understand that new programmers should start with a simple *text processor*, not a simple network game, then work up to a simple clone of nibbles, then maybe give a personal IRC bot a try, then ... It assumes, in short, that you've already done all that, and you're ready to write a real application at this level. Should it mention that that other ground must be covered first or you'll be unhappy with the results? It could. Should it cover all that ground for you? No way. It's not about how smart you are, it's about whether you have the relevant experience to write an application that actually needs Twisted. I think anyone who actually has the experience necessary to tackle an application with concurrency is going to find the doc a lot more friendly than someone who doesn't. I don't know that that's Twisted's fault.
Perhaps the problem is that the twisted docs primarily teach the theory of operation (Deferreds, Protocols, etc.). For someone like myself, the theory of operation is exactly what I want to know. For others, I suspect there is more value in documentation that covers things of a very specific nature, such as "how to build a web application that talks to a database", or "how to build a DNS server", or other such use-case-oriented fare. ... So, maybe a "Build a real, working, application in 15 minutes" is the kind of fare needed to make twisted more palatable to the audience that is currently being frustrated in achieving twisted zen.
Totally agree here, but I still think someone who is ready to "build a web application that talks to a database" is going to understand the walkthrough a lot better than someone who isn't. (I thought the finger tutorial actually covered that, but I guess it doesn't on quick skim-through.) Just a final thought: there's still lots of areas that *aren't* adequately documented by anyone's standards. There are areas not covered by examples, there are areas not covered by HOWTO's. The core is covered, but any new application worth writing probably uses stuff from the fringes. So our hypothetical new Twisted user starts out writing her new application, gets a handle on the core stuff, and then discovers those gaps in the fringes. That can be frustrating. Everyone uses a different part of the fringes, so the fringes need to be covered almost as well as the core. C -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFErq5t3A5SrXAiHQcRAkUEAJ9nvBkTSq1/M43lm+XWTmlbfUdVDgCeMfUs 4QQgyJYHgK1qVpD1zPosEtA= =A5qF -----END PGP SIGNATURE-----
Cory Dodt wrote:
I think that worrying about attracting an audience that prefers to use the thread-based approach is doomed to failure, in the same way that inviting a conservative to adopt liberal ideals is doomed to failure.
Yes!
I can actually quibble with this notion from personal experience: I used Twisted before I did more than very trivial experiments with threading. I read and understood in concept the problems with threading. Only later on, when I tried to use threads in my Twisted programs did I encounter the hazards of threading.
Same here. Ages ago, at about the age of 21 when I was less smart but harder working and NIH seemed like a reason, I wrote a parallel SNMP poller. I copied the mainloop straight out of fping and ported it to python. It was trivially obvious even in my naivety that no thread-based approach was going to serve ~3000 simultaneous "threads". I looked at Stackless, but it (foolishly IMHO) was derided by the BDFL. I didn't know about Twisted or asyncore (shudder - though when I did finally see it I retched on my keyboard). But I immediately understood the problem and the correct solution. Twisted was something I found later on to do away with my custom loop code and concentrate on application code. Now I can tack a web interface onto the poller. Oh, and an SSH CLI. Oh, and an SNMP *proxy*.
This is important because it anecdotally demonstrates that programmers don't always go straight to threads. If they understand from the start that concurrency is going to be hard, they will be (as I was) suspicious of what threads do, and might (as I did) seek experts who've done this stuff before.
If Python were Erlang (i.e. had stackless), Twisted would not exist. But it's not, so it does.
I think I understand the problem. The problem is that concurrency is hard. If you're a new programmer, and you want to start with "a simple network game" (because somebody told you not to start with Doom), you're going to discover all kinds of complexity that your brain isn't formatted to handle.
Yep. Simple problems have simple solutions. Complex problems - anyone even contemplating solving them has a good chance of knowing why the simple solutions have failed.
It's not about how smart you are, it's about whether you have the relevant experience to write an application that actually needs Twisted. I think
Yes, yes, yes!
anyone who actually has the experience necessary to tackle an application with concurrency is going to find the doc a lot more friendly than someone who doesn't. I don't know that that's Twisted's fault.
It certainly is not. The previous two mails encapsulate to my mind the core of the issue. Anyone who needs Twisted, knows it. Anyone who doesn't cannot be persuaded otherwise. They will either discover it, or never need it (and more power to them - but that's not me). Though it rankles, maybe advertising Twisted as a "specialist" framework would make more sense?
On Sat, 08 Jul 2006 00:14:38 +0100, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
If Python were Erlang (i.e. had stackless), Twisted would not exist. But it's not, so it does.
I think that Twisted might still exist. The protocol implementations in the standard library are pretty bad and it includes very few servers. Stackless itself, for example, does not include a viable competitor to Twisted (or at least it didn't, when I last looked at it). The idea behind Twisted is, event driven programming is cool, but we need a standard event model (reactor) in order to write cooperating event-driven programs. You need this even if your lanaguage supports continuations and coroutines, unless the language itself has _very_ good internal process control and I/O management -- few do. Python's recent efforts to grow asynchronous coroutines (yield expressions, etc) are a great example of why this is not a language problem, it's a library and support and conventions problem. The language can give you some support, but unless the runtime is built around these concepts and already includes the support code and conventions that you need, syntax and one-off VM features won't help.
The previous two mails encapsulate to my mind the core of the issue. Anyone who needs Twisted, knows it. Anyone who doesn't cannot be persuaded otherwise. They will either discover it, or never need it (and more power to them - but that's not me).
This is not quite true. There are certainly a lot of Python applications - especially the GNOME GUI stuff - that would be a lot better off if they used Twisted but there is a cultural opposition or ignorance of Twisted.
Though it rankles, maybe advertising Twisted as a "specialist" framework would make more sense?
It's not specialist though. It's generally useful in a huge variety of problem domains. Even if you're just doing IPC, not network IO, Twisted can help prevent deadlocks and generally make applications a lot more robust. The "specialist" label is an unnecessary compromise; if our documentation is crap for some of those domains, then let's just say *that*, and all work to improve it, rather than pretend that there is something wrong with the technology itself as an excuse. If we officially say "this is not a general-purpose tool", then pretty soon all the functionality it provides outside the "specialist" area we artificially create for it will atrophy and eventually be removed.
Hi Valentino, On Fri, July 7, 2006 8:10 am, Valentino Volonghi aka Dialtone wrote:
I don't think we can be satisfied but unfortunately IMHO the real problem with twisted is not twisted itself but the big shift in the way you should think that drives away most people. I know many intelligent and very capable programmers that do understand twisted (or are able to) but they do not intend to learn it because they feel it's hard while threading isn't as hard as we picture it.
This doesn't really get at my mental stumbling blocks. I find the arguments for adopting the Twisted approach quite compelling -- indeed they've fueled my interest and attempts to understand. I think I understand the theory -- if somewhat dimly. But, for me, there seem to be big gaps in the explanatory connections between theory, application, and code. I can't look at a snippet of Twisted code and tell you why it was written the way it was; much less write my own code. It's quite possible that I need more hand-holding than the majority. And it may not be of interest to the community, nor simply cost-effective, to reach down to folks at my level of incompetence. But, look at it another way, if I can be made to understand through better documentation then you know you're reaching the widest possible audience. Think of me as a tough unit test for documentation. Note that I have not looked at the documentation in nearly a year; it may very well have improved substantially since then.
Even writing two alternatives using the two different models could probably help.
As I recall, one of the Python books does this. Code that I can enter, run, and experiment with is definitely helpful in my case. One of the problems that I have with many of the code examples in the Twisted docs is that I don't understand what they're intended to do nor why I would want to do it. May very well be just the widget I need, but lack of context keeps me in the dark. I'm referring here to many of the examples in: http://twistedmatrix.com/projects/web/documentation/examples/
I don't think I can answer this question. When I first learnt twisted I used the documentation and found it pretty good.
Others have said this as well, so clearly the docs are good so far as they go. The question is, can they be improved to reach a wider audience and, if so, how? And are there enough generous folks around with the time, will, and competencies to make it happen?
Maybe it's too concise. Every word in the current documentation must be carefully read because it's meaning is incredibly important to actually understand the text. Some things are implicit in the meaning given to that word and are never explained.
Amen. I found that when I tried to track down enlightening definitions of many of the technical terms in the Twisted documentation I got stuck in tautological loops. This was a clue to me that some of the documentation is the language of an in-group who have worked together closely enough and long enough to have a large body of tacit understandings and assumptions that have not found their way into the docs. This is not a bad thing, per se -- as long as the in-group is only talking among itself. But it does point to a strategy for improving the docs to make them more accessable to more people. Years ago, general semantist S. I. Hayakawa proposed the "ladder of abstraction." Many language constructs, he proposed, can be arrayed on a "ladder of abstraction," starting at the first rung with, say, a pointing operation (I point to Bessie the cow grazing in the field) and ranging up through "Bessie," a symbolic tag attached to the perceptual object; "cow;" "ruminant;" "livestock;" "agricultural asset;" and "enterprise capital," etc. If I'm thinking Bessie and use the term "agricultural asset," you may picture a tractor in your mind and... we've just miscommunicated by a fair stretch. Anyway, this is old stuff. The solution is not to avoid abstractions -- they're powerful and useful -- but to be careful in using highly abstract words... qualify them by moving down the ladder of abstraction as far as possible, ideally to a pointing operation -- in our case, an object diagram or a working code snippet.
This is another 'defect'. Twisted developers are extremely capable in python and they tend to use the language as much as possible. Of course this requires the same knowledge from the reader.
I'm not sure I would call this a defect. We want developers to write the most efficient code possible. But if a world-class programmer needs less competent programmers to understand and/or support or use the code, then he/she is obligated to provide contextual documentation that communicates at a level that the code consumers can understand. And, if the programmer can't do it, then he/she would be wise to recruit/enlist competent documentation writers and spend the time necessary to help them understand what they need to know. I understand, of course, that in the all-volunteer open source army, this is a difficult thing to do.
In my opinion this is a good thing overall, the only problem is that sometimes docstrings are missing and this makes reading code harder than it could be.
Yes, clearer and more abundant docstrings would definitely help me, at least. As would better definitions of technical terms, with explanatory examples, illustrations, diagrams and code snippets where this would help; and more short application examples with thorough contextual explanations of why the code was written the way it was. Many thanks, Valentino, for your thoughtful consideration of the issue. Do you have the time and will to help me develop more Techno Turkey Adventures? Best wishes, Lloyd R. Prentice
On Fri, 7 Jul 2006 13:13:48 -0400 (EDT), lloyd@paisite.com wrote:
Note that I have not looked at the documentation in nearly a year; it may very well have improved substantially since then.
Indeed it has but not enough probably.
Code that I can enter, run, and experiment with is definitely helpful in my case. One of the problems that I have with many of the code examples in the Twisted docs is that I don't understand what they're intended to do nor why I would want to do it. May very well be just the widget I need, but lack of context keeps me in the dark.
I'm referring here to many of the examples in:
http://twistedmatrix.com/projects/web/documentation/examples/
This is a matter of documenting examples... a problem pretty common with all the twisted-related frameworks I know.
I'm not sure I would call this a defect. We want developers to write the most efficient code possible. But if a world-class programmer needs less competent programmers to understand and/or support or use the code, then he/she is obligated to provide contextual documentation that communicates at a level that the code consumers can understand. And, if the programmer can't do it, then he/she would be wise to recruit/enlist competent documentation writers and spend the time necessary to help them understand what they need to know.
I understand, of course, that in the all-volunteer open source army, this is a difficult thing to do.
It's harder the smaller the community is, the only fact that we are discussing about improving documentation means that the community is growing anyway.
Many thanks, Valentino, for your thoughtful consideration of the issue.
Do you have the time and will to help me develop more Techno Turkey Adventures?
I wouldn't mind helping out, hopefully the discussion can take place in this mailing list so that other people (if they want) can help answering/completing/ fixing/evaluating what we write. Thanks for bringing up this topic anyway.
On Fri, July 7, 2006 4:20 pm, Valentino Volonghi aka Dialtone wrote:
On Fri, 7 Jul 2006 13:13:48 -0400 (EDT), lloyd@paisite.com wrote:
Do you have the time and will to help me develop more Techno Turkey Adventures?
I wouldn't mind helping out, hopefully the discussion can take place in this mailing list so that other people (if they want) can help answering/completing/ fixing/evaluating what we write.
Many thanks. I need to rebuild my Twisted environment -- got blasted away last year by an electrical storm. I'll try to have it back up sometime next week. Meanwhile, as you'll note in http:twisted.paisite.com, we had developed four adventures focusing on twisted.web. The last adventure brought up a very simple-minded web-page. I waved my hands a bit in explicating the code. I'm not fully comfortable yet with the concepts introduced. It would be tremendously helpful to have a road-map that spells out a step-by-step development of concepts and suggested programming excercises designed to deepen the programmer's understanding of Twisted and how to effectively apply it. In other words, "where next? ...and next?" I'm not competent enough to lay out the road-map nor to write the exemplary code. Each step in the road-map, then can be the subject of back-and-forth Q&A aimed at bringing crystal clarity to the concepts and guiding the development of code examples. With enough people participating it could be fun, without an undue amount of work for any one person. I can probably contribute best by asking Mickey-the-Dunce questions and pulling it together into Turkeyese. Thanks again, Lloyd
On Fri, 7 Jul 2006 18:17:39 -0400 (EDT), lloyd@paisite.com wrote:
Many thanks.
Thank you :)
I'm not competent enough to lay out the road-map nor to write the exemplary code.
I'll read the adventures and come back here tomorrow with my proposed roadmap that we can discuss then :).
On 7-Jul-06, at 1:20 PM, Valentino Volonghi aka Dialtone wrote:
I wouldn't mind helping out, hopefully the discussion can take place in this mailing list so that other people (if they want) can help answering/ completing/ fixing/evaluating what we write.
What do you think about task-oriented snippets and instructions, like a Twisted Cookbook? It might make writing and consuming the documentation a bit less daunting. Can anyone come up with say ten common questions that come up on the list?
On Fri, 7 Jul 2006 15:27:51 -0700, Beau Hartshorne <hartshorne@gmail.com> wrote:
What do you think about task-oriented snippets and instructions, like a Twisted Cookbook? It might make writing and consuming the documentation a bit less daunting. Can anyone come up with say ten common questions that come up on the list?
The main question is for sure the following: - How can I authenticate with guard using a database? (talk about writing checkers) - How can I use an ORM inside Nevow? (talk about Axiom, twisted.enterprise.adbapi, sqlalchemy+sAsync or simpler transactionToThread) - How do I handle forms in Nevow? (talk about formal) - What's the preferred way to share global state in a Nevow application? (talk about passing something in the root page and having the root page to pass that over and over to all children) - How do I do nested sequences? (there's already an example, should be better documented) - Man I hate how nested data_* directives behave, what are they doing? (talk about IContainer) - What is a macro? (talk about one-time renderers) And other questions that currently I can't remember.
On 7-Jul-06, at 5:12 PM, Valentino Volonghi aka Dialtone wrote:
The main question is for sure the following: - How can I authenticate with guard using a database? (talk about writing checkers) - How can I use an ORM inside Nevow? (talk about Axiom, twisted.enterprise.adbapi, sqlalchemy+sAsync or simpler transactionToThread) - How do I handle forms in Nevow? (talk about formal) - What's the preferred way to share global state in a Nevow application? (talk about passing something in the root page and having the root page to pass that over and over to all children) - How do I do nested sequences? (there's already an example, should be better documented) - Man I hate how nested data_* directives behave, what are they doing? (talk about IContainer) - What is a macro? (talk about one-time renderers)
And other questions that currently I can't remember.
Those sound more like a FAQ. How about titles more like: - Authenticating Web Users - Using ORMs (Databases) - Parse and Validate a Form - Share Global State - Rendering Nested Sequences - Nested Data Directives - One-time Renderers And maybe: - User Sessions - Virtual Host Setup
Hello, Wow! You folks are amazing. I'm really stoked by the energies behind the last twenty-four hours of list traffic. Let me try to summarize/synthesize as best I can. Welcome all restatements, additions, and excisions. -- At the end of several insightful comments, Cary Dodt said: ...there's still lots of areas that *aren't* adequately documented by anyone's standards. There are areas not covered by examples, there are areas not covered by HOWTO's. The core is covered, but any new application worth writing probably uses stuff from the fringes. So our hypothetical new Twisted user starts out writing her new application, gets a handle on the core stuff, and then discovers those gaps in the fringes. That can be frustrating. Everyone uses a different part of the fringes, so the fringes need to be covered almost as well as the core. -- L. Daniel Burr and Valentino Volonghi generously offered help in resurrecting the Turkey series. -- Beau Hartshorne suggested: ...What do you think about task-oriented snippets and instructions, like a Twisted Cookbook? It might make writing and consuming the documentation a bit less daunting. Can anyone come up with say ten common questions that come up on the list? -- L. Daniel Burr responded to my suggestion of a road map: ...As for a roadmap, I think sticking with web-oriented topics is best for the vast majority of users. Most people are building web-apps today, so they represent a large audience. After perhaps adding some more details to your existing "Hello World" example, we could move on to "Talking to a database", then the usual "A web page that talks to a database". After that you could start talking about templating, etc. --Valentino the rolled up his sleeves with the following excellent suggestions for Turkey topics: ...The main question is for sure the following: - How can I authenticate with guard using a database? (talk about writing checkers) - How can I use an ORM inside Nevow? (talk about Axiom, twisted.enterprise.adbapi, sqlalchemy+sAsync or simpler transactionToThread) - How do I handle forms in Nevow? (talk about formal) - What's the preferred way to share global state in a Nevow application? (talk about passing something in the root page and having the root page to pass that over and over to all children) - How do I do nested sequences? (there's already an example, should be better documented) - Man I hate how nested data_* directives behave, what are they doing? (talk about IContainer) - What is a macro? (talk about one-time renderers) --glyph reminded us that our task could be of value to many people and covers substantial ground: ...It's (Twisted) generally useful in a huge variety of problem domains. Even if you're just doing IPC, not network IO, Twisted can help prevent deadlocks and generally make applications a lot more robust. The "specialist" label is an unnecessary compromise; if our documentation is crap for some of those domains, then let's just say *that*, and all work to improve it, rather than pretend that there is something wrong with the technology itself as an excuse. If we officially say "this is not a general-purpose tool", then pretty soon all the functionality it provides outside the "specialist" area we artificially create for it will atrophy and eventually be removed. --Beau Hartshorne elegantly refined Valentino's road-map suggestions: ...How about titles more like: - Authenticating Web Users - Using ORMs (Databases) - Parse and Validate a Form - Share Global State - Rendering Nested Sequences - Nested Data Directives - One-time Renderers - User Sessions - Virtual Host Setup With these suggestions I believe we're well on our way. Questions: --Does Beau's list cover the necessary and sufficient application issues, conceptual concepts, and code objects and components to bring a newbie to reasonable competency when it comes to building websites and applications in good Twisted form and style? --Is the list sequenced to build from least assumptions about prior knowledge to most? --Should we have an adventure dealing with site security and/or putting a Twisted site into production? --The Turkey adventures to date had more-or-less the following structure: - Short, runnable code example - Discussion of anticipated results - Discussion of how it works -- concepts, theory, references to Twisted docs and source - Conclusion Can this structure be improved? Seems to me that with another round or two of hammering on the road map we will be well on our way toward developing some real adventures. Hat's off to all... Lloyd
On Sat, 8 Jul 2006 12:17:52 -0400 (EDT), lloyd@paisite.com wrote:
...How about titles more like:
- Authenticating Web Users - Using ORMs (Databases) - Parse and Validate a Form - Share Global State - Rendering Nested Sequences - Nested Data Directives - One-time Renderers - User Sessions - Virtual Host Setup
With these suggestions I believe we're well on our way.
Questions:
--Does Beau's list cover the necessary and sufficient application issues, conceptual concepts, and code objects and components to bring a newbie to reasonable competency when it comes to building websites and applications in good Twisted form and style?
There's probably one or two more questions: - What's the difference between macros, data, renders and fragments? How do they relate to each other? - Why is the Templating like it is? Does it work well with designers?
--Is the list sequenced to build from least assumptions about prior knowledge to most?
Not really. Let's reorder: - IResource interface - Virtual Host Setup - User Sessions - Templating engine (nested sequences, macros, fragments, data, renderers) - Share Global State - Using ORMs (Databases) - Authenticating Web Users - Per-user State
--Should we have an adventure dealing with site security and/or putting a Twisted site into production?
I think so. We should talk about integrating with lighttpd and apache like it is already partly explained in divmod.org trac wiki.
--The Turkey adventures to date had more-or-less the following structure:
- Short, runnable code example - Discussion of anticipated results - Discussion of how it works -- concepts, theory, references to Twisted docs and source - Conclusion
Can this structure be improved?
I think it's fine enough.
Valentino Volonghi aka Dialtone wrote:
--Is the list sequenced to build from least assumptions about prior knowledge to most?
Not really. Let's reorder:
- IResource interface - Virtual Host Setup - User Sessions - Templating engine (nested sequences, macros, fragments, data, renderers) - Share Global State - Using ORMs (Databases) - Authenticating Web Users - Per-user State
--Should we have an adventure dealing with site security and/or putting a Twisted site into production?
I think so. We should talk about integrating with lighttpd and apache like it is already partly explained in divmod.org trac wiki.
Fanboy time: this is exciting, guys :-) I am both looking forward to seeing where this as well as participating.
Valentino Volonghi aka Dialtone ha scritto:
Can this structure be improved?
I think it's fine enough.
I whould like to suggest to add a complete tutorial, like done for Twisted Core and Woven. The problem is to found an application with which one can introduce each concept incrementally (including, hopefully, Athena - but *not* Axiom). pastebin? Regards Manlio Perillo
On Sat, 08 Jul 2006 14:17:11 -0500, Manlio Perillo <manlio_perillo@libero.it> wrote:
I whould like to suggest to add a complete tutorial, like done for Twisted Core and Woven.
The problem is to found an application with which one can introduce each concept incrementally (including, hopefully, Athena - but *not* Axiom).
Sure, people like the incremental approach. The Finger tutorial does the same thing, but unfortunately I don't think Finger is the kind of example that interests people.
pastebin?
I think a pastebin tutorial would suffer from the same problems as the current Finger tutorial. How many people want actually want to build a pastebin? I'm seriously curious; my guess is that the answer is "not very many". How about a simple CRUD application? They are all the rage these days, and we could create one step by step, using photos or audio files as the example data to be managed. Also, I think a CRUD tutorial would provide a great way to showcase some of the features that make twisted and company so great. L. Daniel Burr
Hi Valentino, I've consolidated your excellent suggestions below: - IResource interface - Virtual host setup - User sessions - Templating -- who needs it? - Templating engine (nested sequences, macros, fragments, data, renderers) - Share global state - Using ORMs (databases) - Authenticating web wsers - Per-user state - Web-server trade-offs -- Twisted vs. Apache vs. lighttpd - Twisted in production - Twisted security This tentative roadmap, I'm sure, will be further developed and refined as we go. But, for now, I think it gives us a good place to start. Given the structure of existing adventures; e.g. - Short, runnable code example - Discussion of anticipated results - Discussion of how it works -- concepts, theory, references to Twisted docs and source - Conclusion ...I've copied the code for Turkey's most recent adventure below. How can we future develop this or, or start with a new code example, to best explicate the IResource interface? References to existing documentation would be helpful. Meanwhile, I'll work over the next couple of days to bring my Turkey environment back up and will update the Turkey site with the new roadmap. Note that Duncan MacGregor has expressed interest in participating... (Thanks, Duncan. And welcome! Please feel free to jump in. We'll need code examples, clear, concise conceptual discussions and definitions of technical terms, testing/debugging when we post new code, critical editorial eyeballing.) And Manlio Perillo and L. Daniel Burr have suggested that this series should focus on building an application -- pastepot or CRUD (Don't know myself what either of those are). This warrants further discussion. For my part, I like the idea, but have the following reservations: -- I'd like to keep the adventures as generic as possible across many potential applications; I fear that focusing on one application may limit our scope. -- Different folks may have widely different levels of interest in different applications, whereas we all need to master the basics. -- Developing a production-ready application may get us into a bunch of nitty-gritty stuff that doesn't have much to do with Twisted, but does have a lot to do with good programming practice. That said, maybe after we've covered the basics, using the example of a good application to put it all together may be an excellent idea. I don't think we're talking either/or here. Also, Terry Jones has raised some very pertainent issues -- well worth further discussion. I'l throw in my two cents in a separate post. Best wishes, Lloyd PS Here's the last code example from Techno Turkey's Adventures: Matt Goodall's Barebones Dynamic Web Server from twisted.application import internet, service from twisted.web import resource, server LOGPATH = './logs/access.log' PORT = 8080 class DynamicResource(resource.Resource): """A simple, dynamic resource with a name. """ def __init__(self, name): resource.Resource.__init__(self) self.name = name def getChild(self, name, request): # if the child's name is '' - the empty segment - then return # myself. if name == '': return self # Return an instance of my type with the requested segment name. return DynamicResource(name) def render(self, request): return '<html><p>I am a Dynamic Resource. My name is %r.</p></html>' % (self.name) application = service.Application('web-server') site = server.Site(DynamicResource('root'), logPath=LOGPATH) internet.TCPServer(PORT, site).setServiceParent(application)
Hi Lloyd, On Mon, 10 Jul 2006 10:25:35 -0500, <lloyd@paisite.com> wrote: [snip]
And Manlio Perillo and L. Daniel Burr have suggested that this series should focus on building an application -- pastepot or CRUD (Don't know myself what either of those are). This warrants further discussion. For my part, I like the idea, but have the following reservations:
CRUD is just an acronym for Create, Read, Update, Delete, and so-called "CRUD apps" have become a popular litmus test for how handy/useful a web application framework is. The typical CRUD application is used as an example of how to use a framework to talk to an RDBMS, render data as HTML, edit data, delete it, etc. This sort of tutorial is popular because a large number of web applications boil down to providing a web UI for editing some data that lives in a database, hence my suggestion.
-- I'd like to keep the adventures as generic as possible across many potential applications; I fear that focusing on one application may limit our scope.
See above. CRUD is pretty generic.
-- Different folks may have widely different levels of interest in different applications, whereas we all need to master the basics.
-- Developing a production-ready application may get us into a bunch of nitty-gritty stuff that doesn't have much to do with Twisted, but does have a lot to do with good programming practice.
My suspicion is that the people looking for tutorials and quick-start type of documentation are, in fact, trying to build a production application in a big hurry, and want to find something to build on. With that in mind, I think that working up to a simple, but production-ready application would meet with a great deal of approval.
That said, maybe after we've covered the basics, using the example of a good application to put it all together may be an excellent idea. I don't think we're talking either/or here.
Agreed. [snip]
PS Here's the last code example from Techno Turkey's Adventures:
Matt Goodall's Barebones Dynamic Web Server
from twisted.application import internet, service from twisted.web import resource, server
LOGPATH = './logs/access.log' PORT = 8080
class DynamicResource(resource.Resource): """A simple, dynamic resource with a name. """
def __init__(self, name): resource.Resource.__init__(self) self.name = name
def getChild(self, name, request): # if the child's name is '' - the empty segment - then return # myself. if name == '': return self # Return an instance of my type with the requested segment name. return DynamicResource(name)
def render(self, request): return '<html><p>I am a Dynamic Resource. My name is %r.</p></html>' % (self.name)
application = service.Application('web-server') site = server.Site(DynamicResource('root'), logPath=LOGPATH) internet.TCPServer(PORT, site).setServiceParent(application)
The only thing I don't like about this example is that DynamicResource is returning an instance of itself for requests to childrend of itself. Granted, this is perfectly legitimate, but I think it introduces some potential confusion for a new reader. I would suggest just creating a "ChildResource" (the nevow examples directory does this), and perhaps returning that instead, to make it more clear what is being done in getChild. Thanks for everyone's efforts and feedback on this, I think we are headed in the right direction now, and perhaps we will attain the critical mass of contributions needed to make this documentation effort a success. L. Daniel Burr
Hi Daniel, On Mon, July 10, 2006 11:49 am, L. Daniel Burr wrote:
CRUD is just an acronym for Create, Read, Update, Delete, and so-called "CRUD apps" have become a popular litmus test for how handy/useful a web application framework is. The typical CRUD application is used as an example of how to use a framework to talk to an RDBMS, render data as HTML, edit data, delete it, etc. This sort of tutorial is popular because a large number of web applications boil down to providing a web UI for editing some data that lives in a database, hence my suggestion.
OK. Yeah, does sound valuable way-station in our journey. Where or how would you see it fitting into, or modifying the road map that I posted this morning?
Matt Goodall's Barebones Dynamic Web Server
The only thing I don't like about this example is that DynamicResource is returning an instance of itself for requests to childrend of itself.
Granted, this is perfectly legitimate, but I think it introduces some potential confusion for a new reader. I would suggest just creating a "ChildResource" (the nevow examples directory does this), and perhaps returning that instead, to make it more clear what is being done in getChild.
Can you post modified code and flesh out your critique? Might be good next step, better preparing us for IResources. What do you think, Valentino? All the best, Lloyd
On Mon, 10 Jul 2006 14:12:38 -0400 (EDT), lloyd@paisite.com wrote:
Can you post modified code and flesh out your critique? Might be good next step, better preparing us for IResources.
What do you think, Valentino?
For IResource the right example is most_basic which uses the following code: from zope.interface import implements from nevow import inevow ## ## How does a request come to the Page? ## ## or How to use Nevow without all the fancy automations ## # This is a simple Root page object, the inevow.IResource interface # tells us that it must implement 2 methods: # locateChild and renderHTTP. # locateChild is used to find children of the current page, it must return a # tuple of (page, remaining_segments) # if there is no page, and you want to display a 404 page, you will need to return # a None, () tuple. class Root(object): implements(inevow.IResource) def locateChild(self, ctx, segments): # This locateChild is 'stupid' since it can only work if the tree of # pages is static. Anyway it will work for our simple example if segments[0] == '': # If the server is looking for the root page segments will be ('',) # then renderHTTP will be called on self return self, () elif segments[0] == 'foo': # Now we received a request whose segments had in the first position # the string foo # like http://example.org/foo/baz/ -> ('foo', 'baz') # after the page has been located we return it with the remaining segments # ('baz') return self.foo, segments[1:] else: return None, () def renderHTTP(self, ctx): # When the server needs to return a response to the request it will call # the renderHTTP method that will return a string of what needs to be sent. return """<html><body>Hello world!<br /> <a href="./foo" id="foo">foo</a></body></html> """ class Foo(object): implements(inevow.IResource) def locateChild(self, ctx, segments): # segments is the remaining segments returned by the root locateChild # see segments[1:] if segments[0] == 'baz': return self.baz, segments[1:] else: return None, () def renderHTTP(self, ctx): return """<html><body><h1 id="heading">You are in Foo</h1> <a href="./foo/baz" id="baz">baz</a></body></html> """ class Baz(object): implements(inevow.IResource) def locateChild(self, ctx, segments): return None, () def renderHTTP(self, ctx): return '<html><body><h1 id="heading">You are in Baz</h1></body></html>' # We are adding children to the pages. # This could also happen inside the class. root = Root() root.foo = Foo() root.foo.baz = Baz() This example was written with the clear intent to just show the IResource interface separated from Nevow. Keep in mind that this is the IResource interface from Nevow and not the one from twisted.web.
Hi Valentino, On Tue, July 11, 2006 8:07 am, Valentino Volonghi aka Dialtone wrote:
For IResource the right example is most_basic which uses the following code:
Note that I've added the road map to http://twisted.paisite.com. When I started to rebuild my Twisted environment, I realized that version updates may have broken Turkey Adventures one through four. Todo list: 1. Retest Adventures one through four using current Twisted versions. 2. Update Adventures one through four if necessary Once I have my environment back up I'll try to tackle these two tasks. If anyone else feels so inclined, feel free to jump in. Re: IRequest code: Great start, Valentino! Questions: -- Does this need some kind or wrapper to run it or will it run as is? -- What's the step-by-step procedure to get it running? -- What should we see when we do get it running? -- How does it work? -- From the big picture point-of-view, what have we learned by running this code? Best wishes, Lloyd
from zope.interface import implements
from nevow import inevow
## ## How does a request come to the Page? ## ## or How to use Nevow without all the fancy automations ##
# This is a simple Root page object, the inevow.IResource interface # tells us that it must implement 2 methods: # locateChild and renderHTTP. # locateChild is used to find children of the current page, it must return a # tuple of (page, remaining_segments) # if there is no page, and you want to display a 404 page, you will need to return # a None, () tuple. class Root(object): implements(inevow.IResource)
def locateChild(self, ctx, segments): # This locateChild is 'stupid' since it can only work if the tree of # pages is static. Anyway it will work for our simple example if segments[0] == '': # If the server is looking for the root page segments will be ('',) # then renderHTTP will be called on self return self, () elif segments[0] == 'foo': # Now we received a request
whose
segments had in the first position # the string foo # like http://example.org/foo/baz/ -> ('foo', 'baz') # after the page has been located we return it with the remaining segments # ('baz') return self.foo, segments[1:] else: return None, ()
def renderHTTP(self, ctx): # When the server needs to return a response to the request it will call # the renderHTTP method that will return a string of what needs to be sent. return """<html><body>Hello world!<br /> <a href="./foo" id="foo">foo</a></body></html> """
class Foo(object): implements(inevow.IResource)
def locateChild(self, ctx, segments): # segments is the remaining segments returned by the root locateChild # see segments[1:] if segments[0] == 'baz': return self.baz, segments[1:] else: return None, ()
def renderHTTP(self, ctx): return """<html><body><h1 id="heading">You are in Foo</h1> <a href="./foo/baz" id="baz">baz</a></body></html> """
class Baz(object): implements(inevow.IResource) def locateChild(self, ctx, segments): return None, () def renderHTTP(self, ctx): return '<html><body><h1 id="heading">You are in Baz</h1></body></html>'
# We are adding children to the pages. # This could also happen inside the class. root = Root() root.foo = Foo() root.foo.baz = Baz()
This example was written with the clear intent to just show the IResource interface separated from Nevow. Keep in mind that this is the IResource interface from Nevow and not the one from twisted.web.
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
On Tue, 11 Jul 2006 14:10:58 -0500, <lloyd@paisite.com> wrote: [snip]
Re: IRequest code:
I've got some suggestion for this IResource example, which I will detail below.
from zope.interface import implements
from nevow import inevow
## ## How does a request come to the Page?
I'd really prefer to be talking about Resources right from the very start, rather than web pages. Note that I mean Resource as in: "The thing that a URL points to". Web applications are becoming a bit less page-centric these days, so it might be helpful to start the reader off with the Resource concept, rather than talking about pages.
## ## or How to use Nevow without all the fancy automations ##
# This is a simple Root page object, the inevow.IResource interface
Maybe something like this: "This is a simple resource, representing the root, or top-most resource of this site. The inevow.IResource interface..."
# tells us that it must implement 2 methods: # locateChild and renderHTTP. # locateChild is used to find children of the current page, it must return a # tuple of (page, remaining_segments) # if there is no page, and you want to display a 404 page, you will need to return # a None, () tuple.
Let's make this simpler: nevow.rend.NotFound is a much more convenient and readable way to spell "None, ()". So, I'd suggest we change this to something like the following: "locateChild is used to find children of the current resource. It must return a tuple of (resource, remaining_segments). If no child resource exists at this location, you may return nevow.rend.NotFound." This ignores the fact that you could also return your own custom error resource, but maybe that should be saved for later docs?
class Root(object): implements(inevow.IResource)
def locateChild(self, ctx, segments): # This locateChild is 'stupid' since it can only work if the tree of # pages is static. Anyway it will work for
"if the tree of resources is static"
our simple example if segments[0] == '': # If the server is looking for the root page segments will be ('',) # then renderHTTP will be called on self return self, () elif segments[0] == 'foo': # Now we received a request whose segments had in the first position # the string foo # like http://example.org/foo/baz/ -> ('foo', 'baz') # after the page has been located we return it with the remaining segments # ('baz') return self.foo, segments[1:] else: return None, () return
def renderHTTP(self, ctx): # When the server needs to return a response to the request it will call # the renderHTTP method that will return a string of what needs to be sent. return """<html><body>Hello world!<br /> <a href="./foo" id="foo">foo</a></body></html> """
class Foo(object): implements(inevow.IResource)
def locateChild(self, ctx, segments): # segments is the remaining segments returned by the root locateChild # see segments[1:] if segments[0] == 'baz': return self.baz, segments[1:] else: return None, ()
"return rend.NotFound" In general, I think it is better to replace the word "page" with "resource" so that we don't lock readers into thinking of everything as a page; so much of what make twisted and nevow handy comes into play when you stop thinking about web pages as the unit of work, and think about resources. Anyone agree, violently disagree? L. Daniel Burr
Hi Daniel, On Tue, July 11, 2006 4:37 pm, L. Daniel Burr wrote:
I've got some suggestion for this IResource example, which I will detail below.
Valentino is better qualified to respond than I. But you've convinced me... provided that we have a really good definition of "Resource." "Resource" is one of the concepts that baffled me last year. I couldn't get my head around what folks were talking about. Your phrase "The thing that a URL.points to..." definitely helps me see the bigger picture. Saying this, I realize that my own work has been moving away from the simple "set of linked pages" model. The Resource concept should give me better language to talk about what I've been doing. Since naive folks like me are accustomed to thinking in terms of "pages," it would probably be good to sharpen up and present your argument that many web apps today have more complex structures than "set of linked pages." We could explicitly point out that abstracting the notion of "page" to "Resource," opens the mind to more creative possiblies, then present a few examples of these possibilties. We should definitely include "page" as an an example of a "Resource," along with a few other examples. Want to try your hand at a crisp, evocative definition with examples? Many thanks, Lloyd
from zope.interface import implements
from nevow import inevow
## ## How does a request come to the Page?
I'd really prefer to be talking about Resources right from the very start, rather than web pages. Note that I mean Resource as in: "The thing that a URL points to". Web applications are becoming a bit less page-centric these days, so it might be helpful to start the reader off with the Resource concept, rather than talking about pages.
## ## or How to use Nevow without all the fancy automations ##
# This is a simple Root page object, the inevow.IResource interface
Maybe something like this:
"This is a simple resource, representing the root, or top-most resource of this site. The inevow.IResource interface..."
# tells us that it must implement 2 methods: # locateChild and renderHTTP. # locateChild is used to find children of the current page, it must return a # tuple of (page, remaining_segments) # if there is no page, and you want to display a 404 page, you will need to return # a None, () tuple.
Let's make this simpler: nevow.rend.NotFound is a much more convenient and readable way to spell "None, ()". So, I'd suggest we change this to something like the following:
"locateChild is used to find children of the current resource. It must return a tuple of (resource, remaining_segments). If no child resource exists at this location, you may return nevow.rend.NotFound."
This ignores the fact that you could also return your own custom error resource, but maybe that should be saved for later docs?
class Root(object): implements(inevow.IResource)
def locateChild(self, ctx, segments): # This locateChild is 'stupid' since it can only work if the tree of # pages is static. Anyway it will work for
"if the tree of resources is static"
our simple example if segments[0] == '': # If the server is looking for the root page segments will be ('',) # then renderHTTP will be called on self return self, () elif segments[0] == 'foo': # Now we received a request whose segments had in the first position # the string foo # like http://example.org/foo/baz/ -> ('foo', 'baz') # after the page has been located we return it with the remaining segments # ('baz') return self.foo, segments[1:] else: return None, () return
def renderHTTP(self, ctx): # When the server needs to return a response to the request it will call # the renderHTTP method that will return a string of what needs to be sent. return """<html><body>Hello world!<br /> <a href="./foo" id="foo">foo</a></body></html> """
class Foo(object): implements(inevow.IResource)
def locateChild(self, ctx, segments): # segments is the remaining segments returned by the root locateChild # see segments[1:] if segments[0] == 'baz': return self.baz, segments[1:] else: return None, ()
"return rend.NotFound"
In general, I think it is better to replace the word "page" with "resource" so that we don't lock readers into thinking of everything as a page; so much of what make twisted and nevow handy comes into play when you stop thinking about web pages as the unit of work, and think about resources.
Anyone agree, violently disagree?
L. Daniel Burr
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
Hi Lloyd, On Tue, 11 Jul 2006 17:35:05 -0500, <lloyd@paisite.com> wrote: [snip]
Valentino is better qualified to respond than I. But you've convinced me... provided that we have a really good definition of "Resource."
Fair enough, I think the Wikipedia definition is pretty good. http://en.wikipedia.org/wiki/Resource_(Web)
"Resource" is one of the concepts that baffled me last year. I couldn't get my head around what folks were talking about. Your phrase "The thing that a URL.points to..." definitely helps me see the bigger picture. Saying this, I realize that my own work has been moving away from the simple "set of linked pages" model. The Resource concept should give me better language to talk about what I've been doing.
Representational State Transfer (REST) is the concept that I most often use when considering resources in a web application. http://en.wikipedia.org/wiki/Representational_State_Transfer#Resources
Since naive folks like me are accustomed to thinking in terms of "pages," it would probably be good to sharpen up and present your argument that many web apps today have more complex structures than "set of linked pages." We could explicitly point out that abstracting the notion of "page" to "Resource," opens the mind to more creative possiblies, then present a few examples of these possibilties. We should definitely include "page" as an an example of a "Resource," along with a few other examples.
Agreed. I didn't really "get it" at first, because I had always though in terms of "web pages". Once I read Fielding's paper and started thinking about logical resources, rather than "every URL is a web page", everything just fell into place, and I have a much easier time designing web applications these days, even if I don't make them strictly in a REST-style.
Want to try your hand at a crisp, evocative definition with examples?
Hopefully, we can just provide links to the two resources I cited, above. That's sort of recursive, in a way, but there you have it.
Many thanks,
Not at all, thanks to you and the others on the list who got the ball rolling again. L. Daniel Burr
On Tue, 11 Jul 2006 18:35:05 -0400 (EDT), lloyd@paisite.com wrote:
I've got some suggestion for this IResource example, which I will detail below.
Valentino is better qualified to respond than I. But you've convinced me... provided that we have a really good definition of "Resource."
Not really :). You are better qualified because you are learning and teminology helps you a lot more than me. Anyway I agree with Daniel with the Resource vs Page thing.
On Tue, 11 Jul 2006 15:10:58 -0400 (EDT), lloyd@paisite.com wrote:
Hi Valentino,
On Tue, July 11, 2006 8:07 am, Valentino Volonghi aka Dialtone wrote:
For IResource the right example is most_basic which uses the following code:
Note that I've added the road map to http://twisted.paisite.com.
When I started to rebuild my Twisted environment, I realized that version updates may have broken Turkey Adventures one through four.
Todo list:
1. Retest Adventures one through four using current Twisted versions. 2. Update Adventures one through four if necessary
Once I have my environment back up I'll try to tackle these two tasks. If anyone else feels so inclined, feel free to jump in.
From what I've seen in your current adventures I don't think you'll need to update anything since currently you only use twisted.web which hasn't been updated for a long time (and twisted.web2 will take its place when ready).
To be honest this changing-situation is true for Nevow too since in a branch (already working and waiting review and approval) Nevow introduces 2 new objects and a new way of dealing with pages that removes the context (ctx argument). This is why in the next adventures I wouldn't spend much time talking about the context except for some basic notions that are needed to do what the new objects allow without using it. Don't worry about it too much then.
Re: IRequest code:
Great start, Valentino!
Questions:
-- Does this need some kind or wrapper to run it or will it run as is?
It will run as is on top of Nevow (which introduces some wrappers for twisted.web). from twisted.internet import reactor from nevow import appserver site = appserver.NevowSite(root) reactor.listenTCP(8080, site) this lines added at the end of the file will make it work. You can run the example obtained in this way using the standard: python myscript.py Then browing to http://localhost:8080/ will start the experience. An alternative solution uses the tac file approach and is the following: from twisted.application import strports, service from nevow import appserver application = service.Application('example') website = appserver.NevowSite(root) webservice = strports.service('8080', website) webservice.setServiceParent(application) You can run the example obtained in this way using: twistd -noy myscript.tac then browsing to http://localhost:8080/ will start the experience. The tac extension is arbitrary and only used because the file uses this alternative way of setting up the application.
-- What's the step-by-step procedure to get it running?
See above.
-- What should we see when we do get it running?
A root page with an Hello world and a link to a child page named foo. Trying to get any other url except the one with the child foo will result in a 404. If you go in the foo child you'll see a page with the content 'you are in foo' and a link to foo's child page baz. Any other child page will result in a 404. If you go in the baz child you'll see a page with the content 'you are in baz'. This page has no children and any other url will result in a 404.
-- How does it work? I think it is explained in the comments. I wouldn't know how to explain it better without precise questions. :)
-- From the big picture point-of-view, what have we learned by running this code?
We have learned that Nevow is fundamentally based on the following request processing schema: arrives request \ --> root resource \ --> root.locateChild(url segments) . child_resource.locateChild(url segments[1:]) . child_resource2.locateChild(url segments[2:]) . so forth until url segments == () ==> FOUND RIGHT RESOURCE ==> RIGHT_RESOURCE.renderHTTP() \ browser <================================ HTH.
Hi Valentino, Outstanding! With this info and Daniel's input on Resources, I should be able to draft the next Turkey adventure -- just have to get my Twisted environment up again. I think I also need to take a day or so to bone up on all the latest Twisted and Nuvow docs. Might take me a week or so to get it all done. I take it that I also need to load Nuvow? Many thanks, Lloyd On Tue, July 11, 2006 9:10 pm, Valentino Volonghi aka Dialtone wrote:
On Tue, 11 Jul 2006 15:10:58 -0400 (EDT), lloyd@paisite.com wrote:
Hi Valentino,
On Tue, July 11, 2006 8:07 am, Valentino Volonghi aka Dialtone wrote:
For IResource the right example is most_basic which uses the following code:
Note that I've added the road map to http://twisted.paisite.com.
When I started to rebuild my Twisted environment, I realized that version updates may have broken Turkey Adventures one through four.
Todo list:
1. Retest Adventures one through four using current Twisted versions. 2. Update Adventures one through four if necessary
Once I have my environment back up I'll try to tackle these two tasks. If anyone else feels so inclined, feel free to jump in.
From what I've seen in your current adventures I don't think you'll need to update anything since currently you only use twisted.web which hasn't been updated for a long time (and twisted.web2 will take its place when ready).
To be honest this changing-situation is true for Nevow too since in a branch (already working and waiting review and approval) Nevow introduces 2 new objects and a new way of dealing with pages that removes the context (ctx argument).
This is why in the next adventures I wouldn't spend much time talking about the context except for some basic notions that are needed to do what the new objects allow without using it. Don't worry about it too much then.
Re: IRequest code:
Great start, Valentino!
Questions:
-- Does this need some kind or wrapper to run it or will it run as is?
It will run as is on top of Nevow (which introduces some wrappers for twisted.web).
from twisted.internet import reactor from nevow import appserver site = appserver.NevowSite(root) reactor.listenTCP(8080, site)
this lines added at the end of the file will make it work. You can run the example obtained in this way using the standard:
python myscript.py Then browing to http://localhost:8080/ will start the experience.
An alternative solution uses the tac file approach and is the following:
from twisted.application import strports, service from nevow import appserver application = service.Application('example') website = appserver.NevowSite(root) webservice = strports.service('8080', website) webservice.setServiceParent(application)
You can run the example obtained in this way using: twistd -noy myscript.tac then browsing to http://localhost:8080/ will start the experience.
The tac extension is arbitrary and only used because the file uses this alternative way of setting up the application.
-- What's the step-by-step procedure to get it running?
See above.
-- What should we see when we do get it running?
A root page with an Hello world and a link to a child page named foo. Trying to get any other url except the one with the child foo will result in a 404.
If you go in the foo child you'll see a page with the content 'you are in foo' and a link to foo's child page baz. Any other child page will result in a 404.
If you go in the baz child you'll see a page with the content 'you are in baz'. This page has no children and any other url will result in a 404.
-- How does it work?
I think it is explained in the comments. I wouldn't know how to explain it better without precise questions. :)
-- From the big picture point-of-view, what have we learned by running this code?
We have learned that Nevow is fundamentally based on the following request processing schema:
arrives request \ --> root resource \ --> root.locateChild(url segments) . child_resource.locateChild(url segments[1:]) . child_resource2.locateChild(url segments[2:]) . so forth until url segments == () ==> FOUND RIGHT RESOURCE ==> RIGHT_RESOURCE.renderHTTP() \ browser <================================
HTH.
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
Valentino Volonghi aka Dialtone ha scritto:
[...]
The main question is for sure the following:
[...]
And other questions that currently I can't remember.
One little thing is how to use sessions (this is explained in the Woven tutorial http://twistedmatrix.com/projects/web/documentation/howto/picturepile.html). I also would like to see documented how guard works. It does a little black magic with redirects and it try to works even with no cookies(?); and I still does not understand how to use guard without cred integration. There was an example on the wiki but it is incomplete (and now I can't find it anymore...) Thanks and regards Manlio Perillo
On Sat, 08 Jul 2006 06:21:58 -0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Valentino Volonghi aka Dialtone ha scritto:
[...]
The main question is for sure the following:
[...]
And other questions that currently I can't remember.
One little thing is how to use sessions (this is explained in the Woven tutorial http://twistedmatrix.com/projects/web/documentation/howto/picturepile.html).
I also would like to see documented how guard works.
It does a little black magic with redirects and it try to works even with no cookies(?); and I still does not understand how to use guard without cred integration. There was an example on the wiki but it is incomplete (and now I can't find it anymore...)
Guard *is* cred integration. It doesn't make sense to try to use guard without cred. Jean-Paul
Jean-Paul Calderone ha scritto:
I also would like to see documented how guard works.
It does a little black magic with redirects and it try to works even with no cookies(?); and I still does not understand how to use guard without cred integration. There was an example on the wiki but it is incomplete (and now I can't find it anymore...)
Guard *is* cred integration. It doesn't make sense to try to use guard without cred.
As I can see, SessionWrapper is for direct cred integration. But in the wiki I have seen an example that uses GuardSession directly. My problem is really with sessions. Regaeds Manlio Perillo
Valentino Volonghi aka Dialtone ha scritto:
[...]
- How do I do nested sequences? (there's already an example, should be better documented)
The example uses the IContainer interface Is this the only solution? Thanks and regards Manlio Perillo
Valentino Volonghi aka Dialtone ha scritto:
On Sun, 16 Jul 2006 15:43:29 -0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
- How do I do nested sequences? (there's already an example, should be better documented)
You can also generate stan on the fly.
Only as a last resource. However I have read some old posts from the archive of the mailing list; thus I (hope) now understand better how data directives works. Regards Manlio Perillo
participants (11)
-
Beau Hartshorne
-
Cory Dodt
-
Duncan McGreggor
-
glyph@divmod.com
-
Jean-Paul Calderone
-
L. Daniel Burr
-
lloyd@paisite.com
-
Manlio Perillo
-
Phil Mayers
-
Terry Jones
-
Valentino Volonghi aka Dialtone