Coder Social home page Coder Social logo

daviddpark / babashka.curl Goto Github PK

View Code? Open in Web Editor NEW

This project forked from babashka/babashka.curl

0.0 0.0 0.0 89 KB

A tiny curl wrapper via idiomatic Clojure, inspired by clj-http, Ring and friends.

License: Eclipse Public License 1.0

Clojure 100.00%

babashka.curl's Introduction

babashka.curl

A tiny curl wrapper via idiomatic Clojure, inspired by clj-http, Ring and friends.

Status

This library is part of babashka but can also be used with JVM Clojure. Check CHANGES.md before upgrading as the API may still undergo some changes. Contributions welcome.

Windows

If you are seeing The system cannot find the path specified when executing a request with babashka.curl in Windows, try creating the directory C:\Temp. The reason for this is that babashka.curl parses headers via a temporary file produced by curl. In GraalVM 19.3.1 on Windows, the temporary directory is hard-coded to C:\Temp. This will be fixed in a future version of GraalVM.

Usage

(require '[babashka.curl :as curl])
(require '[clojure.java.io :as io]) ;; optional
(require '[cheshire.core :as json]) ;; optional

GET

Simple GET request:

(curl/get "https://httpstat.us/200")
;;=> {:status 200, :body "200 OK", :headers { ... }}

Headers

Passing headers:

(def resp (curl/get "https://httpstat.us/200" {:headers {"Accept" "application/json"}}))
(json/parse-string (:body resp)) ;;=> {"code" 200, "description" "OK"}

Query parameters

Query parameters:

(->
  (curl/get "https://postman-echo.com/get" {:query-params {"q" "clojure"}})
  :body
  (json/parse-string true)
  :args)
;;=> {:q "clojure"}

POST

A POST request with a :body:

(def resp (curl/post "https://postman-echo.com/post" {:body "From Clojure"}))
(json/parse-string (:body resp)) ;;=> {"args" {}, "data" "", ...}

Posting a file as a POST body:

(:status (curl/post "https://postman-echo.com/post" {:body (io/file "README.md")}))
;; => 200

Posting a stream as a POST body:

(:status (curl/post "https://postman-echo.com/post" {:body (io/input-stream "README.md")}))
;; => 200

Posting form params:

(:status (curl/post "https://postman-echo.com/post" {:form-params {"name" "Michiel"}}))
;; => 200

Post a file as multipart/form-data:

(->
  (curl/post "https://postman-echo.com/post"
    {:form-params {"filename" "somefile" "file" (io/file "README.md")}})
  :body
  (json/parse-string)
  (get "files")
  (contains? "README.md"))
;; => true

Basic auth

Basic auth:

(:body (curl/get "https://postman-echo.com/basic-auth" {:basic-auth ["postman" "password"]}))
;; => "{\"authenticated\":true}"

Download binary

Download a binary file as a stream:

(io/copy
  (:body (curl/get "https://github.com/borkdude/babashka/raw/master/logo/icon.png"
    {:as :stream}))
  (io/file "icon.png"))
(.length (io/file "icon.png"))
;;=> 7748

Passing through arguments

Passing raw arguments to curl can be done with :raw-args:

(:status (curl/get "http://www.clojure.org" {:raw-args ["--max-redirs" "0"] :throw false}))
;;=> 301

Unix sockets

Talking to a UNIX socket:

(-> (curl/get "http://localhost/images/json"
              {:raw-args ["--unix-socket"
                          "/var/run/docker.sock"]})
    :body
    (json/parse-string true)
    first
    :RepoTags)
;;=> ["borkdude/babashka:0.0.79-SNAPSHOT"]

URL construction

Using the low-level API for fine grained(and safer) URL construction:

(-> (curl/request {:url {:scheme "https"
                         :host   "httpbin.org"
                         :port   443
                         :path   "/get"
                         :query  "q=test"}})
    :body
    (json/parse-string true))
;;=>
{:args {:q "test"},
 :headers
 {:Accept "*/*",
  :Host "httpbin.org",
  :User-Agent "curl/7.64.1",
  :X-Amzn-Trace-Id
  "Root=1-5e63989e-7bd5b1dba75e951a84d61b6a"},
 :origin "46.114.35.45",
 :url "https://httpbin.org/get?q=test"}

Exceptions

An ExceptionInfo will be thrown for all HTTP response status codes other than #{200 201 202 203 204 205 206 207 300 301 302 303 304 307} or if curl exited with a non-zero exit code. The response map is the exception data.

(curl/get "https://httpstat.us/404")
;;=> Execution error (ExceptionInfo) at babashka.curl/request (curl.clj:228).
     status 404

(:status (ex-data *e))
;;=> 404

To opt out of an exception being thrown, set :throw to false.

(:status (curl/get "https://httpstat.us/404" {:throw false}))
;;=> 404

If the body is being returned as a stream then exceptions are never thrown and the :exit value is wrapped in a Delay.

(:exit (curl/get "https://httpstat.us/404" {:as :stream}))
;;=> #object[clojure.lang.Delay 0x75769ab0 {:status :pending, :val nil}]
(force *1)
;;=> 0

Error output

Error output can be found under the :err key:

(:err (curl/get "httpx://postman-echo.com/get" {:throw false}))
;;=> "curl: (1) Protocol \"httpx\" not supported or disabled in libcurl\n"

Debugging requests

Set :debug to true to get debugging information along with the response. The :command value contains the command that was executed to obtain the response. The :options value contains options that were used to construct the command. Note that all of these values are for debugging only and contain implementation details that may change in the future.

(def resp (curl/head "https://postman-echo.com/head" {:debug true}))
(:command resp)
;;=> ["curl" "--silent" "--show-error" "--location" "--dump-header" "/var/folders/2m/h3cvrr1x4296p315vbk7m32c0000gp/T/babashka.curl16567082489957878064.headers" "--head" "https://postman-echo.com/head"]
(:options resp)
;;=> {:debug true, :url "https://postman-echo.com/head", :method :head, :header-file #object[java.io.File 0x61d34b4 "/var/folders/2m/h3cvrr1x4296p315vbk7m32c0000gp/T/babashka.curl16567082489957878064.headers"]}

Test

$ clojure -A:test

License

Copyright © 2020 Michiel Borkent

Distributed under the EPL License, same as Clojure. See LICENSE.

babashka.curl's People

Contributors

borkdude avatar daviddpark-reify avatar jaydeesimon avatar lispyclouds avatar rymndhng avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.