Hacker News new | past | comments | ask | show | jobs | submit login
Responder: A familiar HTTP Service Framework (python-responder.org)
205 points by rayraegah 5 months ago | hide | past | web | favorite | 111 comments

Maybe I’ll accept non-monospace fonts for code. You get the right ligatures, decent kerning, the softer touch of sans-serif... it has some possibility

But psuedo-cursive strings? This font that looks like a retro emulator using a vectorizing filter?

This is too much. I’m not happy about this development at all.

I'm slightly convinced that these kinds of things become slightly popular for a little bit for no reason other than change being nice. When people claim to like them, I wonder if they really just like the feeling of change.

I have a few syntax color sets that I swap between every few months just because its a nice break. I also found that it's really nice to re-arrange my office every 6 months for no reason other than change is nice.

I believe the font is called Operator Mono and seems to have become popularized by the React scene. I was using it for a while and actually kind of like it but lately I've been experimenting with Fira Code, which also has ligature support.

I've tried Fira Code but the ligatures and the overall look and feel of the font somehow feel too "loud" to me.

Now that I'm looking at Operator Mono, I think I'll actually give that a try.

Yeah, using it even on the API documentation page [1] is a bit much. This does look like a cool framework, though.

[1] http://python-responder.org/en/latest/api.html

> non-monospace fonts for code

