picoweb icon indicating copy to clipboard operation
picoweb copied to clipboard

Some things I miss...

Open flusflas opened this issue 4 years ago • 4 comments

Hi!

I'm using Picoweb and it's great. However, I'm feeling that it lacks of some minor features and convenience methods. I'm working on these features as I need them in my project, and I think my work or ideas might be useful to improve Picoweb. These are my thoughts so far:

  1. Request method filtering. Flask uses the route() function for it. I've created a decorator function to handle this.
  2. Manage exceptions in views. Although Picoweb handles the exceptions, I like to send a custom (500) response. Right now I am using the same methods decorator that I created, although it is not an ideal solution.
  3. A simple response class or method to avoid using the StreamWriter directly. I've created a Response class to send simple text/html and application/json responses. I've also created a subclass that format the response based on the JSend specification, although this is a very personal feature.
  4. I miss a body attribute in the request object (or a read() method), although there is a read_form_data() method (only useful with web forms). A json() method would also be great :)
  5. If a request has some body content but it is not read in the view (it may be not necessary), then the server doesn't send any response. That's why I think a body attribute could also help to empty and close the reader stream before the handler is called.

I've solved all of these needs, and I can adapt my code into Picoweb and make a few pull requests. However, I wanted to know what do you think about these features and if it makes sense to include them into the library.

Thank you, and sorry if my English doesn't make sense sometimes...

flusflas avatar Jan 15 '20 22:01 flusflas

Thanks for posting. Note that Picoweb has one important goal - to be the minimalist and simple web nano-framework. It takes inspiration in the words "Perfection is achieved not when there is nothing more to add, but when there is nothing to take away." of one well-known author.

Instead of trying to satisfy everyone, which is impossible, Picoweb aspires to find a core set of functionality which allows to write simple, but useful webapps. And be extensible, so more functionality can be added on top of (not inside) it. I envision over time various plugins, etc. appear for Picoweb, and welcome interested parties to do that. Bu the core should stay simple.

With that in mind, let's look over your list:

  1. Request method filtering. Flask uses the route() function for it.

I'm not sure what exactly you mean, can you elaborate to avoid guesswork?

I've created a decorator function to handle this.

That's the right way to deal with it.

  1. Manage exceptions in views. Although Picoweb handles the exceptions, I like to send a custom (500) response. Right now I am using the same methods decorator that I created, although it is not an ideal solution.

If you mean a kind of catch-all handler, then ok, I see the point. Let me look into adding it. (Note that I would add extension point, not the handler itself.)

  1. A simple response class or method to avoid using the StreamWriter directly.

The whole purpose of Picoweb is to use StreamWriter directly. Of course, if you want to make it more complex than that - sure, you can.

I've created a Response class to send simple text/html and application/json responses.

Well, picoweb has facilities for that itself, it's in (pretty short!) source: https://github.com/pfalcon/picoweb/blob/master/picoweb/init.py#L39 . Let that be the illustration of my point: the more stuff you add, the more people will miss. If there're 10 methods, people will figure out 5 methods and miss 5. If there're 100 methods, people will figure out 5 and miss 95. The only way to stop this vicious circle is to keep project minimal, and invite people to actually read the code they're going to run. That's the mission of Picoweb (and entire Pycopy project, of which Picoweb just one part).

I've also created a subclass that format the response based on the JSend specification, although this is a very personal feature.

That's again how it's intended to be done. If you think that it would be useful to other people, package up this extension as a separate project, and publish/support it on your own.

I miss a body attribute

Not needed, there's req.reader.read*() family of methods. It can't be an attribute, Picoweb can run on systems with some 50K of memory, while somebody may send you a few gigabytes of data.

(or a read() method)

Everything is there - please study the source, it's kept small specifically so it's not a problem for anybody, even beginners, to study it.

A json() method would also be great :)

ujson.loads(string)

If a request has some body content but it is not read in the view

If a request has a body, it's view's responsibility to read it.

pfalcon avatar Jan 16 '20 17:01 pfalcon

Thank you for your answer and for the time it will have taken. First of all, Picoweb is an awesome project, and I would be struggling with myself without it. Precisely, the fact that it is so minimalist helps a lot when using and extending it. I understand the limited resources this library have to deal with, although it's true that I may have not considered it enough. I will try to take it more into account from now on.

With that in mind, my three last points are against minimalism and performance, and I get that anyone (like me) could make a custom implementation for it, but it should not be part of the main project. Also, I didn't notice the jsonify() function.

With respect to the other points:

I'm not sure what exactly you mean, can you elaborate to avoid guesswork?

I mean that it would be nice to be able to filter the HTTP request methods allowed for a certain view (GET, POST, PUT...). However, thinking about it, it may has more sense to just create a custom decorator in order to be able to send a custom 405 response. Anyway, and as many of my other points, this is only a high-level feature that it could be useful but not really required.

If you mean a kind of catch-all handler, then ok, I see the point. Let me look into adding it. (Note that I would add extension point, not the handler itself.)

Yup, a catch-all handler is what I meant. Again, it can be solved with a simple decorator, but I let you value if this is really needed in the core.

This issue was about "what do you think about all these things", since you are the author of this library (and Pycopy) and should have a deep understanding of working with minimal hardware resources. Anyway, if it's worth adding some of these points to Picoweb, great. I will keep doing the rest of my high-level things outside the main code :)

Thank you so much!

flusflas avatar Jan 17 '20 18:01 flusflas

Thanks for clarification!

Just as a quick update (short of time now), I've pushed ability to override "global" exception handling, but mind that it might not work exactly as you might wish, see comments in the code: https://github.com/pfalcon/picoweb/commit/35bf48b9e7d466697666f0b2fb09b7a2292f2653 .

pfalcon avatar Jan 18 '20 15:01 pfalcon

Also posted an example on the above: https://github.com/pfalcon/picoweb/blob/master/examples/example_global_exc.py

pfalcon avatar Jan 18 '20 22:01 pfalcon