diff --git a/README.md b/README.md index dcc8918..68b66ba 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Documentation: https://ml4trading.io/docs/models/ ## Part of the ML4T Library Ecosystem -This library is one of six interconnected ML4T libraries supporting the research and production workflow described in [Machine Learning for Trading](https://ml4trading.io). +This library is one of seven interconnected ML4T libraries supporting the research and production workflow described in [Machine Learning for Trading](https://ml4trading.io). ![ML4T Library Ecosystem](docs/images/ml4t_ecosystem_workflow_color.png) diff --git a/SECURITY.md b/SECURITY.md index bbe9db7..5e3eb02 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,7 +12,7 @@ remain supported only until the next stable release replaces them. ## Report a Vulnerability -Report suspected vulnerabilities privately by email to `stefan@ml4trading.io` with the subject +Report suspected vulnerabilities privately by email to `pm@ml4trading.io` with the subject `[ml4t-models security]`. Do not open a public issue. Include the affected version, impact, reproduction steps, and any known mitigation. Do not include diff --git a/pyproject.toml b/pyproject.toml index 9a221c0..9d05fe4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,14 +27,14 @@ include = [ [project] name = "ml4t-models" dynamic = ["version"] -description = "Finance-specific latent-factor and portfolio-learning models for ML4T" +description = "Finance-specific models for asset pricing, prediction, and portfolio learning" readme = "README.md" license = { text = "MIT" } authors = [ - { name = "Stefan Jansen", email = "stefan@ml4trading.io" }, + { name = "Stefan Jansen", email = "stefan@applied-ai.com" }, ] maintainers = [ - { name = "Stefan Jansen", email = "stefan@ml4trading.io" }, + { name = "Stefan Jansen", email = "pm@ml4trading.io" }, ] keywords = [ "finance", @@ -95,7 +95,7 @@ all = [ ] [project.urls] -Homepage = "https://ml4trading.io/docs/models/" +Homepage = "https://www.ml4trading.io/" Documentation = "https://www.ml4trading.io/docs/models/" Repository = "https://github.com/ml4t/models" Issues = "https://github.com/ml4t/models/issues" diff --git a/tests/test_release_candidate.py b/tests/test_release_candidate.py index 1ae3a1a..d73777e 100644 --- a/tests/test_release_candidate.py +++ b/tests/test_release_candidate.py @@ -4,6 +4,7 @@ import subprocess import tarfile import zipfile +from email.parser import BytesParser from io import BytesIO from pathlib import Path from urllib.parse import parse_qs, urlparse @@ -103,6 +104,35 @@ def test_candidate_contains_typing_and_documentation_contracts(candidate_dir: Pa assert "docs/getting-started/installation.md" in sdist_members +def test_candidate_distributions_expose_canonical_project_metadata(candidate_dir: Path) -> None: + wheel, sdist = candidate._distribution_files(candidate_dir) + with zipfile.ZipFile(wheel) as archive: + metadata_name = next( + name for name in archive.namelist() if name.endswith(".dist-info/METADATA") + ) + wheel_metadata = BytesParser().parsebytes(archive.read(metadata_name)) + + with tarfile.open(sdist, "r:gz") as archive: + metadata_member = next( + member + for member in archive.getmembers() + if member.name.count("/") == 1 and member.name.endswith("/PKG-INFO") + ) + stream = archive.extractfile(metadata_member) + assert stream is not None + sdist_metadata = BytesParser().parsebytes(stream.read()) + + for metadata in (wheel_metadata, sdist_metadata): + assert metadata["Author-email"] == "Stefan Jansen " + assert metadata["Maintainer-email"] == "Stefan Jansen " + assert metadata["Summary"] == ( + "Finance-specific models for asset pricing, prediction, and portfolio learning" + ) + project_urls = metadata.get_all("Project-URL", []) + assert "Homepage, https://www.ml4trading.io/" in project_urls + assert "Documentation, https://www.ml4trading.io/docs/models/" in project_urls + + def _performance_inputs(tmp_path: Path) -> tuple[list[Path], list[Path]]: records: list[Path] = [] arrays: list[Path] = [] diff --git a/tests/test_repo_hygiene.py b/tests/test_repo_hygiene.py index 518a6f0..29812fe 100644 --- a/tests/test_repo_hygiene.py +++ b/tests/test_repo_hygiene.py @@ -155,6 +155,6 @@ def test_security_policy_has_a_private_reporting_route_and_supported_versions() root = Path(__file__).parents[1] policy = (root / "SECURITY.md").read_text(encoding="utf-8") - assert "stefan@ml4trading.io" in policy + assert "pm@ml4trading.io" in policy assert "Do not open a public issue" in policy assert "Latest stable `0.1.x`" in policy