Skip to content

Expose core API at top-level - #107

Merged
lovelydinosaur merged 5 commits into
mainfrom
core-api
Oct 21, 2026
Merged

lovelydinosaur merged 5 commits into
mainfrom
core-api

Conversation

@lovelydinosaur

Copy link
Copy Markdown
Member

Only the core API is exposed at the top-level...

  • Client
  • Binary, Content, File, Files, Form, HTML, JSON, MultiPart, Text
  • Headers
  • Method, Request
  • StatusCode, Response
  • Server
  • Stream
  • sleep, timeout
  • QueryParams, URL

We also have some semi-private undocumented API...

  • hip.parsers (HTTPParser)
  • hip.backends (NetworkBackend, NetworkStream)
  • hip.transports (Transport, Connection, ConnectionPool)

Some thoughts around this...

  • We should currently consider the parsers/backends/transports to not yet be API finalised*.
  • We haven't documented timeout/sleep, also we haven't currently implemented their usage in either Connection or Server.
  • I think the only top-level custom exception should be hip.HTTPException. Some classes might raise built-in exceptions in some cases. Eg. ValueError. We should have a think though / double check the expectations around possible client.request() exception cases.
  • I'm not convinced our client.stream() streaming API should be public yet. It touches on some subtle points that I'm not sure we've finalised yet. Perhaps we can remove this for now.
  • We haven't documented Stream or Content yet.
  • I'm not convinced we should allow non-context managed usage of Client/Server yet. Constraining the allowable interface there ensures that we've only got public API that can also be properly mirrored in async.

* Notes:

  • We currently have hip.parsers.ProtocolError - do we need vs. a built-in?
  • We should drop open_connection in favour of .open() / context managed usage.
  • The network backend interface needs tidying up.
  • The transport API is not finalised, there's some bits still to think about there.

@lovelydinosaur
lovelydinosaur requested a review from cgl October 21, 2026 12:02
@lovelydinosaur

Copy link
Copy Markdown
Member Author

@cgl I think this really helps clean things up. Does this all make sense from your perspective?

Getting the top-level API neatly constrained in time for the sprints seems important to me

@lovelydinosaur

Copy link
Copy Markdown
Member Author

Also, since I mentioned "in time for the sprints"... something else that might be worth getting up and running by then is....

async with hip.Server(...) as server:
    ...

(I know, right!!!)

Like, actually not that challenging from where we are, because...

  • Needs an async backend. Might suggest trio for first pass here, because. Well, because it's excellent.
  • Needs async variant of Stream, or for Stream to support dual-use with .aread() / aclose().
  • Needs async variant of HTTPParser. Hey, unasync to the rescue! Wait isn't this one Sans-IO? No, it's not. Instead it's just really simple, and neatly testable. Seems like an okay trade-off.
  • Needs Server to support async with, wiring up the above for the async case.

Alternatively we start by simply being clear / documenting that we don't yet have the async variant supported, though we're looking at it.

Alternatively, alternatively, we could drive this the other way around, by wiring up for the async case instead, and then working towards adding sync support. Adapting the codebase for async support really isn't a complex change, though it'll be a little noisy in terms of code lines affected.

Anyways, I digress.

@cgl cgl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall. Nice work cleaning up and organising all 💯

Comment thread src/hip/__init__.py
@@ -1,43 +1,37 @@
from ._client import * # Client

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to say goodbye to these import * lines.

Comment thread src/hip/_timeouts.py Outdated
if remaining is None or dur < remaining:
time.sleep(dur)
else:
time.sleep(dur - remaining)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with hip.timeout(1):
      hip.sleep(1.2)

For this example the current code sleeps about 0.2 seconds before raising.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

I've had to add a nocover directive because it's a bit fiddly to reliably test, tho.

@lovelydinosaur

lovelydinosaur commented Oct 21, 2026 •

Copy link
Copy Markdown
Member Author

Incidentally, those tests take a lot longer than I'd expect in the GitHub env. They run through in < 0.3s on my local machine. They list upwards of 60 seconds here.

Anecdotally, I think GitHub might delay test matrixes with multiple combos. Perhaps we'd have neater faster tests if we only checked Python lower/higher bounds???

(Or eg. test a single python version on PRs, and the whole matrix on main commit???)

@lovelydinosaur
lovelydinosaur merged commit fc1972a into main Oct 21, 2026
5 checks passed
@lovelydinosaur
lovelydinosaur deleted the core-api branch October 21, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants