How can I disable babashka/http-clients default behavior to parse a body. I am trying to make a GET request to a url that returns a 302 with no body, I want to get the response headers to parse the Location header. But babashka fails with Cannot open <nil> as a Reader.
(http/get "" {:client (merge http/default-client-opts
{:follow-redirects :never})})
(unfortunately http://cljdoc.org doesn't handle the HEAD method(require '[babashka.http-client :as http]
'[babashka.http-client.interceptors :as interceptors])
#_(prn (map :name interceptors/default-interceptors))
(prn
(http/get ""
{:client (merge http/default-client-opts
{:follow-redirects :never})
:interceptors (filter #(not= :babashka.http-client.interceptors/decode-body (:name %))
interceptors/default-interceptors)})) If you think this is a bug, then we can make this more robust by checking for nil first
PR welcome
wow:
/private/tmp/kondo-performance/metabase/src/metabase/session/task/session_cleanup.clj
Inspected all files in 12,99 seconds.
Heap used: 28.159408569335938 MB:-D
I localized all memoize usage to run! now, so all memory is freed after run!
in graalvm native-image things have become slower though. maybe I shouldn't use a cache at all in some cases. needs more testing, but this is promising
nice job! .. but wrong thread?
whoops sorry!
> If you think this is a bug, then we can make this more robust by checking for nil first
My gut says this is a bug, because I don't think I should have to jump through hoops like that just to make an http request that returns no body (which is perfectly valid and normal).
yeah seems like it
isssue (+ optional PR) welcome
What's weird is that the response I printed in the above script, doesn't even have a :status etc
Yea I just tested it, also no :headers
just :request and :`body`
oh I get it, client shouldn't be a map
so it works like expected, the client should just be like this:
(http/get ""
{:client (http/client (merge http/default-client-opts
{:follow-redirects :never}))
}) the error is confusing since client can also be a function where you do your own thing
https://github.com/babashka/http-client/commit/e7c4631b063010af7e30e18da27dc14a2f9c50d1
oh interesting
I see where I went wrong. The client docstring says "To get the same behavior as the (implicit) default client, pass default-client-opts." and I then passed the twiddled client-opts to request, not the client fn.
yeah, an easy mistake to make, glad we found it
If you need JVM clojure from within babashka, is the best solution just to shell out and call the clj/`clojure` cli? Maybe using babashka.process?
Context is, I have a babashka cli tool with a bunch of subcommands, they all run fine under bb but now I need to add a couple of commands that need jvm stuff (kicking off Lucene indexing jobs, lot of interop). It's fine if these are slow since they'll be slow in any case - and I'd love to keep using the tool under bb since I call the other commands more often and they're much faster under bb.
Thanks for any tips!
@ryantate You can use babashka.tasks/clojure from bb.edn or babashka.deps/clojure (which is really the same function) in code files
e.g.:
(babashka.deps/clojure "-X:foo:bar" {:arg 1})Ah thanks, I had a vague memory there was a facility for this, I could not remember what it was and spent some time looking throug the docs but couldn't track it down.
but shelling out is also a fine option. in bb.edn you can do that using (shell "clojure" ...) which is the same as babashka.process/shell
OK cool, i'll see if tasks can be a good fit first though that sounds good
Just to clarify: does that clojure function run in-process or does it shell out to deps.clj or to the (JVM) CLI?
it runs deps.clj in process
Thanks. I'd seen in CI where bb logged that Clojure tools wasn't in the expected place (so it downloads it) when I used clojure but not when I used shell "clojure" so I wanted to double-check.
yeah, indeed
Is there much reason to prefer one over the other? (in a CI context specifically)
there was a period of time in which shelling out to clojure was very OS-specific and sometimes error-prone, the deps.clj built-in thing was solving that problem.
also deps.clj is there anyway for dependencies in bb.edn.
but if you want to call out to a specific version of clojure on your system, that's fine too. no strong preference
perhaps the github action can be improved by downloading the tools jar as part of the github action installation process when bb is selected
I tend to keep cli: updated and currently setup bb: 'latest' so there wouldn't be much difference. I guess just a minor performance penalty for shelling out to clojure?
that would likely be an improvement wrt/ caching too
Aye, I added .deps.clj (I think) to my GHA caches.
~/.deps.clj right
If you can run the tasks from a running clojure server with a repl running, you can send code into the jvm clojure repl from babashka. we have a https://github.com/metabase/metabase/blob/master/bb.edn#L173-L192 for this.
-n optional:
$ bb -repl -n a.namespace '(do-stuff)'help for it printed below if that helps.
Task Name: -repl
Eval a string of clojure code in the backend dev server
Usages:
-n, --namespace NAMESPACE Namespace to use for the task
-p, --port PORT Port to use for the task, defaults to value in .nrepl-port
Examples:
bb -repl '(+ 1 1)'
- Eval a form in the backend dev server in the user namespace
bb -repl --namespace metabase.app-db.connection @application-db-counter
- Eval a form in the backend dev server in the 'metabase.app-db.connection' namespace
bb -repl --port 59498 --namespace metabase.app-db.connection '(read-string "::hello")'
- Evaluate a keyword inside a namespaceThere's also a small lib here to do a similar thing: https://github.com/babashka/nrepl-client but not sure if that's the goal of the OP
I think I took the code snippet from the babashka book. I added stdout and stderr capture and some other goodies, for claude to use, before there was clojure-mcp 😅