{"id":19421496,"url":"https://github.com/sitbon/presto","last_synced_at":"2025-08-18T03:32:34.278Z","repository":{"id":137573702,"uuid":"573995838","full_name":"sitbon/presto","owner":"sitbon","description":"Presto! Python Requests: REST client \u0026 requests extension library","archived":false,"fork":false,"pushed_at":"2023-03-11T02:10:14.000Z","size":104,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-06T11:50:25.127Z","etag":null,"topics":["asyncio","http","httpx","python","python311","requests","rest","rest-client"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/presto-requests/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sitbon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-04T04:37:04.000Z","updated_at":"2025-06-27T07:39:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"4df897f2-7036-44d6-a148-4e7bdeddb573","html_url":"https://github.com/sitbon/presto","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/sitbon/presto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitbon%2Fpresto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitbon%2Fpresto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitbon%2Fpresto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitbon%2Fpresto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sitbon","download_url":"https://codeload.github.com/sitbon/presto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitbon%2Fpresto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270940362,"owners_count":24671669,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","http","httpx","python","python311","requests","rest","rest-client"],"created_at":"2024-11-10T13:28:30.812Z","updated_at":"2025-08-18T03:32:34.225Z","avatar_url":"https://github.com/sitbon.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Presto! Requests\n\nAn object-oriented REST API client \u0026 requests extesion library.\n\nAs of version 1.0.0, this library can be considered stable, and significant\nchanges to the interface or new features are unlikely to be introduced.\n\n#### Note: This library requires Python 3.11.0rc1 or later.\n\n## Installation\n\n```bash\npip install presto-requests\n```\n```bash\npoetry add presto-requests\n```\n\n#### With async support using httpx:\n```bash\npip install presto-requests[async]\n```\n```bash\npoetry add presto-requests --extras async\n```\n\n### Concept:\n\nPresto! Requests is a library that extends the functionality of the requests library.\nIt provides a simple way to create a REST API client that is object-oriented and easy to use.\n\n### Example:\n\n```python\nfrom presto import Presto\nimport pprint\n\ngithub = Presto(\"https://api.github.com\")\n\nuser = github.users.sitbon()()  # == github.users[\"sitbon\"]().attr\n\nprint(f\"User {user.login} has {user.public_repos} public repositories.\")\n\npprint.pprint(dict(user))\n```\n```shell\nUser sitbon has 15 public repositories.\n{'avatar_url': 'https://avatars.githubusercontent.com/u/1381063?v=4',\n 'bio': None,\n 'blog': '',\n 'company': None,\n 'created_at': '2012-01-26T04:25:21Z',\n 'email': None,\n 'events_url': 'https://api.github.com/users/sitbon/events{/privacy}',\n 'followers': 7,\n 'followers_url': 'https://api.github.com/users/sitbon/followers',\n 'following': 13,\n 'following_url': 'https://api.github.com/users/sitbon/following{/other_user}',\n 'gists_url': 'https://api.github.com/users/sitbon/gists{/gist_id}',\n 'gravatar_id': '',\n 'hireable': None,\n 'html_url': 'https://github.com/sitbon',\n 'id': 1381063,\n 'location': 'Portland, OR, USA',\n 'login': 'sitbon',\n 'name': 'Phillip Sitbon',\n 'node_id': 'MDQ6VXNlcjEzODEwNjM=',\n 'organizations_url': 'https://api.github.com/users/sitbon/orgs',\n 'public_gists': 4,\n 'public_repos': 15,\n 'received_events_url': 'https://api.github.com/users/sitbon/received_events',\n 'repos_url': 'https://api.github.com/users/sitbon/repos',\n 'site_admin': False,\n 'starred_url': 'https://api.github.com/users/sitbon/starred{/owner}{/repo}',\n 'subscriptions_url': 'https://api.github.com/users/sitbon/subscriptions',\n 'twitter_username': None,\n 'type': 'User',\n 'updated_at': '2022-11-22T00:41:18Z',\n 'url': 'https://api.github.com/users/sitbon'}\n\n```\n\n### Usage:\n\nAdding to a request path is as simple as accessing an attribute of the same name\nfrom a `Presto` instance. For example, `Presto(\"http://example.com\").some_path`\nmaps to a request object that defines a GET request to `http://example.com/some_path`.\n\nParameters such as headers are set by calling dotted objects under `Presto`, e.g. `presto.some_path(x=y)`.\n\nThese parameters are eventually passed to requests.request() as keyword arguments, but only\nat a later time when the request is executed by calling the object without any arguments.\n\nThe return value from a parameter-setting call is the object itself, to enable further chaining.\nThus, request parameters can be set and inherited by further dotted paths.\n\nIndexing the object like a list is a convient way to extend the path to a new object for things\nlike id paths, e.g. `Presto(\"http://\u003cbase\u003e\").note[1]` maps to a request for `http://\u003cbase\u003e/note/1`\nand calling that object executes the request.\n\nThere are a few special top-level attributes that can be used to modify the request without\nneeding to call the object and set the `method=` parameter:\n`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`, and finally `R` which is\na request object with no path and no parameters set.\n\n\n#### Example:\n\n```python\nfrom presto import Presto\n\n\npresto = Presto(url=\"http://127.0.0.1:8000\", APPEND_SLASH=True)\n\nprint(\"presto:\", presto)\n\napi = presto.api\n\nprint(\"api:\", api)\n\nnote = api(headers={\"X-User\": \"Testing\"}).note\n\nprint(\"api.note:\", api.note, \"equal:\", api.note == note)\n\nresp = api.note[4]()\n\nprint(\"headers:\", resp.request.headers)\nprint(\"response:\", resp)\nprint(\"note:\", resp.attr)\n```\n```shell\npresto: Presto(url='http://127.0.0.1:8000/', params=adict(method='GET', headers={'Accept': 'application/json'}))\napi: Request(url='http://127.0.0.1:8000/api/', params=adict(method='GET', headers={'Accept': 'application/json'}))\napi.note: Request(url='http://127.0.0.1:8000/api/note/', params=adict(method='GET', headers={'Accept': 'application/json', 'X-User': 'Testing'})) equal: True\nheaders: {'User-Agent': 'python-requests/2.28.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': 'application/json', 'Connection': 'keep-alive', 'X-User': 'Testing'}\nresponse: \u003cResponse [200]\u003e\nnote: adict(user='', id=4, url='http://127.0.0.1:8000/api/note/4/', time='2022-12-02T19:26:09-0800', note='Hello from the API!!', collection={'id': 3, 'url': 'http://127.0.0.1:8000/api/note/coll/3/', 'name': 'Public', 'public': True, 'notes': 1})\n```\n\n`response.attr` is an `adict` instance, which is a dictionary that can be accessed as attributes.\nIt contains the JSON-decoded content of a response, if any.\n\n`APPEND_SLASH` is meant to be client implementation-specific, e.g. for a Django Rest Framework client, one would\ntypically set `Presto.APPEND_SLASH = True` or inherit from `Presto` in a pre-defined API client class.\n\n# Async Support\n\nVersion 1.0.0 adds support for async requests using the `httpx` library.\n\nThe usage is the same as the synchronous version except when it comes to executing requests, so\ncalls to request objects without parameters need to be awaited. See the example below.\n\n```python\nimport asyncio\nfrom presto.asynco import AsyncPresto as Presto\n\n\nasync def main():\n    presto = Presto(url=\"http://127.0.0.1:8000\", APPEND_SLASH=True)\n\n    print(\"presto:\", presto)\n\n    api = presto.api\n\n    print(\"api:\", api)\n\n    note = api(headers={\"X-User\": \"Testing\"}).note\n\n    print(\"api.note:\", api.note, \"equal:\", api.note == note)\n\n    resp = await api.note[4]()\n\n    print(\"headers:\", resp.request.headers)\n    print(\"response:\", resp)\n    print(\"note:\", resp.attr)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n```shell\npresto: AsyncPresto(url='http://127.0.0.1:8000/', params=adict(method='GET', headers={'Accept': 'application/json'}))\napi: Request(url='http://127.0.0.1:8000/api/', params=adict(method='GET', headers={'Accept': 'application/json'}))\napi.note: Request(url='http://127.0.0.1:8000/api/note/', params=adict(method='GET', headers={'Accept': 'application/json', 'X-User': 'Testing'})) equal: True\nheaders: Headers({'host': '127.0.0.1:8000', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'python-httpx/0.23.1', 'accept': 'application/json', 'x-user': 'Testing'})\nresponse: \u003cResponse [200 OK]\u003e\nnote: adict(user='', id=4, url='http://127.0.0.1:8000/api/note/4/', time='2022-12-02T19:26:09-0800', note='Hello from the API!!', collection={'id': 3, 'url': 'http://127.0.0.1:8000/api/note/coll/3/', 'name': 'Public', 'public': True, 'notes': 1})\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsitbon%2Fpresto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsitbon%2Fpresto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsitbon%2Fpresto/lists"}