Package: powernap
PowerNapA small REST client that recharges your batteriesPowerNap is a simplistic JSON REST API client, a small wrapper around httpx that makes your code
read slightly better.Installation$pipinstallpowernapUsage# You will need an httpx Client. Let's do a GitHub client!httpx_client=httpx.Client(base_url="https://api.github.com/v3",headers={"Authorization":f"token{token}"})# Instantiate the PowerNap clientgithub_client=powernap.PowerNap(httpx_client=httpx_client)# PowerNap will help you build complex URLs in a pythonic-looking way:repo=github_client.repos("ewjoachim/powernap").get()# And access the json responses like objectscount_stars=repo.stargazers_count# You can also easily send POST requests.github_client.repos("ewjoachim/powernap").issues(42).comments.post(body=f"Wow look! This repo has{count_stars}stars!")Build complex URLsYou can useclient(something)orclient.something, and chain calls.
With the formclient(something), you can pass multiple parameters, and they
will be joined together# The next calls are all identical and target:#    {base_url}/repos/ewjoachim/powernap/stargazersgithub_client.repos("ewjoachim/powernap").stargazers.get()github_client.repos("ewjoachim").powernap("stargazers").get()github_client.repos("ewjoachim","powernap","stargazers").get()github_client.repos("ewjoachim","powernap")("stargazers").get()github_client("repos/ewjoachim/powernap/stargazers").get()# The recommended way is to use client.something for static parts of the url and# client(something) with a variable for dynamic parts.# You can also target the base url directly# {base_url}github_client().get()Access the json responses like objectsOn the json responses, all objects (even nested) are configured so that you can
get keys with theobject.keysyntax in addition to the classicobject["key"].# GET /nested_json -> {"a": {"b":{"c": "d"}}}response=some_api_client.nested_json.get()assertresponse=={"a":{"b":{"c":"d"}}}assertresponse["a"]["b"]["c"]=="d"# But also the magic form:assertresponse.a.b.c=="d"ArgumentsThe arguments in the.get/delete()calls are used as query parameters on
the call.The arguments in the.post/put/patch()calls are put together, and passed
as the json payload for the call.Response typesIf the response comes withContent-Type: application/json, then you'll get
the "magic" json response as described above. Otherwise, if the content type
istext/*, you'll get astring, and otherwise, you'll getbytes.ExceptionsIf you want to avoidhttpxexceptions to reach your code, so as to maintain
a good abstraction layer, you may want to subclass Powernap and implementhandle_exception(self, exc). You'll receive anhttpx.HttpErrorand it's
your responsibility to raise whatever exception you see fit. Not raising an
exception in this context is considered as an error, though.fromtypingimportNoReturnclassApiError(MyProjectError):passclassForbiddenError(ApiError):passclassApiClient(PowerNap):defhandle_exception(self,exc:httpx.HttpError)->NoReturn:ifexc.response.status_code==403:raiseForbiddenErrorraiseApiErrorMore control over input and outputThis magic is nice and all, but sometimes, you may want more control.
If you want to send additional headers or a non-JSON-dict payload, or
if you want to read the headers on the response, it possible too.Instead of calling.get(), use either.get.i(),.get.o()or.get.io()(it works with any method:get/post/put/patch/delete):If you call with.get.i(...)(or.get.io(...)), you control the input.
The method keyword arguments will be passed to the underlyinghttpx.Client().get(...)as-is.If you call with.get.o(...)(or.get.io(...)), you get the original
output. The function will return ahttpx.Responseobject. (Note that in
this case, we will still have called.raise_for_status())If you regularly useget.io(), it's probably that PowerNap is probably not
the project you need. Usehttpx.Clientdirectly, build something to help you
craft URLs (you canstealcopy the relevant code, don't forget to copy the
license too)NameWhile looking for a name for this lib, I looked at all the synonyms for "small
rest". It's amazing how many other projects have gone the same route. To name a
few:naplooks awesome! Unrelated lib but same
goals as this one. Seems unmaintained but I'm not sure a lib like this needs
a lot of maintenance.catnaprespitesnoozeis not taken butsnooze-serveris and I didn't
want to create confusion.Funnily enough, a consequent number of those projects have the same goals as
this one, yet don't have the exact look and feel I'm trying to achieve.Credits where dueThis lib is heavily inspired from githubpy, which is under Apache license.The version that was used for inspirationAuthor: Michael Liao (askxuefeng@gmail.com)Original license