mt5api 1.0.4__tar.gz → 1.0.6__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 (64) hide show
  1. {mt5api-1.0.4 → mt5api-1.0.6}/PKG-INFO +2 -3
  2. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/constants.py +2 -2
  3. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/dependencies.py +2 -2
  4. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/main.py +7 -5
  5. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/models.py +1 -1
  6. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/account.py +1 -1
  7. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/calc.py +1 -1
  8. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/health.py +2 -2
  9. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/history.py +1 -1
  10. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/market.py +1 -1
  11. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/symbols.py +1 -1
  12. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/trading.py +1 -1
  13. mt5api-1.0.6/pyproject.toml +133 -0
  14. mt5api-1.0.4/.agents/skills/local-qa/SKILL.md +0 -22
  15. mt5api-1.0.4/.agents/skills/local-qa/scripts/qa.sh +0 -32
  16. mt5api-1.0.4/.agents/skills/mt5api/SKILL.md +0 -396
  17. mt5api-1.0.4/.github/CODEOWNERS +0 -2
  18. mt5api-1.0.4/.github/FUNDING.yml +0 -3
  19. mt5api-1.0.4/.github/dependabot.yml +0 -17
  20. mt5api-1.0.4/.github/renovate.json +0 -13
  21. mt5api-1.0.4/.github/workflows/ci.yml +0 -92
  22. mt5api-1.0.4/.github/workflows/claude.yml +0 -57
  23. mt5api-1.0.4/.github/workflows/release.yml +0 -44
  24. mt5api-1.0.4/AGENTS.md +0 -38
  25. mt5api-1.0.4/CLAUDE.md +0 -1
  26. mt5api-1.0.4/docs/api/deployment.md +0 -62
  27. mt5api-1.0.4/docs/api/index.md +0 -69
  28. mt5api-1.0.4/docs/api/rest-api.md +0 -336
  29. mt5api-1.0.4/docs/index.md +0 -75
  30. mt5api-1.0.4/mkdocs.yml +0 -72
  31. mt5api-1.0.4/pyproject.toml +0 -193
  32. mt5api-1.0.4/tests/__init__.py +0 -1
  33. mt5api-1.0.4/tests/conftest.py +0 -231
  34. mt5api-1.0.4/tests/mt5_constants.py +0 -75
  35. mt5api-1.0.4/tests/openapi_mt5_constants.py +0 -34
  36. mt5api-1.0.4/tests/test_account.py +0 -78
  37. mt5api-1.0.4/tests/test_auth.py +0 -177
  38. mt5api-1.0.4/tests/test_calc.py +0 -312
  39. mt5api-1.0.4/tests/test_cli.py +0 -127
  40. mt5api-1.0.4/tests/test_config.py +0 -213
  41. mt5api-1.0.4/tests/test_connection.py +0 -318
  42. mt5api-1.0.4/tests/test_dependencies.py +0 -205
  43. mt5api-1.0.4/tests/test_formatters.py +0 -182
  44. mt5api-1.0.4/tests/test_health.py +0 -256
  45. mt5api-1.0.4/tests/test_history.py +0 -394
  46. mt5api-1.0.4/tests/test_lifespan.py +0 -30
  47. mt5api-1.0.4/tests/test_main.py +0 -215
  48. mt5api-1.0.4/tests/test_market.py +0 -493
  49. mt5api-1.0.4/tests/test_middleware.py +0 -221
  50. mt5api-1.0.4/tests/test_models.py +0 -295
  51. mt5api-1.0.4/tests/test_symbols.py +0 -160
  52. mt5api-1.0.4/tests/test_trading.py +0 -308
  53. mt5api-1.0.4/uv.lock +0 -1742
  54. {mt5api-1.0.4 → mt5api-1.0.6}/.gitignore +0 -0
  55. {mt5api-1.0.4 → mt5api-1.0.6}/LICENSE +0 -0
  56. {mt5api-1.0.4 → mt5api-1.0.6}/README.md +0 -0
  57. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/__init__.py +0 -0
  58. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/__main__.py +0 -0
  59. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/auth.py +0 -0
  60. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/config.py +0 -0
  61. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/formatters.py +0 -0
  62. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/middleware.py +0 -0
  63. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/__init__.py +0 -0
  64. {mt5api-1.0.4 → mt5api-1.0.6}/mt5api/routers/connection.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: mt5api
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: MetaTrader 5 REST API
5
5
  Project-URL: Repository, https://github.com/dceoy/mt5api.git
6
6
  Author-email: dceoy <dceoy@users.noreply.github.com>
