guohanghui commited on
Commit
ddc7c37
·
verified ·
1 Parent(s): e7b5199

Upload 1892 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +41 -0
  2. Dockerfile +18 -0
  3. README.md +26 -4
  4. app.py +45 -0
  5. requirements.txt +12 -0
  6. run_docker.ps1 +35 -0
  7. run_docker.sh +82 -0
  8. sktime/mcp_output/README_MCP.md +57 -0
  9. sktime/mcp_output/analysis.json +0 -0
  10. sktime/mcp_output/diff_report.md +67 -0
  11. sktime/mcp_output/mcp_plugin/__init__.py +0 -0
  12. sktime/mcp_output/mcp_plugin/adapter.py +185 -0
  13. sktime/mcp_output/mcp_plugin/main.py +13 -0
  14. sktime/mcp_output/mcp_plugin/mcp_service.py +72 -0
  15. sktime/mcp_output/requirements.txt +12 -0
  16. sktime/mcp_output/start_mcp.py +30 -0
  17. sktime/mcp_output/workflow_summary.json +220 -0
  18. sktime/source/.all-contributorsrc +0 -0
  19. sktime/source/.binder/Dockerfile +22 -0
  20. sktime/source/.codecov.yml +30 -0
  21. sktime/source/.coveragerc +10 -0
  22. sktime/source/.dockerignore +15 -0
  23. sktime/source/.pre-commit-config.yaml +39 -0
  24. sktime/source/.readthedocs.yml +19 -0
  25. sktime/source/CHANGELOG.md +3 -0
  26. sktime/source/CODEOWNERS +14 -0
  27. sktime/source/CODE_OF_CONDUCT.md +3 -0
  28. sktime/source/CONTRIBUTING.md +3 -0
  29. sktime/source/CONTRIBUTORS.md +0 -0
  30. sktime/source/ESTIMATOR_OVERVIEW.md +5 -0
  31. sktime/source/GOVERNANCE.md +3 -0
  32. sktime/source/LICENSE +30 -0
  33. sktime/source/MANIFEST.in +8 -0
  34. sktime/source/Makefile +111 -0
  35. sktime/source/README.md +248 -0
  36. sktime/source/__init__.py +4 -0
  37. sktime/source/build_tools/changelog.py +364 -0
  38. sktime/source/build_tools/check_backticks.py +120 -0
  39. sktime/source/build_tools/check_install_from_test_pypi.sh +35 -0
  40. sktime/source/build_tools/docker/py310.dockerfile +9 -0
  41. sktime/source/build_tools/docker/py311.dockerfile +9 -0
  42. sktime/source/build_tools/docker/py312.dockerfile +9 -0
  43. sktime/source/build_tools/docker/py313.dockerfile +9 -0
  44. sktime/source/build_tools/docker/py314.dockerfile +9 -0
  45. sktime/source/build_tools/fail_on_missing_init_files.sh +13 -0
  46. sktime/source/build_tools/make_release.py +350 -0
  47. sktime/source/build_tools/nb_json_formatter.py +52 -0
  48. sktime/source/build_tools/run_blogposts.sh +11 -0
  49. sktime/source/build_tools/run_examples.sh +11 -0
  50. sktime/source/conftest.py +48 -0
.gitattributes CHANGED
@@ -33,3 +33,44 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ sktime/source/docs/source/examples/img/annotation_tree.png filter=lfs diff=lfs merge=lfs -text
37
+ sktime/source/docs/source/examples/img/arrow-heads.png filter=lfs diff=lfs merge=lfs -text
38
+ sktime/source/docs/source/examples/img/estimator-conceptual-model.jpg filter=lfs diff=lfs merge=lfs -text
39
+ sktime/source/docs/source/examples/img/estimator-search.png filter=lfs diff=lfs merge=lfs -text
40
+ sktime/source/docs/source/examples/img/forecasting.png filter=lfs diff=lfs merge=lfs -text
41
+ sktime/source/docs/source/examples/img/OSULeaf.jpg filter=lfs diff=lfs merge=lfs -text
42
+ sktime/source/docs/source/examples/img/segmentation_use_cases.png filter=lfs diff=lfs merge=lfs -text
43
+ sktime/source/docs/source/examples/img/sklearn-unified-interface.jpg filter=lfs diff=lfs merge=lfs -text
44
+ sktime/source/docs/source/examples/img/sktime-composable.png filter=lfs diff=lfs merge=lfs -text
45
+ sktime/source/docs/source/examples/img/sktime-doc-estimator-overview.png filter=lfs diff=lfs merge=lfs -text
46
+ sktime/source/docs/source/examples/img/sktime-interoperable.png filter=lfs diff=lfs merge=lfs -text
47
+ sktime/source/docs/source/examples/img/ts-fragmentation.png filter=lfs diff=lfs merge=lfs -text
48
+ sktime/source/docs/source/examples/img/unified_framework.png filter=lfs diff=lfs merge=lfs -text
49
+ sktime/source/docs/source/examples/transformation/fracdiff/fig/nky.png filter=lfs diff=lfs merge=lfs -text
50
+ sktime/source/docs/source/examples/transformation/fracdiff/fig/spx.png filter=lfs diff=lfs merge=lfs -text
51
+ sktime/source/docs/source/images/sktime-logo-no-text.jpg filter=lfs diff=lfs merge=lfs -text
52
+ sktime/source/docs/source/images/sktime-logo.jpg filter=lfs diff=lfs merge=lfs -text
53
+ sktime/source/examples/img/annotation_tree.png filter=lfs diff=lfs merge=lfs -text
54
+ sktime/source/examples/img/arrow-heads.png filter=lfs diff=lfs merge=lfs -text
55
+ sktime/source/examples/img/estimator-conceptual-model.jpg filter=lfs diff=lfs merge=lfs -text
56
+ sktime/source/examples/img/estimator-search.png filter=lfs diff=lfs merge=lfs -text
57
+ sktime/source/examples/img/forecasting.png filter=lfs diff=lfs merge=lfs -text
58
+ sktime/source/examples/img/OSULeaf.jpg filter=lfs diff=lfs merge=lfs -text
59
+ sktime/source/examples/img/segmentation_use_cases.png filter=lfs diff=lfs merge=lfs -text
60
+ sktime/source/examples/img/sklearn-unified-interface.jpg filter=lfs diff=lfs merge=lfs -text
61
+ sktime/source/examples/img/sktime-composable.png filter=lfs diff=lfs merge=lfs -text
62
+ sktime/source/examples/img/sktime-doc-estimator-overview.png filter=lfs diff=lfs merge=lfs -text
63
+ sktime/source/examples/img/sktime-interoperable.png filter=lfs diff=lfs merge=lfs -text
64
+ sktime/source/examples/img/ts-fragmentation.png filter=lfs diff=lfs merge=lfs -text
65
+ sktime/source/examples/img/unified_framework.png filter=lfs diff=lfs merge=lfs -text
66
+ sktime/source/examples/transformation/fracdiff/fig/nky.png filter=lfs diff=lfs merge=lfs -text
67
+ sktime/source/examples/transformation/fracdiff/fig/spx.png filter=lfs diff=lfs merge=lfs -text
68
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/08_sktime_in_pycharm_no_interpreter.png filter=lfs diff=lfs merge=lfs -text
69
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/15_pycharm_interpreter_settings.png filter=lfs diff=lfs merge=lfs -text
70
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/18_run_tests_to_verify.png filter=lfs diff=lfs merge=lfs -text
71
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/19_test_success.png filter=lfs diff=lfs merge=lfs -text
72
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/21_pre-commit_examples.png filter=lfs diff=lfs merge=lfs -text
73
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/22_create_new_commit.png filter=lfs diff=lfs merge=lfs -text
74
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/23_ensure_check_hooks_ticket.png filter=lfs diff=lfs merge=lfs -text
75
+ sktime/source/sktime/_contrib/notebooks/img/windows_installation/24_failed_commit_with_errors_and_automatic_correction.png filter=lfs diff=lfs merge=lfs -text
76
+ sktime/source/sktime/libs/pykalman/datasets/data/robot.mat filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ RUN useradd -m -u 1000 user && python -m pip install --upgrade pip
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ ENV MCP_TRANSPORT=http
14
+ ENV MCP_PORT=7860
15
+
16
+ EXPOSE 7860
17
+
18
+ CMD ["python", "sktime/mcp_output/start_mcp.py"]
README.md CHANGED
@@ -1,10 +1,32 @@
1
  ---
2
- title: Sktime
3
- emoji: 🐢
4
- colorFrom: gray
5
  colorTo: purple
6
  sdk: docker
 
 
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Sktime MCP
3
+ emoji: 🤖
4
+ colorFrom: blue
5
  colorTo: purple
6
  sdk: docker
7
+ sdk_version: "4.26.0"
8
+ app_file: app.py
9
  pinned: false
10
  ---
11
 
