mt5cli 1.2.1__tar.gz → 1.2.2__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 (74) hide show
  1. {mt5cli-1.2.1 → mt5cli-1.2.2}/PKG-INFO +1 -1
  2. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/history.py +9 -1
  3. {mt5cli-1.2.1 → mt5cli-1.2.2}/pyproject.toml +1 -1
  4. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_history.py +14 -3
  5. {mt5cli-1.2.1 → mt5cli-1.2.2}/uv.lock +1 -1
  6. mt5cli-1.2.1/.github/workflows/opencode.yml +0 -72
  7. {mt5cli-1.2.1 → mt5cli-1.2.2}/.agents/skills/local-qa/SKILL.md +0 -0
  8. {mt5cli-1.2.1 → mt5cli-1.2.2}/.agents/skills/local-qa/scripts/qa.sh +0 -0
  9. {mt5cli-1.2.1 → mt5cli-1.2.2}/.agents/skills/mt5cli/SKILL.md +0 -0
  10. {mt5cli-1.2.1 → mt5cli-1.2.2}/.agents/skills/pr-feedback-triage/SKILL.md +0 -0
  11. {mt5cli-1.2.1 → mt5cli-1.2.2}/.claude/agents/codex.md +0 -0
  12. {mt5cli-1.2.1 → mt5cli-1.2.2}/.claude/settings.json +0 -0
  13. {mt5cli-1.2.1 → mt5cli-1.2.2}/.github/FUNDING.yml +0 -0
  14. {mt5cli-1.2.1 → mt5cli-1.2.2}/.github/dependabot.yml +0 -0
  15. {mt5cli-1.2.1 → mt5cli-1.2.2}/.github/renovate.json +0 -0
  16. {mt5cli-1.2.1 → mt5cli-1.2.2}/.github/workflows/ci.yml +0 -0
  17. {mt5cli-1.2.1 → mt5cli-1.2.2}/.github/workflows/claude.yml +0 -0
  18. {mt5cli-1.2.1 → mt5cli-1.2.2}/.github/workflows/release.yml +0 -0
  19. {mt5cli-1.2.1 → mt5cli-1.2.2}/.gitignore +0 -0
  20. {mt5cli-1.2.1 → mt5cli-1.2.2}/AGENTS.md +0 -0
  21. {mt5cli-1.2.1 → mt5cli-1.2.2}/CLAUDE.md +0 -0
  22. {mt5cli-1.2.1 → mt5cli-1.2.2}/LICENSE +0 -0
  23. {mt5cli-1.2.1 → mt5cli-1.2.2}/README.md +0 -0
  24. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/cli.md +0 -0
  25. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/client.md +0 -0
  26. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/converters.md +0 -0
  27. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/exceptions.md +0 -0
  28. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/grafana.md +0 -0
  29. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/history.md +0 -0
  30. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/index.md +0 -0
  31. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/marketdata.md +0 -0
  32. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/observability.md +0 -0
  33. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/public-contract.md +0 -0
  34. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/schemas.md +0 -0
  35. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/telemetry.md +0 -0
  36. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/trading.md +0 -0
  37. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/api/utils.md +0 -0
  38. {mt5cli-1.2.1 → mt5cli-1.2.2}/docs/index.md +0 -0
  39. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/README.md +0 -0
  40. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/compose.yml +0 -0
  41. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/dashboards/mt5cli-market.json +0 -0
  42. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/dashboards/mt5cli-overview.json +0 -0
  43. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/dashboards/mt5cli-trades.json +0 -0
  44. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/provisioning/dashboards/mt5cli.yml +0 -0
  45. {mt5cli-1.2.1 → mt5cli-1.2.2}/examples/grafana/provisioning/datasources/mt5cli-sqlite.yml +0 -0
  46. {mt5cli-1.2.1 → mt5cli-1.2.2}/mkdocs.yml +0 -0
  47. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/__init__.py +0 -0
  48. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/__main__.py +0 -0
  49. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/cli.py +0 -0
  50. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/client.py +0 -0
  51. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/contract.py +0 -0
  52. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/converters.py +0 -0
  53. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/exceptions.py +0 -0
  54. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/grafana.py +0 -0
  55. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/marketdata.py +0 -0
  56. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/observability.py +0 -0
  57. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/retry.py +0 -0
  58. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/schemas.py +0 -0
  59. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/telemetry.py +0 -0
  60. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/trading.py +0 -0
  61. {mt5cli-1.2.1 → mt5cli-1.2.2}/mt5cli/utils.py +0 -0
  62. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/__init__.py +0 -0
  63. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/conftest.py +0 -0
  64. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_cli.py +0 -0
  65. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_client.py +0 -0
  66. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_contracts.py +0 -0
  67. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_examples.py +0 -0
  68. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_grafana.py +0 -0
  69. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_marketdata.py +0 -0
  70. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_observability.py +0 -0
  71. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_packaging.py +0 -0
  72. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_telemetry.py +0 -0
  73. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_trading.py +0 -0
  74. {mt5cli-1.2.1 → mt5cli-1.2.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mt5cli
3
- Version: 1.2.1
3
+ Version: 1.2.2
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>
@@ -1749,9 +1749,17 @@ def _stream_symbol_frames(
1749
1749
  """
1750
1750
  table_exists = False
1751
1751
  for sym in symbols:
1752
+ frame = fetch_frame(sym)
1753
+ if len(frame.columns) == 0:
1754
+ logger.warning(
1755
+ "Skipping %s for symbol=%s: dataset returned no columns",
1756
+ dataset.table_name,
1757
+ sym,
1758
+ )
1759
+ continue
1752
1760
  table_exists = write_streamed_frame(
1753
1761
  conn,
1754
- fetch_frame(sym),
1762
+ frame,
1755
1763
  dataset,
1756
1764
  table_exists,
1757
1765
  if_exists,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mt5cli"
3
- version = "1.2.1"
3
+ version = "1.2.2"
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"}]
@@ -2388,7 +2388,10 @@ class TestIncrementalIntegration:
2388
2388
  "SELECT ticket, time_setup, type FROM history_orders",
2389
2389
  ).fetchall()
2390
2390
  assert rows == [(1, "2024-01-01T00:00:01+00:00", 1)]
2391
- assert "Skipping history_orders: dataset returned no columns" in caplog.text
2391
+ assert (
2392
+ "Skipping history_orders for symbol=GBPUSD: dataset returned no columns"
2393
+ in caplog.text
2394
+ )
2392
2395
 
2393
2396
  def test_write_collected_datasets_and_edge_branches(
2394
2397
  self,
@@ -2541,12 +2544,16 @@ class TestIncrementalIntegration:
2541
2544
  def test_write_rates_skips_empty_schema(
2542
2545
  self,
2543
2546
  tmp_path: Path,
2547
+ caplog: pytest.LogCaptureFixture,
2544
2548
  ) -> None:
2545
- """Test rates writer skips frames with no columns after normalization."""
2549
+ """Test rates writer logs the symbol when a frame has no columns."""
2546
2550
  client = MagicMock()
2547
2551
  client.copy_rates_range.return_value = pd.DataFrame()
2548
2552
  written_columns: dict[Dataset, set[str]] = {}
2549
- with sqlite3.connect(tmp_path / "empty-rates.db") as conn:
2553
+ with (
2554
+ caplog.at_level(logging.WARNING, logger="mt5cli.history"),
2555
+ sqlite3.connect(tmp_path / "empty-rates.db") as conn,
2556
+ ):
2550
2557
  assert not write_rates_dataset(
2551
2558
  conn,
2552
2559
  client,
@@ -2557,6 +2564,10 @@ class TestIncrementalIntegration:
2557
2564
  IfExists.APPEND,
2558
2565
  written_columns,
2559
2566
  )
2567
+ assert (
2568
+ "Skipping rates for symbol=EURUSD: dataset returned no columns"
2569
+ in caplog.text
2570
+ )
2560
2571
 
2561
2572
  def test_write_symbols_dataset_snapshots_metadata(
2562
2573
  self,
@@ -499,7 +499,7 @@ wheels = [
499
499
 
500
500
  [[package]]
501
501
  name = "mt5cli"
502
- version = "1.2.1"
502
+ version = "1.2.2"
503
503
  source = { editable = "." }
504
504
  dependencies = [
505
505
  { name = "click" },
@@ -1,72 +0,0 @@
1
- ---
2
- name: Pull request review and mention bot using OpenCode
3
- on:
4
- pull_request:
5
- types:
6
- - opened
7
- - ready_for_review
8
- issue_comment:
9
- types:
10
- - created
11
- pull_request_review_comment:
12
- types:
13
- - created
14
- pull_request_review:
15
- types:
16
- - submitted
17
- issues:
18
- types:
19
- - opened
20
- - assigned
21
- permissions:
22
- contents: read
23
- jobs:
24
- opencode-review:
25
- if: >
26
- github.event_name == 'pull_request'
27
- && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)
28
- && (! github.event.pull_request.draft)
29
- && (! startsWith(github.head_ref, 'dependabot/'))
30
- && (! startsWith(github.head_ref, 'renovate/'))
31
- permissions:
32
- contents: read
33
- pull-requests: write
34
- issues: write
35
- id-token: write
36
- actions: read
37
- uses: dceoy/gh-actions-for-devops/.github/workflows/opencode-review.yml@main # zizmor: ignore[unpinned-uses]
38
- with:
39
- model: opencode-go/kimi-k2.7-code
40
- secrets:
41
- OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
42
- GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
43
- opencode-bot:
44
- if: >
45
- (
46
- (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
47
- && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
48
- && (contains(github.event.comment.body, '/oc') || contains(github.event.comment.body, '/opencode'))
49
- ) || (
50
- github.event_name == 'pull_request_review'
51
- && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)
52
- && (contains(github.event.review.body, '/oc') || contains(github.event.review.body, '/opencode'))
53
- ) || (
54
- github.event_name == 'issues'
55
- && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)
56
- && (
57
- (contains(github.event.issue.body, '/oc') || contains(github.event.issue.title, '/oc'))
58
- || (contains(github.event.issue.body, '/opencode') || contains(github.event.issue.title, '/opencode'))
59
- )
60
- )
61
- permissions:
62
- contents: read
63
- pull-requests: write
64
- issues: write
65
- id-token: write
66
- actions: read
67
- uses: dceoy/gh-actions-for-devops/.github/workflows/opencode-bot.yml@main # zizmor: ignore[unpinned-uses]
68
- with:
69
- model: opencode-go/glm-5.2
70
- secrets:
71
- OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
72
- GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
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
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