{"id":22480160,"url":"https://github.com/findify/featury","last_synced_at":"2026-03-05T09:03:15.447Z","repository":{"id":40243834,"uuid":"364195197","full_name":"findify/featury","owner":"findify","description":"Friendly ML feature store","archived":false,"fork":false,"pushed_at":"2022-05-19T13:21:17.000Z","size":398,"stargazers_count":45,"open_issues_count":3,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-23T00:34:51.813Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/findify.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}},"created_at":"2021-05-04T08:51:27.000Z","updated_at":"2025-08-19T20:31:38.000Z","dependencies_parsed_at":"2022-09-06T17:22:56.644Z","dependency_job_id":null,"html_url":"https://github.com/findify/featury","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/findify/featury","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/findify%2Ffeatury","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/findify%2Ffeatury/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/findify%2Ffeatury/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/findify%2Ffeatury/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/findify","download_url":"https://codeload.github.com/findify/featury/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/findify%2Ffeatury/sbom","scorecard":{"id":400051,"data":{"date":"2025-08-11","repo":{"name":"github.com/findify/featury","commit":"cc96d4d284db4ed0652075f35aa4ceb1a50fdbb1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/findify/featury/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/findify/featury/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/findify/featury/ci.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T19:53:17.283Z","repository_id":40243834,"created_at":"2025-08-18T19:53:17.283Z","updated_at":"2025-08-18T19:53:17.283Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30117486,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T08:19:04.902Z","status":"ssl_error","status_checked_at":"2026-03-05T08:17:37.148Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":[],"created_at":"2024-12-06T15:19:56.995Z","updated_at":"2026-03-05T09:03:15.413Z","avatar_url":"https://github.com/findify.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Featury: An online ML feature store\n[![CI Status](https://github.com/findify/featury/workflows/CI/badge.svg)](https://github.com/findify/featury/actions)\n[![License: Apache 2](https://img.shields.io/badge/License-Apache2-green.svg)](https://opensource.org/licenses/Apache-2.0)\n![Last commit](https://img.shields.io/github/last-commit/findify/featury)\n![Last release](https://img.shields.io/github/release/findify/featury)\n\nFeatury is an end-to-end framework built to simplify typical scenarios of online-offline ML feature engineering:\n* Online API to serve the latest values of ML features.\n* Feature value changelog is tracked and persisted into an offline storage (HDFS or S3 bucket).\n* Historical ML feature values can be joined with training data offline in Apache Flink to do model training,\n  feature bootstrapping and offline evaluation.\n\nIt differs from existing solutions like Feast/Hopsworks in the following ways:\n* Featury not only handles get-set actions for feature values, but can do stateful processing:\n  * increments for counters and periodic counters\n  * string frequency sampling\n  * numerical stats estimation for median, average and percentiles.\n  * bounded lists and maps.\n* Platform-agnostic offline model training: feature value histories are plain CSV/JSON/Protobuf/Parquet\n  files, so you can use any tool like Spark/Flink/Pandas to do offline training.\n* DB-agnostic for online feature reads: can use Redis/Postgres/Cassandra for persistence.\n* Stateless and cloud-native: single jar file for local development, single k8s Deployment for production\n\n\n## Featury is not (only) a feature store\n\nThe problem solved by feature stores is typical for majority of production ML system deployments:\n* how can you be sure that feature computation is exactly the same while running ML inference online, \n  and training your model offline?\n* feature values drift in time, and while doing offline training, you may need to get access to a historical\n  values of the feature.\n* new features require bootstrapping, so you should be able not only to compute them now, but also for all historical\n  actions back in time\n* while doing online inference, you may need to access hundreds of features for hundreds of items with low latency\n\n![Data flow](docs/img/data_flow.svg)\n\n**Featury** tries to solve these problems by encapsulating feature value tracking task:\n* it logs all feature value changes, so for any feature you have full historical view of changes.\n* Write operations in **Featury** are extremely fast and happening in the background.\n* Feature values are eventually recomputed (like computing running median over a sampled reservoir) and exposed\n  in inference API.\n\n## Data formats\n\nFeatury \"ML features\" accept a set of operations as an input, for example:\n* counter accepts increments\n* periodic counter accepts timestamped increments\n* scalar accepts puts\n* ... etc\n\nThese operations are defined as [protobuf structures](https://github.com/findify/featury/blob/master/core/src/main/protobuf/featury.proto),\n so it listens for operations and applies them.\n\n## Components\n\nFeatury contains of multiple parts:\n1. Online API to serve feature values\n2. Online Flink-based data processing job, which accepts operations and modifies the feature values inside.\n3. Offline Flink-based historical processing job, which can bootstrap or rebuild feature values.\n4. Feature changelog files. Both offline and online jobs are emitting periodic updates to feature values, and the\n complete change history is written to a set of files (on S3, for example)\n\n## Example usage\n\n[Here is](https://github.com/findify/featury/blob/master/examples/src/main/scala/io/findify/featury/example) a small Featury example.\n\nThe example is basically doing the following:\n* defines feature configuration (so what we're going to compute)\n* pipes a set of sample events thru the online Featury job\n* joins sample clickthrough with the latest feature values\n\n## Stability and versioning\n\nFeatury originally was an internal project within [Findify](http://findify.io), built to simplify the complete ML \npipeline within the company. Being open-sourced in 2021, it's still used in production to serve workload for \nthousands merchants and tens of millions of monthly unique visitors.\n\nThe project is quite young, and maintains a [semantic versioning](https://semver.org/). \nWhile it's not yet reached v1.0, it has no guarantees on backwards-compatibility both for API and data formats.\n  \n## License\n\nFeatury is licensed under the Apache 2.0.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffindify%2Ffeatury","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffindify%2Ffeatury","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffindify%2Ffeatury/lists"}