mt5api 1.0.5__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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: mt5api
3
- Version: 1.0.5
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>
@@ -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,195 +0,0 @@
1
- [project]
2
- name = "mt5api"
3
- version = "1.0.5"
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 week"
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.11.0",
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 = [
70
- "F", # Pyflakes (F)
71
- "E", # pycodestyle error (E)
72
- "W", # pycodestyle warning (W)
73
- "C90", # mccabe (C90)
74
- "I", # isort (I)
75
- "N", # pep8-naming (N)
76
- "D", # pydocstyle (D)
77
- "UP", # pyupgrade (UP)
78
- "S", # flake8-bandit (S)
79
- "B", # flake8-bugbear (B)
80
- "C4", # flake8-comprehensions (C4)
81
- "SIM", # flake8-simplify (SIM)
82
- "ARG", # flake8-unused-arguments (ARG)
83
- "PD", # pandas-vet (PD)
84
- "PLC", # Pylint convention (PLC)
85
- "PLE", # Pylint error (PLE)
86
- "PLR", # Pylint refactor (PLR)
87
- "PLW", # Pylint warning (PLW)
88
- "FLY", # flynt (FLY)
89
- "NPY", # NumPy-specific rules (NPY)
90
- "PERF", # Perflint (PERF)
91
- "FURB", # refurb (FURB)
92
- "RUF", # Ruff-specific rules (RUF)
93
- "YTT", # flake8-2020 (YTT)
94
- "ANN", # flake8-annotations (ANN)
95
- "ASYNC", # flake8-async (ASYNC)
96
- "BLE", # flake8-blind-except (BLE)
97
- "FBT", # flake8-boolean-trap (FBT)
98
- "A", # flake8-builtins (A)
99
- "COM", # flake8-commas (COM)
100
- # "CPY", # flake8-copyright (CPY)
101
- "DTZ", # flake8-datetimez (DTZ)
102
- "T10", # flake8-debugger (T10)
103
- "DJ", # flake8-django (DJ)
104
- "EM", # flake8-errmsg (EM)
105
- "EXE", # flake8-executable (EXE)
106
- "FA", # flake8-future-annotations (FA)
107
- "ISC", # flake8-implicit-str-concat (ISC)
108
- "ICN", # flake8-import-conventions (ICN)
109
- "LOG", # flake8-logging (LOG)
110
- "G", # flake8-logging-format (G)
111
- "INP", # flake8-no-pep420 (INP)
112
- "PIE", # flake8-pie (PIE)
113
- "T20", # flake8-print (T20)
114
- "PYI", # flake8-pyi (PYI)
115
- "PT", # flake8-pytest-style (PT)
116
- "Q", # flake8-quotes (Q)
117
- "RSE", # flake8-raise (RSE)
118
- # "RET", # flake8-return (RET)
119
- "SLF", # flake8-self (SLF)
120
- "SLOT", # flake8-slots (SLOT)
121
- "TID", # flake8-tidy-imports (TID)
122
- "TCH", # flake8-type-checking (TCH)
123
- "INT", # flake8-gettext (INT)
124
- "PTH", # flake8-use-pathlib (PTH)
125
- "TD", # flake8-todos (TD)
126
- "FIX", # flake8-fixme (FIX)
127
- "ERA", # eradicate (ERA)
128
- "PGH", # pygrep-hooks (PGH)
129
- "TRY", # tryceratops (TRY)
130
- "FAST", # FastAPI (FAST)
131
- "AIR", # Airflow (AIR)
132
- "DOC", # pydoclint (DOC)
133
- ]
134
- ignore = [
135
- "COM812", # missing-trailing-comma
136
- "FBT001", # boolean-type-hint-positional-argument
137
- "FBT002", # boolean-default-value-positional-argument
138
- ]
139
-
140
- [tool.ruff.lint.per-file-ignores]
141
- "tests/**/*.py" = [
142
- "DOC201", # Missing return documentation
143
- "DOC501", # Raised exception missing from docstring
144
- "PLC2701", # Private name import
145
- "PLR0904", # Too many public methods
146
- "PLR2004", # Magic value used in comparison
147
- "PLR6301", # Method could be function/static/classmethod
148
- "S101", # Use of assert (acceptable in tests)
149
- "S106", # Possible hardcoded password
150
- "SLF001", # Private member accessed
151
- ]
152
-
153
- [tool.ruff.lint.pydocstyle]
154
- convention = "google"
155
-
156
- [tool.ruff.lint.pylint]
157
- max-args = 10
158
- max-public-methods = 40
159
-
160
- [tool.pyright]
161
- exclude = ["build", ".venv"]
162
- venvPath = "."
163
- venv = ".venv"
164
- typeCheckingMode = "strict"
165
- reportMissingTypeStubs = "none"
166
-
167
- [tool.pytest.ini_options]
168
- addopts = [
169
- "--cov=mt5api",
170
- "--cov-branch",
171
- "--doctest-modules",
172
- "--capture=no",
173
- ]
174
- pythonpath = ["."]
175
- testpaths = ["tests"]
176
- python_files = ["test_*.py", "*_test.py"]
177
- python_classes = ["Test*"]
178
- python_functions = ["test_*"]
179
- minversion = "6.0"
180
-
181
- [tool.coverage.run]
182
- source = ["mt5api"]
183
- omit = [
184
- "**/__init__.py",
185
- "tests/**",
186
- ]
187
-
188
- [tool.coverage.report]
189
- show_missing = true
190
- fail_under = 100
191
- exclude_lines = ["if TYPE_CHECKING:"]
192
-
193
- [build-system]
194
- requires = ["hatchling"]
195
- build-backend = "hatchling.build"
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