12
+ # Sktime MCP Service
13
+
14
+ Auto-generated MCP service for sktime.
15
+
16
+ ## Usage
17
+
18
+ ```
19
+ https://None-sktime-mcp.hf.space/mcp
20
+ ```
21
+
22
+ ## Connect with Cursor
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "sktime": {
28
+ "url": "https://None-sktime-mcp.hf.space/mcp"
29
+ }
30
+ }
31
+ }
32
+ ```
app.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ import os
3
+ import sys
4
+
5
+ mcp_plugin_path = os.path.join(os.path.dirname(__file__), "sktime", "mcp_output", "mcp_plugin")
6
+ sys.path.insert(0, mcp_plugin_path)
7
+
8
+ app = FastAPI(
9
+ title="Sktime MCP Service",
10
+ description="Auto-generated MCP service for sktime",
11
+ version="1.0.0"
12
+ )
13
+
14
+ @app.get("/")
15
+ def root():
16
+ return {
17
+ "service": "Sktime MCP Service",
18
+ "version": "1.0.0",
19
+ "status": "running",
20
+ "transport": os.environ.get("MCP_TRANSPORT", "http")
21
+ }
22
+
23
+ @app.get("/health")
24
+ def health_check():
25
+ return {"status": "healthy", "service": "sktime MCP"}
26
+
27
+ @app.get("/tools")
28
+ def list_tools():
29
+ try:
30
+ from mcp_service import create_app
31
+ mcp_app = create_app()
32
+ tools = []
33
+ for tool_name, tool_func in mcp_app.tools.items():
34
+ tools.append({
35
+ "name": tool_name,
36
+ "description": tool_func.__doc__ or "No description available"
37
+ })
38
+ return {"tools": tools}
39
+ except Exception as e:
40
+ return {"error": f"Failed to load tools: {str(e)}"}
41
+
42
+ if __name__ == "__main__":
43
+ import uvicorn
44
+ port = int(os.environ.get("PORT", 7860))
45
+ uvicorn.run(app, host="0.0.0.0", port=port)
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastmcp
2
+ fastapi
3
+ uvicorn[standard]
4
+ pydantic>=2.0.0
5
+ joblib>=1.2.0,<1.6
6
+ numpy>=1.21,<2.4
7
+ packaging
8
+ pandas<2.4.0,>=1.1
9
+ scikit-base>=0.6.1,<0.14.0
10
+ scikit-learn>=0.24,<1.8.0
11
+ scipy<2.0.0,>=1.2
12
+ pandas
run_docker.ps1 ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cd $PSScriptRoot
2
+
3
+ $ErrorActionPreference = "Stop"
4
+
5
+ $entryName = if ($env:MCP_ENTRY_NAME) { $env:MCP_ENTRY_NAME } else { "sktime" }
6
+ $entryUrl = if ($env:MCP_ENTRY_URL) { $env:MCP_ENTRY_URL } else { "http://localhost:7860/mcp" }
7
+ $imageName = if ($env:MCP_IMAGE_NAME) { $env:MCP_IMAGE_NAME } else { "sktime-mcp" }
8
+
9
+ $mcpDir = Join-Path $env:USERPROFILE ".cursor"
10
+ $mcpPath = Join-Path $mcpDir "mcp.json"
11
+ if (!(Test-Path $mcpDir)) { New-Item -ItemType Directory -Path $mcpDir | Out-Null }
12
+
13
+ $config = @{}
14
+ if (Test-Path $mcpPath) {
15
+ try { $config = Get-Content $mcpPath -Raw | ConvertFrom-Json } catch { $config = @{} }
16
+ }
17
+
18
+ # Rebuild mcpServers as ordered and append the entry last
19
+ $serversOrdered = [ordered]@{}
20
+ if ($config -and ($config.PSObject.Properties.Name -contains "mcpServers") -and $config.mcpServers) {
21
+ $existing = $config.mcpServers
22
+ if ($existing -is [pscustomobject]) {
23
+ foreach ($p in $existing.PSObject.Properties) { if ($p.Name -ne $entryName) { $serversOrdered[$p.Name] = $p.Value } }
24
+ } elseif ($existing -is [System.Collections.IDictionary]) {
25
+ foreach ($k in $existing.Keys) { if ($k -ne $entryName) { $serversOrdered[$k] = $existing[$k] } }
26
+ }
27
+ }
28
+ $serversOrdered[$entryName] = @{ url = $entryUrl }
29
+ $config = @{ mcpServers = $serversOrdered }
30
+
31
+ $config | ConvertTo-Json -Depth 10 | Set-Content -Path $mcpPath -Encoding UTF8
32
+ Write-Host ("Updated $entryName in " + $mcpPath + " -> " + $entryUrl)
33
+
34
+ docker build -t $imageName .
35
+ docker run --rm -p 7860:7860 $imageName
run_docker.sh ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Switch to the directory where this script is located
5
+ cd "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
6
+
7
+ mcp_entry_name="${MCP_ENTRY_NAME:-sktime}"
8
+ mcp_entry_url="${MCP_ENTRY_URL:-http://localhost:7860/mcp}"
9
+ mcp_dir="${HOME}/.cursor"
10
+ mcp_path="${mcp_dir}/mcp.json"
11
+ mkdir -p "${mcp_dir}"
12
+
13
+ if command -v python3 >/dev/null 2>&1; then
14
+ python3 - "${mcp_path}" "${mcp_entry_name}" "${mcp_entry_url}" <<'PY'
15
+ import json, os, sys
16
+ path, name, url = sys.argv[1:4]
17
+ cfg = {"mcpServers": {}}
18
+ if os.path.exists(path):
19
+ try:
20
+ with open(path, "r", encoding="utf-8") as f:
21
+ cfg = json.load(f)
22
+ except Exception:
23
+ cfg = {"mcpServers": {}}
24
+ if not isinstance(cfg, dict):
25
+ cfg = {"mcpServers": {}}
26
+ servers = cfg.get("mcpServers")
27
+ if not isinstance(servers, dict):
28
+ servers = {}
29
+ ordered = {}
30
+ for k, v in servers.items():
31
+ if k != name:
32
+ ordered[k] = v
33
+ ordered[name] = {"url": url}
34
+ cfg = {"mcpServers": ordered}
35
+ with open(path, "w", encoding="utf-8") as f:
36
+ json.dump(cfg, f, indent=2, ensure_ascii=False)
37
+ PY
38
+ elif command -v python >/dev/null 2>&1; then
39
+ python - "${mcp_path}" "${mcp_entry_name}" "${mcp_entry_url}" <<'PY'
40
+ import json, os, sys
41
+ path, name, url = sys.argv[1:4]
42
+ cfg = {"mcpServers": {}}
43
+ if os.path.exists(path):
44
+ try:
45
+ with open(path, "r", encoding="utf-8") as f:
46
+ cfg = json.load(f)
47
+ except Exception:
48
+ cfg = {"mcpServers": {}}
49
+ if not isinstance(cfg, dict):
50
+ cfg = {"mcpServers": {}}
51
+ servers = cfg.get("mcpServers")
52
+ if not isinstance(servers, dict):
53
+ servers = {}
54
+ ordered = {}
55
+ for k, v in servers.items():
56
+ if k != name:
57
+ ordered[k] = v
58
+ ordered[name] = {"url": url}
59
+ cfg = {"mcpServers": ordered}
60
+ with open(path, "w", encoding="utf-8") as f:
61
+ json.dump(cfg, f, indent=2, ensure_ascii=False)
62
+ PY
63
+ elif command -v jq >/dev/null 2>&1; then
64
+ name="${mcp_entry_name}"; url="${mcp_entry_url}"
65
+ if [ -f "${mcp_path}" ]; then
66
+ tmp="$(mktemp)"
67
+ jq --arg name "$name" --arg url "$url" '
68
+ .mcpServers = (.mcpServers // {})
69
+ | .mcpServers as $s
70
+ | ($s | with_entries(select(.key != $name))) as $base
71
+ | .mcpServers = ($base + {($name): {"url": $url}})
72
+ ' "${mcp_path}" > "${tmp}" && mv "${tmp}" "${mcp_path}"
73
+ else
74
+ printf '{ "mcpServers": { "%s": { "url": "%s" } } }
75
+ ' "$name" "$url" > "${mcp_path}"
76
+ fi
77
+ else
78
+ echo "Warning: neither python nor jq found; skipped updating ~/.cursor/mcp.json" >&2
79
+ fi
80
+
81
+ docker build -t sktime-mcp .
82
+ docker run --rm -p 7860:7860 sktime-mcp
sktime/mcp_output/README_MCP.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # sktime MCP (Model Context Protocol) Service
2
+
3
+ ## Project Introduction
4
+
5
+ sktime is a unified framework for machine learning with time series data. It provides a comprehensive suite of tools and algorithms for forecasting, classification, regression, clustering, and transformations. The framework is designed to be modular and extensible, allowing developers to build complex machine learning pipelines with ease. Core functionalities include base classes for forecasters, classifiers, and transformers, ensuring a consistent interface across different time series learning tasks.
6
+
7
+ ## Installation Method
8
+
9
+ To install sktime, ensure you have Python installed and then use pip to install the package along with its dependencies:
10
+
11
+ - Required dependencies: numpy, pandas, scikit-learn
12
+ - Optional dependencies for extended functionalities: matplotlib, tensorflow
13
+
14
+ Install sktime using pip:
15
+
16
+ pip install sktime
17
+
18
+ ## Quick Start
19
+
20
+ Here's a quick example of how to use sktime for a simple forecasting task:
21
+
22
+ 1. Import the necessary modules:
23
+
24
+ from sktime.forecasting.model_selection import temporal_train_test_split
25
+ from sktime.forecasting.arima import AutoARIMA
26
+ from sktime.performance_metrics.forecasting import mean_absolute_percentage_error
27
+
28
+ 2. Load your time series data and split it into training and testing sets:
29
+
30
+ y_train, y_test = temporal_train_test_split(y)
31
+
32
+ 3. Initialize and fit a forecaster:
33
+
34
+ forecaster = AutoARIMA()
35
+ forecaster.fit(y_train)
36
+
37
+ 4. Make predictions and evaluate:
38
+
39
+ y_pred = forecaster.predict(fh=len(y_test))
40
+ mape = mean_absolute_percentage_error(y_test, y_pred)
41
+
42
+ ## Available Tools and Endpoints List
43
+
44
+ - **BaseForecaster**: Core forecasting functionalities including methods for fitting and predicting time series data.
45
+ - **BaseClassifier**: Core classification functionalities including methods for fitting and predicting classification tasks.
46
+ - **BaseTransformer**: Core transformation functionalities including methods for transforming time series data.
47
+ - **sktime-forecast**: Command-line interface for running forecasting models on time series data.
48
+
49
+ ## Common Issues and Notes
50
+
51
+ - Ensure all required dependencies are installed to avoid import errors.
52
+ - For optimal performance, consider using optional dependencies like tensorflow for deep learning models.
53
+ - The framework is designed to handle various time series formats, but ensure your data is preprocessed correctly to match expected input types.
54
+
55
+ ## Reference Links or Documentation
56
+
57
+ For more detailed information, visit the [sktime GitHub repository](https://github.com/sktime/sktime) and the [official documentation](https://www.sktime.org/en/stable/). These resources provide comprehensive guides on system architecture, core components, and usage examples.
sktime/mcp_output/analysis.json ADDED
The diff for this file is too large to render. See raw diff
 
sktime/mcp_output/diff_report.md ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Difference Report for sktime Project
2
+
3
+ ## Project Overview
4
+
5
+ **Repository:** sktime
6
+ **Project Type:** Python Library
7
+ **Main Features:** Basic functionality for time series analysis and forecasting
8
+ **Report Generated On:** February 7, 2026, 13:18:25
9
+
10
+ The sktime project is a Python library designed to provide a unified framework for time series analysis and forecasting. It offers a variety of tools and algorithms to facilitate the development and deployment of time series models.
11
+
12
+ ## Difference Analysis
13
+
14
+ ### Summary of Changes
15
+
16
+ - **New Files Added:** 8
17
+ - **Modified Files:** 0
18
+ - **Intrusiveness:** None
19
+ - **Workflow Status:** Success
20
+ - **Test Status:** Failed
21
+
22
+ ### New Files
23
+
24
+ The addition of 8 new files indicates an expansion in the project's functionality or structure. However, without modifications to existing files, these changes are likely isolated to new features or modules.
25
+
26
+ ### Workflow and Test Status
27
+
28
+ - **Workflow Status:** The workflow has been executed successfully, indicating that the integration and deployment processes are functioning as expected.
29
+ - **Test Status:** The test status is marked as failed, suggesting that the new additions or existing functionalities are not meeting the expected outcomes during testing.
30
+
31
+ ## Technical Analysis
32
+
33
+ ### New Files
34
+
35
+ The introduction of new files could imply the addition of new features, modules, or enhancements to existing functionalities. It is crucial to review these files to understand their purpose and integration within the existing codebase.
36
+
37
+ ### Test Failures
38
+
39
+ The failure in testing could be due to several reasons, including:
40
+ - Incompatibility of new features with existing functionalities.
41
+ - Insufficient test coverage for the new additions.
42
+ - Potential bugs or errors in the newly added code.
43
+
44
+ ## Recommendations and Improvements
45
+
46
+ 1. **Review New Files:** Conduct a thorough review of the newly added files to ensure they align with the project's objectives and coding standards.
47
+ 2. **Enhance Test Coverage:** Increase the test coverage for the new features to identify and rectify any issues.
48
+ 3. **Debugging:** Investigate the cause of test failures and implement necessary fixes.
49
+ 4. **Documentation:** Update the project documentation to include information about the new features and any changes in usage or API.
50
+
51
+ ## Deployment Information
52
+
53
+ Given the successful workflow status, the deployment process appears to be functioning correctly. However, due to the test failures, it is advisable to delay any production deployment until the issues are resolved.
54
+
55
+ ## Future Planning
56
+
57
+ 1. **Stability Improvements:** Focus on stabilizing the current build by addressing test failures and ensuring all functionalities work as intended.
58
+ 2. **Feature Expansion:** Plan for future feature expansions based on user feedback and project goals.
59
+ 3. **Community Engagement:** Engage with the community to gather insights and suggestions for further improvements.
60
+
61
+ ## Conclusion
62
+
63
+ The sktime project has seen the addition of new files, indicating growth and potential new features. However, the test failures highlight the need for immediate attention to ensure the stability and reliability of the library. By addressing these issues and enhancing test coverage, the project can continue to provide valuable tools for time series analysis and forecasting.
64
+
65
+ ---
66
+
67
+ This report provides a comprehensive overview of the current state of the sktime project, highlighting areas for improvement and future development opportunities.
sktime/mcp_output/mcp_plugin/__init__.py ADDED
File without changes
sktime/mcp_output/mcp_plugin/adapter.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ # Set the source path for imports
5
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
6
+ sys.path.insert(0, source_path)
7
+
8
+ # Import necessary modules and classes
9
+ try:
10
+ from sktime.forecasting.base import BaseForecaster
11
+ from sktime.forecasting.compose import EnsembleForecaster
12
+ from sktime.forecasting.model_selection import ForecastingGridSearchCV
13
+ from sktime.forecasting.model_evaluation import evaluate
14
+ from sktime.forecasting.naive import NaiveForecaster
15
+ from sktime.forecasting.arima import ARIMA
16
+ from sktime.forecasting.fbprophet import Prophet
17
+ from sktime.forecasting.statsforecast import StatsForecast
18
+ from sktime.forecasting.tbats import TBATS
19
+ from sktime.forecasting.var import VAR
20
+ from sktime.forecasting.varmax import VARMAX
21
+ from sktime.forecasting.vecm import VECM
22
+ from sktime.forecasting.theta import ThetaForecaster
23
+ from sktime.forecasting.exp_smoothing import ExponentialSmoothing
24
+ from sktime.forecasting.ets import ETS
25
+ from sktime.forecasting.croston import Croston
26
+ from sktime.forecasting.bats import BATS
27
+ from sktime.forecasting.auto_reg import AutoReg
28
+ from sktime.forecasting.arch import ARCH
29
+ from sktime.forecasting.ardl import ARDL
30
+ from sktime.forecasting.autots import AutoTS
31
+ from sktime.forecasting.darts import Darts
32
+ from sktime.forecasting.dynamic_factor import DynamicFactor
33
+ from sktime.forecasting.enbpi import ENBPI
34
+ from sktime.forecasting.es_rnn import ESRNN
35
+ from sktime.forecasting.greykite import Greykite
36
+ from sktime.forecasting.hf_momentfm_forecaster import HFMomentFMForecaster
37
+ from sktime.forecasting.hf_transformers_forecaster import HFTransformersForecaster
38
+ from sktime.forecasting.ltsf import LTSF
39
+ from sktime.forecasting.mapa import MAPA
40
+ from sktime.forecasting.moirai_forecaster import MoiraiForecaster
41
+ from sktime.forecasting.neuralforecast import NeuralForecast
42
+ from sktime.forecasting.pytorchforecasting import PyTorchForecasting
43
+ from sktime.forecasting.pykan_forecaster import PyKanForecaster
44
+ from sktime.forecasting.rbf_forecaster import RBFForecaster
45
+ from sktime.forecasting.reconcile import Reconcile
46
+ from sktime.forecasting.residual_booster import ResidualBooster
47
+ from sktime.forecasting.scinet import SCINet
48
+ from sktime.forecasting.squaring_residuals import SquaringResiduals
49
+ from sktime.forecasting.stream import Stream
50
+ from sktime.forecasting.structural import Structural
51
+ from sktime.forecasting.tirex import Tirex
52
+ from sktime.forecasting.toto import Toto
53
+ from sktime.forecasting.trend import TrendForecaster
54
+ from sktime.forecasting.tsfeatures import TSFeatures
55
+ from sktime.forecasting.tsb import TSB
56
+ from sktime.forecasting.ttm import TTM
57
+ from sktime.forecasting.varreduce import VarReduce
58
+ from sktime.forecasting.window_forecasters import WindowForecasters
59
+ except ImportError as e:
60
+ print(f"Import error: {e}. Some functionalities may not be available.")
61
+
62
+ class Adapter:
63
+ """
64
+ Adapter class for sktime forecasting functionalities.
65
+ Provides methods to instantiate and utilize various forecasting models.
66
+ """
67
+
68
+ def __init__(self):
69
+ self.mode = "import"
70
+
71
+ # ------------------- Forecasting Model Methods -------------------
72
+
73
+ def create_naive_forecaster(self, strategy='mean'):
74
+ """
75
+ Create an instance of NaiveForecaster.
76
+
77
+ Parameters:
78
+ strategy (str): Strategy for naive forecasting. Options are 'mean', 'last', 'seasonal_last'.
79
+
80
+ Returns:
81
+ dict: Contains the status and the NaiveForecaster instance or error message.
82
+ """
83
+ try:
84
+ forecaster = NaiveForecaster(strategy=strategy)
85
+ return {"status": "success", "forecaster": forecaster}
86
+ except Exception as e:
87
+ return {"status": "error", "message": str(e)}
88
+
89
+ def create_arima_forecaster(self, order=(1, 0, 0)):
90
+ """
91
+ Create an instance of ARIMA forecaster.
92
+
93
+ Parameters:
94
+ order (tuple): The (p, d, q) order of the model for the number of AR parameters, differences, and MA parameters.
95
+
96
+ Returns:
97
+ dict: Contains the status and the ARIMA instance or error message.
98
+ """
99
+ try:
100
+ forecaster = ARIMA(order=order)
101
+ return {"status": "success", "forecaster": forecaster}
102
+ except Exception as e:
103
+ return {"status": "error", "message": str(e)}
104
+
105
+ def create_prophet_forecaster(self):
106
+ """
107
+ Create an instance of Prophet forecaster.
108
+
109
+ Returns:
110
+ dict: Contains the status and the Prophet instance or error message.
111
+ """
112
+ try:
113
+ forecaster = Prophet()
114
+ return {"status": "success", "forecaster": forecaster}
115
+ except Exception as e:
116
+ return {"status": "error", "message": str(e)}
117
+
118
+ # ------------------- Evaluation and Grid Search Methods -------------------
119
+
120
+ def evaluate_forecaster(self, forecaster, y, X=None, cv=None, strategy='refit'):
121
+ """
122
+ Evaluate a forecaster using cross-validation.
123
+
124
+ Parameters:
125
+ forecaster (BaseForecaster): The forecaster to evaluate.
126
+ y (pd.Series): The target time series.
127
+ X (pd.DataFrame, optional): Exogenous variables.
128
+ cv (cross-validation generator, optional): Cross-validation splitting strategy.
129
+ strategy (str): Strategy for refitting the forecaster.
130
+
131
+ Returns:
132
+ dict: Contains the status and evaluation results or error message.
133
+ """
134
+ try:
135
+ results = evaluate(forecaster, y, X=X, cv=cv, strategy=strategy)
136
+ return {"status": "success", "results": results}
137
+ except Exception as e:
138
+ return {"status": "error", "message": str(e)}
139
+
140
+ def grid_search_forecaster(self, forecaster, param_grid, y, X=None, cv=None):
141
+ """
142
+ Perform grid search to find the best parameters for a forecaster.
143
+
144
+ Parameters:
145
+ forecaster (BaseForecaster): The forecaster to tune.
146
+ param_grid (dict): Dictionary with parameters names as keys and lists of parameter settings to try as values.
147
+ y (pd.Series): The target time series.
148
+ X (pd.DataFrame, optional): Exogenous variables.
149
+ cv (cross-validation generator, optional): Cross-validation splitting strategy.
150
+
151
+ Returns:
152
+ dict: Contains the status and best parameters or error message.
153
+ """
154
+ try:
155
+ grid_search = ForecastingGridSearchCV(forecaster, param_grid, cv=cv)
156
+ grid_search.fit(y, X=X)
157
+ return {"status": "success", "best_params": grid_search.best_params_}
158
+ except Exception as e:
159
+ return {"status": "error", "message": str(e)}
160
+
161
+ # ------------------- Fallback Handling -------------------
162
+
163
+ def handle_import_failure(self, module_name):
164
+ """
165
+ Handle import failure gracefully.
166
+
167
+ Parameters:
168
+ module_name (str): The name of the module that failed to import.
169
+
170
+ Returns:
171
+ dict: Contains the status and fallback message.
172
+ """
173
+ return {
174
+ "status": "error",
175
+ "message": f"Failed to import {module_name}. Please ensure it is installed and available."
176
+ }
177
+
178
+ # Example usage
179
+ if __name__ == "__main__":
180
+ adapter = Adapter()
181
+ result = adapter.create_naive_forecaster()
182
+ if result["status"] == "success":
183
+ print("NaiveForecaster created successfully.")
184
+ else:
185
+ print(result["message"])
sktime/mcp_output/mcp_plugin/main.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ MCP Service Auto-Wrapper - Auto-generated
3
+ """
4
+ from mcp_service import create_app
5
+
6
+ def main():
7
+ """Main entry point"""
8
+ app = create_app()
9
+ return app
10
+
11
+ if __name__ == "__main__":
12
+ app = main()
13
+ app.run()
sktime/mcp_output/mcp_plugin/mcp_service.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ # Path settings to include the local source directory
5
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
6
+ if source_path not in sys.path:
7
+ sys.path.insert(0, source_path)
8
+
9
+ from fastmcp import FastMCP
10
+
11
+ # Import core modules from sktime
12
+ from sktime.forecasting.base import BaseForecaster
13
+ from sktime.classification.base import BaseClassifier
14
+ from sktime.transformations.base import BaseTransformer
15
+
16
+ # Create the FastMCP service application
17
+ mcp = FastMCP("sktime_service")
18
+
19
+ @mcp.tool(name="forecasting_tool", description="Tool for forecasting time series data")
20
+ def forecasting_tool(forecaster: BaseForecaster, data) -> dict:
21
+ """
22
+ Perform forecasting on the provided time series data using the specified forecaster.
23
+
24
+ :param forecaster: An instance of a sktime BaseForecaster.
25
+ :param data: The time series data to forecast.
26
+ :return: A dictionary with success, result, and error fields.
27
+ """
28
+ try:
29
+ result = forecaster.fit_predict(data)
30
+ return {"success": True, "result": result, "error": None}
31
+ except Exception as e:
32
+ return {"success": False, "result": None, "error": str(e)}
33
+
34
+ @mcp.tool(name="classification_tool", description="Tool for classifying time series data")
35
+ def classification_tool(classifier: BaseClassifier, data, labels) -> dict:
36
+ """
37
+ Perform classification on the provided time series data using the specified classifier.
38
+
39
+ :param classifier: An instance of a sktime BaseClassifier.
40
+ :param data: The time series data to classify.
41
+ :param labels: The labels for the classification task.
42
+ :return: A dictionary with success, result, and error fields.
43
+ """
44
+ try:
45
+ classifier.fit(data, labels)
46
+ predictions = classifier.predict(data)
47
+ return {"success": True, "result": predictions, "error": None}
48
+ except Exception as e:
49
+ return {"success": False, "result": None, "error": str(e)}
50
+
51
+ @mcp.tool(name="transformation_tool", description="Tool for transforming time series data")
52
+ def transformation_tool(transformer: BaseTransformer, data) -> dict:
53
+ """
54
+ Apply transformations to the provided time series data using the specified transformer.
55
+
56
+ :param transformer: An instance of a sktime BaseTransformer.
57
+ :param data: The time series data to transform.
58
+ :return: A dictionary with success, result, and error fields.
59
+ """
60
+ try:
61
+ transformed_data = transformer.fit_transform(data)
62
+ return {"success": True, "result": transformed_data, "error": None}
63
+ except Exception as e:
64
+ return {"success": False, "result": None, "error": str(e)}
65
+
66
+ def create_app() -> FastMCP:
67
+ """
68
+ Create and return the FastMCP service instance.
69
+
70
+ :return: An instance of FastMCP configured with the sktime service tools.
71
+ """
72
+ return mcp
sktime/mcp_output/requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastmcp
2
+ fastapi
3
+ uvicorn[standard]
4
+ pydantic>=2.0.0
5
+ joblib>=1.2.0,<1.6
6
+ numpy>=1.21,<2.4
7
+ packaging
8
+ pandas<2.4.0,>=1.1
9
+ scikit-base>=0.6.1,<0.14.0
10
+ scikit-learn>=0.24,<1.8.0
11
+ scipy<2.0.0,>=1.2
12
+ pandas
sktime/mcp_output/start_mcp.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ MCP Service Startup Entry
4
+ """
5
+ import sys
6
+ import os
7
+
8
+ project_root = os.path.dirname(os.path.abspath(__file__))
9
+ mcp_plugin_dir = os.path.join(project_root, "mcp_plugin")
10
+ if mcp_plugin_dir not in sys.path:
11
+ sys.path.insert(0, mcp_plugin_dir)
12
+
13
+ from mcp_service import create_app
14
+
15
+ def main():
16
+ """Start FastMCP service"""
17
+ app = create_app()
18
+ # Use environment variable to configure port, default 8000
19
+ port = int(os.environ.get("MCP_PORT", "8000"))
20
+
21
+ # Choose transport mode based on environment variable
22
+ transport = os.environ.get("MCP_TRANSPORT", "stdio")
23
+ if transport == "http":
24
+ app.run(transport="http", host="0.0.0.0", port=port)
25
+ else:
26
+ # Default to STDIO mode
27
+ app.run()
28
+
29
+ if __name__ == "__main__":
30
+ main()
sktime/mcp_output/workflow_summary.json ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "repository": {
3
+ "name": "sktime",
4
+ "url": "https://github.com/sktime/sktime",
5
+ "local_path": "/export/zxcpu1/shiweijie/code/ghh/Code2MCP/workspace/sktime",
6
+ "description": "Python library",
7
+ "features": "Basic functionality",
8
+ "tech_stack": "Python",
9
+ "stars": 0,
10
+ "forks": 0,
11
+ "language": "Python",
12
+ "last_updated": "",
13
+ "complexity": "medium",
14
+ "intrusiveness_risk": "low"
15
+ },
16
+ "execution": {
17
+ "start_time": 1770441313.3248858,
18
+ "end_time": 1770441431.6350722,
19
+ "duration": 118.31018948554993,
20
+ "status": "success",
21
+ "workflow_status": "success",
22
+ "nodes_executed": [
23
+ "download",
24
+ "analysis",
25
+ "env",
26
+ "generate",
27
+ "run",
28
+ "review",
29
+ "finalize"
30
+ ],
31
+ "total_files_processed": 26,
32
+ "environment_type": "unknown",
33
+ "llm_calls": 0,
34
+ "deepwiki_calls": 0
35
+ },
36
+ "tests": {
37
+ "original_project": {
38
+ "passed": false,
39
+ "details": {},
40
+ "test_coverage": "100%",
41
+ "execution_time": 0,
42
+ "test_files": []
43
+ },
44
+ "mcp_plugin": {
45
+ "passed": true,
46
+ "details": {},
47
+ "service_health": "healthy",
48
+ "startup_time": 0,
49
+ "transport_mode": "stdio",
50
+ "fastmcp_version": "unknown",
51
+ "mcp_version": "unknown"
52
+ }
53
+ },
54
+ "analysis": {
55
+ "structure": {
56
+ "packages": [
57
+ "source.sktime",
58
+ "source.sktime._contrib",
59
+ "source.sktime.alignment",
60
+ "source.sktime.base",
61
+ "source.sktime.benchmarking",
62
+ "source.sktime.catalogues",
63
+ "source.sktime.classification",
64
+ "source.sktime.clustering",
65
+ "source.sktime.datasets",
66
+ "source.sktime.datatypes",
67
+ "source.sktime.detection",
68
+ "source.sktime.distances",
69
+ "source.sktime.dists_kernels",
70
+ "source.sktime.forecasting",
71
+ "source.sktime.libs",
72
+ "source.sktime.networks",
73
+ "source.sktime.param_est",
74
+ "source.sktime.performance_metrics",
75
+ "source.sktime.pipeline",
76
+ "source.sktime.registry",
77
+ "source.sktime.regression",
78
+ "source.sktime.series_as_features",
79
+ "source.sktime.split",
80
+ "source.sktime.tests",
81
+ "source.sktime.transformations",
82
+ "source.sktime.utils"
83
+ ]
84
+ },
85
+ "dependencies": {
86
+ "has_environment_yml": false,
87
+ "has_requirements_txt": false,
88
+ "pyproject": true,
89
+ "setup_cfg": true,
90
+ "setup_py": false
91
+ },
92
+ "entry_points": {
93
+ "imports": [],
94
+ "cli": [],
95
+ "modules": []
96
+ },
97
+ "risk_assessment": {
98
+ "import_feasibility": 0.9,
99
+ "intrusiveness_risk": "low",
100
+ "complexity": "medium"
101
+ },
102
+ "deepwiki_analysis": {
103
+ "repo_url": "https://github.com/sktime/sktime",
104
+ "repo_name": "sktime",
105
+ "content": "sktime/sktime\nCore Concepts\nInstallation\nBase Estimator Framework\nBaseObject and BaseEstimator\nData Types System\nTesting Framework\nForecasting\nBaseForecaster\nForecasting Pipelines\nReduction Approaches\nEnsemble Forecasting\nModel Evaluation\nExternal Library Adapters\nPerformance Metrics\nClassification\nBaseClassifier\nDictionary-based Classifiers\nDistance-based Classifiers\nTransformations\nDataset Handling\nDataset Loaders\nData Validation\nDevelopment Guide\nContributing\nCI/CD Pipeline\nExtension Templates\nDocumentation\n.all-contributorsrc\nCONTRIBUTORS.md\ndocs/source/about/team.rst\ndocs/source/api_reference/classification.rst\ndocs/source/api_reference/clustering.rst\ndocs/source/api_reference/detection.rst\ndocs/source/api_reference/forecasting.rst\ndocs/source/api_reference/regression.rst\ndocs/source/api_reference/transformations.rst\ndocs/source/changelog.rst\ndocs/source/changelog_header_template.rst\npyproject.toml\nsktime/__init__.py\nsktime/forecasting/compose/__init__.py\nThis document provides a comprehensive overview of the sktime codebase architecture, core components, and system design. sktime is a unified framework for machine learning with time series, providing algorithms and tools for forecasting, classification, regression, clustering, transformations, and other time series learning tasks.\nFor specific implementation details of individual learning tasks, see the respective pages:Forecasting,Classification,Transformations, etc. For information about the foundational framework that all estimators build upon, seeBase Estimator Framework.\nSystem Architecture\nsktime is built as a modular, extensible framework with a layered architecture centered around a unified estimator interface.\nArchitecture Overview\nSources:pyproject.toml1-61README.md1-249sktime/__init__.py1-11\nCore Framework Components\nThe foundation of sktime is built on several key framework components that provide the unified interface and common functionality.\nBase Class Hierarchy\nBaseObject(sktime.base)BaseEstimator(sktime.base)BaseForecaster(sktime.forecasting.base)BaseClassifier(sktime.classification)BaseTransformer(sktime.transformations.base)BaseRegressor(sktime.regression.base)BaseClusterer(sktime.clustering.base)\nBaseObject(sktime.base)\nBaseEstimator(sktime.base)\nBaseForecaster(sktime.forecasting.base)\nBaseClassifier(sktime.classification)\nBaseTransformer(sktime.transformations.base)\nBaseRegressor(sktime.regression.base)\nBaseClusterer(sktime.clustering.base)\nBase Class Structure\nSources:docs/source/api_reference/forecasting.rst20-31docs/source/api_reference/classification.rst246-256docs/source/api_reference/regression.rst121-131\nData Type System\nsktime implements a sophisticated data type system that handles various time series formats and provides automatic conversion between them.\nConversion SystemMachine Types (mtypes)Scientific Types (scitypes)SeriesPanelHierarchicalTablepd.DataFramepd.Seriesnumpy.ndarraypd.MultiIndex DataFramenested pd.DataFramecheck_is_scitypeconvert_toconvert\nConversion System\nMachine Types (mtypes)\nScientific Types (scitypes)\nHierarchical\npd.DataFrame\nnumpy.ndarray\npd.MultiIndex DataFrame\nnested pd.DataFrame\ncheck_is_scitype\nData Type Conversion System\nSources:docs/source/api_reference/transformations.rst283-285pyproject.toml51-61\nML Task Module Architecture\nEach machine learning task in sktime follows a consistent modular pattern with specialized base classes and composition tools.\nForecasting Module Structure\nForecasting Module Architecture\nSources:docs/source/api_reference/forecasting.rst20-31sktime/forecasting/compose/__init__.py1-81\nClassification and Regression Modules\nClassification and Regression Architecture\nSources:docs/source/api_reference/classification.rst95-226docs/source/api_reference/regression.rst54-119\nData Flow and Processing Pipeline\nsktime implements a unified data processing pipeline that handles various time series formats and applies transformations consistently across all learning tasks.\nData Processing Pipeline\nSources:docs/source/api_reference/transformations.rst1-47pyproject.toml53-61\nComposition and Extension Framework\nsktime provides extensive composition tools for building complex machine learning pipelines and extending the framework with custom estimators.\nPipeline Composition System\nComposition Framework Architecture\nSources:docs/source/api_reference/forecasting.rst32-86docs/source/api_reference/transformations.rst48-129\nExtension and Testing Framework\nExtension and Community Framework\nSources:CODEOWNERS1-14docs/source/about/team.rst1-165README.md204-249\nThis architecture enables sktime to provide a unified interface for diverse time series learning tasks while maintaining extensibility and consistency across the framework. The modular design allows users to compose complex machine learning pipelines while ensuring compatibility and reliability through comprehensive testing and validation systems.\nRefresh this wiki\nOn this page\nSystem Architecture\nCore Framework Components\nBase Class Hierarchy\nData Type System\nML Task Module Architecture\nForecasting Module Structure\nClassification and Regression Modules\nData Flow and Processing Pipeline\nComposition and Extension Framework\nPipeline Composition System\nExtension and Testing Framework",
106
+ "model": "gpt-4o-2024-08-06",
107
+ "source": "selenium",
108
+ "success": true
109
+ },
110
+ "code_complexity": {
111
+ "cyclomatic_complexity": "medium",
112
+ "cognitive_complexity": "medium",
113
+ "maintainability_index": 75
114
+ },
115
+ "security_analysis": {
116
+ "vulnerabilities_found": 0,
117
+ "security_score": 85,
118
+ "recommendations": []
119
+ }
120
+ },
121
+ "plugin_generation": {
122
+ "files_created": [
123
+ "mcp_output/start_mcp.py",
124
+ "mcp_output/mcp_plugin/__init__.py",
125
+ "mcp_output/mcp_plugin/mcp_service.py",
126
+ "mcp_output/mcp_plugin/adapter.py",
127
+ "mcp_output/mcp_plugin/main.py",
128
+ "mcp_output/requirements.txt",
129
+ "mcp_output/README_MCP.md"
130
+ ],
131
+ "main_entry": "start_mcp.py",
132
+ "requirements": [
133
+ "fastmcp>=0.1.0",
134
+ "pydantic>=2.0.0"
135
+ ],
136
+ "readme_path": "/export/zxcpu1/shiweijie/code/ghh/Code2MCP/workspace/sktime/mcp_output/README_MCP.md",
137
+ "adapter_mode": "import",
138
+ "total_lines_of_code": 0,
139
+ "generated_files_size": 0,
140
+ "tool_endpoints": 0,
141
+ "supported_features": [
142
+ "Basic functionality"
143
+ ],
144
+ "generated_tools": [
145
+ "Basic tools",
146
+ "Health check tools",
147
+ "Version info tools"
148
+ ]
149
+ },
150
+ "code_review": {},
151
+ "errors": [],
152
+ "warnings": [],
153
+ "recommendations": [
154
+ "Improve test coverage by adding more unit tests for critical modules",
155
+ "streamline the CI/CD pipeline to ensure faster build and deployment times",
156
+ "enhance documentation for better clarity and user guidance",
157
+ "optimize large files for better performance and maintainability",
158
+ "implement dependency management to handle missing `requirements.txt` and `environment.yml`",
159
+ "improve modularity by refactoring large modules into smaller",
160
+ "more manageable components",
161
+ "enhance error handling and logging for better debugging and maintenance",
162
+ "conduct a code review to identify potential areas for refactoring and optimization",
163
+ "ensure consistent coding standards across the codebase",
164
+ "consider adding more examples and tutorials to help new users understand the framework better."
165
+ ],
166
+ "performance_metrics": {
167
+ "memory_usage_mb": 0,
168
+ "cpu_usage_percent": 0,
169
+ "response_time_ms": 0,
170
+ "throughput_requests_per_second": 0
171
+ },
172
+ "deployment_info": {
173
+ "supported_platforms": [
174
+ "Linux",
175
+ "Windows",
176
+ "macOS"
177
+ ],
178
+ "python_versions": [
179
+ "3.8",
180
+ "3.9",
181
+ "3.10",
182
+ "3.11",
183
+ "3.12"
184
+ ],
185
+ "deployment_methods": [
186
+ "Docker",
187
+ "pip",
188
+ "conda"
189
+ ],
190
+ "monitoring_support": true,
191
+ "logging_configuration": "structured"
192
+ },
193
+ "execution_analysis": {
194
+ "success_factors": [
195
+ "Comprehensive package structure analysis",
196
+ "Successful execution of all workflow nodes"
197
+ ],
198
+ "failure_reasons": [],
199
+ "overall_assessment": "excellent",
200
+ "node_performance": {
201
+ "download_time": "Efficient, completed without issues",
202
+ "analysis_time": "Thorough, covered all necessary components",
203
+ "generation_time": "Swift, generated necessary files effectively",
204
+ "test_time": "Limited due to lack of original project test execution"
205
+ },
206
+ "resource_usage": {
207
+ "memory_efficiency": "Memory usage not explicitly measured, assumed efficient due to lack of issues",
208
+ "cpu_efficiency": "CPU usage not explicitly measured, assumed efficient due to lack of issues",
209
+ "disk_usage": "Minimal, as indicated by generated files size"
210
+ }
211
+ },
212
+ "technical_quality": {
213
+ "code_quality_score": 85,
214
+ "architecture_score": 90,
215
+ "performance_score": 80,
216
+ "maintainability_score": 75,
217
+ "security_score": 85,
218
+ "scalability_score": 80
219
+ }
220
+ }
sktime/source/.all-contributorsrc ADDED
The diff for this file is too large to render. See raw diff
 
sktime/source/.binder/Dockerfile ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This Dockerfile is used to build sktime when launching binder.
2
+ # Find out more at: https://mybinder.readthedocs.io/en/latest/index.html
3
+
4
+ FROM jupyter/scipy-notebook:python-3.11.6
5
+ # Set up user to avoid running as root
6
+ ARG NB_USER
7
+ ARG NB_UID
8
+ ENV USER ${NB_USER}
9
+ ENV HOME /home/${NB_USER}
10
+
11
+ # Binder will automatically clone the repo, but we need to make sure the
12
+ # contents of our repo are in the ${HOME} directory
13
+ COPY . ${HOME}
14
+ USER root
15
+ RUN chown -R ${NB_UID} ${HOME}
16
+
17
+ # Switch user and directory
18
+ USER ${USER}
19
+ WORKDIR ${HOME}
20
+
21
+ # Install extra requirements and sktime based on master branch
22
+ RUN pip install --upgrade pip --no-cache-dir && pip install .[binder]
sktime/source/.codecov.yml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # paths to ignore
2
+ ignore:
3
+ - "docs/**/*"
4
+ - "build_tools/**/*"
5
+ - "examples/*"
6
+ - ".github/*"
7
+ - ".binder/*"
8
+ - "extension_templates/*"
9
+ - "sktime/_contrib/**/*"
10
+ - "*.md"
11
+ - "*.yml"
12
+ - "*.yaml"
13
+
14
+ # PR status check
15
+ coverage:
16
+ status:
17
+ project:
18
+ default:
19
+ # threshold: 1%
20
+ informational: true
21
+ patch:
22
+ default:
23
+ informational: true
24
+
25
+ # post coverage report as comment on PR
26
+ comment: false
27
+
28
+ # enable codecov to report to GitHub status checks
29
+ github_checks:
30
+ annotations: false
sktime/source/.coveragerc ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ [report]
2
+ show_missing = True
3
+
4
+ [run]
5
+ source = sktime
6
+ omit =
7
+ */setup.py
8
+ */sktime/__init__.py
9
+ */sktime/setup.py
10
+ */sktime/_contrib/*
sktime/source/.dockerignore ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .binder
2
+ .eggs
3
+ .git
4
+ .github
5
+ .ipynb_checkpoints
6
+ .pytest_cache
7
+ .vscode
8
+ build
9
+ dist
10
+ docs/_build
11
+ htmlcov
12
+ sktime.egg-info
13
+ testdir
14
+ **/*.pyc
15
+ **/__pycache__
sktime/source/.pre-commit-config.yaml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: check-added-large-files
6
+ args:
7
+ - --maxkb=1000
8
+ - id: check-case-conflict
9
+ - id: check-merge-conflict
10
+ - id: check-symlinks
11
+ - id: check-yaml
12
+ - id: debug-statements
13
+ - id: end-of-file-fixer
14
+ exclude: "^docs/source/examples/"
15
+ - id: requirements-txt-fixer
16
+ - id: trailing-whitespace
17
+ - id: mixed-line-ending
18
+ args: ['--fix=lf']
19
+
20
+ - repo: https://github.com/astral-sh/ruff-pre-commit
21
+ rev: v0.13.1
22
+ hooks:
23
+ - id: ruff-format
24
+ - id: ruff-check
25
+ args: [--fix]
26
+
27
+ - repo: https://github.com/mgedmin/check-manifest
28
+ rev: "0.50"
29
+ hooks:
30
+ - id: check-manifest
31
+ stages: [manual]
32
+
33
+ # We use the Python version instead of the original version which seems to require Docker
34
+ # https://github.com/koalaman/shellcheck-precommit
35
+ - repo: https://github.com/shellcheck-py/shellcheck-py
36
+ rev: v0.11.0.1
37
+ hooks:
38
+ - id: shellcheck
39
+ name: shellcheck
sktime/source/.readthedocs.yml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ version: 2
5
+
6
+ python:
7
+ install:
8
+ - method: pip
9
+ path: .
10
+ extra_requirements:
11
+ - docs
12
+ build:
13
+ os: ubuntu-22.04
14
+ tools:
15
+ python: "3.12"
16
+
17
+ sphinx:
18
+ configuration: docs/source/conf.py
19
+ # fail_on_warning: True
sktime/source/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Changelog
2
+
3
+ You can find the sktime changelog on our [website](https://www.sktime.net/en/latest/changelog.html).
sktime/source/CODEOWNERS ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # The file specifies framework level core developers for automated review requests
2
+ #
3
+ # Note: historically, this file has been used to maintain a list of
4
+ # algorithm maintainers as specified in GOVERNANCE.md.
5
+ # This is no longer the case, algorithm maintainers are now
6
+ # specified directly in the estimator,
7
+ # in the "maintainers" tag of the respective scikit-base object.
8
+ #
9
+ # Algorithm maintainers are programmatically queryable
10
+ # via Estimator.get_class_tag("maintainers").
11
+ # Further lookup such as "which algorithms does M maintain"
12
+ # can be carried out using registry.all_estimators
13
+
14
+ * @benheid @felipeangelimvieira @fkiraly @fnhirwa @geetu040 @pranavvp16 @SaiRevanth25 @XinyuWuu @yarnabrina
sktime/source/CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Code of Conduct
2
+
3
+ You can find our Code of Conduct on our [website](https://www.sktime.net/en/latest/get_involved/code_of_conduct.html).
sktime/source/CONTRIBUTING.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Contributing guide
2
+
3
+ You can find our contributing guide on our [website](https://www.sktime.net/en/latest/get_involved/contributing.html).
sktime/source/CONTRIBUTORS.md ADDED
The diff for this file is too large to render. See raw diff
 
sktime/source/ESTIMATOR_OVERVIEW.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ This file is outdated and present only for downwards compatibility of links.
2
+
3
+ Please visit instead:
4
+ * the [sktime API reference](https://www.sktime.net/en/stable/api_reference.html)
5
+ * the [tabular estimator overview](https://www.sktime.net/en/stable/estimator_overview.html)
sktime/source/GOVERNANCE.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Governance
2
+
3
+ You can find our governance guidelines on our [website](https://www.sktime.net/en/latest/get_involved/governance.html).
sktime/source/LICENSE ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2019 - present, The sktime developers.
4
+
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this
11
+ list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+
17
+ * Neither the name of the copyright holder nor the names of its
18
+ contributors may be used to endorse or promote products derived from
19
+ this software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sktime/source/MANIFEST.in ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ include *.rst
2
+ recursive-include docs *
3
+ include *.md
4
+ recursive-include examples *
5
+ recursive-include sktime *.py
6
+ recursive-include sktime *.c *.h *.pyx *.pxd *.pxi *.tp
7
+ recursive-include sktime/datasets *.csv *.csv.gz *.arff *.arff.gz *.txt *.ts *.tsv *.tsf
8
+ include LICENSE
sktime/source/Makefile ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Makefile for easier installation and cleanup.
2
+ #
3
+ # Uses self-documenting macros from here:
4
+ # http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
5
+
6
+ PACKAGE=sktime
7
+ DOC_DIR=./docs
8
+ BUILD_TOOLS=./build_tools
9
+ TEST_DIR=testdir
10
+
11
+ .PHONY: help release install test lint clean dist doc docs
12
+
13
+ .DEFAULT_GOAL := help
14
+
15
+ help:
16
+ @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) |\
17
+ awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m\
18
+ %s\n", $$1, $$2}'
19
+
20
+ release: ## Make a release
21
+ python3 $(BUILD_TOOLS)/make_release.py
22
+
23
+ install: ## Install for the current user using the default python command
24
+ python3 setup.py build_ext --inplace && python setup.py install --user
25
+
26
+ test: ## Run unit tests
27
+ -rm -rf ${TEST_DIR}
28
+ mkdir -p ${TEST_DIR}
29
+ cp .coveragerc ${TEST_DIR}
30
+ cp setup.cfg ${TEST_DIR}
31
+ python -m pytest
32
+
33
+ full_test: ## Run all tests
34
+ -rm -rf ${TEST_DIR}
35
+ mkdir -p ${TEST_DIR}
36
+ cp .coveragerc ${TEST_DIR}
37
+ cp setup.cfg ${TEST_DIR}
38
+ python -m pytest --only_changed_modules False
39
+
40
+ test_without_datasets: ## Run unit tests skipping sktime/datasets
41
+ -rm -rf ${TEST_DIR}
42
+ mkdir -p ${TEST_DIR}
43
+ cp .coveragerc ${TEST_DIR}
44
+ cp setup.cfg ${TEST_DIR}
45
+ python -m pytest --ignore sktime/datasets
46
+
47
+ test_check_suite: ## run only estimator contract tests in TestAll classes
48
+ -rm -rf ${TEST_DIR}
49
+ mkdir -p ${TEST_DIR}
50
+ cp .coveragerc ${TEST_DIR}
51
+ cp setup.cfg ${TEST_DIR}
52
+ python -m pytest -k 'TestAll' $(PYTESTOPTIONS)
53
+
54
+ test_softdeps: ## Run unit tests to check soft dependency handling in estimators
55
+ -rm -rf ${TEST_DIR}
56
+ mkdir -p ${TEST_DIR}
57
+ cp setup.cfg ${TEST_DIR}
58
+ cd ${TEST_DIR}
59
+ python -m pytest -v -n auto --showlocals -k 'test_all_estimators' $(PYTESTOPTIONS) --pyargs sktime.registry
60
+ python -m pytest -v -n auto --showlocals -k 'test_check_estimator_does_not_raise' $(PYTESTOPTIONS) --pyargs sktime.utils.tests
61
+ python -m pytest -v -n auto --showlocals $(PYTESTOPTIONS) --pyargs sktime.tests.test_softdeps
62
+
63
+ test_softdeps_full: ## Run all non-suite unit tests without soft dependencies or downloading datasets
64
+ -rm -rf ${TEST_DIR}
65
+ mkdir -p ${TEST_DIR}
66
+ cp setup.cfg ${TEST_DIR}
67
+ cd ${TEST_DIR}
68
+ python -m pytest -v --showlocals --ignore sktime/datasets -k 'not TestAll' $(PYTESTOPTIONS)
69
+
70
+ test_mlflow: ## Run mlflow integration tests
71
+ -rm -rf ${TEST_DIR}
72
+ mkdir -p ${TEST_DIR}
73
+ cp setup.cfg ${TEST_DIR}
74
+ cd ${TEST_DIR}
75
+ python -m pytest -v --showlocals $(PYTESTOPTIONS) --pyargs sktime.utils.tests.test_mlflow_sktime_model_export
76
+
77
+ tests: test
78
+
79
+ clean: ## Clean build dist and egg directories left after install
80
+ rm -rf ./dist
81
+ rm -rf ./build
82
+ rm -rf ./pytest_cache
83
+ rm -rf ./htmlcov
84
+ rm -rf ./junit
85
+ rm -rf ./$(PACKAGE).egg-info
86
+ rm -rf coverage.xml
87
+ rm -f MANIFEST
88
+ rm -rf ./wheelhouse/*
89
+ find . -type f -iname "*.so" -delete
90
+ find . -type f -iname '*.pyc' -delete
91
+ find . -type d -name '__pycache__' -empty -delete
92
+
93
+ dist: ## Make Python source distribution
94
+ python3 setup.py sdist bdist_wheel
95
+
96
+ build:
97
+ python -m build --sdist --wheel --outdir wheelhouse
98
+
99
+ docs: doc
100
+
101
+ doc: ## Build documentation with Sphinx
102
+ $(MAKE) -C $(DOC_DIR) html
103
+
104
+ nb: clean
105
+ rm -rf .venv || true
106
+ python3 -m venv .venv
107
+ . .venv/bin/activate && python -m pip install .[all_extras,binder] && ./build_tools/run_examples.sh
108
+
109
+ dockertest:
110
+ docker build -t sktime -f build_tools/docker/$(PYTHON_VERSION).dockerfile .
111
+ docker run -it --name sktime sktime bash -c "make full_test"
sktime/source/README.md ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ ## Welcome to sktime
3
+
4
+ <a href="https://www.sktime.net"><img src="https://github.com/sktime/sktime/blob/main/docs/source/images/sktime-logo.svg" width="175" align="right" /></a>
5
+
6
+ > A unified interface for machine learning with time series
7
+
8
+ :rocket: **Version 0.40.1 out now!** [Check out the release notes here](https://www.sktime.net/en/latest/changelog.html).
9
+
10
+ sktime is a library for time series analysis in Python. It provides a unified interface for multiple time series learning tasks. Currently, this includes forecasting, time series classification, clustering, anomaly/changepoint detection, and other tasks. It comes with [time series algorithms](https://www.sktime.net/en/stable/estimator_overview.html) and [scikit-learn] compatible tools to build, tune, and validate time series models.
11
+
12
+ [scikit-learn]: https://scikit-learn.org/stable/
13
+
14
+ | | **[Documentation](https://www.sktime.net/en/stable/users.html)** · **[Tutorials](https://www.sktime.net/en/stable/examples.html)** · **[Release Notes](https://www.sktime.net/en/stable/changelog.html)** |
15
+ |---|---|
16
+ | **Open&#160;Source** | [![BSD 3-clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/sktime/sktime/blob/main/LICENSE) [![GC.OS Sponsored](https://img.shields.io/badge/GC.OS-Sponsored%20Project-orange.svg?style=flat&colorA=0eac92&colorB=2077b4)](https://gc-os-ai.github.io/) |
17
+ | **Tutorials** | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/sktime/sktime/main?filepath=examples) [![!youtube](https://img.shields.io/static/v1?logo=youtube&label=YouTube&message=tutorials&color=red)](https://www.youtube.com/playlist?list=PLKs3UgGjlWHqNzu0LEOeLKvnjvvest2d0) |
18
+ | **Community** | [![!discord](https://img.shields.io/static/v1?logo=discord&label=discord&message=chat&color=lightgreen)](https://discord.com/invite/54ACzaFsn7) [![!slack](https://img.shields.io/static/v1?logo=linkedin&label=LinkedIn&message=news&color=lightblue)](https://www.linkedin.com/company/scikit-time/) |
19
+ | **CI/CD** | [![github-actions](https://img.shields.io/github/actions/workflow/status/sktime/sktime/wheels.yml?logo=github)](https://github.com/sktime/sktime/actions/workflows/wheels.yml) [![readthedocs](https://img.shields.io/readthedocs/sktime?logo=readthedocs)](https://www.sktime.net/en/latest/?badge=latest) [![platform](https://img.shields.io/conda/pn/conda-forge/sktime)](https://github.com/sktime/sktime) |
20
+ | **Code** | [![!pypi](https://img.shields.io/pypi/v/sktime?color=orange)](https://pypi.org/project/sktime/) [![!conda](https://img.shields.io/conda/vn/conda-forge/sktime)](https://anaconda.org/conda-forge/sktime) [![!python-versions](https://img.shields.io/pypi/pyversions/sktime)](https://www.python.org/) [![!black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
21
+ | **Downloads** | ![PyPI - Downloads](https://img.shields.io/pypi/dw/sktime) ![PyPI - Downloads](https://img.shields.io/pypi/dm/sktime) [![Downloads](https://static.pepy.tech/personalized-badge/sktime?period=total&units=international_system&left_color=grey&right_color=blue&left_text=cumulative%20(pypi))](https://pepy.tech/project/sktime) |
22
+ | **Citation** | [![!zenodo](https://zenodo.org/badge/DOI/10.5281/zenodo.3749000.svg)](https://doi.org/10.5281/zenodo.3749000) |
23
+
24
+ ## :books: Documentation
25
+
26
+ | Documentation | |
27
+ |--------------------------------------| -------------------------------------------------------------- |
28
+ | :star: **[Tutorials]** | New to sktime? Here's everything you need to know! |
29
+ | :clipboard: **[Binder Notebooks]** | Example notebooks to play with in your browser. |
30
+ | :woman_technologist: **[Examples]** | How to use sktime and its features. |
31
+ | :scissors: **[Extension Templates]** | How to build your own estimator using sktime's API. |
32
+ | :control_knobs: **[API Reference]** | The detailed reference for sktime's API. |
33
+ | :tv: **[Video Tutorial]** | Our video tutorial from 2021 PyData Global. |
34
+ | :hammer_and_wrench: **[Changelog]** | Changes and version history. |
35
+ | :deciduous_tree: **[Roadmap]** | sktime's software and community development plan. |
36
+ | :pencil: **[Related Software]** | A list of related software. |
37
+
38
+ [tutorials]: https://www.sktime.net/en/latest/tutorials.html
39
+ [binder notebooks]: https://mybinder.org/v2/gh/sktime/sktime/main?filepath=examples
40
+ [examples]: https://www.sktime.net/en/latest/examples.html
41
+ [video tutorial]: https://github.com/sktime/sktime-tutorial-pydata-global-2021
42
+ [api reference]: https://www.sktime.net/en/latest/api_reference.html
43
+ [changelog]: https://www.sktime.net/en/latest/changelog.html
44
+ [roadmap]: https://www.sktime.net/en/latest/roadmap.html
45
+ [related software]: https://www.sktime.net/en/latest/related_software.html
46
+
47
+ ## :speech_balloon: Where to ask questions
48
+
49
+ Questions and feedback are extremely welcome! We strongly believe in the value of sharing help publicly, as it allows a wider audience to benefit from it.
50
+
51
+ | Type | Platforms |
52
+ | ------------------------------- | --------------------------------------- |
53
+ | :bug: **Bug Reports** | [GitHub Issue Tracker] |
54
+ | :sparkles: **Feature Requests & Ideas** | [GitHub Issue Tracker] |
55
+ | :woman_technologist: **Usage Questions** | [GitHub Discussions] · [Stack Overflow] |
56
+ | :speech_balloon: **General Discussion** | [GitHub Discussions] |
57
+ | :factory: **Contribution & Development** | `dev-chat` channel · [Discord] |
58
+ | :globe_with_meridians: **Meet-ups and collaboration sessions** | [Discord] - Fridays 13 UTC, dev/meet-ups channel |
59
+
60
+ [github issue tracker]: https://github.com/sktime/sktime/issues
61
+ [github discussions]: https://github.com/sktime/sktime/discussions
62
+ [stack overflow]: https://stackoverflow.com/questions/tagged/sktime
63
+ [discord]: https://discord.com/invite/54ACzaFsn7
64
+
65
+ ## :dizzy: Features
66
+ Our objective is to enhance the interoperability and usability of the time series analysis ecosystem in its entirety. sktime provides a __unified interface for distinct but related time series learning tasks__. It features [__dedicated time series algorithms__](https://www.sktime.net/en/stable/estimator_overview.html) and __tools for composite model building__, such as pipelining, ensembling, tuning, and reduction, empowering users to apply algorithms designed for one task to another.
67
+
68
+ sktime also provides **interfaces to related libraries**, for example [scikit-learn], [statsmodels], [tsfresh], [PyOD], and [fbprophet], among others.
69
+
70
+ [statsmodels]: https://www.statsmodels.org/stable/index.html
71
+ [tsfresh]: https://tsfresh.readthedocs.io/en/latest/
72
+ [pyod]: https://pyod.readthedocs.io/en/latest/
73
+ [fbprophet]: https://facebook.github.io/prophet/
74
+
75
+ | Module | Status | Links |
76
+ |---|---|---|
77
+ | **[Forecasting]** | stable | [Tutorial](https://www.sktime.net/en/latest/examples/01_forecasting.html) · [API Reference](https://www.sktime.net/en/latest/api_reference/forecasting.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/forecasting.py) |
78
+ | **[Time Series Classification]** | stable | [Tutorial](https://github.com/sktime/sktime/blob/main/examples/02_classification.ipynb) · [API Reference](https://www.sktime.net/en/latest/api_reference/classification.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/classification.py) |
79
+ | **[Time Series Regression]** | stable | [API Reference](https://www.sktime.net/en/latest/api_reference/regression.html) |
80
+ | **[Transformations]** | stable | [Tutorial](https://github.com/sktime/sktime/blob/main/examples/03_transformers.ipynb) · [API Reference](https://www.sktime.net/en/latest/api_reference/transformations.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/transformer.py) |
81
+ | **[Detection tasks]** | maturing | [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/detection.py) |
82
+ | **[Parameter fitting]** | maturing | [API Reference](https://www.sktime.net/en/latest/api_reference/param_est.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/transformer.py) |
83
+ | **[Time Series Clustering]** | maturing | [API Reference](https://www.sktime.net/en/latest/api_reference/clustering.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/clustering.py) |
84
+ | **[Time Series Distances/Kernels]** | maturing | [Tutorial](https://github.com/sktime/sktime/blob/main/examples/03_transformers.ipynb) · [API Reference](https://www.sktime.net/en/latest/api_reference/dists_kernels.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/dist_kern_panel.py) |
85
+ | **[Time Series Alignment]** | experimental | [API Reference](https://www.sktime.net/en/latest/api_reference/alignment.html) · [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/alignment.py) |
86
+ | **[Time Series Splitters]** | maturing | [Extension Template](https://github.com/sktime/sktime/blob/main/extension_templates/split.py) | |
87
+ | **[Distributions and simulation]** | experimental | |
88
+
89
+ [forecasting]: https://github.com/sktime/sktime/tree/main/sktime/forecasting
90
+ [time series classification]: https://github.com/sktime/sktime/tree/main/sktime/classification
91
+ [time series regression]: https://github.com/sktime/sktime/tree/main/sktime/regression
92
+ [time series clustering]: https://github.com/sktime/sktime/tree/main/sktime/clustering
93
+ [detection tasks]: https://github.com/sktime/sktime/tree/main/sktime/detection
94
+ [time series distances/kernels]: https://github.com/sktime/sktime/tree/main/sktime/dists_kernels
95
+ [time series alignment]: https://github.com/sktime/sktime/tree/main/sktime/alignment
96
+ [transformations]: https://github.com/sktime/sktime/tree/main/sktime/transformations
97
+ [distributions and simulation]: https://github.com/sktime/sktime/tree/main/sktime/proba
98
+ [time series splitters]: https://github.com/sktime/sktime/tree/main/sktime/split
99
+ [parameter fitting]: https://github.com/sktime/sktime/tree/main/sktime/param_est
100
+
101
+
102
+ ## :hourglass_flowing_sand: Install sktime
103
+ For troubleshooting and detailed installation instructions, see the [documentation](https://www.sktime.net/en/latest/installation.html).
104
+
105
+ - **Operating system**: macOS X · Linux · Windows 8.1 or higher
106
+ - **Python version**: Python 3.10, 3.11, 3.12, and 3.13 (only 64-bit)
107
+ - **Package managers**: [pip] · [conda] (via `conda-forge`)
108
+
109
+ [pip]: https://pip.pypa.io/en/stable/
110
+ [conda]: https://docs.conda.io/en/latest/
111
+
112
+ ### pip
113
+ Using pip, sktime releases are available as source packages and binary wheels.
114
+ Available wheels are listed [here](https://pypi.org/simple/sktime/).
115
+
116
+ ```bash
117
+ pip install sktime
118
+ ```
119
+
120
+ or, with maximum dependencies,
121
+
122
+ ```bash
123
+ pip install sktime[all_extras]
124
+ ```
125
+
126
+ For curated sets of soft dependencies for specific learning tasks:
127
+
128
+ ```bash
129
+ pip install sktime[forecasting] # for selected forecasting dependencies
130
+ pip install sktime[forecasting,transformations] # forecasters and transformers
131
+ ```
132
+
133
+ or similar. Valid sets are:
134
+
135
+ * `forecasting`
136
+ * `transformations`
137
+ * `classification`
138
+ * `regression`
139
+ * `clustering`
140
+ * `param_est`
141
+ * `networks`
142
+ * `detection`
143
+ * `alignment`
144
+
145
+ Cave: in general, not all soft dependencies for a learning task are installed,
146
+ only a curated selection.
147
+
148
+ ### conda
149
+ You can also install sktime from `conda` via the `conda-forge` channel.
150
+ The feedstock including the build recipe and configuration is maintained
151
+ in [this conda-forge repository](https://github.com/conda-forge/sktime-feedstock).
152
+
153
+ ```bash
154
+ conda install -c conda-forge sktime
155
+ ```
156
+
157
+ or, with maximum dependencies,
158
+
159
+ ```bash
160
+ conda install -c conda-forge sktime-all-extras
161
+ ```
162
+
163
+ (as `conda` does not support dependency sets,
164
+ flexible choice of soft dependencies is unavailable via `conda`)
165
+
166
+ ## :zap: Quickstart
167
+
168
+ ### Forecasting
169
+
170
+ ``` python
171
+ from sktime.datasets import load_airline
172
+ from sktime.forecasting.base import ForecastingHorizon
173
+ from sktime.forecasting.theta import ThetaForecaster
174
+ from sktime.split import temporal_train_test_split
175
+ from sktime.performance_metrics.forecasting import mean_absolute_percentage_error
176
+
177
+ y = load_airline()
178
+ y_train, y_test = temporal_train_test_split(y)
179
+ fh = ForecastingHorizon(y_test.index, is_relative=False)
180
+ forecaster = ThetaForecaster(sp=12) # monthly seasonal periodicity
181
+ forecaster.fit(y_train)
182
+ y_pred = forecaster.predict(fh)
183
+ mean_absolute_percentage_error(y_test, y_pred)
184
+ >>> 0.08661467738190656
185
+ ```
186
+
187
+ ### Time Series Classification
188
+
189
+ ```python
190
+ from sktime.classification.interval_based import TimeSeriesForestClassifier
191
+ from sktime.datasets import load_arrow_head
192
+ from sklearn.model_selection import train_test_split
193
+ from sklearn.metrics import accuracy_score
194
+
195
+ X, y = load_arrow_head()
196
+ X_train, X_test, y_train, y_test = train_test_split(X, y)
197
+ classifier = TimeSeriesForestClassifier()
198
+ classifier.fit(X_train, y_train)
199
+ y_pred = classifier.predict(X_test)
200
+ accuracy_score(y_test, y_pred)
201
+ >>> 0.8679245283018868
202
+ ```
203
+
204
+ ## :wave: How to get involved
205
+
206
+ There are many ways to join the sktime community. We follow the [all-contributors](https://github.com/all-contributors/all-contributors) specification: all kinds of contributions are welcome - not just code.
207
+
208
+ | Documentation | |
209
+ | -------------------------- | -------------------------------------------------------------- |
210
+ | :gift_heart: **[Contribute]** | How to contribute to sktime. |
211
+ | :school_satchel: **[Mentoring]** | New to open source? Apply to our mentoring program! |
212
+ | :date: **[Meetings]** | Join our discussions, tutorials, workshops, and sprints! |
213
+ | :woman_mechanic: **[Developer Guides]** | How to further develop sktime's code base. |
214
+ | :construction: **[Enhancement Proposals]** | Design a new feature for sktime. |
215
+ | :medal_sports: **[Contributors]** | A list of all contributors. |
216
+ | :raising_hand: **[Roles]** | An overview of our core community roles. |
217
+ | :money_with_wings: **[Donate]** | Fund sktime maintenance and development. |
218
+ | :classical_building: **[Governance]** | How and by whom decisions are made in sktime's community. |
219
+
220
+ [contribute]: https://www.sktime.net/en/latest/get_involved/contributing.html
221
+ [donate]: https://opencollective.com/sktime
222
+ [extension templates]: https://github.com/sktime/sktime/tree/main/extension_templates
223
+ [developer guides]: https://www.sktime.net/en/latest/developer_guide.html
224
+ [contributors]: https://github.com/sktime/sktime/blob/main/CONTRIBUTORS.md
225
+ [governance]: https://www.sktime.net/en/latest/get_involved/governance.html
226
+ [mentoring]: https://github.com/sktime/mentoring
227
+ [meetings]: https://calendar.google.com/calendar/u/0/embed?src=sktime.toolbox@gmail.com&ctz=UTC
228
+ [enhancement proposals]: https://github.com/sktime/enhancement-proposals
229
+ [roles]: https://www.sktime.net/en/latest/about/team.html
230
+
231
+ ## :trophy: Hall of fame
232
+
233
+ Thanks to all our community for all your wonderful contributions, PRs, issues, ideas.
234
+
235
+ <a href="https://github.com/sktime/sktime/graphs/contributors">
236
+ <img src="https://opencollective.com/sktime/contributors.svg?width=600&button=false" />
237
+ </a>
238
+ <br>
239
+
240
+ ## :bulb: Project vision
241
+
242
+ * **By the community, for the community** -- developed by a friendly and collaborative community.
243
+ * The **right tool for the right task** -- helping users to diagnose their learning problem and suitable scientific model types.
244
+ * **Embedded in state-of-art ecosystems** and **provider of interoperable interfaces** -- interoperable with [scikit-learn], [statsmodels], [tsfresh], and other community favorites.
245
+ * **Rich model composition and reduction functionality** -- build tuning and feature extraction pipelines, solve forecasting tasks with [scikit-learn] regressors.
246
+ * **Clean, descriptive specification syntax** -- based on modern object-oriented design principles for data science.
247
+ * **Fair model assessment and benchmarking** -- build your models, inspect your models, check your models, and avoid pitfalls.
248
+ * **Easily extensible** -- easy extension templates to add your own algorithms compatible with sktime's API.
sktime/source/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ sktime Project Package Initialization File
4
+ """
sktime/source/build_tools/changelog.py ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """RestructuredText changelog generator."""
2
+
3
+ import os
4
+ from collections import defaultdict
5
+
6
+ HEADERS = {
7
+ "Accept": "application/vnd.github.v3+json",
8
+ }
9
+
10
+ if os.getenv("GITHUB_TOKEN") is not None:
11
+ HEADERS["Authorization"] = f"token {os.getenv('GITHUB_TOKEN')}"
12
+
13
+ OWNER = "sktime"
14
+ REPO = "sktime"
15
+ GITHUB_REPOS = "https://api.github.com/repos"
16
+
17
+
18
+ def fetch_merged_pull_requests(page: int = 1) -> list[dict]:
19
+ """Fetch a page of merged pull requests.
20
+
21
+ Parameters
22
+ ----------
23
+ page : int, optional
24
+ Page number to fetch, by default 1.
25
+ Returns all merged pull request from the ``page``-th page of closed PRs,
26
+ where pages are in descending order of last update.
27
+
28
+ Returns
29
+ -------
30
+ list
31
+ List of merged pull requests from the ``page``-th page of closed PRs.
32
+ Elements of list are dictionaries with PR details, as obtained
33
+ from the GitHub API via ``httpx.get``, from the ``pulls`` endpoint.
34
+ """
35
+ import httpx
36
+
37
+ params = {
38
+ "base": "main",
39
+ "state": "closed",
40
+ "page": page,
41
+ "per_page": 50,
42
+ "sort": "updated",
43
+ "direction": "desc",
44
+ }
45
+ r = httpx.get(
46
+ f"{GITHUB_REPOS}/{OWNER}/{REPO}/pulls",
47
+ headers=HEADERS,
48
+ params=params,
49
+ )
50
+ return [pr for pr in r.json() if pr["merged_at"]]
51
+
52
+
53
+ def fetch_latest_release(): # noqa: D103
54
+ """Fetch the latest release from the GitHub API.
55
+
56
+ Returns
57
+ -------
58
+ dict
59
+ Dictionary with details of the latest release.
60
+ Dictionary is as obtained from the GitHub API via ``httpx.get``,
61
+ for ``releases/latest`` endpoint.
62
+ """
63
+ import httpx
64
+
65
+ response = httpx.get(
66
+ f"{GITHUB_REPOS}/{OWNER}/{REPO}/releases/latest", headers=HEADERS
67
+ )
68
+
69
+ if response.status_code == 200:
70
+ return response.json()
71
+ else:
72
+ raise ValueError(response.text, response.status_code)
73
+
74
+
75
+ def fetch_pull_requests_since_last_release() -> list[dict]:
76
+ """Fetch all pull requests merged since last release.
77
+
78
+ Returns
79
+ -------
80
+ list
81
+ List of pull requests merged since the latest release.
82
+ Elements of list are dictionaries with PR details, as obtained
83
+ from the GitHub API via ``httpx.get``, through ``fetch_merged_pull_requests``.
84
+ """
85
+ from dateutil import parser
86
+
87
+ release = fetch_latest_release()
88
+ published_at = parser.parse(release["published_at"])
89
+ print(f"Latest release {release['tag_name']} was published at {published_at}")
90
+
91
+ is_exhausted = False
92
+ page = 1
93
+ all_pulls = []
94
+ while not is_exhausted:
95
+ pulls = fetch_merged_pull_requests(page=page)
96
+ all_pulls.extend(
97
+ [p for p in pulls if parser.parse(p["merged_at"]) > published_at]
98
+ )
99
+ is_exhausted = any(parser.parse(p["updated_at"]) < published_at for p in pulls)
100
+ page += 1
101
+ return all_pulls
102
+
103
+
104
+ def github_compare_tags(tag_left: str, tag_right: str = "HEAD"):
105
+ """Compare commit between two tags."""
106
+ import httpx
107
+
108
+ response = httpx.get(
109
+ f"{GITHUB_REPOS}/{OWNER}/{REPO}/compare/{tag_left}...{tag_right}"
110
+ )
111
+ if response.status_code == 200:
112
+ return response.json()
113
+ else:
114
+ raise ValueError(response.text, response.status_code)
115
+
116
+
117
+ def render_row(pr):
118
+ """Render a single row with PR in restructuredText format."""
119
+ # Process the title to handle user credits at beginning of title
120
+ title = pr["title"]
121
+ extra_users = []
122
+
123
+ # Check for prefixed user credits like &username
124
+ if title.startswith("&"):
125
+ parts = title.split(" ", 1)
126
+ user_part = parts[0].strip()
127
+ if len(parts) > 1:
128
+ title = parts[1].strip()
129
+ # Extract username without the & prefix
130
+ username = user_part[1:]
131
+ extra_users.append(username)
132
+
133
+ # Handle dependabot PRs: enclose package names and versions in double backticks
134
+ if "dependabot" in pr["user"]["login"].lower():
135
+ # Match patterns like "Update package requirement from <1.0.0 to <2.0.0"
136
+ import re
137
+
138
+ # Pattern to match package name and version bounds
139
+ pattern = r"Update ([\w\-\.]+) requirement from (<[\d\.]+,?>?[>=]*[\d\.]+) to ([>=]*[\d\.]+,?<[\d\.]+)" # noqa: E501
140
+ match = re.search(pattern, title)
141
+
142
+ pattern2 = r"Bump ([\w\-/]+) from (\d+(?:\.\d+)*) to (\d+(?:\.\d+)*)" # noqa: E501
143
+ match2 = re.search(pattern2, title)
144
+
145
+ if match or match2:
146
+ m = match if match else match2
147
+ package, from_ver, to_ver = m.groups()
148
+
149
+ # add double backticks if not already present
150
+ def add_backticks(text):
151
+ if not text.startswith("``") and not text.endswith("``"):
152
+ return f"`{text}`"
153
+ return text
154
+
155
+ package = add_backticks(package)
156
+ from_ver = add_backticks(from_ver)
157
+ to_ver = add_backticks(to_ver)
158
+
159
+ # Replace with proper backticks
160
+ if match:
161
+ title = f"Update {package} requirement from {from_ver} to {to_ver}"
162
+ elif match2:
163
+ title = f"Bump {package} from {from_ver} to {to_ver}"
164
+
165
+ # Replace single backticks with double backticks
166
+ title = title.replace("`", "``")
167
+ # Replace quadruple backticks with double backticks,
168
+ # in case double backticks were already present
169
+ title = title.replace("````", "``")
170
+
171
+ # Print the PR line
172
+ print(
173
+ f"* {title} "
174
+ f"(:pr:`{pr['number']}`)"
175
+ + ", ".join([f":user:`{user}`" for user in extra_users])
176
+ + (", " if extra_users else "")
177
+ + f" :user:`{pr['user']['login']}`"
178
+ )
179
+
180
+
181
+ def assign_prs(prs, categs: list[dict[str, list[str]]]):
182
+ """Assign PR to categories based on labels."""
183
+ assigned = defaultdict(list)
184
+
185
+ for i, pr in enumerate(prs):
186
+ for cat in categs:
187
+ pr_labels = [label["name"] for label in pr["labels"]]
188
+ if not set(cat["labels"]).isdisjoint(set(pr_labels)):
189
+ assigned[cat["title"]].append(i)
190
+
191
+ # if any(l.startswith("module") for l in pr_labels):
192
+ # print(i, pr_labels)
193
+
194
+ # Assign unmatched PRs to "Other" category
195
+ assigned["Other"] = list(
196
+ set(range(len(prs))) - {i for _, j in assigned.items() for i in j}
197
+ )
198
+
199
+ return assigned
200
+
201
+
202
+ def render_changelog(prs, assigned, label_to_subsection=None, module_order=None):
203
+ """Render changelog with subsections based on module tags.
204
+
205
+ Parameters
206
+ ----------
207
+ prs : list
208
+ List of pull requests.
209
+ assigned : dict
210
+ Dictionary mapping category titles to list of PR indices.
211
+ label_to_subsection : dict, optional
212
+ Dictionary mapping module tags to subsection titles.
213
+ module_order : list, optional
214
+ List of subsection titles in the desired order.
215
+ """
216
+ from dateutil import parser
217
+
218
+ SECTION_ORDER = ["Enhancements", "Documentation", "Maintenance", "Fixes", "Other"]
219
+ for title in SECTION_ORDER:
220
+ if title not in assigned:
221
+ continue
222
+
223
+ pr_group = [prs[i] for i in assigned[title]]
224
+ if not pr_group:
225
+ continue
226
+ print()
227
+ print(title)
228
+ print("~" * len(title))
229
+
230
+ # Group PRs by module labels
231
+ def group_prs_by_module(pr_group: list[dict]) -> dict[str, list[dict]]:
232
+ """Group PRs by module labels and return a dictionary."""
233
+ subsection_map: dict[str, list[dict]] = defaultdict(list)
234
+
235
+ for pr in pr_group:
236
+ labels = [label["name"] for label in pr["labels"]]
237
+ added = False
238
+
239
+ for label in labels:
240
+ if label in LABEL_TO_SUBSECTION:
241
+ subsection_map[LABEL_TO_SUBSECTION[label]].append(pr)
242
+ added = True
243
+ if not added:
244
+ subsection_map["Other"].append(pr)
245
+
246
+ return subsection_map
247
+
248
+ def render_subsection(subsection_map: dict[str, list[dict]]) -> None:
249
+ """Render subsections and their PRs in order."""
250
+ # Render subsections
251
+ for subsection_title in MODULE_ORDER:
252
+ pr_list = subsection_map.get(subsection_title, [])
253
+ if pr_list is None or not pr_list:
254
+ continue
255
+ print()
256
+ print(subsection_title)
257
+ print("^" * len(subsection_title))
258
+ print()
259
+ for pr in sorted(pr_list, key=lambda x: parser.parse(x["merged_at"])):
260
+ render_row(pr)
261
+
262
+ if title in ["Enhancements", "Fixes"]:
263
+ subsection_map = group_prs_by_module(pr_group)
264
+ render_subsection(subsection_map)
265
+ else:
266
+ for pr in sorted(pr_group, key=lambda x: parser.parse(x["merged_at"])):
267
+ render_row(pr)
268
+
269
+
270
+ def render_contributors(prs: list, fmt: str = "rst"):
271
+ """Find unique authors and print a list in given format.
272
+
273
+ Parameters
274
+ ----------
275
+ prs : list
276
+ List of pull requests
277
+ fmt : str, default="rst"
278
+ Format of the output, either "github" or "rst"
279
+ """
280
+ authors = sorted({pr["user"]["login"] for pr in prs}, key=lambda x: x.lower())
281
+
282
+ header = "Contributors"
283
+ if fmt == "github":
284
+ print(f"### {header}")
285
+ print(", ".join(f"@{user}" for user in authors))
286
+ elif fmt == "rst":
287
+ print(header)
288
+ print("~" * len(header), end="\n\n")
289
+ print(",\n".join(f":user:`{user}`" for user in authors))
290
+
291
+
292
+ if __name__ == "__main__":
293
+ # configuration of categories, sections, label mapping, and order
294
+ # ---------------------------------------------------------------
295
+ categories = [
296
+ {"title": "Enhancements", "labels": ["feature", "enhancement"]},
297
+ {"title": "Documentation", "labels": ["documentation"]},
298
+ {"title": "Maintenance", "labels": ["maintenance", "chore"]},
299
+ {"title": "Fixes", "labels": ["bug", "fix", "bugfix"]},
300
+ ]
301
+
302
+ # sourcery skip: use-named-expression
303
+ LABEL_TO_SUBSECTION = {
304
+ "module:base-framework": "BaseObject and base framework",
305
+ "module:deep-learning&networks": "Other",
306
+ "module:detection": "Time series anomalies, changepoints, segmentation",
307
+ "module:distances&kernels": "Time series anomalies, changepoints, segmentation",
308
+ "module:datasets&loaders": "Data sets and data loaders",
309
+ "module:datatypes": "Datatypes, checks, conversions",
310
+ "module:forecasting": "Forecasting",
311
+ "module:metrics&benchmarking": "Benchmarking, Metrics, Splitters",
312
+ "module:parameter-estimators": "Parameter estimation and hypothesis testing",
313
+ "module:plotting&utilities": "Other",
314
+ "module:probability&simulation": "Other",
315
+ "module:splitters&resamplers": "Benchmarking, Metrics, Splitter",
316
+ "module:classification": "Time series classification",
317
+ "module:clustering": "Time series clustering",
318
+ "module:regression": "Time series regression",
319
+ "module:transformations": "Transformations",
320
+ "module:tests": "Test framework",
321
+ }
322
+ # labels start with module
323
+ # Subsection title comes after label
324
+
325
+ MODULE_ORDER = [
326
+ "BaseObject and base framework",
327
+ "Benchmarking, Metrics, Splitters",
328
+ "Data sets and data loaders",
329
+ "Datatypes, checks, conversions",
330
+ "Forecasting",
331
+ "Parameter estimation and hypothesis testing",
332
+ "Registry and search",
333
+ "Time series alignment",
334
+ "Time series anomalies, changepoints, segmentation",
335
+ "Time series classification",
336
+ "Time series clustering",
337
+ "Time series regression",
338
+ "Transformations",
339
+ "Test framework",
340
+ "Other",
341
+ ]
342
+
343
+ # end configuration
344
+
345
+ pulls = fetch_pull_requests_since_last_release()
346
+ print(f"Found {len(pulls)} merged PRs since last release")
347
+ assigned = assign_prs(pulls, categories)
348
+ render_changelog(
349
+ pulls,
350
+ assigned,
351
+ label_to_subsection=LABEL_TO_SUBSECTION,
352
+ module_order=MODULE_ORDER,
353
+ )
354
+ print()
355
+ render_contributors(pulls)
356
+
357
+ release = fetch_latest_release()
358
+ diff = github_compare_tags(release["tag_name"])
359
+ if diff["total_commits"] != len(pulls):
360
+ raise ValueError(
361
+ "Something went wrong and not all PR were fetched. "
362
+ f"There are {len(pulls)} PRs but {diff['total_commits']} in the diff. "
363
+ "Please verify that all PRs are included in the changelog."
364
+ )
sktime/source/build_tools/check_backticks.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3 -u
2
+ # copyright: sktime developers, BSD-3-Clause License (see LICENSE file)
3
+
4
+ """Test script to check for invalid use of single-backticks."""
5
+
6
+ __author__ = ["geetu040"]
7
+
8
+ import argparse
9
+ import ast
10
+ import glob
11
+ import re
12
+
13
+
14
+ def find_py_files(folder_path):
15
+ """Find all Python files in a given folder path."""
16
+ return glob.glob(f"{folder_path}/**/*.py", recursive=True)
17
+
18
+
19
+ def extract_docstrings(filename):
20
+ """Extract docstrings from a Python file."""
21
+ # create abstract syntax tree from the file
22
+ with open(filename) as f:
23
+ tree = ast.parse(f.read())
24
+
25
+ # walk through all nodes in the tree
26
+ docstrings = {}
27
+ for node in ast.walk(tree):
28
+ if (
29
+ isinstance(node, ast.Expr)
30
+ and isinstance(node.value, ast.Constant)
31
+ and isinstance(node.value.value, str)
32
+ ):
33
+ # if the node is an expression and
34
+ # its value is a constant and
35
+ # constant's value is a string
36
+ # the node represents a docstring
37
+ # See https://docs.python.org/3/library/ast.html#abstract-grammar
38
+ docstring = node.value.value
39
+ lineno = node.value.lineno
40
+ docstrings[lineno] = docstring
41
+
42
+ return docstrings
43
+
44
+
45
+ def find_invalid_backtick_text(docstring):
46
+ """Find invalid backtick text in a docstring."""
47
+ # remove all multiple backticks to avoid interference
48
+ # we are looking only for invalid single-backtick
49
+ docstring = re.sub(r"`{2,}.*?`{2,}", "", docstring, flags=re.DOTALL)
50
+
51
+ all_backtick_text = re.findall(r"`.*?`", docstring, flags=re.DOTALL)
52
+ # expressions like :math:`d(x, y):= (x-y)^2` are valid cases
53
+ valid_backtick_text = re.findall(r":.*?:(`.*?`)", docstring, flags=re.DOTALL)
54
+
55
+ # find all the invalid backtick code snippets
56
+ invalid_backtick_text = set()
57
+ for text in all_backtick_text:
58
+ if text in valid_backtick_text:
59
+ continue
60
+ # rst hyperlinks are valid cases
61
+ if re.match(r"`.*?<http.*?>`", text, flags=re.DOTALL):
62
+ continue
63
+ invalid_backtick_text.add(text)
64
+
65
+ return invalid_backtick_text
66
+
67
+
68
+ def main():
69
+ """Execute the main function of the script."""
70
+ # parse command line arguments
71
+ parser = argparse.ArgumentParser(
72
+ description="Test script to check for invalid use of single-backticks."
73
+ )
74
+ parser.add_argument(
75
+ "folder_path",
76
+ nargs="?",
77
+ default="./sktime",
78
+ help="Folder path to search for Python files",
79
+ )
80
+ args = parser.parse_args()
81
+
82
+ folder_path = args.folder_path
83
+ results = {}
84
+
85
+ # list all the python files in the project
86
+ py_files = find_py_files(folder_path)
87
+
88
+ for file in py_files:
89
+ docstrings = extract_docstrings(file)
90
+ results_on_file = {}
91
+
92
+ for lineno, docstring in docstrings.items():
93
+ invalid_backtick_text = find_invalid_backtick_text(docstring)
94
+
95
+ if len(invalid_backtick_text) > 0:
96
+ results_on_file[lineno] = invalid_backtick_text
97
+
98
+ if len(results_on_file) > 0:
99
+ results[file] = results_on_file
100
+
101
+ # print the lines along with the invalid backticks text
102
+ print(f'Results in "{folder_path}"') # noqa: T201
103
+ if len(results) > 0:
104
+ print(f"Total Files with invalid backticks: {len(results)}") # noqa: T201
105
+ for filename, result in results.items():
106
+ for lineno, errors in result.items():
107
+ print(f"{filename}:{lineno} {' '.join(errors)}") # noqa: T201
108
+ else:
109
+ print("No invalid backticks found") # noqa: T201
110
+
111
+
112
+ if __name__ == "__main__":
113
+ """
114
+ Usage: defaults to "./sktime"
115
+ python build_tools/check_backticks.py
116
+
117
+ Usage: folder path as argument
118
+ python build_tools/check_backticks.py sktime/classification/distance_based
119
+ """
120
+ main()
sktime/source/build_tools/check_install_from_test_pypi.sh ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Helper script to download and install sktime from test PyPI to check wheel
4
+ # and upload prior to new release
5
+
6
+ set -e
7
+
8
+ # Version to test, passed as input argument to script
9
+ VERSION=$1
10
+
11
+ # Make temporary directory
12
+ echo "Making test directory ..."
13
+ mkdir "$HOME"/testdir
14
+ cd "$HOME"/testdir
15
+
16
+ # Create test environment
17
+ echo "Creating test environment ..."
18
+
19
+ # shellcheck disable=SC1091
20
+ source "$(conda info --base)"/etc/profile.d/conda.sh # set up conda
21
+ conda create -n sktime_testenv python=3.8
22
+ conda activate sktime_testenv
23
+
24
+ # Install from test PyPI
25
+ echo "Installing sktime from Test PyPI ..."
26
+ pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple sktime=="$VERSION"
27
+ echo "Successfully installed sktime from Test PyPI."
28
+
29
+ # Clean up test directory and environment
30
+ echo "Cleaning up ..."
31
+ conda deactivate
32
+ conda remove -n sktime_testenv --all -y
33
+ rm -r "$HOME"/testdir
34
+
35
+ echo "Done."
sktime/source/build_tools/docker/py310.dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /usr/src/sktime
4
+
5
+ COPY . .
6
+
7
+ RUN apt-get update && apt-get install --no-install-recommends -y build-essential gcc git && apt-get clean
8
+ RUN python -m pip install -U pip
9
+ RUN python -m pip install .[all_extras_pandas2,dev,binder]
sktime/source/build_tools/docker/py311.dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /usr/src/sktime
4
+
5
+ COPY . .
6
+
7
+ RUN apt-get update && apt-get install --no-install-recommends -y build-essential gcc git && apt-get clean
8
+ RUN python -m pip install -U pip
9
+ RUN python -m pip install .[all_extras_pandas2,dev,binder]
sktime/source/build_tools/docker/py312.dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /usr/src/sktime
4
+
5
+ COPY . .
6
+
7
+ RUN apt-get update && apt-get install --no-install-recommends -y build-essential gcc git && apt-get clean
8
+ RUN python -m pip install -U pip
9
+ RUN python -m pip install .[all_extras_pandas2,dev,binder]
sktime/source/build_tools/docker/py313.dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.13-slim
2
+
3
+ WORKDIR /usr/src/sktime
4
+
5
+ COPY . .
6
+
7
+ RUN apt-get update && apt-get install --no-install-recommends -y build-essential gcc git && apt-get clean
8
+ RUN python -m pip install -U pip
9
+ RUN python -m pip install .[all_extras_pandas2,dev,binder]
sktime/source/build_tools/docker/py314.dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.14-slim
2
+
3
+ WORKDIR /usr/src/sktime
4
+
5
+ COPY . .
6
+
7
+ RUN apt-get update && apt-get install --no-install-recommends -y build-essential gcc git && apt-get clean
8
+ RUN python -m pip install -U pip
9
+ RUN python -m pip install .[all_extras_pandas2,dev,binder]
sktime/source/build_tools/fail_on_missing_init_files.sh ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Script to search for missing init FILES.
4
+ set -euxo pipefail
5
+
6
+ FILES=$( find ./sktime -type d '!' -exec test -e "{}/__init__.py" ";" -not -path "**/__pycache__" -not -path "**/datasets/data*" -not -path "**/contrib/*" -print )
7
+
8
+ if [[ -n "$FILES" ]]
9
+ then
10
+ echo "Missing __init__.py files detected in the following modules:"
11
+ echo "$FILES"
12
+ exit 1
13
+ fi
sktime/source/build_tools/make_release.py ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3 -u
2
+ # copyright: sktime developers, BSD-3-Clause License (see LICENSE file)
3
+ """Do-nothing script for making a release.
4
+
5
+ This idea comes from here:
6
+ - https://blog.danslimmon.com/2019/07/15/do-nothing-scripting-the-key-to
7
+ -gradual-automation/
8
+
9
+ The script is adapted from:
10
+ - https://github.com/alan-turing-institute/CleverCSV/blob/master
11
+ /make_release.py
12
+ """
13
+
14
+ __author__ = ["mloning"]
15
+
16
+ import codecs
17
+ import os
18
+ import re
19
+ import webbrowser
20
+
21
+ import colorama
22
+
23
+ ROOT_DIR = os.path.abspath(os.path.dirname(__file__)).replace("build_tools", "")
24
+ PACKAGE_NAME = "sktime"
25
+
26
+
27
+ class URLs:
28
+ """Container class for URLs."""
29
+
30
+ DOCS_LOCAL = "file://" + os.path.realpath(
31
+ os.path.join(ROOT_DIR, "docs/_build/html/index.html")
32
+ )
33
+ DOCS_ONLINE = "https://www.sktime.net"
34
+ PYPI = f"https://pypi.org/simple/{PACKAGE_NAME}/"
35
+
36
+
37
+ def read(*parts):
38
+ """Read from parts."""
39
+ # intentionally *not* adding an encoding option to open, See:
40
+ # https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
41
+ with codecs.open(os.path.join(ROOT_DIR, *parts), "r") as fp:
42
+ return fp.read()
43
+
44
+
45
+ def find_version(*file_paths):
46
+ """Find version string."""
47
+ version_file = read(*file_paths)
48
+ version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M)
49
+ if version_match:
50
+ return version_match.group(1)
51
+ else:
52
+ raise RuntimeError("Unable to find version string.")
53
+
54
+
55
+ def open_website(website):
56
+ """Open website."""
57
+ webbrowser.open(website, new=1)
58
+
59
+
60
+ def colored(msg, color=None, style=None):
61
+ """Print message with colors."""
62
+ colors = {
63
+ "red": colorama.Fore.RED,
64
+ "green": colorama.Fore.GREEN,
65
+ "cyan": colorama.Fore.CYAN,
66
+ "yellow": colorama.Fore.YELLOW,
67
+ "magenta": colorama.Fore.MAGENTA,
68
+ None: "",
69
+ }
70
+ styles = {
71
+ "bright": colorama.Style.BRIGHT,
72
+ "dim": colorama.Style.DIM,
73
+ None: "",
74
+ }
75
+ pre = colors[color] + styles[style]
76
+ post = colorama.Style.RESET_ALL
77
+ return f"{pre}{msg}{post}"
78
+
79
+
80
+ def cprint(msg, color=None, style=None):
81
+ """Coloured printing."""
82
+ print(colored(msg, color=color, style=style))
83
+
84
+
85
+ def wait_for_enter():
86
+ """Wait for Enter."""
87
+ input(colored("\nPress Enter to continue", style="dim"))
88
+ print()
89
+
90
+
91
+ class Step:
92
+ """Abstraction for release step."""
93
+
94
+ def pre(self, context):
95
+ """Pre-step."""
96
+
97
+ def post(self, context):
98
+ """Post-step."""
99
+ wait_for_enter()
100
+
101
+ def run(self, context):
102
+ """Run step."""
103
+ try:
104
+ self.pre(context)
105
+ self.action(context)
106
+ self.post(context)
107
+ except KeyboardInterrupt:
108
+ cprint("\nInterrupted.", color="red")
109
+ raise SystemExit(1)
110
+
111
+ @staticmethod
112
+ def instruct(msg):
113
+ """Instruction."""
114
+ cprint(msg, color="green")
115
+
116
+ def print_run(self, msg):
117
+ """Print run step."""
118
+ cprint("Run:", color="cyan", style="bright")
119
+ self.print_cmd(msg)
120
+
121
+ @staticmethod
122
+ def print_cmd(msg):
123
+ """Print cmd step."""
124
+ cprint("\t" + msg, color="cyan", style="bright")
125
+
126
+ @staticmethod
127
+ def do_cmd(cmd):
128
+ """Wait for confirmation."""
129
+ cprint(f"Going to run: {cmd}", color="magenta", style="bright")
130
+ wait_for_enter()
131
+ os.system(cmd)
132
+
133
+ def action(self, context):
134
+ """Carry out action."""
135
+ raise NotImplementedError("abstract method")
136
+
137
+
138
+ class ConfirmGitStatus(Step):
139
+ """Confirm git status."""
140
+
141
+ def __init__(self, branch):
142
+ self.branch = branch
143
+
144
+ def action(self, context):
145
+ """Carry out action."""
146
+ self.instruct(
147
+ f"Make sure you're on: {self.branch}, you're local "
148
+ f"branch is up-to-date, and all new changes are merged "
149
+ f"in."
150
+ )
151
+ self.do_cmd(f"git checkout {self.branch}")
152
+ self.do_cmd("git pull")
153
+
154
+
155
+ class UpdateChangelog(Step):
156
+ """Update the changelog."""
157
+
158
+ def action(self, context):
159
+ """Carry out action."""
160
+ self.instruct(f"Update CHANGELOG for version: {context['version']}")
161
+
162
+
163
+ class UpdateReadme(Step):
164
+ """Update the readme."""
165
+
166
+ def action(self, context):
167
+ """Carry out action."""
168
+ self.instruct(f"Update README for version: {context['version']}")
169
+
170
+
171
+ class UpdateVersion(Step):
172
+ """Update sktime version."""
173
+
174
+ def action(self, context):
175
+ """Carry out action."""
176
+ self.instruct("Update __init__.py with new version")
177
+
178
+ def post(self, context):
179
+ """Post-action step."""
180
+ wait_for_enter()
181
+ context["version"] = find_version(context["package_name"], "__init__.py")
182
+
183
+
184
+ class MakeClean(Step):
185
+ """Make clean."""
186
+
187
+ def action(self, context):
188
+ """Carry out action."""
189
+ self.do_cmd("make clean")
190
+
191
+
192
+ class MakeDocs(Step):
193
+ """Make docs."""
194
+
195
+ def action(self, context):
196
+ """Carry out action."""
197
+ self.do_cmd("make docs")
198
+
199
+
200
+ class MakeDist(Step):
201
+ """Make dist."""
202
+
203
+ def action(self, context):
204
+ """Carry out action."""
205
+ self.do_cmd("make dist")
206
+
207
+
208
+ class UploadToTestPyPI(Step):
209
+ """Upload to test pypi."""
210
+
211
+ def action(self, context):
212
+ """Carry out action."""
213
+ self.instruct("Upload to TestPyPI")
214
+ cmd = "twine upload --repository-url https://test.pypi.org/legacy/ dist/*"
215
+ self.do_cmd(cmd)
216
+
217
+
218
+ class InstallFromTestPyPI(Step):
219
+ """Install from test pypi."""
220
+
221
+ def action(self, context):
222
+ """Carry out action."""
223
+ self.instruct("Check installation from TestPyPI")
224
+ self.do_cmd(
225
+ f"sh build_tools/check_install_from_test_pypi.sh {context['version']}"
226
+ )
227
+
228
+
229
+ class CheckVersionNumber(Step):
230
+ """Check version number."""
231
+
232
+ def action(self, context):
233
+ """Carry out action."""
234
+ self.instruct(
235
+ f"Ensure that the following command gives version: {context['version']}"
236
+ )
237
+ self.do_cmd(
238
+ f"python -c 'import {context['package_name']}; print("
239
+ f"{context['package_name']}.__version__)'"
240
+ )
241
+
242
+
243
+ class GitTagRelease(Step):
244
+ """Git tag release."""
245
+
246
+ def action(self, context):
247
+ """Carry out action."""
248
+ self.instruct("Tag version as a release")
249
+ self.do_cmd(f"git tag v{context['version']}")
250
+
251
+
252
+ class GitTagPreRelease(Step):
253
+ """Git tag prerelease."""
254
+
255
+ def action(self, context):
256
+ """Carry out action."""
257
+ self.instruct("Tag version as a pre-release (increment as needed)")
258
+ self.print_run(f"git tag v{context['version']}-rc.1")
259
+
260
+
261
+ class PushToGitHub(Step):
262
+ """Push to GitHub."""
263
+
264
+ def action(self, context):
265
+ """Carry out action."""
266
+ self.instruct("Add and commit to git, then push to GitHub")
267
+
268
+
269
+ class CheckCIStatus(Step):
270
+ """Check CI status."""
271
+
272
+ def action(self, context):
273
+ """Carry out action."""
274
+ self.instruct("Wait for CI to complete and check status")
275
+
276
+
277
+ class CheckOnlineDocs(Step):
278
+ """Check online docs."""
279
+
280
+ def action(self, context):
281
+ """Carry out action."""
282
+ self.instruct("Check online docs")
283
+ open_website(URLs.DOCS_ONLINE)
284
+
285
+
286
+ class CheckLocalDocs(Step):
287
+ """Check local docs."""
288
+
289
+ def action(self, context):
290
+ """Carry out action."""
291
+ self.instruct("Check local docs")
292
+ open_website(URLs.DOCS_LOCAL)
293
+
294
+
295
+ class CheckPyPIFiles(Step):
296
+ """Check pypi files."""
297
+
298
+ def action(self, context):
299
+ """Carry out action."""
300
+ self.instruct("Check PyPI files")
301
+ open_website(URLs.PYPI)
302
+
303
+
304
+ class PushTagToGitHub(Step):
305
+ """Push tag to GitHub."""
306
+
307
+ def action(self, context):
308
+ """Carry out action."""
309
+ self.do_cmd(f"git push origin v{context['version']}")
310
+
311
+
312
+ def main():
313
+ """Run release, main script."""
314
+ colorama.init()
315
+ steps = [
316
+ # prepare and run final checks
317
+ ConfirmGitStatus(branch="main"),
318
+ MakeClean(),
319
+ UpdateVersion(),
320
+ CheckVersionNumber(),
321
+ UpdateReadme(),
322
+ UpdateChangelog(),
323
+ MakeDocs(),
324
+ CheckLocalDocs(),
325
+ MakeDist(),
326
+ UploadToTestPyPI(),
327
+ InstallFromTestPyPI(),
328
+ PushToGitHub(),
329
+ CheckCIStatus(),
330
+ # check pre-release online
331
+ # GitTagPreRelease(),
332
+ # PushTagToGitHub(),
333
+ # make release
334
+ GitTagRelease(),
335
+ PushTagToGitHub(),
336
+ CheckCIStatus(),
337
+ CheckOnlineDocs(),
338
+ CheckPyPIFiles(),
339
+ ]
340
+ context = dict()
341
+ context["package_name"] = PACKAGE_NAME
342
+ context["version"] = find_version(context["package_name"], "__init__.py")
343
+ context["testdir"] = "temp/"
344
+ for step in steps:
345
+ step.run(context)
346
+ cprint("\nDone!", color="yellow", style="bright")
347
+
348
+
349
+ if __name__ == "__main__":
350
+ main()
sktime/source/build_tools/nb_json_formatter.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Notebook formatter.
2
+
3
+ Formats jupyter notebooks as follows:
4
+
5
+ * changes execution count to consecutive numbers, starting with 1
6
+ * sets json indent to 1 space
7
+ * adds a newline at the end, if not present
8
+
9
+ Does not change cell content or output.
10
+ """
11
+
12
+
13
+ def format_nb_json(notebook_path, indent=1):
14
+ """Format a jupyter notebook.
15
+
16
+ Changes notebook at ``notebook_path`` in place, as follows:
17
+
18
+ Formats jupyter notebooks as follows:
19
+
20
+ * changes execution count to consecutive numbers, starting with 1
21
+ * sets json indent to 1 space
22
+ * adds a newline at the end, if not present
23
+
24
+ Does not change cell content or output.
25
+
26
+ Parameters
27
+ ----------
28
+ notebook_path : str
29
+ Path to the notebook file. Accessed via ``open``.
30
+ indent: int, optional, default=1
31
+ Indentation to use for json output. Used in ``json.dump``.
32
+ """
33
+ import json
34
+
35
+ # Read the notebook
36
+ with open(notebook_path, encoding="utf-8") as f:
37
+ notebook = json.load(f)
38
+
39
+ # Update execution counts
40
+ execution_count = 1
41
+ for cell in notebook["cells"]:
42
+ if cell["cell_type"] == "code":
43
+ cell["execution_count"] = execution_count
44
+ execution_count += 1
45
+ for output in cell.get("outputs", []):
46
+ if "execution_count" in output:
47
+ output["execution_count"] = cell["execution_count"]
48
+
49
+ # Write the updated notebook back
50
+ with open(notebook_path, "w", encoding="utf-8") as f:
51
+ json.dump(notebook, f, indent=indent, ensure_ascii=False)
52
+ f.write("\n") # Add a newline at the end of the file
sktime/source/build_tools/run_blogposts.sh ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Script to run all blog post notebooks.
4
+ set -euxo pipefail
5
+
6
+ CMD="jupyter nbconvert --to notebook --inplace --execute --ExecutePreprocessor.timeout=600"
7
+
8
+ for notebook in examples/blog_posts/*.ipynb; do
9
+ echo "Running: $notebook"
10
+ $CMD "$notebook"
11
+ done
sktime/source/build_tools/run_examples.sh ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Script to run all example notebooks.
4
+ set -euxo pipefail
5
+
6
+ CMD="jupyter nbconvert --to notebook --inplace --execute --ExecutePreprocessor.timeout=600"
7
+
8
+ for notebook in examples/*.ipynb; do
9
+ echo "Running: $notebook"
10
+ $CMD "$notebook"
11
+ done
sktime/source/conftest.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Main configuration file for pytest.
2
+
3
+ Contents:
4
+ adds the following options to pytest
5
+ --matrixdesign : bool, default False
6
+ allows to turn on/off the sub-sampling in the tests (for shorter runtime)
7
+ "on" condition is partition/block design to ensure each estimator full tests are run
8
+ on each operating system at least once, and on each python version at least once,
9
+ but not necessarily on each operating system / python version combination
10
+ --only_changed_modules : bool, default False
11
+ turns on/off differential testing (for shorter runtime)
12
+ "on" condition ensures that only estimators are tested that have changed,
13
+ more precisely, only estimators whose class is in a module
14
+ that has changed compared to the main branch
15
+ "off" = runs tests for all estimators
16
+
17
+ by default, all options are off, including for default local runs of pytest
18
+ if multiple options are turned on, they are combined with AND,
19
+ i.e., intersection of estimators satisfying the conditions
20
+ """
21
+
22
+ # copyright: sktime developers, BSD-3-Clause License (see LICENSE file)
23
+
24
+ __author__ = ["fkiraly"]
25
+
26
+
27
+ def pytest_addoption(parser):
28
+ """Pytest command line parser options adder."""
29
+ parser.addoption(
30
+ "--matrixdesign",
31
+ default=False,
32
+ help="sub-sample estimators in tests by os/version matrix partition design",
33
+ )
34
+ parser.addoption(
35
+ "--only_changed_modules",
36
+ default=False,
37
+ help="test only estimators from modules that have changed compared to main",
38
+ )
39
+
40
+
41
+ def pytest_configure(config):
42
+ """Pytest configuration preamble."""
43
+ from sktime.tests import _config
44
+
45
+ if config.getoption("--matrixdesign") in [True, "True"]:
46
+ _config.MATRIXDESIGN = True
47
+ if config.getoption("--only_changed_modules") in [True, "True"]:
48
+ _config.ONLY_CHANGED_MODULES = True