A proportional font helps when working with codebases that tend to have long lines (e.g. those written in Java or C#).

What I really need is a python web framework that has first class support for serving SPA applications (VueJS, React etc).

I spent quite a bit of time setting up my Django app to serve VueJS (replacing the built-in Jinja templates). Once ready, it became a powerful application with ORM, middleware and all other Django goodies coupled with modern JS framework on the frontend.

I hear Rails 6 is going to support modern web frameworks and using npm libraries, so something like that for Python/Django world.

Sounds like you're confusing the purpose of the web framework. Don't try to force front-end specifics into a primarily back-end focused web server. Just because you create web templates for the back-end to RENDER does not mean you need to force it to push out VueJS. In theory VueJS should be able to run behind Apache stand-alone and make requests to your Python API which could be an entirely different codebase. No ambiguity if you did it this way instead, and some web frameworks let you serve up static files / HTML. If your JS front-end app is mostly static, you can just serve it up, and serve up basic HTML from the controller.

I understand the benefits of keeping front-end separate from back-end.

- Separate teams working on front-end and back-end independently

- Front end bundle can be served fast and cheap via CDN (only the naive serve static files with gunicorn/uwsgi right?)

- and much more

Knowing all that, I chose to mix up VueJS with Django solely to optimise for speed in a single person company. Thanks to this setup,

- Authentication is handled via Django sessions (didn't have to spend time on JWT tokens)

- I don't need to setup deployment pipeline, monitoring, testing for 2 applications.

- Keep working on a single codebase and quickly iterate (slightly debatable, but still).

While the setup is not ideal for everyone, it certainly has advantages that I value at my current stage. If you're curious this is the application: https://reviewnb.com

> Authentication is handled via Django sessions (didn't have to spend time on JWT tokens)

That's intriguing, wondered how that'd work out with a SPA. I'm not big on SPA's currently they only make sense for certain type of websites to me, don't mind them if they're done correctly though. But hey if what you've done works for you that's good to me, until I have to touch that code :) Hopefully it's not too awful, it just sounds a little bit out of the norm, but I'd lie if I said I've never done out of the norm solutions...

> Front end bundle can be served fast and cheap via CDN (only the naive serve static files with gunicorn/uwsgi right?)

Not just a CDN, for internal apps I seve all static files through Apache or nginx. I rather let a normal web server do it's job. I trust a C backend to serve static files more efficiently than some web framework, but that's just my personal view.

Using Django sessions in an SPA is actually very easy. It just works, the browser handles the cookies for you. The only thing that developers has to do is to remember to include CSRF header with unsafe requests (such as PUT or POST), this is usually done by adding some kind of a pre-send hook in your request library of choice. There is a section in Django docs that explains how to do just this.

I suggest you check out this development in Responder then –released in v0.1.0 40 minutes ago :)


I'll continue helping Kenneth with this, cause that's a pain point I also want to solve for myself.

On a related note, I tried to build something similar for Django in the past. (it worked, but it's somewhat under construction again due to changes in Django 2)


Out of curiosity, what kind of “first class support” would you expect from a Python framework? You can write your React app as a fully decoupled codebase and then use any Python framework that serves HTTP for the API backend. The only other potentially useful feature might be server side rendering of (some of) your components, but you would have to do that in Node anyway.

(disclaimer: I don't know how this looks) if you follow the old-school web app model, you're working on the basis of stateless requests. This means that if you want to make a multi-page form, you have to build up coordination mechanisms between pages.

In something like an SPA, you end up having frontend state, but you're lacking the corresponding backend state. There are a lot of times where I've wanted to do something in the backend like:

    first_response = await render('first_form.html')
    if is_valid(first_response):
       final_confirmation = await render('second_form.html')
(This is obviously more conceptual than actual code, since actual code would require suspending python VMs for some unknown future)

In a framework that is more amenable to the fact that frontend clients have state, you should be able to write out multi-request flows more easily. Perhaps with some base notion of a request trace (with the understanding that the frontend also need to send extra info to identify itself).

Websockets are something interesting, but it doesn't quite enable this. And it won't be easy to get right. Failure cases in particular will require some coordination.

The backend request handling layer pretty much has to be stateless if you want to horizontally scale it anyway. Granted, it’s really helpful to have good abstractions for managing session state, but multi-request flows are just a sequence of requests that you have to handle statelessly anyway, even if that involves maintaining, fetching, and sometimes caching session state and other data more explicitly. I see value in having mechanisms for doing that easily (e.g. my request handler function taking a “state” argument that’s automatically populated from a session state store based on a request trace, JWT, cookie, or other mechanism), but I don’t see how those mechanisms would require tightly coupling your frontend and backend aside from enforcing the session protocol.

beyond the session protocol, you have to think about the bundle of state you need to carry between requests in a _clean_ way (preferably something that goes beyond "stuff it in the session dict", because that's basically global variables). You also most likely want ways to do things like fetch non-stale versions of objects from the DB, help with certain data assertions, etc.

You don't need to have a stateless backend for horizontal scale, you can have relatively smart routing, or relying on stuff like the database to help you with the coordination. Especially if you do things like say "this session is held to for up to an hour" you could even consider suspending VMs! If you have the resources to do so, that is.

I think that "coupling frontend and backend" is not really what is being requested here, but more about providing functionality that lets you build rich backends based on the fact that our frontends are way richer than they used to be

I'm somewhat torn about that idea. Here's why.

My story is that I composed a django+angular app. Rather than replace the jinja templates, I treated them as a noop and wrapped the angular in verbatim blocks. Was a rather trivial bit of code and "Just Worked."

For the same reason we look to circumvent jinja templates now is broadly why I don't think python web frameworks should be in the business of servicing one particular SPA framework. I can see some slight benefits in e.g. integrated routing support, maybe some level of model integration, but I'm hard pressed to think of how one could gain _huge_ conveniences without a real reorientation of how I look at the separations between the python and JS sides of things. (which is largely why I'm curious if I _am_ looking at all this in a very amateurish way)

Anyway, I should probably take this as a reason to learn more than nothing about Rails, since all of the above may be answered by seeing what their end product looks like.

> I spent quite a bit of time setting up my Django app to serve VueJS (replacing the built-in Jinja templates). Once ready, it became a powerful application with ORM, middleware and all other Django goodies coupled with modern JS framework on the frontend.

Have you thought about writing this up? I'd be interested in reading how you went about it.

Rails 5 already has webpack support and React support.

https://github.com/rails/webpacker https://github.com/reactjs/react-rails

Can use it pretty much fully in place of the asset pipeline.

Can use standard ERB and spice it up with React using a simple tag with the component name and props as a hash.

Builtin Django templating isn't Jinja thought...

Ohh please. No mixing of NPM with Django.

Pretty cool, but I can't shake the feeling that the first example looks an awful lot like javascript...

Perhaps... Maybe ... its because I have been "cheating" on Python with JS. I mean, it is a pain in the booty to code up a web app in python without JS. Try to code a mobile app with Python and Kivy... not all that fun (not practical). In less than a week with React, I have done both. So... why not just skip Python all together? I have been asking myself that question.

Bottom line: The authors of this "service framework" states the Python world doesn't need another web framework, I agree.

It needs some serious love in GUI land.

I've started to wonder what the place of Python is at all. Machine Learning has become deeply coupled with Python, so you have that side of things, but that's not my personal area of interest.

People say that it's good for "short scripts", but whenever I decide to write something in Python instead of TS, I'm instantly met with so many runtime type errors that I wonder how people can honestly believe lack of static typing increases productivity in these "short scripts". For instance, the second I decide to refactor, I know that even once I think I've cleaned everything up, the next few minutes will be spent running the code a few times to flush out all the type errors.

Python is not my primary language, so that could play a part in the issues I have, but if I am allowed to lose humility for a second or two: even though I primarily use TS, my Python is still, in my opinion, stronger than many of my (college student) peers. I hate to imagine all the issues a novice would face.

To be fair, I haven't used mypy in a while. I remember that being decent, but nowhere near the level of TS, in terms of both the power of the type system and the editor support.

Coming at it from the other side (Python has put food on my table for ~7 years now), it's not the "short scripts" that make Python great to develop in, it's that it can handle the growth of your app.

Writing scientific/academic code and writing business application code is somewhat different, but the speed at which you can develop and maintain Python code is very high, as is the volume of aid available should you run into trouble.

I don't think there's a language out there that's both easy to initially pick up and as well supported by its community as Python. The speed at which you can develop application code is astounding, once you get the hang of it and the noise out of the way (CI/CD, code coverage, unit and integration testing, a general familiarity with the major frameworks, etc.), and the maintenance is... tolerable.

I wonder if you have a different definition of "short scripts" than many others. It seems to me that a genuinely short script wouldn't require big refactors, or types---that would be overkill for a short script.

Personally, I use Python as a Bash replacement a lot, that's what I think of when I hear "short scripts." Sort of what people used to use Perl for. Pushing strings around, complicated repetitive filesystem manipulations. (And data sciencey stuff of course.)

I agree with you. Automate some task? Scrape some web content? Glue some programs together by translating the output of one to fit the input of the other?

Python it is! If it doesn't already have something in the standard library for your task, it's definitely in the PyPI. This reduces your work to importing a library and writing 5-20 lines of code.

> Sort of what people used to use Perl for.

Used to? People still do this (I should know; I'm one of them).

Heh, fair enough! I think I still have an open-ended bet with a friend about using Perl 6 for something...

And bash/zsh. Bash can be really powerful. Slow for some tasks though (much slower than perl for example), but little times I've had that problem.

I use "short scripts" to mean: I have an idea I want to play around with, usually involving data analysis or some data structure or algorithm sketch, and I'd like to devote the next 2-3 hours to writing a 100-200 line program that evolves with me as I refine what exactly it is that I would like to be examining.

Python has an excellent ecosystem for those in the sciences, finance or those working with data. A few popular and mature web frameworks are written in Python. It has a place next to Bash et al when it comes to system scripting and acting as glue between different streams, utilities and resources.

Static analysis tooling is excellent and type annotations only aid their accuracy.

It's my impression that developers tend to learn to love static typing if they didn't cut their teeth on a statically typed platform. It takes experience to know that certain errors can be mitigated via language features and to know how annoying those errors are when they needlessly pop up.

Unenforced explicit typing was and is still a boon for Python. Typing is often lost on developers who are still in "Hello, world!" territory and scientists who are using it as an adjunct to MATLAB. It can be a hindrance to rapid development, as well.

it's the quality of the libraries above all else that keeps me coming back to python. truly world class.

Don't forget the community and the support for those libraries. It's extremely welcoming and newbie-friendly.

Shout out to Django!

In further reflection, it is perhaps only because I am so used to TS that I try to make as intense of refactorings as I do. A programmer who does not have prior experience working with as well tooled of a language would not be attempting the kinds of transformations I do, and thus may not experience as many issues.

It sounds like you should invest some time in learning to program python in a pythonic way. If you are trying to build stuff using tons of design patterns factory patterns, you are doing it wrong. Most of those where made to work around limitations of type-systems which aren’t there in python, and naturally you end up having issues solving things like that when you don’t have typing. (Which you do still have with mypy, but as you say you’re not using that). At the end of the day you are using python and there must be a better way! though just like anything else you need to dedicate time to lean not just the syntax but also how to effectively use the language without needlessly over complicating things.

I'm not trying to build using tons of factory patterns or the like, quite the opposite actually. I try to code as close to the bare language as possible, and work under the assumption that if I at some point would like to pivot my reasoning or approach to a program, the language and the tooling available will help me do so. This is simply not true without types.

I'm not alone in thinking that, the creator of Python himself has devoted his recent work to adding types to Python. Is that just because he doesn't write his code "the correct way"? Does he simply know the syntax but not hoe to effectively use the language? I don't think so.

You need `import typing`, and an editor with integrated mypy (e.g. vim). It is almost as good as static typing.

Initial thoughts from looking through https://docs.python.org/3/library/typing.html#:

1. Love that it doesn't use structural typing, NewType seems great.

2. The syntax is bad. Maybe this is a "it just takes getting used to" thing, but I actually find it really bad. In TS, the syntax for typing almost always directly matches the syntax for the rest of the language. In Python, its a weird sort of LISPy DSL think that they made... compare:

  Py: Callable[[List[Tuple[int, string]], Dict[string, string]], int]
  TS: ([number, string][], { [key: string]: string }) => int
This only gets worse as you chain callables together, whereas in TS everything left-associates as you'd expect and it all works out nicely.

3. Admittedly, the TS dict syntax isn't beautiful, but it becomes very helpful for things like `{ [K in keyof T]: K extends number ? T[K] : never }`, which does not seem to be possible in Py.

4. Related to 3, but no never type? I see NoReturn, but it does not seem to actually cause any errors when you try to assign it to a variable. See below.

5. Type narrowing... does it exist? Seemingly not, see below.

6. Literals as types (enums)?

7. Generics, do I really need to pass in the internal representation of the type I'd like to use? That seems absurd. Will bad things happen if these internal identifiers collide? (Reference: `T = Generic('T')` creates a generic type)

Demo code that should throw an error at the assertUnreachable and nowhere else, but actually throws errors everywhere but the assert unreachable (types seemingly aren't narrowed by `type() == ...` checks):

  def foo(x: Union[str, int, float]):
    if (type(x) == int):
        return x / 3
    if (type(x) == str):
        return x.upper()

    return assertUnreachable()

  def assertUnreachable() -> NoReturn:
    raise RuntimeError('no way')
(this is all checked using mypy, v. 0.641)

If you use isinstance(x, (int, float)) instead of type(x) == int then I think you'll find your expected behavior.

When you say type narrowing do you mean floats should be automatically interpreted as int? There is typing.{SupportsInt, SupportsFloat} which can be considered "number" base classes which you may consider as type narrowing. Otherwise if you mean "type of x is known in this if-block" you do get that with `isinstance` type checks (which is the preferred, pythonic way).

I agree that mypy should warn if a NoReturn is assigned; apparently it just ignores typechecking below the NoReturn function call, and is really only used to ensure the NoReturn function is guaranteed to raise before it returns.

`isinstance` is what I wanted for narrowing, thanks!

Regarding #2, the python code has the arguable advantage that (with appropriate variables in scope) it's valid standard python code[0] that could evaluate to (a representation of) the desired type, whereas the typescript isn't valid javascript code, and I don't think it's a valid (value-level) typescript expression either.

3 and 4 are disappointing though.

0: I'm assuming the extra [ after Callable is a typo.

Is there a utility to having your types and your values in the same namespace?

The extra [ is not a typo, the syntax is: `Callable[[Arg1Type, Arg2Type], ReturnType]`. Or, if the arguments don't matter, `Callable[..., ReturnType]`, but this does not mean that the type is not a valid expression.

Edit: I was missing a ] actually, separating the arguments from the return value.

> Is there a utility to having your types and your values in the same namespace?

Well somewhat[0], but the main putative benefit would be having types be valid expressions in the target language, since you can do type-checking with function decorators, and generally interact with types useing the normal language mechanism for interacting with values, rather than some horrid bolted-on piece of crap like C++ templates.

  Server = Tuple[Address,ConnectionOptions] # array subscipt might not the best choice here, but it works
  UserId = NewType('UserId',int) # ordinary function call
  Scalar = int | str # could be equivalent to Union[int,str] with appropriate value of Type.__or__
0: for example:

  def intBit(N):
    if N==0: return type(None)
    if N==1: return Bool
    if N>INT_WIDTH: return long
    return int

mypy's response to that code:

  error:invalid type comment or annotation
  note:Suggestion: use intBit[...] instead of intBit(...)
So what's really happening is the type expressions are pretending to be "just everyday python", but actually they have arbitrary restrictions (cannot be functions? need to work via overriding `__getitem__`?) that neither you nor I were aware of. This is probably the least "pythonic" implementation possible.

And even if the code were valid, it's relying on N being a statically known value, which is a bit off because sure, you could have N be some global const config variable, but it would be very weird for configuring the value of the variable to require you to also go into the code and change things around to work with bool's or None's instead of int's.

> So what's really happening is the type expressions are pretending to be "just everyday python", but actually they have arbitrary restrictions (cannot be functions? need to work via overriding `__getitem__`?) that neither you nor I were aware of.

Yeah, that sounds about par for the course for bolt-on static-y typing in languages that aren't supposed to be statically typed.

At least we have TS.

I'd argue that python needs an async django, which will hopefully be django in a few releases.

There is an async Flask in the form of Sanic[1]. Looks quite usable compared to raw aiohttp or twisted spaghetti I had to help maintain a couple months ago.

[1] https://sanic.readthedocs.io/en/latest/

I used aiohttp for a small project recently and found that it to be very good.

Combined with aiohttp-json-rpc I had a very effective websocket-based JSON RPC backend service up and running in a very short time and with very little boilerplate. I'll be using this pattern again for sure.

What would have been the advantage of me using Sanic instead (I haven't RTFM for sanic yet but I'm about to...)?

[disclosure I am a sanic contributor] aiohttp is a great project, very similar to sanic, I'd say the big thing is sanic is slightly more flask like than aiohttp in ergonomics (which is something aiohttp has been working on[1]).

Sanic also makes performance a key development goal so you can feel comfortable the project will scale gracefully. But I will stress I don't have current benchmarks to compare against aiohttp


The thing I like about Django is that it is an opinionated framework so lots of decisions were already made for me. Flask is a not too distant second place.

With aiohttp you can make neat things it is operating a level below Sanic - in my experience people end up writing their own half-baked undocumented framework based on a combination of aiohttp, some ORM and a template engine - sometimes with half a dozen combinations in the same company.

We actually use Sanic alongside Django for some of our machine learning services. Has been working well so far.

Yeah I mean the async landscape for web frameworks isn't exactly as populated as the "yet another web framework" statement makes it seem.

This is how we get to async Django, and I think that's part of why Tom Christie is helping out. I also doubt Reitz thinks this is the usurper of Django anyway. It's more than an experiment, but less than "the new One True Way".

As for ASGI python web frameworks, there are no mature winners in the space yet (compare uvicorn's quickstart example to this project's before you throw that project out as an example). This is Truly New Shit, and I'm pumped these two devs are working on it together.

Yo. Yeah my (bit of) involvement is mostly around wanting to help guide the new ASGI ecosystem.

For example, I'd like to see Python's async frameworks building on ASGI middleware rather than all re-writing their own middleware APIs. That way we end up with lots of cross-framework compatible middleware implementations, and we're all working together much more coherently.

Similarly for test clients. We don't really need frameworks to all be building their own individual test clients to interact against their own interfaces, when we can instead build test clients to interface against ASGI, and then be able to use them against any ASGI framework.

That's part of what the Starlette project (which Responder uses) is all about: https://www.starlette.io/

(FWIW Starlette also composes all those bits and pieces into a framework in its own right)

Async support is actually planned for django in upcoming releases. Here's some info about that https://www.aeracode.org/2018/06/04/django-async-roadmap/

From what I understand ASGI was developed by Andrew Godwin for Django Channels.

I'm super excited for that development work to begin!

But just thinking about my own experiences, being able to look at what other people have done so far with it would help immensely when building the nuts and the bolts of the feature. This project will help immensely with that.

Andrew gave a great talk on this very topic at PyCon AU in August. Still at the formative stages it seems...


Tornado[0] is not on per when it comes to features richness of Django. Yet, it's async and a joy to write. You should check it out if you have not. I would like to hear more from others about Tornado vs other Python frameworks as well.

[0]: http://www.tornadoweb.org/en/stable/

+1 I used Tornado in the past because it had an async event loop before it was native to Python. So much simpler than having to set up wsgi servers etc with the added benefit of easily-configured background tasks (like having cron jobs built in to your application). This is really good when you're building an application that you want other people to be able to install and run easily.

It seems that Tornado is now offering the choice of its own event loop or the asyncio event loop. I built something recently in aiohttp because it felt like it had been built on asyncio from the ground up but will explore Tornado again.

If you can manage with Flask there's Quart [1]

[1] https://gitlab.com/pgjones/quart

I've been using quart for some projects recently. Was super easy to move to from flask (though had to upstream a couple compat fixes). Overall, super pleased

Django’s channels project actually gets pretty close to this. It’s not flawless, but it makes it fairly simple to support websockets, etc.

There are numerous async frameworks already, aiohttp to name one, in addition to others mentioned above.

I'm aware of all of the flask inspired async micro frameworks.

By django like I meant a batteries included framework with an integrated async ORM, auth, DRF and etc. From what I've seen we'll probably have to wait for django to get there, which might take a few years.

I love Python for back-end web development, it's hard to shake it off of me, except if I were doing ASP .NET Core (I'm ok with C#). So I think in that area it's pretty solid, but I agree, I wish the GUI side of Python got more love, maybe a proper RAD environment like VB had, hate on VB all you want, but damn it was neat. I'm surprised Kivy doesn't have a RAD editor, if it does then I am way behind. For now I'll keep using Tkinter.

>The Python world certainly doesn't need more web frameworks. But, it does need more creativity.

Then why create a "new python HTTP service framework"? The Flask and Falcon communities are very welcoming to creativity.

This project strikes me as a fun side project that doesn't have serious legs or ambitions, which, don't get me wrong, is totally encouraged and fine! However, when it's being touted as a new framework for people to use, complete with its own logo and testimonials(???), it really presents itself as yet another soon-to-be unsupported and unmaintained/discarded project. We have to judge it based on how its presented, and in my humble opinion, it's being presented as The Hot New Shit, when it's maybe 300 original lines on top of massive existing frameworks.

> This project strikes me as a fun side project that doesn't have serious legs or ambitions

And it totally is! "The primary goal here is to learn, not to get adoption" [1]. Kenneth Reitz is just another developer who created a public repo with some docs, a logo and the clear indication that it is just for fun. I don't see why everyone is so on the fence with this.

[1] https://github.com/kennethreitz/responder#the-goal

Maybe it's a bit disingenuous to claim that's your primary goal when you've gone to the trouble of designing a logo and adding "testimonials" to your README.

And Kenneth Reitz isn't "just another developer". He's well known, and isn't shy to mention his `requests` library ("uses the actual Requests you know and love").

Cynically, you might say the "just for learning" phrase is a great way of avoiding comparisons to existing frameworks initially. The thing is, it could compare favorably. For one thing, Flask and Falcon support/have to support (?) old Python versions - Falcon even says they support Python 2.6, which is ridiculous (EDIT: doesn't seem to be true from the tox file, but the website still claims it does). All that compatibility stuff provides zero value for new projects.

Background tasks are a great idea. Being a bit opinionated isn't necessarily a bad thing either; Flask would benefit hugely if they recommend people use app factories and blueprints from day 1. It adds almost no overhead, but makes building the application out much, much easier in the future.

Yeah, it has quite a bit of marketing juju going on, which flies in the face of the "just for fun" disclaimer. If its just for fun, why push it so hard? The testimonials is especially cringe.

Its not just another web framework, its another plea for approval.

This is Kenneth Reitz, it’ll be supported.

Sorry, but invoking the name of someone who has many half-baked projects on their github (and again, that's totally fine), doesn't instill confidence in me to put my business's new product on it. There's nothing groundbreaking here. Innovation has to outweigh the lack of project maturity for serious people to use it in production, and the innovation just isn't here.

You really have no idea who Kenneth Reitz is, do you?

He wrote Requests. His many other side projects are not nearly adopted, supported, or maintained like Requests. This project will likely be the same as the vast majority of those other side projects.

This cult of personality stuff is really bizarre though. I actually feel bad for Kenneth in this regard, since he'll never know if what he makes is actually any good, since his followers will tell him it's the greatest thing since sliced bread regardless. I have legitimate support concerns before I would even consider using this for something real, and I've had two responses so far that address them by merely invoking his name. What a sad place to be in.

Requests is a work of art. And the man is a self taught programmer. In that regard he can be my patron saint for that matter. How many of us have repos that we don’t maintain. He does this work for free. So if he wants to let something languish so be it. If you depend on a work he doesn’t upkeep then fork it and add to it.

Call me old fashioned, but I like functions that return something. Hard pass.

Part of me agrees with you, the other part of me wants to point out that this can be solved trivially with a decorator.

The amount of negative feedback this post is getting is excessive.

Agreed. There's a lot to like here.

Liking is subjective. It is code written around Flask. Do you really need that?

Yeah, I think we do.

Are benchmarks available? And "nginx not needed"? Is uvicorn really that great?

> Background tasks, spawned off in a ThreadPoolExecutor.

This could be very nice; something that I've often found clunky when building a prototype is the amount of infrastructure required to get a more full-featured task queue up and running (say Celery or RQ). You can always just run an event loop, but then you have to reinvent a lot of the nice delay/scheduling machinery.

async & fstrings - seems Kenneth is on board with Python 3 then.

One of his other really great applications is "das inbox" https://github.com/kennethreitz/inbox.py - it's brevity is inspiring - actually Responder seems very similar to das inbox.

It's not very encouraging to see that one as archived by the developer. I'd hope this new web framework he made doesn't end up the same way. I wouldn't mind experimenting with it.

As a very regular Requests user I'm pretty excited about Responder. There are times when I just want to stand up a 'glue' API, and this looks extremely convenient for that purpose. I've wasted too many hours futzing with flask+WSGI+nginx+ubuntu to want to stand up something with it on a whim.

I was able to follow a whim and use responder for a simple task where I just need to provide a single endpoint with one parameter that returns a JSON object with data from a SQL query. After about 2 hours (mostly spent trying to get a dependency issue ironed out) and 13 lines of code I have everything I need. I'm a happy customer so far.

What about the performance of python-responder?


I still remember when kenneth closed every single open ticket on his envoy project without any fixes. Problems? What problems? Serves me right for taking the time to write a detailed bug report. I won't make that mistake again.

I’ve got plenty of criticism for pipenv, but comments like these don’t endear me towards Kenneth’s critics.

What's wrong with pipenv? I've been meaning to try it

So I've been using it a bunch on my more recent Python projects. The promise and the reality are unfortunately not close.

For the record I love having a one stop tool for virtualenvs and dependency management. That's quite nice. The Pipfile is nice. The Pipfile.lock is awesome.

The tool itself is:

1. Painfully slow. 2. Very buggy.

For example `pipenv graph --json` is broken in the latest release. This is the mechanism that other tools use to hook into pipenv. It's actually been broken in various ways since May.

It's also incompatible in subtle ways with the latest pip. So I had to downgrade to pip 10.x.

I've had some frustrating experiences lately now that the honeymoon is over.

I'm going to keep using it, but I really hope some serious improvement is made in the next 6 to 12 months around performance and stability.

Here's some sources. This bug in 2017 is characteristic "Pipenv Halloween easter egg" [0]. Pipenv has caused lots of unneeded drama in the Python community[1] - just search for past Pipenv posts.

Most of the criticism comes from software developers, and I suspect Pipenv fans are hobbyists (like fuck me for choosing Python in production, right?) I doubt Go's tooling accepts this strange behavior from the maintainers[2]. Kenneth Rietz is NOT a core Python developer.

So for my opinion, we have Pipenv instead of Requests support for async/futures, HTTP2.0, Websockets, or better encoding. But the documentation gets updates I see: "Requests is the only Non-GMO... organic, grass-fed HTTP/1.1 requests"[3]. This emojifuck for humans has no drive, so Go has better HTTP packages now.

Python's packaging has gotten political. I hate politics. I won't help new programmers with Pipenv, and I don't care if that's good or bad. At least Poetry _respects_ PEPs with it's well-defined specification. But I'm not gonna fight a losing battle. Maybe Pipenv gets ironed out one day. Hell, maybe Java replaces Maven. But I grow weary of immature repo maintainers. I just need working code; yet I feel this answers to nobody.

[0] https://github.com/pypa/pipenv/issues/786

[1] https://chriswarrick.com/blog/2018/07/17/pipenv-promises-a-l...

[2] https://github.com/pypa/pipenv/commit/fe78628903948013e8687d...

[3] http://docs.python-requests.org/en/master/

Yeah, the speed thing with lockfiles is painful. But python dependency management is such a mess anyway that it's probably the best thing out there.

Consider https://github.com/sdispater/poetry as an alternative.

Another good one is pip-tools: https://github.com/jazzband/pip-tools (which pipenv set out to replace initially, but it does a terrible job of it IMO)

This looks really nice! That dependency example makes relying on pipenv seem kinda scary, and I really like how it replaces the setup.py too.

I tried using it for a heroku app since it was recommended in the Python setup (I used a plain requirements.txt in other projects)

For me, it broke very often, would take forever to recalculate stuff, and would simply get in the way _way_ too much. I get the logic of the system but in practice pip + requirements.txt basically works for my use cases.

I tried it, and honestly it's fine for most cases, but it's pretty slow compared to just plain virtualenv. Considering virtualenv is prefectly fine I eventually switched back.

The fact that it couples dependency management to virtualenv management is really unfortunate for people that use docker. Can’t wait for pipfiles and such to be native to pip.

Just try it, but also try the other alternatives and form your own opinion.

I used to hire people who have created their own frameworks like this one and our codebase were so bloated. At one point I had to let people go and spend the next year removing tens of thousands of lines of useless nonsense. Since that lesson, I look at candidates Github and if I see a custom built framework, I pass, regardless of how good they performed.

You can do that if you want... but it seems a bit extreme to rule out a candidate based on one project that could be really quite well designed and useful for whatever community it aims to benefit.

Especially considering there's a big difference between what people work on for fun/publish to Github and what they'd consider using in a workplace environment.

But this is Kenneth Reitz. He's written multiple everyone on earth uses this-level libraries. Hardly likely to produce useless nonsense.

There are definitely people who create frameworks who shouldn't, out of wanting to be "the guy", or not wanting to learn existing tooling. But frameworks/libraries are code too. SOMEONE has to write them. And sometimes there are genuinely good/unique ideas. It's good that strong coders w/ genuine knowledge of the problem domain tackle them. Your statement is equivalent to "I've read bad books, therefore I'd never hire an author."

This is an insane notion, and I don't mean "insane" as a hyperbole, but literally not sane.

Honestly, I very much doubt what you've written is even true, it's that nuts.

I would say I can predict with relative accuracy how bloated a codebase is by looking at how many custom frameworks I find at team member profiles.

The problem with this statement is that you're acting like everyone and their mother has a GitHub profile to begin with, and then that they've invariably got a "custom framework" there as well.

None of this meshes with any reality I'm aware of. I'm willing to be wrong here, but considering the statistics I know about hiring, GitHub recreational usage among the average software dev, and... I dunno, my own proclivity to write frameworks, your story is pretty far from believable.

Can you though? There's likely a correlation between the codebase size and how experienced people work on it. If you have a beginner, they're both unlikely to work on a large project and unlikely to create their own framework. And to connect the last bit - the larger project becomes, the more likely it is you'll find some bloat in it. So the custom-framework : bloated-codebase relation becomes a bit of self fulfilling prophecy.

I agree that might be a bit heavy handed, I personally like implementing frameworks or tools in new languages that I'm learning because it's fun and build familiarity. Production code is way different than that.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact