|
11 | 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12 | 12 | # See the License for the specific language governing permissions and
|
13 | 13 | # limitations under the License.
|
14 |
| - |
| 14 | +import json |
15 | 15 | import logging
|
16 | 16 | import warnings
|
17 | 17 | from datetime import datetime
|
|
23 | 23 | import yaml
|
24 | 24 | from colorama import Fore, Style
|
25 | 25 | from dateutil import parser
|
| 26 | +from pygments import formatters, highlight, lexers |
26 | 27 |
|
27 | 28 | from feast import flags, flags_helper, utils
|
28 | 29 | from feast.constants import DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT
|
@@ -758,5 +759,61 @@ def disable_alpha_features(ctx: click.Context):
|
758 | 759 | store.config.write_to_path(Path(repo_path))
|
759 | 760 |
|
760 | 761 |
|
| 762 | +@cli.command("validate") |
| 763 | +@click.option( |
| 764 | + "--feature-service", "-f", help="Specify a feature service name", |
| 765 | +) |
| 766 | +@click.option( |
| 767 | + "--reference", "-r", help="Specify a validation reference name", |
| 768 | +) |
| 769 | +@click.option( |
| 770 | + "--no-profile-cache", is_flag=True, help="Do not store cached profile in registry", |
| 771 | +) |
| 772 | +@click.argument("start_ts") |
| 773 | +@click.argument("end_ts") |
| 774 | +@click.pass_context |
| 775 | +def validate( |
| 776 | + ctx: click.Context, |
| 777 | + feature_service: str, |
| 778 | + reference: str, |
| 779 | + start_ts: str, |
| 780 | + end_ts: str, |
| 781 | + no_profile_cache, |
| 782 | +): |
| 783 | + """ |
| 784 | + Perform validation of logged features (produced by a given feature service) against provided reference. |
| 785 | +
|
| 786 | + START_TS and END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' |
| 787 | + """ |
| 788 | + repo = ctx.obj["CHDIR"] |
| 789 | + cli_check_repo(repo) |
| 790 | + store = FeatureStore(repo_path=str(repo)) |
| 791 | + |
| 792 | + feature_service = store.get_feature_service(name=feature_service) |
| 793 | + reference = store.get_validation_reference(reference) |
| 794 | + |
| 795 | + result = store.validate_logged_features( |
| 796 | + source=feature_service, |
| 797 | + reference=reference, |
| 798 | + start=datetime.fromisoformat(start_ts), |
| 799 | + end=datetime.fromisoformat(end_ts), |
| 800 | + throw_exception=False, |
| 801 | + cache_profile=not no_profile_cache, |
| 802 | + ) |
| 803 | + |
| 804 | + if not result: |
| 805 | + print(f"{Style.BRIGHT + Fore.GREEN}Validation successful!{Style.RESET_ALL}") |
| 806 | + return |
| 807 | + |
| 808 | + errors = [e.to_dict() for e in result.report.errors] |
| 809 | + formatted_json = json.dumps(errors, indent=4) |
| 810 | + colorful_json = highlight( |
| 811 | + formatted_json, lexers.JsonLexer(), formatters.TerminalFormatter() |
| 812 | + ) |
| 813 | + print(f"{Style.BRIGHT + Fore.RED}Validation failed!{Style.RESET_ALL}") |
| 814 | + print(colorful_json) |
| 815 | + exit(1) |
| 816 | + |
| 817 | + |
761 | 818 | if __name__ == "__main__":
|
762 | 819 | cli()
|
0 commit comments