@@ -21,7 +21,6 @@ Requires-Dist: pandas>=3.0.3
21
21
  Requires-Dist: pdmt5>=1.2.0
22
22
  Requires-Dist: pyarrow>=18.0.0
23
23
  Requires-Dist: pydantic>=2.13.4
24
- Requires-Dist: python-multipart>=0.0.31
25
24
  Requires-Dist: uvicorn[standard]>=0.32.0
26
25
  Description-Content-Type: text/markdown
27
26
 
@@ -22,9 +22,9 @@ ENV_MT5API_PORT = "MT5API_PORT"
22
22
  ENV_MT5API_LOG_LEVEL = "MT5API_LOG_LEVEL"
23
23
  ENV_MT5API_ROUTER_PREFIX = "MT5API_ROUTER_PREFIX"
24
24
  ENV_MT5API_MAX_MARKET_BOOK_SUBSCRIPTIONS = "MT5API_MAX_MARKET_BOOK_SUBSCRIPTIONS"
25
- ENV_MT5API_SECRET_KEY = "MT5API_SECRET_KEY" # noqa: S105
25
+ ENV_MT5API_SECRET_KEY = "MT5API_SECRET_KEY" # ruff: ignore[hardcoded-password-string]
26
26
 
27
- DEFAULT_API_HOST = "0.0.0.0" # noqa: S104
27
+ DEFAULT_API_HOST = "0.0.0.0" # ruff: ignore[hardcoded-bind-all-interfaces]
28
28
  DEFAULT_API_PORT = 8000
29
29
  DEFAULT_API_LOG_LEVEL = "INFO"
30
30
  DEFAULT_API_ROUTER_PREFIX = ""
@@ -165,8 +165,8 @@ async def release_market_book_subscriptions(state: Mt5RuntimeState) -> None:
165
165
 
166
166
  async def run_in_threadpool(
167
167
  func: Callable[..., T],
168
- *args: Any, # noqa: ANN401
169
- **kwargs: Any, # noqa: ANN401
168
+ *args: Any, # ruff: ignore[any-type]
169
+ **kwargs: Any, # ruff: ignore[any-type]
170
170
  ) -> T:
171
171
  """Run a synchronous MT5 function without blocking the event loop.
172
172
 
@@ -226,13 +226,15 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
226
226
  app,
227
227
  max_market_book_subscriptions=get_configured_max_market_book_subscriptions(),
228
228
  )
229
- yield
230
- logger.info("Shutting down MT5 REST API...")
231
229
  try:
232
- await release_market_book_subscriptions(state)
230
+ yield
233
231
  finally:
234
- shutdown_mt5_client(state)
235
- logger.info("MT5 connection closed")
232
+ logger.info("Shutting down MT5 REST API...")
233
+ try:
234
+ await release_market_book_subscriptions(state)
235
+ finally:
236
+ shutdown_mt5_client(state)
237
+ logger.info("MT5 connection closed")
236
238
 
237
239
 
238
240
  app = FastAPI(
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from datetime import datetime # noqa: TC003
5
+ from datetime import datetime # ruff: ignore[typing-only-standard-library-import]
6
6
  from enum import StrEnum
7
7
  from typing import Annotated, Any, Self, TypeAlias
8
8
 
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  from typing import TYPE_CHECKING, Annotated
6
6
 
7
7
  from fastapi import APIRouter, Depends
8
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
8
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
9
9
 
10
10
  from mt5api.auth import verify_api_key
11
11
  from mt5api.dependencies import (
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  from typing import TYPE_CHECKING, Annotated
6
6
 
7
7
  from fastapi import APIRouter, Depends
8
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
8
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
9
9
 
10
10
  from mt5api.auth import verify_api_key
11
11
  from mt5api.dependencies import (
@@ -6,7 +6,7 @@ import logging
6
6
  from typing import TYPE_CHECKING, Annotated
7
7
 
8
8
  from fastapi import APIRouter, Depends, Request
9
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
9
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
10
10
 
11
11
  from mt5api.auth import verify_api_key
12
12
  from mt5api.constants import API_VERSION
@@ -54,7 +54,7 @@ async def get_health(request: Request) -> HealthResponse:
54
54
  if version_dict:
55
55
  mt5_version = f"{version_dict.get('mt5_terminal_version', 'unknown')}"
56
56
  mt5_connected = True
57
- except Exception as e: # noqa: BLE001
57
+ except Exception as e: # ruff: ignore[blind-except]
58
58
  logger.debug("MT5 not available for health check: %s", e)
59
59
 
60
60
  return HealthResponse(
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  from typing import TYPE_CHECKING, Annotated
6
6
 
7
7
  from fastapi import APIRouter, Depends
8
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
8
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
9
9
 
10
10
  from mt5api.auth import verify_api_key
11
11
  from mt5api.dependencies import (
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  from typing import TYPE_CHECKING, Annotated
6
6
 
7
7
  from fastapi import APIRouter, Depends
8
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
8
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
9
9
 
10
10
  from mt5api.auth import verify_api_key
11
11
  from mt5api.dependencies import (
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  from typing import TYPE_CHECKING, Annotated
6
6
 
7
7
  from fastapi import APIRouter, Depends
8
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
8
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
9
9
 
10
10
  from mt5api.auth import verify_api_key
11
11
  from mt5api.dependencies import (
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Annotated, Any
7
7
 
8
8
  from fastapi import APIRouter, Depends, Request, status
9
9
  from fastapi.responses import JSONResponse
10
- from pdmt5.dataframe import Mt5DataClient # noqa: TC002
10
+ from pdmt5.dataframe import Mt5DataClient # ruff: ignore[typing-only-third-party-import]
11
11
 
12
12
  from mt5api.auth import verify_api_key
13
13
  from mt5api.constants import ENV_MT5API_MAX_MARKET_BOOK_SUBSCRIPTIONS
@@ -0,0 +1,133 @@
1
+ [project]
2
+ name = "mt5api"
3
+ version = "1.0.6"
4
+ description = "MetaTrader 5 REST API"
5
+ authors = [{name = "dceoy", email = "dceoy@users.noreply.github.com"}]
6
+ maintainers = [{name = "dceoy", email = "dceoy@users.noreply.github.com"}]
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ readme = "README.md"
10
+ requires-python = ">= 3.11, < 3.15"
11
+ dependencies = [
12
+ "pdmt5 >= 1.2.0",
13
+ "fastapi >= 0.115.0",
14
+ "uvicorn[standard] >= 0.32.0",
15
+ "pandas >= 3.0.3",
16
+ "pydantic >= 2.13.4",
17
+ "pyarrow >= 18.0.0",
18
+ ]
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Environment :: Console",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Operating System :: Microsoft :: Windows",
24
+ "Programming Language :: Python",
25
+ "Programming Language :: Python :: 3",
26
+ "Intended Audience :: Financial and Insurance Industry",
27
+ "Topic :: Office/Business :: Financial :: Investment",
28
+ ]
29
+
30
+ [project.urls]
31
+ Repository = "https://github.com/dceoy/mt5api.git"
32
+
33
+ [tool.uv]
34
+ required-environments = ["platform_system == 'Windows'"]
35
+ exclude-newer = "1 day"
36
+ exclude-newer-package = { pdmt5 = false }
37
+
38
+ [dependency-groups]
39
+ dev = [
40
+ "httpx >= 0.27.0",
41
+ "httpx2 >= 2.0.0",
42
+ "ruff >= 0.17.1",
43
+ "pyright >= 1.1.407",
44
+ "pytest >= 8.0.0",
45
+ "pytest-asyncio >= 0.25.2",
46
+ "pytest-mock >= 3.12.0",
47
+ "pytest-cov >= 5.0.0",
48
+ "pandas-stubs >= 3.0.3.260530",
49
+ "types-pygments >= 2.19.0.20250516",
50
+ "types-colorama >= 0.4.15.20240311",
51
+ "types-pexpect >= 4.9.0.20250516",
52
+ "mkdocs >= 1.6.1",
53
+ "mkdocs-material >= 9.6.15",
54
+ "mkdocstrings[python] >= 0.29.1",
55
+ ]
56
+
57
+ [tool.hatch.build.targets.sdist]
58
+ only-include = ["mt5api"]
59
+
60
+ [tool.hatch.build.targets.wheel]
61
+ packages = ["mt5api"]
62
+
63
+ [tool.ruff]
64
+ line-length = 88
65
+ exclude = ["build", ".venv"]
66
+ preview = true
67
+
68
+ [tool.ruff.lint]
69
+ select = ["ALL"]
70
+ ignore = [
71
+ "CPY", # flake8-copyright (CPY)
72
+ "RET", # flake8-return (RET)
73
+ "missing-trailing-comma", # missing-trailing-comma
74
+ "boolean-type-hint-positional-argument", # boolean-type-hint-positional-argument
75
+ "boolean-default-value-positional-argument", # boolean-default-value-positional-argument
76
+ ]
77
+
78
+ [tool.ruff.lint.per-file-ignores]
79
+ "tests/**/*.py" = [
80
+ "docstring-missing-returns", # Missing return documentation
81
+ "docstring-missing-exception", # Raised exception missing from docstring
82
+ "import-private-name", # Private name import
83
+ "too-many-public-methods", # Too many public methods
84
+ "magic-value-comparison", # Magic value used in comparison
85
+ "no-self-use", # Method could be function/static/classmethod
86
+ "assert", # Use of assert (acceptable in tests)
87
+ "hardcoded-password-func-arg", # Possible hardcoded password
88
+ "private-member-access", # Private member accessed
89
+ ]
90
+
91
+ [tool.ruff.lint.pydocstyle]
92
+ convention = "google"
93
+
94
+ [tool.ruff.lint.pylint]
95
+ max-args = 10
96
+ max-public-methods = 40
97
+
98
+ [tool.pyright]
99
+ exclude = ["build", ".venv"]
100
+ venvPath = "."
101
+ venv = ".venv"
102
+ typeCheckingMode = "strict"
103
+ reportMissingTypeStubs = "none"
104
+
105
+ [tool.pytest.ini_options]
106
+ addopts = [
107
+ "--cov=mt5api",
108
+ "--cov-branch",
109
+ "--doctest-modules",
110
+ "--capture=no",
111
+ ]
112
+ pythonpath = ["."]
113
+ testpaths = ["tests"]
114
+ python_files = ["test_*.py", "*_test.py"]
115
+ python_classes = ["Test*"]
116
+ python_functions = ["test_*"]
117
+ minversion = "6.0"
118
+
119
+ [tool.coverage.run]
120
+ source = ["mt5api"]
121
+ omit = [
122
+ "**/__init__.py",
123
+ "tests/**",
124
+ ]
125
+
126
+ [tool.coverage.report]
127
+ show_missing = true
128
+ fail_under = 100
129
+ exclude_lines = ["if TYPE_CHECKING:"]
130
+
131
+ [build-system]
132
+ requires = ["hatchling"]
133
+ build-backend = "hatchling.build"
@@ -1,22 +0,0 @@
1
- ---
2
- name: local-qa
3
- description: Run local QA including formatting, linting, and testing for the repository. Use whenever any file has been updated.
4
- disable-model-invocation: false
5
- ---
6
-
7
- # Local QA (format, lint, and test)
8
-
9
- Run the local QA script `scripts/qa.sh` in this skill.
10
-
11
- ## Procedure
12
-
13
- - Execute the script exactly as shown above when this skill is triggered.
14
- - Capture and summarize key output (success/failure, major warnings, and any files modified).
15
- - If the script fails due to missing tooling (`command not found`, missing executable, or equivalent), install the missing tool(s) and rerun `./scripts/qa.sh`.
16
- - Install tools using this order of preference:
17
- 1. Use the project's package manager when applicable (`uv`/`poetry` for Python, package manager scripts/dependencies for Node.js).
18
- 2. Use a system package manager (`brew` on macOS, `apt` on Debian/Ubuntu) when project-local install is not applicable.
19
- 3. Use language-specific installers as fallback (`pipx`/`pip`, `npm`, `go install`, etc.).
20
- - If multiple tools are missing, repeat install -> rerun until QA completes or you hit a blocker.
21
- - If installation fails or requires unavailable privileges, report what was attempted, the exact failure, and stop.
22
- - Do not run unrelated commands; only run commands needed for QA and missing-tool installation.
@@ -1,32 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- set -euox pipefail
4
- cd "$(git rev-parse --show-toplevel)"
5
-
6
- COOLDOWN_DAYS=7
7
- export UV_EXCLUDE_NEWER="${COOLDOWN_DAYS} days"
8
- export NPM_CONFIG_MIN_RELEASE_AGE="${COOLDOWN_DAYS}"
9
- export PNPM_CONFIG_MINIMUM_RELEASE_AGE=$((COOLDOWN_DAYS * 24 * 60))
10
-
11
- # Python
12
- uv sync
13
- uv run ruff format .
14
- uv run ruff check --fix .
15
- uv run pyright .
16
- uv run pytest
17
-
18
- # Markdown
19
- npx -y prettier --write './**/*.md'
20
-
21
- # GitHub Actions
22
- case "${OSTYPE}" in
23
- darwin* | linux* )
24
- zizmor --fix=safe .github/workflows
25
- git ls-files -z -- '.github/workflows/*.yml' | xargs -0 -t actionlint
26
- git ls-files -z -- '.github/workflows/*.yml' | xargs -0 -t yamllint -d '{"extends": "relaxed", "rules": {"line-length": "disable"}}'
27
- checkov --framework=all --output=github_failed_only --directory=.
28
- ;;
29
- * )
30
- echo "GitHub Actions linting is only supported on Linux and macOS."
31
- ;;
32
- esac