Fork me on GitHub
Adrian Imanuel11:02:08

Hi Guys, i'd like to connect clojure with google sheets. Question is where should i put this in the project.clj ? [google-apps-clj "0.6.1"] is it under dependencies?

(defproject asdf "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url ""}
  :dependencies [[org.clojure/clojure "1.10.1"]]
  :main ^:skip-aot asdf.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts [""]}})

Adrian Imanuel14:02:00

@UEQPKG7HQ, ive tried to follow steps : Obtaining OAuth 2 Credentials but stuck at step 6, i've create the google-creds.edn, where should i save this?

Adrian Imanuel14:02:57

whenever i called (edn/read-string (slurp "config/google-creds.edn")) , repl error said no such namespace: edn


there's no namespace called edn


read-string is a function that exists in clojure.edn : Check out the examples here:


Hi, I'm taking a look at

;; good
(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

;; bad
(defn print-seq [s]
  (when-not (empty? s)
    (prn (first s))
    (recur (rest s))))
I always use empty? because I find it more clear and readable. Would anyone please explain why it's considered bad?


It's not that it's bad or better, it's more idiomatic...


user=> (doc empty?)
  Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))


The thing about seq is that it will return the collection, whereas empty? will simply return true or false


Also empty? is implemented as (not (seq coll)) so you're kinda doing a double negation.


you could use if it helps with the reading, but has the same outputs as seq


I would posit too that a clojurist reading clojure code would understand if they saw something like (when-let [foo (seq (get-data))] ... ) would know what's going on ๐Ÿ™‚

Adrian Imanuel14:02:47

Hi i've tried to follow steps : Obtaining OAuth 2 Credentials but stuck at step 6, i've create the google-creds.edn, where should i save this? whenever i called (edn/read-string (slurp "config/google-creds.edn")) , repl error said no such namespace: edn


You need to bring in the edn namespace,


