Skip to content
BEGS(3)Library Functions (borrowed)BEGS(3)

NAME

begs – HTTP for humans who have run out of options – pleads with servers until they respond

SYNOPSIS

import begs

begs.get(url, please=True)
begs.post(url, json=data, insistence=3)
begs.grovel(url)
begs.bribe(url, amount=5)
begs.fax(url)

DESCRIPTION

begs is an HTTP library for Python built on a simple principle: ask nicely and you're more likely to get an answer. Ask desperately and you'll at least get sympathy.

When a server responds with an error, begs doesn't give up. It repeats the request – a little more politely each time, a little more desperately each time. Experts call this exponential begging: the delay between attempts doubles, and so does the number of exclamation marks.

Besides status_code, text and json(), every response has a mood attribute that reveals how reluctantly the server replied. Possible values: "gladly", "fine", "just this once" and "only because it's you".

FUNCTIONS

begs.get(url, please=False)
Fetches a resource. Without please=True, begs responds with 428 Precondition Required. The missing precondition is manners.
begs.post(url, json=None, insistence=1)
Sends data. From insistence=5 onward, begs also emails the administrator; from insistence=10, the administrator's mother.
begs.grovel(url)
The last resort. Sends the request on its knees: with every known user agent at once and a handwritten letter of apology, scanned as a PDF, in the body.
begs.bribe(url, amount=5)
Adds an X-Tip header to the request. Works on a surprising number of enterprise APIs.
begs.fax(url)
For servers run by German public authorities. Sends the request by fax; the response arrives by post within six to eight weeks. A stamped return envelope is enclosed.
begs.Session()
Remembers cookies, headers and every rejection. After the hundredth one, session.relationship_status is set to "it's complicated".

STATUS CODES

begs knows every official HTTP status code, plus a few that should have been introduced years ago:

CodeMeaning
202Accepted. Being processed. Really. Soon.
299OK, but just this once.
304Not modified – just like your situation.
402Payment required. See begs.bribe().
418I'm a teapot. begs asks for coffee anyway.
428Manners required.
509Patience exceeded.

EXAMPLES

Ask for a raise:

>>> r = begs.get("https://api.example.com/salary/raise")
>>> r.status_code
428
>>> r = begs.get("https://api.example.com/salary/raise", please=True)
>>> r.json()
{'raise': 0, 'message': "We'll get back to you."}
>>> r.mood
'fine'

What actually gets sent on retries:

$ BEGS_DEBUG=1 python script.py
begs: attempt 1  GET /api/data   Accept: application/json
begs: attempt 2  GET /api/data   X-Please: please
begs: attempt 3  GET /api/data   X-Please: please please
begs: attempt 4  GET /api/data   X-Please: PLEASE!!
begs: attempt 5  GET /api/data   X-Please: I have a family, you know
begs: attempt 6  GET /api/data   X-Please: ok sorry, didn't mean it like that
begs: response 503 – server is on vacation. Out-of-office reply in body.

Apply for a building permit:

>>> r = begs.fax("https://planning.example.de/permit/garden-shed")
>>> r.status_code
202
>>> r.expected
datetime.date(2027, 3, 14)
>>> r.text
'Your application is incomplete. Please submit form B-17a (by fax only).'

EXCEPTIONS

begs.Rejection
The server responded with a 4xx. Don't take it personally. The server doesn't.
begs.LeftOnRead
Timeout. The server has read your request. Two blue ticks.
begs.RestrainingOrder
429 Too Many Requests. You asked too often. The server has obtained a court order.

BUGS

begs does not work with servers that have no feelings. As far as we know, that is all of them. The bug is marked "wontfix", with the comment "please don't".

SEE ALSO

left-bad(3), maybealloc(3), wingit(W), demands(3) – for people who don't ask

begs 2.31.0-pretty-pleaseOctober 28, 2026BEGS(3)

More from Libraries

See all of Libraries