{"id":17331989,"url":"https://github.com/ocramz/cmbnt-test","last_synced_at":"2026-04-30T17:31:34.774Z","repository":{"id":66327597,"uuid":"171006608","full_name":"ocramz/cmbnt-test","owner":"ocramz","description":null,"archived":false,"fork":false,"pushed_at":"2019-02-25T12:52:19.000Z","size":85,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-27T06:25:38.808Z","etag":null,"topics":["classification","classification-algorithm","data-engineering","data-mining","data-science","docker","fisher-discriminant-analysis","microservice","quadratic-discriminant-analysis","rest-api","statistical-learning"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ocramz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-16T13:25:38.000Z","updated_at":"2019-12-05T06:36:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"b3615765-7f76-4530-a6ab-a43b55cbc57a","html_url":"https://github.com/ocramz/cmbnt-test","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ocramz/cmbnt-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocramz%2Fcmbnt-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocramz%2Fcmbnt-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocramz%2Fcmbnt-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocramz%2Fcmbnt-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ocramz","download_url":"https://codeload.github.com/ocramz/cmbnt-test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocramz%2Fcmbnt-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32472396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["classification","classification-algorithm","data-engineering","data-mining","data-science","docker","fisher-discriminant-analysis","microservice","quadratic-discriminant-analysis","rest-api","statistical-learning"],"created_at":"2024-10-15T14:56:13.407Z","updated_at":"2026-04-30T17:31:34.759Z","avatar_url":"https://github.com/ocramz.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pred-serv\n\nA little prediction server\n\n# Dependencies\n\n* `stack` (https://docs.haskellstack.org/en/stable/README/)\n* `docker`\n\n\n# Environment\n\n* OSX : A `docker-machine` environment (i.e. OS and networking virtualization) should be running.\n\nWrite down the IP address produced by `docker-machine env`; this will be necessary for testing the project on localhost. This IP (let's call it `DOCKER_IP`) is also visible in the DOCKER_HOST env var:\n\n\n    $ echo ${DOCKER_HOST}\n\n\n# Building\n\nFirst thing, make sure that `docker.enable` is set to `true` in the `stack.yaml` configuration file. This ensures that the project is built in an Alpine Linux container, since the deployment image will be based on this Linux distribution as well.\n\nBuild the development image and the project, test the project and build the deployment image:\n\n\n    $ make all\n\n\nAt this point `docker images` will list three new images:\n\n* `alpine` containing an installation of Alpine Linux (if this was not already present) (5.5 MB)\n\n* `ocramz/cmbnt-test-dev` : the development image with build tools etc. (1.1 GB)\n\n* `pred-serv:1.0` : the prediction server image ready to be deployed (around 22 MB)\n\n\n# Running\n\n    $ docker run -p 3000:3000 -it pred-serv:1.0\n\nwill start a HTTP webserver at `${DOCKER_IP}:3000`. The server will only log the incoming REST calls to console, and can be stopped with Control-C (i.e. SIGINT).\n\n## REST endpoints\n\n* Liveness : the `/liveness/` endpoint replies with 200 OK if the prediction server is online.\n\n\n### v2 API\n\nThe `v2` API lets the user reconfigure the classifier at runtime, i.e. by providing different training data and a classification method.\n\nFor now, the only two classification methods supported are FDA (Fisher linear discriminant analysis) and QDA (quadratic discriminant analysis).\n\nExample usage of the training endpoint :\n\n    POST http://${DOCKER_IP}:3000/model/v2/train/\n    {\n    \"clcTrainingSet\":[\n        {\"slabel\":false,\"sy\":0.7145113953210204,\"sx\":-0.6214134912880266},\n\t{\"slabel\":true,\"sy\":-0.5067041565111601,\"sx\":1.0299942802199769},\n\t{\"slabel\":false,\"sy\":0.18514230070868073,\"sx\":0.12440603711836776},\n\t{\"slabel\":false,\"sy\":0.9504106504744793,\"sx\":0.43845269753671307},\n\t{\"slabel\":false,\"sy\":0.5200132456123451,\"sx\":0.806956117527472},\n\t{\"slabel\":false,\"sy\":0.24590087515509454,\"sx\":-1.593655827995092e-2},\n\t{\"slabel\":true,\"sy\":-0.4134296465409296,\"sx\":1.454319160697646},\n\t{\"slabel\":true,\"sy\":-0.39239141788819104,\"sx\":1.0157021298747575},\n\t{\"slabel\":true,\"sy\":0.3120120296852688,\"sx\":2.040571734630943},\n\t{\"slabel\":false,\"sy\":0.3247240243855006,\"sx\":3.696035731787589e-2}\n\t],\n    \"clcClassifier\":\"QDA\"\n    }\n\n* The one-shot prediction endpoint is queried via GET query parameters; the `x` and `y` parameters are the query coordinates, e.g. : \n\n    `/model/v2/one-shot/?x=\u003cpoint_x\u003e\u0026y=\u003cpoint_y\u003e`\n\n* The batch endpoint is queried by passing the query points as a JSON object in the body of a POST request:\n\n    `/model/v1/batch/`\n\nEach query point in the batch is represented as a list of floating point numbers, for example:\n\n    POST http://${DOCKER_IP}:3000/model/v2/batch/\n    {\n      \"batch\": [[1.9747777403969031,0.1703482031671503],\n            [0.2268872897216034,0.9602596319569988],\n            [0.577768094821916,0.8049502627101064]]\n    }\n\nwhich will return\n\n    {\"prediction\":[true,false,false]}\n\nNB: since the internal model is restricted to classifying points in 2D, lists that have more or less than 2 elements will cause a parse error.\n\nThe current configuration can always be retrieved on the `GET /current-config/` endpoint\n\nAfterwards, the server can be queried in batch or one-shot mode just like with the v1 API on the corresponding endpoints :\n\n    POST model/v2/batch/\n\n    GET model/v2/one-shot/\n\n\n## Local testing\n\nThe server can also be built and tested as a regular Haskell application (i.e. without Docker):\n\n    $ stack build\n\n    $ stack exec -- pred-serv\n\n(NB: `docker.enable` should be set to `false` for local usage)\n\nThis will spin up a webserver at `\u003clocalhost\u003e:3000`.\n\nThe file path of the default training dataset can also be changed with a command line option, see the help screen :\n\n    $ stack exec -- pred-serv -h\n\n    Usage: pred-serv [-d|--dataset-path PATH]\n    pred-serv - a little prediction server\n\n    Available options:\n      -d,--dataset-path PATH   Path of the default training\n                               dataset (default: \"data/samples.csv\")\n      -h,--help                Show this help text\n\n\nThe unit tests are executed with `stack test`.\n\n# Building the HTML documentation\n\n\n    $ stack haddock\n\nthe path to the documentation index page can be found after the line `Updating Haddock index for local packages in` in the stack haddock log.\n\nApparently, this can only be run when `docker.enable` is set to `false` in stack.yaml . Once the documentation is built, the user can revert to `docker.enable = true` and build the docker images as explained above.\n\n\n# Project structure\n\n\n    |-- LICENSE\n    |-- Makefile\n    |-- README.md\n    |-- Setup.hs\n    |-- analysis\n    |   `-- plot_samples.R\n    |-- app\n    |   `-- Main.hs\n    |-- data\n    |   |-- model.csv\n    |   `-- samples.csv\n    |-- docker\n    |   |-- deploy\n    |   |   `-- Dockerfile\n    |   `-- dev\n    |       `-- Dockerfile\n    |-- pred-serv.cabal\n    |-- src\n    |   |-- Lib\n    |   |   |-- Math.hs\n    |   |   `-- Types.hs\n    |   `-- Lib.hs\n    |-- stack.yaml\n    `-- test\n        |-- LibSpec.hs\n        `-- Spec.hs\n\n`src/` is the project source library. The server implementation is in `app/Main.hs`.\n\n`test/` contains only unit tests for now (in `LibSpec.hs`).\n\n`data/` contains the default model parameters and a small labeled dataset.\n\n`docker/` contains the Dockerfiles for the development and deployment images. The statically-linked server binary meant to be deployed is copied in `docker/deploy`.\n\n`stack.yaml` and `pred-serv.cabal` are project files, containing dependency and configuration information.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focramz%2Fcmbnt-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Focramz%2Fcmbnt-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focramz%2Fcmbnt-test/lists"}