Clojure icon

Clojure Quick Start Guide

Get started with FacePing's face recognition API using Clojure

Prerequisites

Installation

Create a new project using Leiningen:

lein new compojure faceping-demo
cd faceping-demo

Update project.clj with required dependencies:

(defproject faceping-demo "0.1.0-SNAPSHOT"
  :description "FacePing API integration"
  :dependencies [[org.clojure/clojure "1.11.1"]
                [compojure "1.7.0"]
                [ring/ring-defaults "0.3.4"]
                [ring/ring-json "0.5.1"]
                [clj-http "3.12.3"]
                [environ "1.2.0"]]
  :plugins [[lein-ring "0.12.6"]
           [lein-environ "1.2.0"]]
  :ring {:handler faceping-demo.handler/app})

Create profiles.clj to store your API key:

{:dev {:env {:faceping-api-key "your_api_key_here"}}}

Step 1: Create Face Group

Update src/faceping_demo/handler.clj:

(ns faceping-demo.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [clj-http.client :as client]
            [ring.middleware.json :refer [wrap-json-response]]
            [ring.util.response :refer [response]]
            [environ.core :refer [env]]))

(defn create-group [group-name]
  (try
    (let [resp (client/post (str "https://api.faceping.ai/groups/" group-name)
                           {:headers {"Authorization" (str "Bearer " (env :faceping-api-key))}})]
      (response {:message "Group created successfully"}))
    (catch Exception e
      (-> {:error (.getMessage e)}
          (response)
          (assoc :status 500)))))

Step 2: Upload Face Image

Add to handler.clj:

(defn upload-face [group-name request]
  (if-let [file (get-in request [:multipart-params "image"])]
    (try
      (let [resp (client/post (str "https://api.faceping.ai/groups/" group-name "/faces")
                             {:headers {"Authorization" (str "Bearer " (env :faceping-api-key))}
                              :multipart [{:name "image"
                                         :content (clojure.java.io/file (:tempfile file))
                                         :filename (:filename file)}]})]
        (response {:message "Face uploaded successfully"}))
      (catch Exception e
        (-> {:error (.getMessage e)}
            (response)
            (assoc :status 500))))
    (-> {:error "No image file provided"}
        (response)
        (assoc :status 400))))

Step 3: Search for Faces

Add to handler.clj:

(defn search-faces [group-name request]
  (if-let [file (get-in request [:multipart-params "image"])]
    (try
      (let [resp (client/post (str "https://api.faceping.ai/groups/" group-name "/search")
                             {:headers {"Authorization" (str "Bearer " (env :faceping-api-key))}
                              :multipart [{:name "image"
                                         :content (clojure.java.io/file (:tempfile file))
                                         :filename (:filename file)}]})]
        (response (json/parse-string (:body resp) true)))
      (catch Exception e
        (-> {:error (.getMessage e)}
            (response)
            (assoc :status 500))))
    (-> {:error "No image file provided"}
        (response)
        (assoc :status 400))))

(defroutes app-routes
  (POST "/groups/:group-name" [group-name]
        (create-group group-name))
  (POST "/groups/:group-name/faces" [group-name :as request]
        (upload-face group-name request))
  (POST "/groups/:group-name/search" [group-name :as request]
        (search-faces group-name request))
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      wrap-json-response))

Security Notes

  • Images are immediately discarded after vector conversion
  • Face vectors cannot be reverse-engineered into images
  • Always use HTTPS in production
  • Store your API keys in environment variables or profiles.clj

Ready to get started?

Take a look at the API documentation
API docs