{"id":17159134,"url":"https://github.com/scull7/patron","last_synced_at":"2025-04-13T13:50:54.651Z","repository":{"id":57653595,"uuid":"88904336","full_name":"scull7/patron","owner":"scull7","description":"A wrapper around the hyper.rs library to allow for targeted clients to specific remote APIs.","archived":false,"fork":false,"pushed_at":"2017-05-01T01:43:26.000Z","size":31,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T14:45:39.959Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scull7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-20T19:45:19.000Z","updated_at":"2018-06-15T13:01:43.000Z","dependencies_parsed_at":"2022-08-26T07:11:25.863Z","dependency_job_id":null,"html_url":"https://github.com/scull7/patron","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scull7%2Fpatron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scull7%2Fpatron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scull7%2Fpatron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scull7%2Fpatron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scull7","download_url":"https://codeload.github.com/scull7/patron/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248331976,"owners_count":21086009,"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","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":[],"created_at":"2024-10-14T22:13:25.452Z","updated_at":"2025-04-13T13:50:54.621Z","avatar_url":"https://github.com/scull7.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# patron\nA wrapper around the hyper.rs library to allow for targeted clients to\nspecific remote APIs. This library should be useful on it's own or as a\nbuilding block for specific remote API wrappers.\n\n## The Interface\n\n### Exports\nWe want to give out an owned `std::sync::Arc` wrapped client so that the user can\nutilize the client between threads if ncessary.\n\n```rust\npub type Client = std::sync::Arc\u003cpatron::Client\u003e;\n\n```\n\n### Create an HTTP Star Wars API client.\n```rust\nstruct Person {\n  name: String,\n  birth_year: String,\n  eye_color: String,\n  height: String,\n  mass: String,\n}\n\nlet client = try!(patron::from_str(\"http://swapi.co/api\")\n  .build()\n);\n\nlet han_solo: Person = try!client.get(\"/people/14\")\n  .send()\n  .and_then(|res| res.deserialize())\n);\n```\n\n\n### Creating an HTTPs GitHub Api client with an OAuth2 token.\n```rust\nuse patron;\n\nlet client: patron::Client = try!(\n  patron::from_str(\"https://api.github.com\")\n  .set_oauth_token(\"0b79bab50daca910b000d4f1a2b675d604257e42\")\n  .build()\n);\n```\n\n### Creating an HTTPs GitHub Api client using query based tokens.\n```rust\nuse patron;\n\nlet client: patron::Client = try!(\n  patron::from_str(\"https://api.github.com\")\n  .add_query_param(\"client_id\", \"ABCDEFGHIKLMNOP\")\n  .add_query_param(\"client_secret\", \"QRSTUVWXYZABCDE\")\n  .build()\n);\n```\n\n### Creating an HTTP client for CouchDB.\n```rust\nuse patron;\n\nlet url: patron::Url = try!(\n  patron::Url::new()\n  .set_scheme(patron::Scheme::Http)\n  .set_host('localhost')\n  .set_port(5984)\n  .build()\n);\n\nlet client: patron::Client = try!(\n  patron::from_url(url)\n  .add_path(\"somedatabase\")\n  .basic_auth(\"anna\", \"secret\")\n  .build()\n);\n```\n\n### Example usage for ArangoDB\n***THIS IS NOT FULLY IMPLEMENTED, LIES ABOUND!***\n```rust\nuse serde_json;\nuse patron;\n\n#[derive(Debug, Deserialize)]\nstruct AuthRes {\n  jwt: String,\n  must_change_password: bool,\n}\n\n// Generally this would be built from some configuration object.\nlet mut url = patron::url::Url::new()\nurl.set_scheme(patron::Scheme::Http)\nurl.set_host(\"localhost\")\nurl.set_port(8529)\n\nlet auth: AuthRes = try!(\n  patron::Request::new(url)\n  .post(\"/_open/auth\")\n  .add_body_param(\"username\", \"root\")\n  .add_body_param(\"password\", \"password\")\n  .send()\n);\n\nlet mydb_client: patron::Client = try!(\n  patron::from_url(url)\n  .set_oauth_token(auth.jwt)\n  .add_path(\"/_db/mydb/\")\n  .build()\n);\n\n#[derive(Debug, Deserialize)]\nstruct Version {\n  version: String,\n  server: String,\n}\n\nlet version: Version = try!(client.get(\"/_api/version\").send());\n\n#[derive(Debug, Deserialize, Serialize)]\nstruct NewDoc {\n  #[serde(rename = \"_key\")]\n  key: String,\n  #[serde(rename = \"_id\")]\n  id: String,\n  #[serde(rename = \"_rev\")]\n  revision: String,\n}\n\nlet newdoc: NewDoc = try!(\n  client.post(\"/_api/demo\")\n  .add_body_param(\"message\", serde_json::to_value(\"\u003creplace_me\u003e\").unwrap())\n  .add_query_param(\"waitForSync\", \"true\")\n  .send()\n);\n\n#[derive(Debug, Deserialize, Serialize)]\nstruct Document {\n  #[serde(rename = \"_key\")]\n  key: String,\n  #[serde(rename = \"_id\")]\n  id: String,\n  #[serde(rename = \"_rev\")]\n  revision: String,\n  message: Option\u003cString\u003e\n}\n  \nlet mut hello: Document = try!(\n  client.get(\"/_api/document/demo/\")\n  .add_path(newdoc.id)\n  .send()\n);\n\nhello.message = Some(\"Hello, World!\");\n\n#[derive(Debug, Deserialize, Serialize)]\nstruct UpdateRes {\n  #[serde(rename = \"_key\")]\n  key: String,\n  #[serde(rename = \"_id\")]\n  id: String,\n  #[serde(rename = \"_rev\")]\n  revision: String,\n  #[serde(rename = \"_oldRev\")]\n  previous_revision: String,\n}\n\nlet res: UpdateRes = try!(\n  client.put(\"/api/document/demo\")\n  .add_path(hello.id)\n  .set_body(hello)\n  .send()\n);\n```\n\n### Design\nResponse Objects: [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)  \n\n### Notes\n* Should the client be passed into the send method?\n* I would like to only have one representation of a request configuration instead of the current 2.\n* A more functional style design?\n* I like how the fetch API returns a response object with the ability to retrieve the `Body` in \n  different formats. How can this be presented along with a nice `Result` based interface?\n  ```rust\n  client.get('/foo')\n    .send()\n    .unwrap()\n    .json()\n  ```\n  `send()` will return a `Response` object which you can call `.json()`.  The `.json()` method will return\n  a `Result\u003cserde_json::Value, Error\u003e`\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscull7%2Fpatron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscull7%2Fpatron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscull7%2Fpatron/lists"}