httpp
from httpp import Server
app = Server()
@app.get("/hello/{name}")
def hello(name):
return f"hello {name}"
app.listen("127.0.0.1", 8000) # that's it — no separate server process needed
pip install httpp gives you a Python package, a command-line tool, and a compiled C++ library with
headers and a CMake config. Every third-party component is built from source, so nothing has to be
installed system-wide (no apt, brew or choco).
Contents
Features
- Client and server in one library. Most lightweight HTTP libraries only do one side.
- Decorator-style routing in Python, in the spirit of Flask and FastAPI: path parameters, typed
conversion, JSON responses,
async defhandlers. - Built-in server. No ASGI/WSGI layer and no separate process to launch.
- Real async.
async defhandlers run on one shared asyncio event loop and release their worker thread while theyawait. Idle connections wait in an event loop too (epoll, kqueue or IOCP, via Asio), so thousands of slow or idle requests cost almost no threads. - Python, C++ and a CLI from the same wheel. One binary core, three front ends.
- HTTP and HTTPS on the client (mbedtls, vendored).
- Hooks, streaming and files on the server:
before_request/after_request, error and exception handlers, generators as streamed bodies, files sent from disk, cookies and redirects. - A client with a real error model:
res.json(),res.error,raise_for_status(), typed exceptions, sessions, anAsyncClient, timeouts, redirects, TLS verification. - Downloads that can resume, with a tqdm-style progress bar (drawn on stderr, so piped output stays clean). The features above exist in both C++ and Python, with similar APIs.
- A migration path for
libcurlcode:httpp/curl_compat.hprovides acurl_easy_*subset. - No system dependencies. Nothing to install system-wide; the only build-time download is the header-only Asio (about 3 MB, pinned by hash), which can be supplied locally instead.
Install
pip install httpp
Requires Python 3.8 or newer. Building the C++ side on its own needs CMake 3.21+ and a C++17 compiler (see Build from source).
Python
Serving: routes
Register handlers with decorators, then call listen():
import asyncio
from httpp import Server
app = Server()
@app.get("/hello/{name}") # "/hello/<name>" is accepted too
def hello(name):
return f"hello {name}"
@app.get("/square/{n}")
def square(n: int): # annotate as int/float to get a converted value
return {"n": n, "square": n * n} # dict/list -> JSON
@app.post("/items")
def create_item(request): # ask for `request` by name
return {"got": request.json()}, 201, {"Location": "/items/1"}
@app.get("/slow")
async def slow(): # async handlers: no thread is held while awaiting
await asyncio.sleep(1)
return "done"
app.listen("127.0.0.1", 8000)
All of get, post, put, patch and delete are available, and route() takes a list of methods
(@app.route("/thing", methods=["PUT", "PATCH"])). Register routes before calling listen().
Static files can be served next to your routes:
app.serve_directory("/static", "./public")
Handler reference
A handler may declare any of its path parameters by name, plus request. It returns one of:
| Return value | Response |
|---|---|
str |
200, text/plain; charset=utf-8 |
bytes |
200, application/octet-stream |
dict / list |
200, application/json |
None |
200, empty body |
(body, status) |
same, with your status code |
(body, status, headers) |
same, with extra headers: a dict, or a list of (name, value) pairs when a name repeats, e.g. several Set-Cookie (a Content-Type you set wins) |
| a generator / async generator | 200, sent in chunks as it produces str or bytes pieces (see Streaming and files) |
httpp.file(path) |
200, the file streamed from disk, Content-Type guessed from its extension |
The request object:
| Attribute | Meaning |
|---|---|
method, path |
HTTP method and path |
body / text / json() |
raw bytes, decoded text, parsed JSON |
headers |
dict, names lower-cased (request.headers["x-token"]) |
query |
dict of ?a=1 parameters |
path_params |
dict of captured path parameters (all str) |
cookies |
dict parsed from the Cookie header (first value wins) |
For repeated headers or query names the first value wins.
Error behavior:
- Return a status yourself for expected failures:
return {"error": "not found"}, 404. - A path parameter annotated
int/floatthat does not parse answers 422 automatically. - An uncaught exception answers a generic 500; the traceback goes to stderr, never to the client.
@app.exception_handler(...)and@app.error_handler(...)let you shape these answers (see Hooks and error handling). - A response header whose name or value contains a line break is refused (a 500), never sent.
Streaming and files
import asyncio, httpp
@app.get("/events")
async def events():
async def pieces():
for n in range(3):
await asyncio.sleep(1)
yield f"data: {n}\n\n" # str or bytes
return pieces(), 200, {"Content-Type": "text/event-stream"}
@app.get("/report")
def report():
return httpp.file("/srv/reports/latest.pdf") # streamed from disk, length known
@app.get("/old")
def old():
return httpp.redirect("/new", 301) # default status 302
@app.get("/login")
def login():
return "welcome", 200, [httpp.set_cookie("session", token, max_age=3600, same_site="lax"),
httpp.set_cookie("theme", "dark", http_only=False)]
- A generator (or async generator, in a plain or an
async defroute) is sent chunked, one piece at a time, so the whole body never sits in memory. Without aContent-Typeof yours it istext/plain; charset=utf-8. A generator that raises midway drops the connection: the client sees a truncated body rather than a clean end, and the traceback goes to stderr. If the client hangs up, the generator is released. httpp.file(path)takes an optionalcontent_type. A missing or unreadable file answers 404.pathis trusted: never build it from user input (path traversal); useserve_directoryfor that.httpp.set_cookiedefaults toPath=/; HttpOnly, like the C++ helper. A name or value that is not cookie-safe raisesValueError(percent-encode spaces, quotes, commas and semicolons yourself).
Settings
app = Server(threads=8, read_timeout=10, max_body=5_000_000, handler_timeout=30)
| Argument | Meaning (leave it out to keep the default) |
|---|---|
threads, max_threads |
worker threads for plain def handlers: threads are kept, up to max_threads are used under load. Default: about one per core, at least 8, growing to 4x that |
read_timeout, write_timeout, keep_alive_timeout |
seconds to read a request, write a response, keep an idle connection (default 5 each) |
keep_alive_max |
requests served per connection (default 100) |
max_body |
largest request body in bytes, refused above it with a 413 (a client still sending a huge body may see the connection closed instead); 0 = no limit |
handler_timeout |
seconds an async def handler may take (default 60, None = never): after that the coroutine is cancelled and the client gets a 504 |
handler_timeout only covers async def handlers: a plain def handler cannot be cancelled. The time
spent streaming the body afterwards is not counted. The same settings exist as methods
(app.set_read_timeout(10), ...), each returning app, mirroring the C++ httpp::server.
Hooks and error handling
@app.on_startup
def starting():
print("about to listen")
@app.before_request
def require_key(request):
if request.headers.get("x-key") != "secret":
return {"error": "forbidden"}, 403 # answers here; the route never runs
@app.after_request
def stamp(request, response):
response.set_header("X-Served-By", "httpp") # status and headers only
@app.error_handler(404)
def not_found(request):
return {"error": "no such page", "path": request.path}
@app.exception_handler(ValueError)
def bad_value(request, exc):
return {"error": str(exc)}, 400
before_requestreturnsNoneto carry on, or anything a route may return to answer right there.after_requestgets aResponseHead(status,headersas a list of pairs, plusheader(),set_header(),add_header()); the body is not passed, because it may be a huge file or a stream.- Both run for every request, static files and unknown paths included, and you can register several:
they run in registration order. Hooks may be
async def, but they hold their worker thread while they await. A hook that raises answers a 500. error_handler(404, ...)dresses only errors the server makes itself (no such route, body too large, ...), never a response a route returned on purpose, and it keeps the original status unless you return another. A handler that raises leaves the plain error as it was.exception_handler(Exc, ...)runs when a route raises; the most specific class wins, the status defaults to 500, and an exception nobody handles is still the generic 500. A handler that raises itself is a generic 500 too.on_startup/on_shutdown(plain orasync def) run aroundlisten(): startup before the server listens, shutdown after it stopped, in reverse order. A failing startup hook stops the launch; a failing shutdown hook is logged and the others still run.
Free-threaded Python (3.13t, 3.14t)
There are three kinds of wheel: a cp39-abi3 wheel per platform for every ordinary Python 3.9+, a
cp313-abi3 wheel per platform that pip prefers on Python 3.13+ (it is built against the newer stable ABI),
and version-specific cp313-cp313t / cp314-cp314t wheels for the free-threaded builds, which have no
stable ABI yet (it arrives with 3.15 as abi3t; we will move to it once Cython and
scikit-build-core support it). The extension declares itself free-threading compatible, so importing
httpp keeps the GIL off. On such an interpreter plain def handlers on the server's pool threads
are meant to run in parallel, in one process. What is verified so far: the whole Python test suite
and a mixed sync/async/client stress test pass on 3.14t with the GIL off, on a single-core machine;
speed-up on several cores is not measured yet, and the classifier says "Unstable" until it is.
Your own handler code must be thread-safe: shared dicts, counters and globals now really are
touched by several threads at once.
Running the server
app.run() is the launcher: python app.py is all it takes. The same app also runs from the shell
with httpp run main:app.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000) # defaults: 127.0.0.1, 8000
httpp run main:app --host 0.0.0.0 --port 8000
httpp run main:app --workers 4 # four processes sharing the port (Linux only)
httpp run main:app --workers auto # one per usable CPU
-
run()stops on Ctrl+C or SIGTERM, gracefully: in-flight work ends andon_shutdownhooks run.httpp.run(app_or_"module:attr", ...)is the same function;listen()stays as the low-level call. -
--workers N(workers=N) is how you get past the GIL. Python code in a handler needs the GIL whatever the server does, so one process runs at most one handler's Python at a time. N processes each have their own GIL and share one port (SO_REUSEPORT; the kernel spreads connections). Each worker is a fresh process that imports the app itself, which is whyworkers > 1needs an import string ("main:app"), like uvicorn and gunicorn; module-level state is therefore per worker. Linux only for now. If a worker dies, the supervisor stops the others and exits with code 1 (let systemd or Docker restart it); it does not respawn workers yet. Keep the supervisor alive: killing it with SIGKILL leaves its workers running. -
workers="auto"/--workers autostarts one worker per CPU the process can use: its affinity mask, capped by a container CPU quota (rounded down, at least 1). It runs a single process on one CPU, off Linux, and whenappis an object rather than an import string (it says so). -
reuse_port=True/--reuse-portlets separately started httpp processes share a port the same way. It is off by default, because it also lets an unrelated process of the same user bind the port silently. -
It blocks until
stop()is called or you press Ctrl+C. -
It raises
OSErrorif the address cannot be bound (for example, the port is already taken). Two httpp servers cannot share a port unless both setreuse_port(above). -
Plain
defhandlers run on the server's thread pool (see Settings), so a handler that blocks holds its thread for as long as it blocks. -
async defhandlers run on one shared asyncio event loop (a background thread, started when the server starts listening). The server's I/O thread parses the request, matches the route and queues it for the loop right there, without taking the GIL and without a thread-pool hop (abefore_requesthook, which may block, still goes through the pool first). It pokes the loop through a socket, and the loop thread takes the GIL once per burst of requests, not once per request. Each request is one asyncio task, and a handler that does not takerequestnever gets one built. While theyawait, no thread is held, so far more requests can be in flight than there are threads. Because every request shares the same loop, loop-bound objects (anaiohttp.ClientSession, an async DB pool) can be created once and reused. A blocking call inside anasync defhandler blocks every async route, since they all share that loop. -
Speed.
benchmarks/bench.pymeasures requests per second against uvicorn (a bare ASGI app, uvloop, httptools) withoha. On one core, with the server and the load generator sharing it, in one run, plaindefandasync defroutes did about 1.3 to 1.5 times the requests per second of uvicorn in all four scenarios (hello, a path parameter with a JSON body, reading a header, and the last of 300 routes). Run to run the numbers move by 10 to 30 percent on that machine, so only comparisons inside one run mean anything. This is CPU cost per request on one core, not multi-core scaling (not measured yet), and a real handler's own work is not in it. Finding a route takes the same time with 6 routes or 600. -
The server is event-driven on every platform: all socket I/O (accepting, reading, keep-alive idle connections, timeouts, writing) runs on one Asio thread (epoll on Linux, kqueue on macOS, IOCP on Windows), and requests are parsed by llhttp. Idle connections cost no worker thread. A worker is used only while your handler (or a file/stream body piece) is actually running, never while waiting for the network. This also applies to async routes. Keep-alive works on every platform.
Sessions and async
Requests made from asyncio code run on the library's own non-blocking network thread (Asio + llhttp, with TLS and proxy support): no thread per request, keep-alive connections are pooled and reused, so thousands can be in flight.
import asyncio, httpp
async def main():
# one request
r = await httpp.Request("https://example.com/api").params({"q": "x"}).run_async()
# many requests to one server; at most 16 in flight at once, the rest wait their turn
async with httpp.AsyncClient("https://example.com", max_connections=16, headers={"X-Token": "abc"}) as c:
replies = await asyncio.gather(*(c.get(f"/items/{i}") for i in range(1000)))
asyncio.run(main())
Redirects are off by default (follow_redirects=True follows up to 20 hops; Authorization and Cookie
are not sent to a different origin). A cancelled await stops waiting, but the request itself keeps
running until it finishes. In C++: request::run_async() returns a std::future, or takes a callback
that runs on the network thread; async_client is the session form.
Build from source
Most dependencies are vendored (cpp-httplib, unmodified; llhttp, unmodified) or git submodules
(mbedtls, liburlparser, asio). The full history of the mbedtls submodule is large; if you only need the source, clone
with git clone --depth 1 --recurse-submodules --shallow-submodules.
Asio (header-only, used unmodified) is found in this order:
-DHTTPP_ASIO_INCLUDE_DIR=<dir containing asio.hpp>, then a copy in src/third_party/asio (for example a
git submodule), then it is downloaded at configure time (about 3 MB, pinned to 1.34.2 by SHA-256). Offline
builds should pass the first option. See src/third_party/README.md.
cmake -B build -G Ninja -DHTTPP_BUILD_TESTS=ON && ninja -C build # the C++ library and its tests
build/tests/cpp/test_httpp_cpp
pip install . # the Python package
Status
httpp is alpha: the API can still change between minor versions. Current limitations:
- Awaitable downloads (
Download.run_async) still run on the event loop's thread pool; downloads have no timeout option; the server's hooks hold a worker thread while they await; a plaindefhandler cannot be cancelled byhandler_timeout. Handler code is Python, so it still needs the GIL:async defhandlers share one loop thread, plaindefhandlers take the GIL on pool threads (setthreads=to fit your blocking calls), and real parallelism needs--workersor a free-threaded Python (below). - HTTP/1.1 only; the server does not speak TLS; a cancelled
awaitstops waiting but the request itself keeps running until it finishes. - Platforms: the connection layer is tested on Linux. Windows and macOS are untested by the author; CI on those platforms is the real check.
- There is no ASGI or WSGI interface (see above), so ASGI/WSGI applications such as FastAPI or Flask cannot be mounted on it yet.
cpp-httplib(unmodified) now serves only the synchronous client; the server and the async engine are our own (Asio + llhttp). It is planned to retire it once the synchronous client is ours too.- The libcurl compatibility layer covers a subset of
curl_easy_*. - No auto-reload.
--workersis Linux only and does not respawn dead workers.
Issues and pull requests are welcome.
Logging
The library logs through AixLog, privately (it never touches std::clog or your own logging). By default
warnings and errors go to stderr, e.g. a handler that throws with no exception handler installed.
httpp::set_log_level(httpp::log_level::debug); // trace, debug, info, warning (default), error, off
httpp::set_log_file("httpp.log"); // instead of stderr; "" goes back
httpp::set_log_callback([](httpp::log_level, const std::string& where, const std::string& message) { /* your logger */ });
httpp.set_log_level("debug") # same levels, as strings
httpp.set_log_file("httpp.log")
httpp.set_log_callback(lambda level, where, message: ...) # called from library threads
License
Metadata
Release files for httpp 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| httpp-0.7.0.tar.gz | 996.4 kB | Without provenance | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| httpp-0.7.0-cp315-cp315t-win_amd64.whl | CPython 3.15 | CPython 3.15 free-threading | Windows x86-64 | Details |
| httpp-0.7.0-cp315-cp315t-win32.whl | CPython 3.15 | CPython 3.15 free-threading | Windows x86-32 | Details |
| httpp-0.7.0-cp315-cp315t-musllinux_1_2_x86_64.whl | CPython 3.15 | CPython 3.15 free-threading | Linux musl 1.2+ x86-64 | Details |
| httpp-0.7.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.15 | CPython 3.15 free-threading | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| httpp-0.7.0-cp315-cp315t-macosx_10_15_universal2.whl | CPython 3.15 | CPython 3.15 free-threading | macOS 10.15+ universal2 (ARM64, x86-64) | Details |
| httpp-0.7.0-cp314-cp314t-win_amd64.whl | CPython 3.14 | CPython 3.14 free-threading | Windows x86-64 | Details |
| httpp-0.7.0-cp314-cp314t-win32.whl | CPython 3.14 | CPython 3.14 free-threading | Windows x86-32 | Details |
| httpp-0.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl | CPython 3.14 | CPython 3.14 free-threading | Linux musl 1.2+ x86-64 | Details |
| httpp-0.7.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.14 | CPython 3.14 free-threading | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| httpp-0.7.0-cp314-cp314t-macosx_10_15_universal2.whl | CPython 3.14 | CPython 3.14 free-threading | macOS 10.15+ universal2 (ARM64, x86-64) | Details |
| httpp-0.7.0-cp313-cp313t-win_amd64.whl | CPython 3.13 | CPython 3.13 free-threading | Windows x86-64 | Details |
| httpp-0.7.0-cp313-cp313t-win32.whl | CPython 3.13 | CPython 3.13 free-threading | Windows x86-32 | Details |
| httpp-0.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl | CPython 3.13 | CPython 3.13 free-threading | Linux musl 1.2+ x86-64 | Details |
| httpp-0.7.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.13 | CPython 3.13 free-threading | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| httpp-0.7.0-cp313-cp313t-macosx_10_13_universal2.whl | CPython 3.13 | CPython 3.13 free-threading | macOS 10.13+ universal2 (ARM64, x86-64) | Details |
| httpp-0.7.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| httpp-0.7.0-cp39-abi3-win32.whl | CPython 3.9 | abi3 | Windows x86-32 | Details |
| httpp-0.7.0-cp39-abi3-musllinux_1_2_x86_64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ x86-64 | Details |
| httpp-0.7.0-cp39-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| httpp-0.7.0-cp39-abi3-macosx_10_13_universal2.whl | CPython 3.9 | abi3 | macOS 10.13+ universal2 (ARM64, x86-64) | Details |
Total release size: 46.2 MB
Release files / httpp-0.7.0.tar.gz
| Download URL | httpp-0.7.0.tar.gz |
|---|---|
| Size | 996.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ebff452ecb9a35385c708b5e9f82de16e79405da71c9877a6ab0ad4ff71f849
|
|
BLAKE2b-256 checksum How to use checksums |
ce8f6810c22815abdc90ed6c3ee64bfade785cf7f369376f5fddefe0a62b34a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp315-cp315t-win_amd64.whl
| Download URL | httpp-0.7.0-cp315-cp315t-win_amd64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading Windows x86-64 |
|
SHA-256 checksum How to use checksums |
b6932b14d4674a6d536c8186f24740a26d84eeeda649cc6792a2116b0fc3eac1
|
|
BLAKE2b-256 checksum How to use checksums |
401c0a2b5449b9f8301228cb4784cef41185e2f9aa7104ab6a3dccacb7419ad7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp315-cp315t-win32.whl
| Download URL | httpp-0.7.0-cp315-cp315t-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading Windows x86-32 |
|
SHA-256 checksum How to use checksums |
11829e5846f39bada09d3b2e3b845b38251c7c77f0e0b2bc4d9bd86ffcf4c830
|
|
BLAKE2b-256 checksum How to use checksums |
206178d1d28451acdbf1e13303d72fe57f40bf1101a50c926b12f531b3d7b926
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp315-cp315t-musllinux_1_2_x86_64.whl
| Download URL | httpp-0.7.0-cp315-cp315t-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
13d86a000683af6604f1c3c6fed1b8835a2c1dbf59324d74452a3f0ccca9184c
|
|
BLAKE2b-256 checksum How to use checksums |
156a63f8a9f4094bb71aa86beaba619ff7b3b18c164036a65723a554f0b63650
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | httpp-0.7.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
0b8d87bb5cc6c92c5d438bb4283f9a7ea805de314865dedea1fdb6ecb84f9ecc
|
|
BLAKE2b-256 checksum How to use checksums |
b0e18773cea786985a148c4968ee6ac880b7abefa74872cdec3423230d00a289
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp315-cp315t-macosx_10_15_universal2.whl
| Download URL | httpp-0.7.0-cp315-cp315t-macosx_10_15_universal2.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.15 CPython 3.15 free-threading macOS 10.15+ universal2 (ARM64, x86-64) |
|
SHA-256 checksum How to use checksums |
9254c3eda81771bcb0b1946b502383c2e4c500a22e64b7d43bb07c2a54b30b1f
|
|
BLAKE2b-256 checksum How to use checksums |
29ea1f7288df7dbd3bf3cce573054dc01c94e3499b47c1c957e18bdb85863753
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp314-cp314t-win_amd64.whl
| Download URL | httpp-0.7.0-cp314-cp314t-win_amd64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Windows x86-64 |
|
SHA-256 checksum How to use checksums |
b824ea126d50e811f0c3bb2caac4a9b392244a2dc81b3e61381355a46d2b659b
|
|
BLAKE2b-256 checksum How to use checksums |
e8dbdfd5802bd6918f05fd8d3b5532e9d3f83cf198467c7d85b1e49d93e369a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp314-cp314t-win32.whl
| Download URL | httpp-0.7.0-cp314-cp314t-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Windows x86-32 |
|
SHA-256 checksum How to use checksums |
dc5fb76fdc032b4378d3a226feee948f288366a2a9f82b7e4f3a8748c08d58a9
|
|
BLAKE2b-256 checksum How to use checksums |
7098677bc84f002f0b1c9c9c5bc247183705f14b25af3dd6527f7d923d785603
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl
| Download URL | httpp-0.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
53078c7bc3667912ac86c3be1169a40a036ffa308729ea43185fb29ad275ece2
|
|
BLAKE2b-256 checksum How to use checksums |
695b9449d16829bc1306b7490d4ae250e0f4c61cabf237b5f2de6e7e901feacd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | httpp-0.7.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
5c85b335851ad4fa4367b8d49fc5190bd0c85ae8f5e63554db0004e7539f12d1
|
|
BLAKE2b-256 checksum How to use checksums |
f943a3058d0d72371cbc5e1599621c3c092bdb75329027616a73c380e780dd68
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp314-cp314t-macosx_10_15_universal2.whl
| Download URL | httpp-0.7.0-cp314-cp314t-macosx_10_15_universal2.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading macOS 10.15+ universal2 (ARM64, x86-64) |
|
SHA-256 checksum How to use checksums |
95f08a28ac91ee1b1786bf37a6dacdfa7930ed24873f718709d9aae9a0cb9940
|
|
BLAKE2b-256 checksum How to use checksums |
84642ee9a88508c676d290684bfa763c8efbc752fa8e92921ee288b5795b4a5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp313-cp313t-win_amd64.whl
| Download URL | httpp-0.7.0-cp313-cp313t-win_amd64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.13 CPython 3.13 free-threading Windows x86-64 |
|
SHA-256 checksum How to use checksums |
e2752c573e830b8dad55ade0843767e8e594f161a9452674c898ff640f0fc79d
|
|
BLAKE2b-256 checksum How to use checksums |
b7889d31e7e9ba5855c6ee0813cb5d0cbc54c39c6c9e39e514b1610112c87263
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp313-cp313t-win32.whl
| Download URL | httpp-0.7.0-cp313-cp313t-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.13 CPython 3.13 free-threading Windows x86-32 |
|
SHA-256 checksum How to use checksums |
50ab756ecb56a4641d8fc4ebe678bd593005d754772b3dc2cdeb36dbcbf6ca01
|
|
BLAKE2b-256 checksum How to use checksums |
6d638f2dd9b56000a2614b213754ef73e363444fa9745f7e38f4571f2099ffea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl
| Download URL | httpp-0.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.13 CPython 3.13 free-threading Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
67455bae427ad34f2365c1db5cd141735a5aeb4a76f4dd0c6665ffc6f0dfcd35
|
|
BLAKE2b-256 checksum How to use checksums |
05645bd8b0cbd70a4e9c9dfe955eeb538f4329449f7432525e7080ce8eb2bf73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | httpp-0.7.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.13 CPython 3.13 free-threading Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
4940debccace30e921b6a171f6d785077c3d8240b00796ead1d6d8912bceff26
|
|
BLAKE2b-256 checksum How to use checksums |
c18f7704cb2f37f24ec734b56a737855ad4df0b9d5cd7991305fe11d9f30b291
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp313-cp313t-macosx_10_13_universal2.whl
| Download URL | httpp-0.7.0-cp313-cp313t-macosx_10_13_universal2.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.13 CPython 3.13 free-threading macOS 10.13+ universal2 (ARM64, x86-64) |
|
SHA-256 checksum How to use checksums |
92fe1002c00e583a29b8e361a759487be3edcc0376778bbb5b6eff6fa8da210b
|
|
BLAKE2b-256 checksum How to use checksums |
8875e979926fde6ec17df20da359d719d4af3a46b9d7b71e456458c1478306d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp39-abi3-win_amd64.whl
| Download URL | httpp-0.7.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
14266c84d9f22e0e1db30b9d571e8f6916c5b40e7de01dae35a5b8da6ad082cb
|
|
BLAKE2b-256 checksum How to use checksums |
3bc362c3d2763eaa6b6822d16f4973281d63e79f3570ee4aa03ffb7a87fd20bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp39-abi3-win32.whl
| Download URL | httpp-0.7.0-cp39-abi3-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.9 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
ebf5eae77aec4e78916aff38b6ab239572f989448b0568be3ae38cca96040003
|
|
BLAKE2b-256 checksum How to use checksums |
06b38c01c96e808c6167a34acbe7e4ca48be03980f14d2415dd2d42079f4289d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | httpp-0.7.0-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
927e2833d99069111de499b5fe208e7d45733c25efc185df29dec9632640a281
|
|
BLAKE2b-256 checksum How to use checksums |
c2e70d376fb8b42ab5bd6aac7318c82e51715dc29ae5c1dd5567d1d6dfd925db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp39-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | httpp-0.7.0-cp39-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.9 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
df03a8b3f75ac3386db071ae418320e353b21ae7ce00121d849a86775a956429
|
|
BLAKE2b-256 checksum How to use checksums |
b13df73932ed16423c45632881c1160c1c602c0e555e54b3a8bbdfc12a75c47e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / httpp-0.7.0-cp39-abi3-macosx_10_13_universal2.whl
| Download URL | httpp-0.7.0-cp39-abi3-macosx_10_13_universal2.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.9 abi3 macOS 10.13+ universal2 (ARM64, x86-64) |
|
SHA-256 checksum How to use checksums |
33b628a33e87da67323c1851c08386aa8c8b261b643881c41bfd60414b50a2ae
|
|
BLAKE2b-256 checksum How to use checksums |
298e60c6e1c4bad3aed4ef3477e61ca3eeb0d61ed19e0b8ea82a4e6d21c22abc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for httpp 0.7.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.