(require '[clojure.edn :as edn])


user=> (require '[clojure.edn :as edn])


user=> (edn/read-string (slurp "/home/david/foo.edn"))
{:foo [1 2 3]}

Adrian Imanuel14:02:13

does clojre.edn , the "clojure" can be changed with my project name? (require '[asdf.edn :as edn])


No, it's a "core" library, part of clojure


it's namespace is clojure.edn


it's like, in java doing an import java.time.LocalDate

Adrian Imanuel15:02:09

@dharrigan then in step 9 how do i call google-apps-clj.credentials/get-auth-map?


I would imagine, without knowing the api at all, something like this:


Their tests sorta show how it works


so instead of calling default-credential you call get-auth-map passing in the slurped data from the edn file


(gauth/get-auth-map (edn/read-string (slurp "/home/adrian/my-credentials.edn")) scope)


with scope set to be "" or one of the other examples

Adrian Imanuel15:02:54

I'm lost here... Apologize bcs I'm still newbie here. I'd like to ask when we put this [google-apps-clj "0.6.1"]within dependencies in project.clj then i run lein deps in my cmd. it's kinda installing/downloading, where this library stored?


that's okay, we're all beginners ๐Ÿ™‚


Okay, so you are using leiningen, you have a project.clj?


or are you using deps.edn?

Adrian Imanuel15:02:43

i use project.clj


Take for example, the google apis project.clj


you can see that the dependencies are in a block called dependencies


in your project, you would add in the google-aps-clj into your dependencies block

Adrian Imanuel15:02:18

yes, i've add [google-apps-clj "0.6.1"] in my dependencies block


so, now you can do lein repl to bring up a repl for experimentation


great, so now you can require in the various libraries for playing around, such as the google apps library

Adrian Imanuel15:02:28

my repl now ready


very good, now you can add in the requires, think of "imports" like you would in java


their tests, which I linked previously, shows how to import their libraries

Adrian Imanuel15:02:27

OHHHHHHHHHHHH... like this? since i'm going to use google sheets, i take the require from


not quite, nealry


you don't ns their stuff


you require it into yours

Adrian Imanuel15:02:31

sorry, this is revised


Let me show you...


that is better


now you have their stuff required into your namespace


that should get you going now ๐Ÿ™‚


It's okay, it's a warning

Adrian Imanuel15:02:16

step 9 still is really confusing.

Adrian Imanuel15:02:31

it doesn't result anything in repl.


You're not using the function step 9 is telling you to call.

Adrian Imanuel15:02:20

I'm sorry, but how to call it?


Is this your first time using Clojure may I ask?

Adrian Imanuel16:02:04

Sadly yes.. I'm learning from braveclojure until ch 9 now

Adrian Imanuel16:02:32

apologize if i really don't understand... i never touch java either


I think, learning to do oauth2 authentication to google, is a big big step

๐Ÿ˜… 3

Could you start with something smaller perhaps? Learn how to invoke functions, passing in arguments?


loading (requiring) in namespaces and working with the functions defined within them?


Very happy to help, but it does seem like more basics are required first, until you tackle the beast that is oauth2


and trust me, oauth2 sucks

Adrian Imanuel16:02:18

allright, i'll re-learn again about the :require once i could do the csv api, but this google things... is very difficult


I would also recommend the courses


they are good too

Adrian Imanuel16:02:09

ahhh okay, thank you so much for the help... step 9 is like last boss... i'll go levelling first

Tim Robinson17:02:29

Hi all. I have 2 namespaces implementing the same functions and I'm trying to dynamically select one based on a configuration entry. I don't really want to get into dependency injection frameworks, interfaces, protocols and all of that stuff unless I have to. I've figured out that this seems to work: (let [namespace (if some-config-flag 'namespace1 'namespace2)] (require [namespace :as implementation])) (implementation/do-something) Is this considered a sensible thing to do, or an abominable hack?

Alex Miller (Clojure team)17:02:53

closer to the latter :)


can you just require both? (if (= option :a) (the-a-choice/launch-missles) (tests/launch-console-text-missiles))

Alex Miller (Clojure team)17:02:51

using requiring-resolve with a fully-qualified var would be better


I have a use case that I do for this, and yup, Alex beat me to it, (requiring-resolve)

Alex Miller (Clojure team)17:02:11

assuming you need the dynaload

Tim Robinson17:02:08

I have about 20 functions in the implementing namespace, and it's something that is used very heavily in my app (the main persistence module). does requiring-resolve make sense for that or would it have a high runtime overhead?

Tim Robinson17:02:16

also I don't need to load it dynamically - both implementations will be present in the released package

Alex Miller (Clojure team)17:02:40

I mean, from what you describe, I'd probably use a protocol

Alex Miller (Clojure team)17:02:21

and just use config to choose what to instantiate

Alex Miller (Clojure team)17:02:26

doing the conditional require stuff makes it a lot harder for editors, tools, etc to understand what you're doing (and possibly other developers as well)

Tim Robinson18:02:27

Thanks - yes I did notice that clj-kondo didn't like what I was doing ๐Ÿ™‚ I was put off protocols thinking they were really intended just for java interop, but it looks to me like the best match


I know very little about web application security, but I'm trying to learn more. I know it is normal to protect certain parts of an application, and require the user to be authenticated in order to be authorized to see whatever is protected. But what if I also wanted to encrypt the information going into the system from the client, so that the database administrator or someone who gained entry to the database would not be able to see whatever was stored there. Is this feasible, or common? Can the information be decrypted fast enough for the system to respond like a normal web application, or would that process be very slow? Does anyone know of any good resources for doing things like this in Clojure, or just a general overview of web application security? So far I have found this:


given a hypothetical database that stores encrypted data, it would need to decrypt it to do all the good things databases do (build indices, enforce constraints, etc). so the database will need to be able to decrypt it, which means if someone has the highest level access to the database (typical of a database admin) that means they can also decrypt it


so no, not feasible


if you aren't interested in a database, and just want a blob key value store, it is feasible. if you aren't familiar, and haven't work with something like a sql database before, you might equate a database with a key value store, but they definitely are not the same thing


Thanks, this has given me something to consider!

Tim Robinson07:02:40

encryption of the data across the network is normally handled by HTTPS or similar. for encryption of stored data you would normally use disk-level encryption (like windows bitlocker) which would be configured in the hosting center. you can't easily protect the data from a system administrator or DBA who knows that they are doing - you could encrypt the contents of individual fields or blobs yourself but then you'd need to store the encryption key somewhere, and the administrator would be able to find it (plus, as hiredman says, it makes it really inconvenient to use). If you want secure encryption of the data, I'd recommend putting the database engine on your own VM using disk encryption, to which only you know they password, then protecting access to the database so you know who's accessing it. Whatever you decide to do, the performance overhead of enccryption is unlikely to be significant


in my experience, encryption all the way to the database level is rare


however, saying that, I know that our AWS RDS instances do encrypt the storage underneath


however, that's at the block level, not at the application level, so I can easily psql into a RDS instance and do normal selects etc...


our internal API calls are all TLS (which makes debugging a bit difficult, unless you plug in a MITM on your work machine ๐Ÿ™‚ )


however, this is probably better discussed in #off-topic ๐Ÿ™‚

๐Ÿ‘ 3