mt5cli 0.9.6__tar.gz → 0.9.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {mt5cli-0.9.6 → mt5cli-0.9.7}/PKG-INFO +9 -2
  2. {mt5cli-0.9.6 → mt5cli-0.9.7}/README.md +6 -0
  3. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/index.md +6 -0
  4. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/utils.py +9 -0
  5. {mt5cli-0.9.6 → mt5cli-0.9.7}/pyproject.toml +5 -2
  6. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_contracts.py +22 -0
  7. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_utils.py +12 -0
  8. {mt5cli-0.9.6 → mt5cli-0.9.7}/uv.lock +10 -3
  9. {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/local-qa/SKILL.md +0 -0
  10. {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/local-qa/scripts/qa.sh +0 -0
  11. {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/mt5cli/SKILL.md +0 -0
  12. {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/pr-feedback-triage/SKILL.md +0 -0
  13. {mt5cli-0.9.6 → mt5cli-0.9.7}/.claude/agents/codex.md +0 -0
  14. {mt5cli-0.9.6 → mt5cli-0.9.7}/.claude/settings.json +0 -0
  15. {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/FUNDING.yml +0 -0
  16. {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/dependabot.yml +0 -0
  17. {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/renovate.json +0 -0
  18. {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/workflows/ci.yml +0 -0
  19. {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/workflows/claude.yml +0 -0
  20. {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/workflows/release.yml +0 -0
  21. {mt5cli-0.9.6 → mt5cli-0.9.7}/.gitignore +0 -0
  22. {mt5cli-0.9.6 → mt5cli-0.9.7}/AGENTS.md +0 -0
  23. {mt5cli-0.9.6 → mt5cli-0.9.7}/CLAUDE.md +0 -0
  24. {mt5cli-0.9.6 → mt5cli-0.9.7}/LICENSE +0 -0
  25. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/cli.md +0 -0
  26. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/client.md +0 -0
  27. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/converters.md +0 -0
  28. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/exceptions.md +0 -0
  29. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/history.md +0 -0
  30. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/index.md +0 -0
  31. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/public-contract.md +0 -0
  32. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/schemas.md +0 -0
  33. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/sdk.md +0 -0
  34. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/storage.md +0 -0
  35. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/trading.md +0 -0
  36. {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/utils.md +0 -0
  37. {mt5cli-0.9.6 → mt5cli-0.9.7}/mkdocs.yml +0 -0
  38. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/__init__.py +0 -0
  39. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/__main__.py +0 -0
  40. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/cli.py +0 -0
  41. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/client.py +0 -0
  42. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/contract.py +0 -0
  43. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/converters.py +0 -0
  44. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/exceptions.py +0 -0
  45. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/history.py +0 -0
  46. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/retry.py +0 -0
  47. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/schemas.py +0 -0
  48. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/sdk.py +0 -0
  49. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/storage.py +0 -0
  50. {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/trading.py +0 -0
  51. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/__init__.py +0 -0
  52. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/conftest.py +0 -0
  53. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_cli.py +0 -0
  54. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_history.py +0 -0
  55. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_sdk.py +0 -0
  56. {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_trading.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mt5cli
3
- Version: 0.9.6
3
+ Version: 0.9.7
4
4
  Summary: Generic MT5 data and execution infrastructure for Python applications
5
5
  Project-URL: Repository, https://github.com/dceoy/mt5cli.git
6
6
  Author-email: dceoy <dceoy@users.noreply.github.com>
@@ -18,8 +18,9 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
18
18
  Requires-Python: <3.14,>=3.11
19
19
  Requires-Dist: click>=8.1.0
20
20
  Requires-Dist: pdmt5>=0.3.0
21
- Requires-Dist: pyarrow>=19.0.0
22
21
  Requires-Dist: typer>=0.15.0
22
+ Provides-Extra: parquet
23
+ Requires-Dist: pyarrow>=19.0.0; extra == 'parquet'
23
24
  Description-Content-Type: text/markdown
24
25
 
25
26
  # mt5cli
@@ -53,6 +54,12 @@ Built on top of [pdmt5](https://github.com/dceoy/pdmt5), a pandas-based data han
53
54
  pip install -U mt5cli MetaTrader5
54
55
  ```
55
56
 
57
+ Parquet export is not included by default. To enable it, install the `parquet` extra:
58
+
59
+ ```bash
60
+ pip install -U "mt5cli[parquet]" MetaTrader5
61
+ ```
62
+
56
63
  ## Python API (downstream packages)
57
64
 
58
65
  Import `MT5Client` for generic MT5 data access, schema normalization, and optional order primitives.
@@ -29,6 +29,12 @@ Built on top of [pdmt5](https://github.com/dceoy/pdmt5), a pandas-based data han
29
29
  pip install -U mt5cli MetaTrader5
30
30
  ```
31
31
 
32
+ Parquet export is not included by default. To enable it, install the `parquet` extra:
33
+
34
+ ```bash
35
+ pip install -U "mt5cli[parquet]" MetaTrader5
36
+ ```
37
+
32
38
  ## Python API (downstream packages)
33
39
 
34
40
  Import `MT5Client` for generic MT5 data access, schema normalization, and optional order primitives.
@@ -27,6 +27,12 @@ mt5cli provides a stable `MT5Client` Python API, standardized dataset schemas, s
27
27
  pip install mt5cli
28
28
  ```
29
29
 
30
+ Parquet export is not included by default. To enable it, install the `parquet` extra:
31
+
32
+ ```bash
33
+ pip install "mt5cli[parquet]"
34
+ ```
35
+
30
36
  ## Python API for downstream packages
31
37
 
32
38
  Import `MT5Client` for generic MT5 data access, schema normalization, and optional order primitives.
@@ -314,6 +314,7 @@ def export_dataframe(
314
314
  table_name: Table name for SQLite3 output.
315
315
 
316
316
  Raises:
317
+ ImportError: If the parquet format is requested but pyarrow is not installed.
317
318
  ValueError: If the output format is not supported.
318
319
  """
319
320
  if output_format == "csv":
@@ -326,6 +327,14 @@ def export_dataframe(
326
327
  indent=2,
327
328
  )
328
329
  elif output_format == "parquet":
330
+ try:
331
+ __import__("pyarrow")
332
+ except ImportError as exc:
333
+ msg = (
334
+ "Parquet export requires the optional dependency pyarrow. "
335
+ 'Install it with: pip install "mt5cli[parquet]"'
336
+ )
337
+ raise ImportError(msg) from exc
329
338
  df.to_parquet(output_path, index=False)
330
339
  elif output_format == "sqlite3":
331
340
  export_dataframe_to_sqlite(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mt5cli"
3
- version = "0.9.6"
3
+ version = "0.9.7"
4
4
  description = "Generic MT5 data and execution infrastructure for Python applications"
5
5
  authors = [{name = "dceoy", email = "dceoy@users.noreply.github.com"}]
6
6
  maintainers = [{name = "dceoy", email = "dceoy@users.noreply.github.com"}]
@@ -11,7 +11,6 @@ requires-python = ">= 3.11, < 3.14"
11
11
  dependencies = [
12
12
  "pdmt5>=0.3.0",
13
13
  "click >= 8.1.0",
14
- "pyarrow >= 19.0.0",
15
14
  "typer >= 0.15.0",
16
15
  ]
17
16
  classifiers = [
@@ -25,6 +24,9 @@ classifiers = [
25
24
  "Topic :: Office/Business :: Financial :: Investment",
26
25
  ]
27
26
 
27
+ [project.optional-dependencies]
28
+ parquet = ["pyarrow >= 19.0.0"]
29
+
28
30
  [project.scripts]
29
31
  mt5cli = "mt5cli.cli:main"
30
32
 
@@ -42,6 +44,7 @@ dev = [
42
44
  "pytest-mock >= 3.12.0",
43
45
  "pytest-cov >= 5.0.0",
44
46
  "pandas-stubs >= 2.2.3.250527",
47
+ "pyarrow >= 19.0.0",
45
48
  "mkdocs >= 1.6.1",
46
49
  "mkdocs-material >= 9.7.6",
47
50
  "mkdocstrings[python] >= 1.0.4",
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import re
6
6
  import sqlite3
7
7
  from datetime import UTC, datetime
8
+ from importlib.metadata import requires
8
9
  from pathlib import Path
9
10
  from typing import get_type_hints
10
11
  from unittest.mock import MagicMock
@@ -832,3 +833,24 @@ class TestStableSdkContract:
832
833
  assert result.index.tz is not None
833
834
  assert "time" not in result.columns
834
835
  assert "close" in result.columns
836
+
837
+
838
+ # ---------------------------------------------------------------------------
839
+ # Packaging metadata
840
+ # ---------------------------------------------------------------------------
841
+
842
+
843
+ def test_parquet_extra_declares_pyarrow() -> None:
844
+ """Package metadata lists pyarrow under the parquet optional extra."""
845
+ reqs = requires("mt5cli") or []
846
+ parquet_reqs = [r for r in reqs if "pyarrow" in r and "parquet" in r]
847
+ assert parquet_reqs, "pyarrow not found in parquet optional extra"
848
+
849
+
850
+ def test_pyarrow_not_in_core_dependencies() -> None:
851
+ """Pyarrow is not a core dependency; it belongs only in the parquet extra."""
852
+ reqs = requires("mt5cli") or []
853
+ core_reqs = [r for r in reqs if "extra ==" not in r]
854
+ assert not any("pyarrow" in r for r in core_reqs), (
855
+ "pyarrow should not appear in core dependencies"
856
+ )
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  import sqlite3
7
+ import sys
7
8
  from datetime import UTC, datetime
8
9
  from typing import TYPE_CHECKING
9
10
 
@@ -111,6 +112,17 @@ class TestExportDataframe:
111
112
  result = pd.read_parquet(output)
112
113
  pd.testing.assert_frame_equal(result, sample_df)
113
114
 
115
+ def test_export_parquet_without_pyarrow(
116
+ self,
117
+ tmp_path: Path,
118
+ sample_df: pd.DataFrame,
119
+ monkeypatch: pytest.MonkeyPatch,
120
+ ) -> None:
121
+ """Test that a clear error is raised when pyarrow is not installed."""
122
+ monkeypatch.setitem(sys.modules, "pyarrow", None)
123
+ with pytest.raises(ImportError, match="mt5cli\\[parquet\\]"):
124
+ export_dataframe(sample_df, tmp_path / "out.parquet", "parquet")
125
+
114
126
  def test_export_sqlite3(self, tmp_path: Path, sample_df: pd.DataFrame) -> None:
115
127
  """Test SQLite3 export."""
116
128
  output = tmp_path / "out.db"
@@ -487,21 +487,26 @@ wheels = [
487
487
 
488
488
  [[package]]
489
489
  name = "mt5cli"
490
- version = "0.9.6"
490
+ version = "0.9.7"
491
491
  source = { editable = "." }
492
492
  dependencies = [
493
493
  { name = "click" },
494
494
  { name = "pdmt5" },
495
- { name = "pyarrow" },
496
495
  { name = "typer" },
497
496
  ]
498
497
 
498
+ [package.optional-dependencies]
499
+ parquet = [
500
+ { name = "pyarrow" },
501
+ ]
502
+
499
503
  [package.dev-dependencies]
500
504
  dev = [
501
505
  { name = "mkdocs" },
502
506
  { name = "mkdocs-material" },
503
507
  { name = "mkdocstrings", extra = ["python"] },
504
508
  { name = "pandas-stubs" },
509
+ { name = "pyarrow" },
505
510
  { name = "pymdown-extensions" },
506
511
  { name = "pyright" },
507
512
  { name = "pytest" },
@@ -514,9 +519,10 @@ dev = [
514
519
  requires-dist = [
515
520
  { name = "click", specifier = ">=8.1.0" },
516
521
  { name = "pdmt5", specifier = ">=0.3.0" },
517
- { name = "pyarrow", specifier = ">=19.0.0" },
522
+ { name = "pyarrow", marker = "extra == 'parquet'", specifier = ">=19.0.0" },
518
523
  { name = "typer", specifier = ">=0.15.0" },
519
524
  ]
525
+ provides-extras = ["parquet"]
520
526
 
521
527
  [package.metadata.requires-dev]
522
528
  dev = [
@@ -524,6 +530,7 @@ dev = [
524
530
  { name = "mkdocs-material", specifier = ">=9.7.6" },
525
531
  { name = "mkdocstrings", extras = ["python"], specifier = ">=1.0.4" },
526
532
  { name = "pandas-stubs", specifier = ">=2.2.3.250527" },
533
+ { name = "pyarrow", specifier = ">=19.0.0" },
527
534
  { name = "pymdown-extensions", specifier = ">=10.21.2" },
528
535
  { name = "pyright", specifier = ">=1.1.407" },
529
536
  { name = "pytest", specifier = ">=9.0.3" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes