From d1bbfc3b3b636f0c20ff0c92036da5dcdb6f86da Mon Sep 17 00:00:00 2001 From: Oliver Marks Date: Tue, 9 Jan 2024 16:07:58 +0000 Subject: [PATCH] Mailersend first api requests. --- .../helpers/src/org/aplex/helpers/core.cljc | 8 ++- .../src/org/aplex/helpers/interface.clj | 18 ------ .../src/org/aplex/helpers/interface.cljc | 21 +++++++ components/rest-mailersend/deps.edn | 4 ++ .../resources/mailersend/.keep | 1 + .../src/org/aplex/mailersend/core.cljc | 44 ++++++++++++++ .../src/org/aplex/mailersend/interface.clj | 8 +++ .../src/org/aplex/mailersend/interface.cljc | 14 +++++ .../org/aplex/mailersend/interface_test.clj | 6 ++ .../src/org/aplex/rest_stability_ai/core.cljc | 41 ++++++++----- .../aplex/rest_stability_ai/interface.cljc | 10 ++-- .../src/org/aplex/stability_ai/core.cljc | 16 ++--- .../src/org/aplex/stability_ai/interface.cljc | 1 + deps.edn | 24 ++++---- development/src/backend/mailersend.clj | 58 ++++++++++++++++++ development/src/frontend/portfolio/core.cljs | 4 +- .../src/frontend/portfolio/mailersend.cljs | 22 +++++++ .../src/frontend/portfolio/stability_ai.cljs | 59 ++++++++++--------- readme.org | 9 +-- 19 files changed, 275 insertions(+), 93 deletions(-) delete mode 100644 components/helpers/src/org/aplex/helpers/interface.clj create mode 100644 components/helpers/src/org/aplex/helpers/interface.cljc create mode 100644 components/rest-mailersend/deps.edn create mode 100644 components/rest-mailersend/resources/mailersend/.keep create mode 100644 components/rest-mailersend/src/org/aplex/mailersend/core.cljc create mode 100644 components/rest-mailersend/src/org/aplex/mailersend/interface.clj create mode 100644 components/rest-mailersend/src/org/aplex/mailersend/interface.cljc create mode 100644 components/rest-mailersend/test/org/aplex/mailersend/interface_test.clj create mode 100644 development/src/backend/mailersend.clj create mode 100644 development/src/frontend/portfolio/mailersend.cljs diff --git a/components/helpers/src/org/aplex/helpers/core.cljc b/components/helpers/src/org/aplex/helpers/core.cljc index 796b4ce..90ca7bd 100644 --- a/components/helpers/src/org/aplex/helpers/core.cljc +++ b/components/helpers/src/org/aplex/helpers/core.cljc @@ -1,6 +1,6 @@ (ns org.aplex.helpers.core - (:require - [clojure.string :as s])) + (:require [clojure.string :as s]) + #?(:clj (:import (java.lang System)))) (defn map-replace "Given a string with {:key} strings substitute the matching key in a hash map" @@ -14,3 +14,7 @@ (defn attach-handler [hm fn] (assoc hm :handler fn)) + +#?(:clj + (defn get-env [key default-value] + (or (System/getenv key) default-value))) diff --git a/components/helpers/src/org/aplex/helpers/interface.clj b/components/helpers/src/org/aplex/helpers/interface.clj deleted file mode 100644 index 4e0f170..0000000 --- a/components/helpers/src/org/aplex/helpers/interface.clj +++ /dev/null @@ -1,18 +0,0 @@ -(ns org.aplex.helpers.interface - (:require - [org.aplex.helpers.core :as c]) - (:import - (java.lang System))) - -(defmacro load-default-env [env-var] - (System/getenv env-var)) - -(defn map-replace [text m] - (c/map-replace text m)) - - -(defn build-url [root-url path params] - (c/build-url root-url path params)) - -(defn attach-handler [hm fn] - (c/attach-handler hm fn)) diff --git a/components/helpers/src/org/aplex/helpers/interface.cljc b/components/helpers/src/org/aplex/helpers/interface.cljc new file mode 100644 index 0000000..327eda9 --- /dev/null +++ b/components/helpers/src/org/aplex/helpers/interface.cljc @@ -0,0 +1,21 @@ +(ns org.aplex.helpers.interface + #?(:cljs (:require-macros [org.aplex.helpers.interface])) + (:require [org.aplex.helpers.core :as c ])) + +#?(:clj + (defmacro get-env [key default-value] + (or (System/getenv key) default-value) + #_(c/get-env key default-value))) + +(defn map-replace [text m] + (c/map-replace text m)) + +(defn build-url [root-url path params] + (c/build-url root-url path params)) + +(defn attach-handler [hm fn] + (c/attach-handler hm fn)) + +(comment + (macroexpand get-env) + (c/get-env "STABILITY_API_KEY" "2")) diff --git a/components/rest-mailersend/deps.edn b/components/rest-mailersend/deps.edn new file mode 100644 index 0000000..28d4733 --- /dev/null +++ b/components/rest-mailersend/deps.edn @@ -0,0 +1,4 @@ +{:paths ["src" "resources"] + :deps {} + :aliases {:test {:extra-paths ["test"] + :extra-deps {}}}} diff --git a/components/rest-mailersend/resources/mailersend/.keep b/components/rest-mailersend/resources/mailersend/.keep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/components/rest-mailersend/resources/mailersend/.keep @@ -0,0 +1 @@ + diff --git a/components/rest-mailersend/src/org/aplex/mailersend/core.cljc b/components/rest-mailersend/src/org/aplex/mailersend/core.cljc new file mode 100644 index 0000000..c288df1 --- /dev/null +++ b/components/rest-mailersend/src/org/aplex/mailersend/core.cljc @@ -0,0 +1,44 @@ +(ns org.aplex.mailersend.core + (:require + [ajax.core :refer [json-request-format json-response-format]] + [org.aplex.helpers.interface :as h])) + +(def version "v1") +(def api-config (atom {:api-host "https://api.mailersend.com/" + :api-key (h/get-env "MAILERSENDER_API_KEY" "NO API KEY SUPPLIED")})) + +(def default-authed-payload {:headers {"Authorization" (str "Bearer " (:api-key @api-config)) + "content-type" "application/json"}}) + +(defn init-config [cfg] + (reset! api-config (merge @api-config cfg))) + +(defn build-url [path] + (str (:api-host @api-config) version path)) + +(defn send-email [email] + (merge default-authed-payload + {:uri (build-url "/email") + :method :post + :format (json-request-format) + :response-format (json-response-format {:keywords? true}) + :keywords? true + :params email})) + +(defn list-domains [] + (merge default-authed-payload + {:uri (build-url "/domains") + :method :get + :format (json-request-format) + :response-format (json-response-format {:keywords? true}) + :keywords? true})) + +(defn fetch-domain [domain-id] + (merge default-authed-payload + {:uri (build-url (str "/domains/" domain-id)) + :method :get + :format (json-request-format) + :response-format (json-response-format {:keywords? true}) + :keywords? true})) + +(comment (send-email {:to ""})) diff --git a/components/rest-mailersend/src/org/aplex/mailersend/interface.clj b/components/rest-mailersend/src/org/aplex/mailersend/interface.clj new file mode 100644 index 0000000..9ee9c31 --- /dev/null +++ b/components/rest-mailersend/src/org/aplex/mailersend/interface.clj @@ -0,0 +1,8 @@ +(ns org.aplex.mailersend.interface + (:require [org.aplex.mailersend.core :as c])) + +(defn init-config [cfg] + (c/init-config cfg)) + +(defn send-email [email] + (c/send-email email)) diff --git a/components/rest-mailersend/src/org/aplex/mailersend/interface.cljc b/components/rest-mailersend/src/org/aplex/mailersend/interface.cljc new file mode 100644 index 0000000..f94bfe0 --- /dev/null +++ b/components/rest-mailersend/src/org/aplex/mailersend/interface.cljc @@ -0,0 +1,14 @@ +(ns org.aplex.mailersend.interface + (:require [org.aplex.mailersend.core :as c])) + +(defn init-config [cfg] + (c/init-config cfg)) + +(defn send-email [email] + (c/send-email email)) + +(defn list-domains [] + (c/list-domains)) + +(defn fetch-domain [domain-id] + (c/fetch-domain domain-id)) diff --git a/components/rest-mailersend/test/org/aplex/mailersend/interface_test.clj b/components/rest-mailersend/test/org/aplex/mailersend/interface_test.clj new file mode 100644 index 0000000..e5d14e6 --- /dev/null +++ b/components/rest-mailersend/test/org/aplex/mailersend/interface_test.clj @@ -0,0 +1,6 @@ +(ns org.aplex.mailersend.interface-test + (:require [clojure.test :as test :refer :all] + [org.aplex.mailersend.interface :as mailsend])) + +(deftest dummy-test + (is (= 1 1))) diff --git a/components/rest-stability-ai/src/org/aplex/rest_stability_ai/core.cljc b/components/rest-stability-ai/src/org/aplex/rest_stability_ai/core.cljc index 1a6143f..ba9d017 100644 --- a/components/rest-stability-ai/src/org/aplex/rest_stability_ai/core.cljc +++ b/components/rest-stability-ai/src/org/aplex/rest_stability_ai/core.cljc @@ -1,38 +1,47 @@ (ns org.aplex.rest-stability-ai.core (:require [org.aplex.helpers.interface :as h])) +(def version "v1") (def api-config (atom {:api-host "https://api.stability.ai" - :api-key "STABILITY_API_KEY"})) + :api-key (h/get-env "STABILITY_API_KEY" "NO API KEY SUPPLIED")})) -(def api-host "https://api.stability.ai") -(def api-key "sk-t8dmTcOV2jOAALqJ4yjS8qEOgr4NZHumuHd3ppuMsQn9os2W") - -(def default-authed-payload {:headers {"Authorization" (str "Bearer " api-key) +(def default-authed-payload {:headers {"Authorization" (str "Bearer " (-> @api-config :api-key)) "content-type" "application/json"}}) (defn init-config [cfg] (reset! api-config (merge @api-config cfg))) (defn build-url [path] - (str api-host path)) + (str (-> @api-config :api-host) path)) (defn fetch-user-account [] - (merge default-authed-payload - {:url (build-url "/v1/user/account") - :handler prn})) + (merge default-authed-payload + {:uri (build-url "/v1/user/account") + :method :get + })) (defn fetch-user-balance [] - (merge default-authed-payload - {:url (build-url "/v1/user/balance") - :handler prn})) + (merge default-authed-payload + {:uri (build-url "/v1/user/balance") + :method :get + :format :json + })) -(defn fetch-generation-text-to-image [] - (merge default-authed-payload - {:url (build-url "/v1/user/balance") +(defn fetch-available-engines [] + (merge default-authed-payload + {:uri (build-url "/v1/engines/list") + :method :get + :format :json + })) + +(defn fetch-generation-text-to-image [required optional] + (merge default-authed-payload + {:uri (build-url "/v1/user/balance") + :method :post :format :json :response-format :json :params {:text_prompts [{:text "A wooden hand crafted light house" :weight 0.5}]} - :handler prn})) + })) diff --git a/components/rest-stability-ai/src/org/aplex/rest_stability_ai/interface.cljc b/components/rest-stability-ai/src/org/aplex/rest_stability_ai/interface.cljc index 5abbf0d..a5d7070 100644 --- a/components/rest-stability-ai/src/org/aplex/rest_stability_ai/interface.cljc +++ b/components/rest-stability-ai/src/org/aplex/rest_stability_ai/interface.cljc @@ -1,8 +1,10 @@ (ns org.aplex.rest-stability-ai.interface - (:require [org.aplex.stability-ai.core :as c])) + (:require [org.aplex.rest-stability-ai.core :as c])) +(def api-config c/api-config) (defn init-config [cfg] (c/init-config cfg)) -(defn fetch-user-account [] (c/fetch-user-account )) -(defn fetch-user-balance [] (c/fetch-user-balance )) -(defn fetch-generation-text-to-image [required optional] (c/fetch-generation-text-to-image required optional)) +(defn fetch-user-account [handler] (c/fetch-user-account handler)) +(defn fetch-user-balance [handler] (c/fetch-user-balance handler)) +(defn fetch-available-engines [handler] (c/fetch-available-engines handler)) +(defn fetch-generation-text-to-image [handler required optional] (c/fetch-generation-text-to-image handler required optional)) diff --git a/components/stability-ai/src/org/aplex/stability_ai/core.cljc b/components/stability-ai/src/org/aplex/stability_ai/core.cljc index 3dba801..f62c37d 100644 --- a/components/stability-ai/src/org/aplex/stability_ai/core.cljc +++ b/components/stability-ai/src/org/aplex/stability_ai/core.cljc @@ -1,12 +1,12 @@ (ns org.aplex.stability-ai.core - (:require [org.aplex.helpers.interface :as h]) - ) + (:require [org.aplex.helpers.interface :as h])) +(def version "v1") (def api-config (atom {:api-host "https://api.stability.ai" - :api-key "STABILITY_API_KEY"})) + :api-key (h/get-env "STABILITY_API_KEY" "NO API KEY SUPPLIED")})) (def api-host "https://api.stability.ai") -(def api-key "sk-t8dmTcOV2jOAALqJ4yjS8qEOgr4NZHumuHd3ppuMsQn9os2W") +(def api-key (h/get-env "STABILITY_API_KEY" "NO API KEY SUPPLIED")) (def default-authed-payload {:headers {"Authorization" (str "Bearer " api-key) "content-type" "application/json"}}) @@ -15,7 +15,7 @@ (reset! api-config (merge @api-config cfg))) (defn build-url [path] - (str api-host path)) + (str (:api-host api-config) "/" version path)) (defn fetch-user-account [] (merge default-authed-payload @@ -27,13 +27,13 @@ {:url (build-url "/v1/user/balance") :handler prn})) -(defn fetch-generation-text-to-image [] +(defn fetch-generation-text-to-image [body] (merge default-authed-payload {:url (build-url "/v1/user/balance") + :method :post :format :json :response-format :json - :params {:text_prompts [{:text "A wooden hand crafted light house" - :weight 0.5}]} + :params body :handler prn})) diff --git a/components/stability-ai/src/org/aplex/stability_ai/interface.cljc b/components/stability-ai/src/org/aplex/stability_ai/interface.cljc index 1d87756..fdde2a6 100644 --- a/components/stability-ai/src/org/aplex/stability_ai/interface.cljc +++ b/components/stability-ai/src/org/aplex/stability_ai/interface.cljc @@ -1,6 +1,7 @@ (ns org.aplex.stability-ai.interface (:require [org.aplex.stability-ai.core :as c])) +(def api-config c/api-config) (defn init-config [cfg] (c/init-config cfg)) (defn fetch-user-account [] (c/fetch-user-account )) diff --git a/deps.edn b/deps.edn index f86af47..9a646d1 100644 --- a/deps.edn +++ b/deps.edn @@ -1,23 +1,23 @@ -{:paths ["development/src"] - :deps { - org.clojure/clojure {:mvn/version "1.11.1"} - +{:paths ["development/src" + "components/helpers/src" + "components/rest-stability-ai/src" + "components/rest-mailersend/src"] + :deps {org.clojure/clojure {:mvn/version "1.11.1"} + org.clojure/clojurescript {:mvn/version "1.11.60"} + thheller/shadow-cljs {:mvn/version "2.25.2"} + cljs-ajax/cljs-ajax {:mvn/version "0.8.4"} djblue/portal {:mvn/version "0.49.1"} no.cjohansen/portfolio {:mvn/version "2023.07.15"} io.github.nextjournal/clerk {:mvn/version "0.15.957"} - refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"} - - } + refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"}} :aliases {:dev {:extra-paths ["development/src"] :extra-deps {org.clojure/clojure {:mvn/version "1.11.1"} - + thheller/shadow-cljs {:mvn/version "2.25.2"} djblue/portal {:mvn/version "0.49.1"} + cljs-ajax/cljs-ajax {:mvn/version "0.8.4"} no.cjohansen/portfolio {:mvn/version "2023.07.15"} io.github.nextjournal/clerk {:mvn/version "0.15.957"} - - refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"} - - }} + refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"}}} :shadow-cljs-run {:extra-deps {thheller/shadow-cljs {:mvn/version "2.25.2"} diff --git a/development/src/backend/mailersend.clj b/development/src/backend/mailersend.clj new file mode 100644 index 0000000..62be892 --- /dev/null +++ b/development/src/backend/mailersend.clj @@ -0,0 +1,58 @@ +(ns src.backend.mailersend + (:require + [org.aplex.helpers.interface :as h] + [ajax.core + :refer [ajax-request GET json-request-format json-response-format POST ]] + [org.aplex.mailersend.interface :as m])) + +(def response (atom nil)) + +(-> {:to [{:email "olymk2@gmail.com" + :name "oly"}] + :from {:email "test@theplantscape.com" + :name "test"} + :subject "Test mailersend api" + :text "Hi {$name}" + :html "Hi {$name}" + :variables [{:email "olymk2@gmail.com" + :substitutions [{:var "name" + :value "Test name"}]}]} + + (m/send-email) + (h/attach-handler prn)) + +(-> {:to [{:email "olymk2@gmail.com" + :name "oly"}] + :from {:email "test@theplantscape.com" + :name "test"} + :subject "Test mailersend api" + :text "Hi {$name}" + :html "Hi {$name}" + :variables [{:email "olymk2@gmail.com" + :substitutions [{:var "name" + :value "Test name"}]}]} + + (m/send-email) + (h/attach-handler (partial reset! response)) + (ajax-request) + (deref)) + +@response + + + +(-> (m/list-domains) + (h/attach-handler (partial reset! response)) + (ajax-request) + (deref)) + +@response + + + +(-> (m/fetch-domain "jpzkmgqvynvl059v") + (h/attach-handler (partial reset! response)) + (ajax-request) + (deref)) + +@response diff --git a/development/src/frontend/portfolio/core.cljs b/development/src/frontend/portfolio/core.cljs index d008f04..9fc50fe 100644 --- a/development/src/frontend/portfolio/core.cljs +++ b/development/src/frontend/portfolio/core.cljs @@ -1,6 +1,8 @@ (ns frontend.portfolio.core - (:require [portfolio.ui :as ui])) + (:require [portfolio.ui :as ui] + [org.aplex.rest-stability-ai.interface :as st])) +(prn st/api-config) (defn launch [] (ui/start! diff --git a/development/src/frontend/portfolio/mailersend.cljs b/development/src/frontend/portfolio/mailersend.cljs new file mode 100644 index 0000000..553fab5 --- /dev/null +++ b/development/src/frontend/portfolio/mailersend.cljs @@ -0,0 +1,22 @@ +(ns frontend.portfolio.mailersend + (:require + [ajax.core + :refer [ajax-request GET json-request-format json-response-format POST]] + [org.aplex.mailersend.interface :as m])) + +(m/send-mail {:to {:email "olymk2@gmail.com" + :name "oly"} + :from {:email "test@theplantscape.com" + :name "test"} + :subject "Test mailersend api" + :text "Hi {$name}" + :html "Hi {$name}" + :variables [{:email "" + :substitutions [{:var "name" + :value "Test name"}]}]}) + + +(-> (m/send-mail prn) + (merge {:format (json-request-format) + :response-format (json-response-format {:keywords? true})}) + ajax-request) diff --git a/development/src/frontend/portfolio/stability_ai.cljs b/development/src/frontend/portfolio/stability_ai.cljs index ac2a4f0..a5345cc 100644 --- a/development/src/frontend/portfolio/stability_ai.cljs +++ b/development/src/frontend/portfolio/stability_ai.cljs @@ -1,37 +1,41 @@ (ns src.frontend.portfolio.stability-ai - (:require ;[clj-http.client :as client] - [ajax.core :refer [GET POST]] - [portfolio.ui :as ui] - [portfolio.dumdom :as d] - [portfolio.dom :as r])) + (:require + [ajax.core + :refer [ajax-request GET json-request-format json-response-format POST]] + [org.aplex.helpers.interface :as h] + [org.aplex.rest-stability-ai.interface :as st] + [portfolio.dumdom :as d])) ;; api root paths shoudl not end in a slash ;; the payloads should be maps no coupling to http libraries ;; each api should have an init to set the api key and change the host along side any other config - - -(def api-host "https://api.stability.ai") -(def api-key "") - -(def default-authed-payload {:headers {"Authorization" (str "Bearer " api-key) - "content-type" "application/json"}}) - -(defn build-url [path] - (str api-host path)) - - - -(GET (build-url "/v1/user/account") - (merge default-authed-payload - {:handler prn})) - -(GET (build-url "/v1/user/balance") - (merge default-authed-payload - {:handler prn})) (def temp-response (atom nil)) -(POST (build-url "/v1/generation/stable-diffusion-v1-5/text-to-image") +@st/api-config + +(st/fetch-user-account) + +(-> (st/fetch-user-account prn) + (merge {:format (json-request-format) + :response-format (json-response-format {:keywords? true})}) + ajax-request) + +(-> (st/fetch-user-balance prn) + (merge {:format (json-request-format) + :response-format (json-response-format {:keywords? true})}) + ajax-request) + +(-> (st/fetch-generation-text-to-image (fn [r] + (prn r) + (reset! temp-response r)) {} {}) + (merge {:format (json-request-format) + :response-format (json-response-format {:keywords? true})}) + ajax-request) + + + +#_(POST (build-url "/v1/generation/stable-diffusion-v1-5/text-to-image") (merge default-authed-payload {:handler (fn [r] (prn r) @@ -39,8 +43,7 @@ :format :json :response-format :json :params {:text_prompts [{:text "A wooden hand crafted light house" - :weight 0.5}]} - })) + :weight 0.5}]}})) diff --git a/readme.org b/readme.org index e2ffa09..21572ce 100644 --- a/readme.org +++ b/readme.org @@ -1,7 +1,8 @@ #+TITLE: aplex Api's -* Each library should have an init function to configur url tokens or anything else specific users -* Library's do not need to be complete as they can be expanded as sneeded +* Each library should have an init function to configure url tokens or anything else user specific for the api +* Library's do not need to be complete as they can be expanded as needed, hopefully this will help things expand and flesh out over time * There should be one function for each api route -* API libraries should just build the requests as maps. -* Validation should be seperate to the requests making it optional and written in a way to pipe the request into the validation. +* API libraries should just build the requests as maps which can be formatted and passed over to which ever library the project has chosen. +** This allow us to avoid pulling in different http libraries and implementations per api +* Validation should be seperate to the requests making ie optional and written in a way to pipe the request into the validation.