1#  Licensed to Elasticsearch B.V. under one or more contributor
2#  license agreements. See the NOTICE file distributed with
3#  this work for additional information regarding copyright
4#  ownership. Elasticsearch B.V. licenses this file to you under
5#  the Apache License, Version 2.0 (the "License"); you may
6#  not use this file except in compliance with the License.
7#  You may obtain a copy of the License at
8#
9# 	http://www.apache.org/licenses/LICENSE-2.0
10#
11#  Unless required by applicable law or agreed to in writing,
12#  software distributed under the License is distributed on an
13#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14#  KIND, either express or implied.  See the License for the
15#  specific language governing permissions and limitations
16#  under the License.
17
18from ..utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
19
20
21class MlClient(NamespacedClient):
22    @query_params("from_", "size")
23    def get_filters(self, filter_id=None, params=None):
24        """
25
26        :arg filter_id: The ID of the filter to fetch
27        :arg from_: skips a number of filters
28        :arg size: specifies a max number of filters to get
29        """
30        return self.transport.perform_request(
31            "GET", _make_path("_xpack", "ml", "filters", filter_id), params=params
32        )
33
34    @query_params()
35    def get_datafeeds(self, datafeed_id=None, params=None):
36        """
37
38        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-datafeed.html>`_
39
40        :arg datafeed_id: The ID of the datafeeds to fetch
41        """
42        return self.transport.perform_request(
43            "GET", _make_path("_xpack", "ml", "datafeeds", datafeed_id), params=params
44        )
45
46    @query_params()
47    def get_datafeed_stats(self, datafeed_id=None, params=None):
48        """
49
50        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-datafeed-stats.html>`_
51
52        :arg datafeed_id: The ID of the datafeeds stats to fetch
53        """
54        return self.transport.perform_request(
55            "GET",
56            _make_path("_xpack", "ml", "datafeeds", datafeed_id, "_stats"),
57            params=params,
58        )
59
60    @query_params(
61        "anomaly_score",
62        "desc",
63        "end",
64        "exclude_interim",
65        "expand",
66        "from_",
67        "size",
68        "sort",
69        "start",
70    )
71    def get_buckets(self, job_id, timestamp=None, body=None, params=None):
72        """
73
74        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-bucket.html>`_
75
76        :arg job_id: ID of the job to get bucket results from
77        :arg timestamp: The timestamp of the desired single bucket result
78        :arg body: Bucket selection details if not provided in URI
79        :arg anomaly_score: Filter for the most anomalous buckets
80        :arg desc: Set the sort direction
81        :arg end: End time filter for buckets
82        :arg exclude_interim: Exclude interim results
83        :arg expand: Include anomaly records
84        :arg from_: skips a number of buckets
85        :arg size: specifies a max number of buckets to get
86        :arg sort: Sort buckets by a particular field
87        :arg start: Start time filter for buckets
88        """
89        if job_id in SKIP_IN_PATH:
90            raise ValueError("Empty value passed for a required argument 'job_id'.")
91        return self.transport.perform_request(
92            "GET",
93            _make_path(
94                "_xpack",
95                "ml",
96                "anomaly_detectors",
97                job_id,
98                "results",
99                "buckets",
100                timestamp,
101            ),
102            params=params,
103            body=body,
104        )
105
106    @query_params("reset_end", "reset_start")
107    def post_data(self, job_id, body, params=None):
108        """
109
110        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-post-data.html>`_
111
112        :arg job_id: The name of the job receiving the data
113        :arg body: The data to process
114        :arg reset_end: Optional parameter to specify the end of the bucket
115            resetting range
116        :arg reset_start: Optional parameter to specify the start of the bucket
117            resetting range
118        """
119        for param in (job_id, body):
120            if param in SKIP_IN_PATH:
121                raise ValueError("Empty value passed for a required argument.")
122        return self.transport.perform_request(
123            "POST",
124            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_data"),
125            params=params,
126            body=self.client._bulk_body(body),
127        )
128
129    @query_params("force", "timeout")
130    def stop_datafeed(self, datafeed_id, params=None):
131        """
132
133        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-stop-datafeed.html>`_
134
135        :arg datafeed_id: The ID of the datafeed to stop
136        :arg force: True if the datafeed should be forcefully stopped.
137        :arg timeout: Controls the time to wait until a datafeed has stopped.
138            Default to 20 seconds
139        """
140        if datafeed_id in SKIP_IN_PATH:
141            raise ValueError(
142                "Empty value passed for a required argument 'datafeed_id'."
143            )
144        return self.transport.perform_request(
145            "POST",
146            _make_path("_xpack", "ml", "datafeeds", datafeed_id, "_stop"),
147            params=params,
148        )
149
150    @query_params()
151    def get_jobs(self, job_id=None, params=None):
152        """
153
154        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-job.html>`_
155
156        :arg job_id: The ID of the jobs to fetch
157        """
158        return self.transport.perform_request(
159            "GET",
160            _make_path("_xpack", "ml", "anomaly_detectors", job_id),
161            params=params,
162        )
163
164    @query_params()
165    def delete_expired_data(self, params=None):
166        """"""
167        return self.transport.perform_request(
168            "DELETE", "/_xpack/ml/_delete_expired_data", params=params
169        )
170
171    @query_params()
172    def put_job(self, job_id, body, params=None):
173        """
174
175        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-put-job.html>`_
176
177        :arg job_id: The ID of the job to create
178        :arg body: The job
179        """
180        for param in (job_id, body):
181            if param in SKIP_IN_PATH:
182                raise ValueError("Empty value passed for a required argument.")
183        return self.transport.perform_request(
184            "PUT",
185            _make_path("_xpack", "ml", "anomaly_detectors", job_id),
186            params=params,
187            body=body,
188        )
189
190    @query_params()
191    def validate_detector(self, body, params=None):
192        """
193
194        :arg body: The detector
195        """
196        if body in SKIP_IN_PATH:
197            raise ValueError("Empty value passed for a required argument 'body'.")
198        return self.transport.perform_request(
199            "POST",
200            "/_xpack/ml/anomaly_detectors/_validate/detector",
201            params=params,
202            body=body,
203        )
204
205    @query_params("end", "start", "timeout")
206    def start_datafeed(self, datafeed_id, body=None, params=None):
207        """
208
209        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-start-datafeed.html>`_
210
211        :arg datafeed_id: The ID of the datafeed to start
212        :arg body: The start datafeed parameters
213        :arg end: The end time when the datafeed should stop. When not set, the
214            datafeed continues in real time
215        :arg start: The start time from where the datafeed should begin
216        :arg timeout: Controls the time to wait until a datafeed has started.
217            Default to 20 seconds
218        """
219        if datafeed_id in SKIP_IN_PATH:
220            raise ValueError(
221                "Empty value passed for a required argument 'datafeed_id'."
222            )
223        return self.transport.perform_request(
224            "POST",
225            _make_path("_xpack", "ml", "datafeeds", datafeed_id, "_start"),
226            params=params,
227            body=body,
228        )
229
230    @query_params(
231        "desc",
232        "end",
233        "exclude_interim",
234        "from_",
235        "record_score",
236        "size",
237        "sort",
238        "start",
239    )
240    def get_records(self, job_id, body=None, params=None):
241        """
242
243        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-record.html>`_
244
245        :arg job_id: None
246        :arg body: Record selection criteria
247        :arg desc: Set the sort direction
248        :arg end: End time filter for records
249        :arg exclude_interim: Exclude interim results
250        :arg from_: skips a number of records
251        :arg record_score:
252        :arg size: specifies a max number of records to get
253        :arg sort: Sort records by a particular field
254        :arg start: Start time filter for records
255        """
256        if job_id in SKIP_IN_PATH:
257            raise ValueError("Empty value passed for a required argument 'job_id'.")
258        return self.transport.perform_request(
259            "GET",
260            _make_path(
261                "_xpack", "ml", "anomaly_detectors", job_id, "results", "records"
262            ),
263            params=params,
264            body=body,
265        )
266
267    @query_params()
268    def update_job(self, job_id, body, params=None):
269        """
270
271        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-update-job.html>`_
272
273        :arg job_id: The ID of the job to create
274        :arg body: The job update settings
275        """
276        for param in (job_id, body):
277            if param in SKIP_IN_PATH:
278                raise ValueError("Empty value passed for a required argument.")
279        return self.transport.perform_request(
280            "POST",
281            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_update"),
282            params=params,
283            body=body,
284        )
285
286    @query_params()
287    def put_filter(self, filter_id, body, params=None):
288        """
289
290        :arg filter_id: The ID of the filter to create
291        :arg body: The filter details
292        """
293        for param in (filter_id, body):
294            if param in SKIP_IN_PATH:
295                raise ValueError("Empty value passed for a required argument.")
296        return self.transport.perform_request(
297            "PUT",
298            _make_path("_xpack", "ml", "filters", filter_id),
299            params=params,
300            body=body,
301        )
302
303    @query_params()
304    def update_datafeed(self, datafeed_id, body, params=None):
305        """
306
307        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-update-datafeed.html>`_
308
309        :arg datafeed_id: The ID of the datafeed to update
310        :arg body: The datafeed update settings
311        """
312        for param in (datafeed_id, body):
313            if param in SKIP_IN_PATH:
314                raise ValueError("Empty value passed for a required argument.")
315        return self.transport.perform_request(
316            "POST",
317            _make_path("_xpack", "ml", "datafeeds", datafeed_id, "_update"),
318            params=params,
319            body=body,
320        )
321
322    @query_params()
323    def preview_datafeed(self, datafeed_id, params=None):
324        """
325
326        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-preview-datafeed.html>`_
327
328        :arg datafeed_id: The ID of the datafeed to preview
329        """
330        if datafeed_id in SKIP_IN_PATH:
331            raise ValueError(
332                "Empty value passed for a required argument 'datafeed_id'."
333            )
334        return self.transport.perform_request(
335            "GET",
336            _make_path("_xpack", "ml", "datafeeds", datafeed_id, "_preview"),
337            params=params,
338        )
339
340    @query_params("advance_time", "calc_interim", "end", "skip_time", "start")
341    def flush_job(self, job_id, body=None, params=None):
342        """
343
344        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-flush-job.html>`_
345
346        :arg job_id: The name of the job to flush
347        :arg body: Flush parameters
348        :arg advance_time: Advances time to the given value generating results
349            and updating the model for the advanced interval
350        :arg calc_interim: Calculates interim results for the most recent bucket
351            or all buckets within the latency period
352        :arg end: When used in conjunction with calc_interim, specifies the
353            range of buckets on which to calculate interim results
354        :arg skip_time: Skips time to the given value without generating results
355            or updating the model for the skipped interval
356        :arg start: When used in conjunction with calc_interim, specifies the
357            range of buckets on which to calculate interim results
358        """
359        if job_id in SKIP_IN_PATH:
360            raise ValueError("Empty value passed for a required argument 'job_id'.")
361        return self.transport.perform_request(
362            "POST",
363            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_flush"),
364            params=params,
365            body=body,
366        )
367
368    @query_params("force", "timeout")
369    def close_job(self, job_id, params=None):
370        """
371
372        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-close-job.html>`_
373
374        :arg job_id: The name of the job to close
375        :arg force: True if the job should be forcefully closed
376        :arg timeout: Controls the time to wait until a job has closed. Default
377            to 30 minutes
378        """
379        if job_id in SKIP_IN_PATH:
380            raise ValueError("Empty value passed for a required argument 'job_id'.")
381        return self.transport.perform_request(
382            "POST",
383            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_close"),
384            params=params,
385        )
386
387    @query_params()
388    def open_job(self, job_id, params=None):
389        """
390
391        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-open-job.html>`_
392
393        :arg job_id: The ID of the job to open
394        """
395        if job_id in SKIP_IN_PATH:
396            raise ValueError("Empty value passed for a required argument 'job_id'.")
397        return self.transport.perform_request(
398            "POST",
399            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_open"),
400            params=params,
401        )
402
403    @query_params("force")
404    def delete_job(self, job_id, params=None):
405        """
406
407        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html>`_
408
409        :arg job_id: The ID of the job to delete
410        :arg force: True if the job should be forcefully deleted
411        """
412        if job_id in SKIP_IN_PATH:
413            raise ValueError("Empty value passed for a required argument 'job_id'.")
414        return self.transport.perform_request(
415            "DELETE",
416            _make_path("_xpack", "ml", "anomaly_detectors", job_id),
417            params=params,
418        )
419
420    @query_params("duration", "expires_in")
421    def forecast_job(self, job_id, params=None):
422        """
423
424        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-forecast.html>`_
425
426        :arg job_id: The name of the job to close
427        :arg duration: A period of time that indicates how far into the future to forecast
428        :arg expires_in: The period of time that forecast results are retained.
429        """
430        if job_id in SKIP_IN_PATH:
431            raise ValueError("Empty value passed for a required argument 'job_id'.")
432        return self.transport.perform_request(
433            "POST",
434            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_forecast"),
435            params=params,
436        )
437
438    @query_params()
439    def update_model_snapshot(self, job_id, snapshot_id, body, params=None):
440        """
441
442        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-update-snapshot.html>`_
443
444        :arg job_id: The ID of the job to fetch
445        :arg snapshot_id: The ID of the snapshot to update
446        :arg body: The model snapshot properties to update
447        """
448        for param in (job_id, snapshot_id, body):
449            if param in SKIP_IN_PATH:
450                raise ValueError("Empty value passed for a required argument.")
451        return self.transport.perform_request(
452            "POST",
453            _make_path(
454                "_xpack",
455                "ml",
456                "anomaly_detectors",
457                job_id,
458                "model_snapshots",
459                snapshot_id,
460                "_update",
461            ),
462            params=params,
463            body=body,
464        )
465
466    @query_params()
467    def delete_filter(self, filter_id, params=None):
468        """
469
470        :arg filter_id: The ID of the filter to delete
471        """
472        if filter_id in SKIP_IN_PATH:
473            raise ValueError("Empty value passed for a required argument 'filter_id'.")
474        return self.transport.perform_request(
475            "DELETE", _make_path("_xpack", "ml", "filters", filter_id), params=params
476        )
477
478    @query_params()
479    def validate(self, body, params=None):
480        """
481
482        :arg body: The job config
483        """
484        if body in SKIP_IN_PATH:
485            raise ValueError("Empty value passed for a required argument 'body'.")
486        return self.transport.perform_request(
487            "POST", "/_xpack/ml/anomaly_detectors/_validate", params=params, body=body
488        )
489
490    @query_params("from_", "size")
491    def get_categories(self, job_id, category_id=None, body=None, params=None):
492        """
493
494        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-category.html>`_
495
496        :arg job_id: The name of the job
497        :arg category_id: The identifier of the category definition of interest
498        :arg body: Category selection details if not provided in URI
499        :arg from_: skips a number of categories
500        :arg size: specifies a max number of categories to get
501        """
502        if job_id in SKIP_IN_PATH:
503            raise ValueError("Empty value passed for a required argument 'job_id'.")
504        return self.transport.perform_request(
505            "GET",
506            _make_path(
507                "_xpack",
508                "ml",
509                "anomaly_detectors",
510                job_id,
511                "results",
512                "categories",
513                category_id,
514            ),
515            params=params,
516            body=body,
517        )
518
519    @query_params(
520        "desc",
521        "end",
522        "exclude_interim",
523        "from_",
524        "influencer_score",
525        "size",
526        "sort",
527        "start",
528    )
529    def get_influencers(self, job_id, body=None, params=None):
530        """
531
532        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-influencer.html>`_
533
534        :arg job_id: None
535        :arg body: Influencer selection criteria
536        :arg desc: whether the results should be sorted in decending order
537        :arg end: end timestamp for the requested influencers
538        :arg exclude_interim: Exclude interim results
539        :arg from_: skips a number of influencers
540        :arg influencer_score: influencer score threshold for the requested
541            influencers
542        :arg size: specifies a max number of influencers to get
543        :arg sort: sort field for the requested influencers
544        :arg start: start timestamp for the requested influencers
545        """
546        if job_id in SKIP_IN_PATH:
547            raise ValueError("Empty value passed for a required argument 'job_id'.")
548        return self.transport.perform_request(
549            "GET",
550            _make_path(
551                "_xpack", "ml", "anomaly_detectors", job_id, "results", "influencers"
552            ),
553            params=params,
554            body=body,
555        )
556
557    @query_params()
558    def put_datafeed(self, datafeed_id, body, params=None):
559        """
560
561        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-put-datafeed.html>`_
562
563        :arg datafeed_id: The ID of the datafeed to create
564        :arg body: The datafeed config
565        """
566        for param in (datafeed_id, body):
567            if param in SKIP_IN_PATH:
568                raise ValueError("Empty value passed for a required argument.")
569        return self.transport.perform_request(
570            "PUT",
571            _make_path("_xpack", "ml", "datafeeds", datafeed_id),
572            params=params,
573            body=body,
574        )
575
576    @query_params("force")
577    def delete_datafeed(self, datafeed_id, params=None):
578        """
579
580        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-datafeed.html>`_
581
582        :arg datafeed_id: The ID of the datafeed to delete
583        :arg force: True if the datafeed should be forcefully deleted
584        """
585        if datafeed_id in SKIP_IN_PATH:
586            raise ValueError(
587                "Empty value passed for a required argument 'datafeed_id'."
588            )
589        return self.transport.perform_request(
590            "DELETE",
591            _make_path("_xpack", "ml", "datafeeds", datafeed_id),
592            params=params,
593        )
594
595    @query_params()
596    def get_job_stats(self, job_id=None, params=None):
597        """
598
599        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-job-stats.html>`_
600
601        :arg job_id: The ID of the jobs stats to fetch
602        """
603        return self.transport.perform_request(
604            "GET",
605            _make_path("_xpack", "ml", "anomaly_detectors", job_id, "_stats"),
606            params=params,
607        )
608
609    @query_params("delete_intervening_results")
610    def revert_model_snapshot(self, job_id, snapshot_id, body=None, params=None):
611        """
612
613        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-revert-snapshot.html>`_
614
615        :arg job_id: The ID of the job to fetch
616        :arg snapshot_id: The ID of the snapshot to revert to
617        :arg body: Reversion options
618        :arg delete_intervening_results: Should we reset the results back to the
619            time of the snapshot?
620        """
621        for param in (job_id, snapshot_id):
622            if param in SKIP_IN_PATH:
623                raise ValueError("Empty value passed for a required argument.")
624        return self.transport.perform_request(
625            "POST",
626            _make_path(
627                "_xpack",
628                "ml",
629                "anomaly_detectors",
630                job_id,
631                "model_snapshots",
632                snapshot_id,
633                "_revert",
634            ),
635            params=params,
636            body=body,
637        )
638
639    @query_params("desc", "end", "from_", "size", "sort", "start")
640    def get_model_snapshots(self, job_id, snapshot_id=None, body=None, params=None):
641        """
642
643        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-snapshot.html>`_
644
645        :arg job_id: The ID of the job to fetch
646        :arg snapshot_id: The ID of the snapshot to fetch
647        :arg body: Model snapshot selection criteria
648        :arg desc: True if the results should be sorted in descending order
649        :arg end: The filter 'end' query parameter
650        :arg from_: Skips a number of documents
651        :arg size: The default number of documents returned in queries as a
652            string.
653        :arg sort: Name of the field to sort on
654        :arg start: The filter 'start' query parameter
655        """
656        if job_id in SKIP_IN_PATH:
657            raise ValueError("Empty value passed for a required argument 'job_id'.")
658        return self.transport.perform_request(
659            "GET",
660            _make_path(
661                "_xpack",
662                "ml",
663                "anomaly_detectors",
664                job_id,
665                "model_snapshots",
666                snapshot_id,
667            ),
668            params=params,
669            body=body,
670        )
671
672    @query_params()
673    def delete_model_snapshot(self, job_id, snapshot_id, params=None):
674        """
675
676        `<http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-snapshot.html>`_
677
678        :arg job_id: The ID of the job to fetch
679        :arg snapshot_id: The ID of the snapshot to delete
680        """
681        for param in (job_id, snapshot_id):
682            if param in SKIP_IN_PATH:
683                raise ValueError("Empty value passed for a required argument.")
684        return self.transport.perform_request(
685            "DELETE",
686            _make_path(
687                "_xpack",
688                "ml",
689                "anomaly_detectors",
690                job_id,
691                "model_snapshots",
692                snapshot_id,
693            ),
694            params=params,
695        )
696