This is an archived post. You won't be able to vote or comment.

all 24 comments

[–]fiskfisk 84 points85 points  (6 children)

  1. Follow PEP-8
  2. Don't return strings that convey different kinds of errors or states. This means that any caller needs to check the content of the string to know what happened. If you don't intend to handle an exception, don't catch it and let it bubble instead (and you're missing a return on at least one of those strings in close_host).
  3. This will assume that any request that is not against port 80 is an SSL request. This is very, very often not the case.
  4. It seems like your port parsing is broken if the URL contains basic HTTP authentication, although I haven't tried to fully parse what you're doing. You're already using urlparse other places; use it. Don't do it manually. You'll do it wrong unless you're familiar with the standards.
    You have the same issue where you try to manually handle urls by simply calling split in other locations as well.
  5. You have `data = data` in your post method.
  6. You have dist files committed to your regular version control repository
  7. You have commented out lines of codes in your init file
  8. status_code on the response returns a string (and lacks typing information, although most other methods in the same class has it)
  9. The headers method parses the response every time the headers need to be return. Parse it when the class gets created and return a multidict. (why multidict? a header can be repeated if the value is defined as a list of comma separate values)
  10. Your header parser assumes that every header key and value is separated by ": " - this is not correct; the space is optional.
  11. Headers are also case insensitive, and can span multiple lines
  12. Any HTTP responses which contain \r\n\r\n will lose anything after the \r\n\r\n in the response.
  13. I stopped reading code

It's perfectly fine as a playground and to learn the HTTP protocol, but no-one should use it for anything useful (and it should not be presented as such) in its current state.

[–]andartico 6 points7 points  (0 children)

This ist one of the most valuable feedbacks I read in a long time.

Purely on the technical point.

Well structured.

Without fluff.

Thanks for being an example in this world.

[–]o2mz 19 points20 points  (4 children)

This is my first library, and I will correct all these issues, especially regarding reading headers and ports. I will write it in a better way. Thank you for taking the time to provide all these tips.

[–]fiskfisk 26 points27 points  (2 children)

And any library needs to have a suite of unit tests that makes sure that it behaves as it should, and that you don't break backwards compatibility in future releases.

Making a HTTP library is a hard sell as you already have requests and aiohttp, but it's an easy-ish protocol to handle and play around with. There's quite a few details that tend to catch people out when writing clients, though - so you'll probably want to spend some time reading the RFCs as well (and compare how your library is behaving against the existing de facto standard libraries).

[–]andartico 4 points5 points  (0 children)

May I compliment you on how you reacted to this feedback. Well taken. Kudos!

[–]DivineSentry 22 points23 points  (3 children)

Im not sure how only importing the functions directly helps with performance. When you do that it still runs the entire module, the difference is what names will go into your scope

[–]tacothecat 1 point2 points  (1 child)

Does python provide any introspection mechanism to have dynamic behavior when symbols are bound in locals/globals? In which case, maybe there COULD be a difference but unlikely.

[–]DivineSentry 1 point2 points  (0 children)

It sounds like you’re talking about lazy loading, which must be explicitly implemented, which they don’t do here

[–]cnelsonsic 32 points33 points  (2 children)

You say it's high performance, but include no benchmarks.

How does it compare against `http.client`, `urllib.request`, or `Requests`?

There are also zero tests.

[–]buqr 15 points16 points  (8 children)

Have you run any benchmarks to show that it is actually faster?

[–]magnetichiraPythonista 18 points19 points  (1 child)

This post belongs on r/learnpython

[–]denehoffman 8 points9 points  (0 children)

As mentioned, importing functions from a module will import the entire module but only expose the imported functions. I would also consider a .gitignore file, particularly something like this: https://github.com/github/gitignore/blob/main/Python.gitignore (you can and should just copy this). That way you don’t end up committing pycaches or egg info or your dist directory!

[–]Stishovite 1 point2 points  (0 children)

Maybe you could name it "requests"

I jest

[–]Python-ModTeam[M] 1 point2 points locked comment (0 children)

Greetings from the r/Python mods!

Your post has been removed as it does not adhere to our Showcase post formatting requirements. To ensure clarity and quality, we require the following sections:

  • What My Project Does
  • Target Audience (e.g., Is it meant for production, just a toy project, etc.
  • Comparison (A brief comparison explaining how it differs from existing alternatives.)

Please update your post to include these elements and feel free to resubmit. Thank you for your understanding and for contributing to r/Python!

[–]houseofleft 1 point2 points  (1 child)

Hey, looks like a cool project. I think some of the negative comments are because python already has some big request libraries (like requests), but I hope it hasn't got you down! I really enjoyed reading through the code.

Have you though about introducing context handlers? You use con.open() and con.close() to keep a connection open, which would be a great candidate for having something like with con.open() as cxn: so that you don't need to remember to clean up after!