mainsequence 3.3.8__tar.gz → 3.4.1__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 (126) hide show
  1. {mainsequence-3.3.8 → mainsequence-3.4.1}/PKG-INFO +57 -5
  2. mainsequence-3.4.1/README.md +68 -0
  3. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/cli/cli.py +0 -88
  4. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/models_tdag.py +110 -33
  5. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/data_nodes/run_operations.py +9 -11
  6. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence.egg-info/PKG-INFO +57 -5
  7. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence.egg-info/requires.txt +1 -0
  8. {mainsequence-3.3.8 → mainsequence-3.4.1}/pyproject.toml +2 -1
  9. mainsequence-3.3.8/README.md +0 -17
  10. {mainsequence-3.3.8 → mainsequence-3.4.1}/LICENSE +0 -0
  11. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/__init__.py +0 -0
  12. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/__main__.py +0 -0
  13. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/cli/__init__.py +0 -0
  14. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/cli/api.py +0 -0
  15. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/cli/config.py +0 -0
  16. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/cli/ssh_utils.py +0 -0
  17. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/__init__.py +0 -0
  18. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/base.py +0 -0
  19. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  20. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  21. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/data_sources_interfaces/timescale.py +0 -0
  22. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/exceptions.py +0 -0
  23. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/models_helpers.py +0 -0
  24. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/models_report_studio.py +0 -0
  25. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/models_vam.py +0 -0
  26. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/client/utils.py +0 -0
  27. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/__init__.py +0 -0
  28. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/__init__.py +0 -0
  29. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/config.toml +0 -0
  30. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
  31. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/image_1_base64.txt +0 -0
  32. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/image_2_base64.txt +0 -0
  33. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/image_3_base64.txt +0 -0
  34. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/image_4_base64.txt +0 -0
  35. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/image_5_base64.txt +0 -0
  36. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/assets/logo.png +0 -0
  37. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/core/__init__.py +0 -0
  38. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/core/theme.py +0 -0
  39. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
  40. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/dashboards/streamlit/scaffold.py +0 -0
  41. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instrumentation/__init__.py +0 -0
  42. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instrumentation/utils.py +0 -0
  43. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/__init__.py +0 -0
  44. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/data_interface/__init__.py +0 -0
  45. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/data_interface/data_interface.py +0 -0
  46. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/__init__.py +0 -0
  47. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/base_instrument.py +0 -0
  48. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/bond.py +0 -0
  49. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/european_option.py +0 -0
  50. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/interest_rate_swap.py +0 -0
  51. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/json_codec.py +0 -0
  52. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/knockout_fx_option.py +0 -0
  53. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/position.py +0 -0
  54. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/ql_fields.py +0 -0
  55. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments/vanilla_fx_option.py +0 -0
  56. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/instruments.default.toml +0 -0
  57. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/__init__.py +0 -0
  58. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/black_scholes.py +0 -0
  59. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/bond_pricer.py +0 -0
  60. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/fx_option_pricer.py +0 -0
  61. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/indices.py +0 -0
  62. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/knockout_fx_pricer.py +0 -0
  63. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/pricing_models/swap_pricer.py +0 -0
  64. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/settings.py +0 -0
  65. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/instruments/utils.py +0 -0
  66. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/logconf.py +0 -0
  67. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/reportbuilder/__init__.py +0 -0
  68. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/reportbuilder/__main__.py +0 -0
  69. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/reportbuilder/examples/ms_template_report.py +0 -0
  70. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/reportbuilder/model.py +0 -0
  71. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/reportbuilder/slide_templates.py +0 -0
  72. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/__init__.py +0 -0
  73. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/__main__.py +0 -0
  74. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/config.py +0 -0
  75. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/data_nodes/__init__.py +0 -0
  76. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/data_nodes/build_operations.py +0 -0
  77. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/data_nodes/data_nodes.py +0 -0
  78. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/data_nodes/persist_managers.py +0 -0
  79. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/data_nodes/utils.py +0 -0
  80. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/future_registry.py +0 -0
  81. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/tdag/utils.py +0 -0
  82. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/__init__.py +0 -0
  83. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/agent_interface.py +0 -0
  84. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/config_handling.py +0 -0
  85. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
  86. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/__init__.py +0 -0
  87. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/etf_replicator_app.py +0 -0
  88. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/generate_report.py +0 -0
  89. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/load_external_portfolio.py +0 -0
  90. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/news_app.py +0 -0
  91. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/portfolio_report_app.py +0 -0
  92. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/portfolio_table.py +0 -0
  93. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/run_named_portfolio.py +0 -0
  94. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/run_portfolio.py +0 -0
  95. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/templates/base.html +0 -0
  96. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/apps/templates/report.html +0 -0
  97. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +0 -0
  98. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +0 -0
  99. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +0 -0
  100. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +0 -0
  101. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +0 -0
  102. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +0 -0
  103. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/prices/__init__.py +0 -0
  104. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +0 -0
  105. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/prices/utils.py +0 -0
  106. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +0 -0
  107. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +0 -0
  108. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/data_nodes.py +0 -0
  109. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/enums.py +0 -0
  110. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/models.py +0 -0
  111. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/notebook_handling.py +0 -0
  112. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/portfolio_interface.py +0 -0
  113. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
  114. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/resource_factory/app_factory.py +0 -0
  115. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/resource_factory/base_factory.py +0 -0
  116. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +0 -0
  117. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +0 -0
  118. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence/virtualfundbuilder/utils.py +0 -0
  119. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence.egg-info/SOURCES.txt +0 -0
  120. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence.egg-info/dependency_links.txt +0 -0
  121. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence.egg-info/entry_points.txt +0 -0
  122. {mainsequence-3.3.8 → mainsequence-3.4.1}/mainsequence.egg-info/top_level.txt +0 -0
  123. {mainsequence-3.3.8 → mainsequence-3.4.1}/setup.cfg +0 -0
  124. {mainsequence-3.3.8 → mainsequence-3.4.1}/tests/test_agent.py +0 -0
  125. {mainsequence-3.3.8 → mainsequence-3.4.1}/tests/test_portfolio.py +0 -0
  126. {mainsequence-3.3.8 → mainsequence-3.4.1}/tests/test_replicator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.3.8
3
+ Version: 3.4.1
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -87,6 +87,7 @@ Requires-Dist: duckdb
87
87
  Requires-Dist: plotly
88
88
  Requires-Dist: typer
89
89
  Requires-Dist: QuantLib
90
+ Requires-Dist: streamlit
90
91
  Dynamic: license-file
91
92
 
92
93
  <p align="center">
@@ -97,12 +98,63 @@ Dynamic: license-file
97
98
 
98
99
 
99
100
 
100
- The **Main Sequence Python SDK** is a powerful set of client libraries designed to facilitate interaction with Main Sequence systems using Python.
101
+ The Main Sequence Python SDK is a high-performance client library that enables seamless integration with the Main Sequence platform.
102
+ It provides a unified and intuitive interface for interacting with data, compute, and intelligence services across the platform.
101
103
 
102
- **We strongly** encourage you to go through our examples.
103
- We have built the examples as individual Jupyter notebooks that explain the SDK through use cases.
104
- Since most platform usage involves a combination of operations, this is the most intuitive way to learn about Main Sequence.
104
+ Main Sequence functions as a centralized engine for data intelligence—integrating information from diverse data sources and systems
105
+ while abstracting away the complexity of underlying storage layers. This allows quants, researchers, analysts,
106
+ and engineers to focus on the data-generating process itself, while Main Sequence optimizes all CRUD operations and manages
107
+ the mapping between logical data structures and physical storage.
105
108
 
109
+ The Main Sequence SDK is also a foundational component of all Main Sequence Platform projects.
110
+ It acts as the backbone for automation, process orchestration, and the rapid development of dashboards,
111
+ data nodes, and agentic tools built on top of the platform.
106
112
 
113
+ ---
114
+
115
+ ## Developing with the Main Sequence SDK & Platform
116
+ To make it easy to work on Main Sequence projects from your local environment, you have two options:
117
+
118
+ 1. **Use the MainSequence CLI directly in your terminal**, or
119
+ 2. **Use the Main Sequence VS Code extension** (recommended if you already work in VS Code).
120
+
121
+ The VS Code extension provides a more visual, editor-integrated workflow on top of what the CLI offers.
122
+
123
+
124
+ ### Visual Studio Code Extension
125
+
126
+ 1. **Open the Extensions view in VS Code**
127
+
128
+ - **macOS:** Press `Cmd` + `Shift` + `X`
129
+ - **Windows/Linux:** Press `Ctrl` + `Shift` + `X`
130
+ - Or click the **Extensions** icon in the Activity Bar on the left side of the window.
131
+
132
+ 2. **Search for the extension**
133
+
134
+ In the Extensions search box, type Main Sequence and press Enter.:
135
+
136
+
137
+ ![img.png](/docs/img/vs_code_extension.png)
138
+
139
+ ### MainSequence CLI
140
+
141
+ MainSequence CLI is a small helper tool to:
142
+
143
+ - Authenticate against the Main Sequence backend
144
+ - Manage your local project checkouts (clone, open, delete)
145
+ - Set up SSH deploy keys for project repos
146
+ - Generate and maintain a `.env` file with project-specific tokens and endpoints
147
+ - Build & run your project in Docker (via `uv` + `docker`)
148
+ - Bundle and copy AI/LLM instruction markdowns to the clipboard
149
+
150
+ The CLI is implemented with [Typer](https://typer.tiangolo.com/) and exposes a `mainsequence` command.
107
151
 
108
152
  ---
153
+
154
+ ## Installation & Invocation
155
+
156
+ How you install the CLI depends on how this repository is packaged, but assuming it’s installed in your environment and provides the `mainsequence` entry point:
157
+
158
+ ```bash
159
+ # General form
160
+ mainsequence --help
@@ -0,0 +1,68 @@
1
+ <p align="center">
2
+ <img src="https://main-sequence.app/static/media/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
3
+ </p>
4
+
5
+ # Main Sequence Python SDK
6
+
7
+
8
+
9
+ The Main Sequence Python SDK is a high-performance client library that enables seamless integration with the Main Sequence platform.
10
+ It provides a unified and intuitive interface for interacting with data, compute, and intelligence services across the platform.
11
+
12
+ Main Sequence functions as a centralized engine for data intelligence—integrating information from diverse data sources and systems
13
+ while abstracting away the complexity of underlying storage layers. This allows quants, researchers, analysts,
14
+ and engineers to focus on the data-generating process itself, while Main Sequence optimizes all CRUD operations and manages
15
+ the mapping between logical data structures and physical storage.
16
+
17
+ The Main Sequence SDK is also a foundational component of all Main Sequence Platform projects.
18
+ It acts as the backbone for automation, process orchestration, and the rapid development of dashboards,
19
+ data nodes, and agentic tools built on top of the platform.
20
+
21
+ ---
22
+
23
+ ## Developing with the Main Sequence SDK & Platform
24
+ To make it easy to work on Main Sequence projects from your local environment, you have two options:
25
+
26
+ 1. **Use the MainSequence CLI directly in your terminal**, or
27
+ 2. **Use the Main Sequence VS Code extension** (recommended if you already work in VS Code).
28
+
29
+ The VS Code extension provides a more visual, editor-integrated workflow on top of what the CLI offers.
30
+
31
+
32
+ ### Visual Studio Code Extension
33
+
34
+ 1. **Open the Extensions view in VS Code**
35
+
36
+ - **macOS:** Press `Cmd` + `Shift` + `X`
37
+ - **Windows/Linux:** Press `Ctrl` + `Shift` + `X`
38
+ - Or click the **Extensions** icon in the Activity Bar on the left side of the window.
39
+
40
+ 2. **Search for the extension**
41
+
42
+ In the Extensions search box, type Main Sequence and press Enter.:
43
+
44
+
45
+ ![img.png](/docs/img/vs_code_extension.png)
46
+
47
+ ### MainSequence CLI
48
+
49
+ MainSequence CLI is a small helper tool to:
50
+
51
+ - Authenticate against the Main Sequence backend
52
+ - Manage your local project checkouts (clone, open, delete)
53
+ - Set up SSH deploy keys for project repos
54
+ - Generate and maintain a `.env` file with project-specific tokens and endpoints
55
+ - Build & run your project in Docker (via `uv` + `docker`)
56
+ - Bundle and copy AI/LLM instruction markdowns to the clipboard
57
+
58
+ The CLI is implemented with [Typer](https://typer.tiangolo.com/) and exposes a `mainsequence` command.
59
+
60
+ ---
61
+
62
+ ## Installation & Invocation
63
+
64
+ How you install the CLI depends on how this repository is packaged, but assuming it’s installed in your environment and provides the `mainsequence` entry point:
65
+
66
+ ```bash
67
+ # General form
68
+ mainsequence --help
@@ -752,94 +752,6 @@ def project_set_up_locally(
752
752
  typer.echo("Public key copied to clipboard.")
753
753
 
754
754
 
755
- @app.command("build_and_run")
756
- def build_and_run(
757
- dockerfile: str | None = typer.Argument(
758
- None, help="Path to Dockerfile to build & run. If omitted, only lock & export requirements."
759
- )
760
- ):
761
- """
762
- - uv lock
763
- - uv export --format requirements --no-dev --hashes > requirements.txt
764
- - If DOCKERFILE argument is given: docker build -f DOCKERFILE . && docker run IMAGE
765
- """
766
-
767
- # ----- sanity checks for uv + project files -----
768
- if shutil.which("uv") is None:
769
- typer.secho("uv is not installed. Install it with: pip install uv", fg=typer.colors.RED)
770
- raise typer.Exit(1)
771
-
772
- if not pathlib.Path("pyproject.toml").exists():
773
- typer.secho(f"pyproject.toml not found in {pathlib.Path.cwd()}", fg=typer.colors.RED)
774
- raise typer.Exit(1)
775
-
776
- # ----- 1) solve and lock -----
777
- typer.secho("Running: uv lock", fg=typer.colors.BLUE)
778
- p = subprocess.run(["uv", "lock"])
779
- if p.returncode != 0:
780
- typer.secho("uv lock failed.", fg=typer.colors.RED)
781
- raise typer.Exit(p.returncode)
782
-
783
- # ----- 2) export pinned, hashed requirements -----
784
- typer.secho("Exporting hashed requirements to requirements.txt", fg=typer.colors.BLUE)
785
- p = subprocess.run(
786
- ["uv", "export", "--format", "requirements", "--no-dev", "--hashes"],
787
- capture_output=True,
788
- text=True,
789
- )
790
- if p.returncode != 0:
791
- typer.secho("uv export failed:", fg=typer.colors.RED)
792
- if p.stderr:
793
- typer.echo(p.stderr.strip())
794
- raise typer.Exit(p.returncode)
795
-
796
- pathlib.Path("requirements.txt").write_text(p.stdout, encoding="utf-8")
797
- typer.secho("requirements.txt written.", fg=typer.colors.GREEN)
798
-
799
- # ----- 3) optional Docker build + run -----
800
- if dockerfile is None:
801
- typer.secho("No Dockerfile provided; skipping Docker build/run.", fg=typer.colors.BLUE)
802
- return
803
-
804
- df_path = pathlib.Path(dockerfile)
805
- if not df_path.exists():
806
- typer.secho(f"Dockerfile not found: {dockerfile}", fg=typer.colors.RED)
807
- raise typer.Exit(1)
808
-
809
- if shutil.which("docker") is None:
810
- typer.secho("Docker CLI is not installed or not on PATH.", fg=typer.colors.RED)
811
- raise typer.Exit(1)
812
-
813
- # Image name: directory-name + '-img' (overridable via env IMAGE_NAME)
814
- cwd_name = pathlib.Path.cwd().name
815
- safe_name = re.sub(r"[^a-z0-9_.-]+", "-", cwd_name.lower())
816
- image_name = os.environ.get("IMAGE_NAME", f"{safe_name}-img")
817
-
818
- # Tag: short git sha if available, else timestamp (overridable via env TAG)
819
- tag = os.environ.get("TAG")
820
- if not tag:
821
- try:
822
- tag = subprocess.check_output(
823
- ["git", "rev-parse", "--short", "HEAD"], text=True
824
- ).strip()
825
- except Exception:
826
- tag = time.strftime("%Y%m%d%H%M%S")
827
-
828
- image_ref = f"{image_name}:{tag}"
829
-
830
- typer.secho(f"Building Docker image: {image_ref}", fg=typer.colors.BLUE)
831
- build = subprocess.run(["docker", "build", "-f", str(df_path), "-t", image_ref, "."])
832
- if build.returncode != 0:
833
- typer.secho("docker build failed.", fg=typer.colors.RED)
834
- raise typer.Exit(build.returncode)
835
-
836
- typer.secho(f"Running container: {image_ref}", fg=typer.colors.BLUE)
837
- try:
838
- # interactive by default; relies on your ENTRYPOINT
839
- subprocess.check_call(["docker", "run", "--rm", "-it", image_ref])
840
- except subprocess.CalledProcessError as e:
841
- typer.secho(f"docker run failed (exit {e.returncode}).", fg=typer.colors.RED)
842
- raise typer.Exit(e.returncode)
843
755
 
844
756
 
845
757
  @app.command("copy-llm-instructions")
@@ -1066,40 +1066,52 @@ class DataNodeStorage(BasePydanticModel, BaseObjectOrm):
1066
1066
  df = df.set_index(stc.index_names)
1067
1067
  return df
1068
1068
 
1069
-
1070
-
1071
- def get_data_between_dates_from_api(
1072
- self,
1073
- start_date: datetime.datetime = None,
1074
- end_date: datetime.datetime = None,
1075
- great_or_equal: bool = None,
1076
- less_or_equal: bool = None,
1077
- unique_identifier_list: list = None,
1078
- columns: list = None,
1079
- unique_identifier_range_map: None | UniqueIdentifierRangeMap = None,
1080
- column_range_descriptor: None | UniqueIdentifierRangeMap = None,
1081
- ):
1082
- """Helper function to make a single batch request (or multiple paged requests if next_offset)."""
1069
+ @classmethod
1070
+ def _get_data_between_dates_common(
1071
+ cls,
1072
+ url: str,
1073
+ start_date: datetime.datetime = None,
1074
+ end_date: datetime.datetime = None,
1075
+ great_or_equal: bool = None,
1076
+ less_or_equal: bool = None,
1077
+ unique_identifier_list: list = None,
1078
+ columns: list = None,
1079
+ unique_identifier_range_map: None | UniqueIdentifierRangeMap = None,
1080
+ column_range_descriptor: None | UniqueIdentifierRangeMap = None,
1081
+ node_identifier: str | None = None,
1082
+ ) -> pd.DataFrame:
1083
+ """Internal shared implementation for fetching data between dates."""
1083
1084
 
1084
1085
  def fetch_one_batch(chunk_range_map):
1085
1086
  all_results_chunk = []
1086
1087
  offset = 0
1088
+
1087
1089
  while True:
1088
- payload = {
1089
- "json": {
1090
- "start_date": start_date.timestamp() if start_date else None,
1091
- "end_date": end_date.timestamp() if end_date else None,
1092
- "great_or_equal": great_or_equal,
1093
- "less_or_equal": less_or_equal,
1094
- "unique_identifier_list": unique_identifier_list,
1095
- "columns": columns,
1096
- "offset": offset, # pagination offset
1097
- "unique_identifier_range_map": chunk_range_map,
1098
- }
1090
+ payload_json = {
1091
+ "start_date": start_date.timestamp() if start_date else None,
1092
+ "end_date": end_date.timestamp() if end_date else None,
1093
+ "great_or_equal": great_or_equal,
1094
+ "less_or_equal": less_or_equal,
1095
+ "unique_identifier_list": unique_identifier_list,
1096
+ "columns": columns,
1097
+ "offset": offset, # pagination offset
1098
+ "unique_identifier_range_map": chunk_range_map,
1099
+ # "column_range_descriptor": column_range_descriptor, # if/when needed
1099
1100
  }
1100
1101
 
1102
+ if node_identifier is not None:
1103
+ payload_json["node_identifier"] = node_identifier
1104
+
1105
+ payload = {"json": payload_json}
1106
+
1101
1107
  # Perform the POST request
1102
- r = make_request(s=s, loaders=self.LOADERS, payload=payload, r_type="POST", url=url)
1108
+ r = make_request(
1109
+ s=s,
1110
+ loaders=cls.LOADERS,
1111
+ payload=payload,
1112
+ r_type="POST",
1113
+ url=url,
1114
+ )
1103
1115
  if r.status_code != 200:
1104
1116
  logger.warning(f"Error in request: {r.text}")
1105
1117
  return []
@@ -1119,28 +1131,34 @@ class DataNodeStorage(BasePydanticModel, BaseObjectOrm):
1119
1131
 
1120
1132
  return all_results_chunk
1121
1133
 
1122
- s = self.build_session()
1123
- url = self.get_object_url() + f"/{self.id}/get_data_between_dates_from_remote/"
1134
+ s = cls.build_session()
1124
1135
 
1136
+ # Deep copy & convert date fields in unique_identifier_range_map
1125
1137
  unique_identifier_range_map = copy.deepcopy(unique_identifier_range_map)
1126
1138
  if unique_identifier_range_map is not None:
1127
1139
  for _, date_info in unique_identifier_range_map.items():
1128
1140
  # Convert start_date if present
1129
1141
  if "start_date" in date_info and isinstance(
1130
- date_info["start_date"], datetime.datetime
1142
+ date_info["start_date"], datetime.datetime
1131
1143
  ):
1132
- date_info["start_date"] = int(date_info["start_date"].timestamp())
1144
+ date_info["start_date"] = int(
1145
+ date_info["start_date"].timestamp()
1146
+ )
1133
1147
 
1134
1148
  # Convert end_date if present
1135
- if "end_date" in date_info and isinstance(date_info["end_date"], datetime.datetime):
1136
- date_info["end_date"] = int(date_info["end_date"].timestamp())
1149
+ if "end_date" in date_info and isinstance(
1150
+ date_info["end_date"], datetime.datetime
1151
+ ):
1152
+ date_info["end_date"] = int(
1153
+ date_info["end_date"].timestamp()
1154
+ )
1137
1155
 
1138
1156
  all_results = []
1139
1157
  if unique_identifier_range_map:
1140
1158
  keys = list(unique_identifier_range_map.keys())
1141
1159
  chunk_size = 100
1142
1160
  for start_idx in range(0, len(keys), chunk_size):
1143
- key_chunk = keys[start_idx : start_idx + chunk_size]
1161
+ key_chunk = keys[start_idx: start_idx + chunk_size]
1144
1162
 
1145
1163
  # Build sub-dictionary for this chunk
1146
1164
  chunk_map = {k: unique_identifier_range_map[k] for k in key_chunk}
@@ -1155,6 +1173,65 @@ class DataNodeStorage(BasePydanticModel, BaseObjectOrm):
1155
1173
 
1156
1174
  return pd.DataFrame(all_results)
1157
1175
 
1176
+ def get_data_between_dates_from_api(
1177
+ self,
1178
+ start_date: datetime.datetime = None,
1179
+ end_date: datetime.datetime = None,
1180
+ great_or_equal: bool = None,
1181
+ less_or_equal: bool = None,
1182
+ unique_identifier_list: list = None,
1183
+ columns: list = None,
1184
+ unique_identifier_range_map: None | UniqueIdentifierRangeMap = None,
1185
+ column_range_descriptor: None | UniqueIdentifierRangeMap = None,
1186
+ ):
1187
+ """Public helper for /{id}/get_data_between_dates_from_remote/."""
1188
+ url = self.get_object_url() + f"/{self.id}/get_data_between_dates_from_remote/"
1189
+
1190
+ return self._get_data_between_dates_common(
1191
+ url=url,
1192
+ start_date=start_date,
1193
+ end_date=end_date,
1194
+ great_or_equal=great_or_equal,
1195
+ less_or_equal=less_or_equal,
1196
+ unique_identifier_list=unique_identifier_list,
1197
+ columns=columns,
1198
+ unique_identifier_range_map=unique_identifier_range_map,
1199
+ column_range_descriptor=column_range_descriptor,
1200
+ node_identifier=None,
1201
+ )
1202
+
1203
+ @classmethod
1204
+ def get_data_between_dates_from_node_identifier(
1205
+ cls,
1206
+ node_identifier: str,
1207
+ start_date: datetime.datetime = None,
1208
+ end_date: datetime.datetime = None,
1209
+ great_or_equal: bool = None,
1210
+ less_or_equal: bool = None,
1211
+ unique_identifier_list: list = None,
1212
+ columns: list = None,
1213
+ unique_identifier_range_map: None | UniqueIdentifierRangeMap = None,
1214
+ column_range_descriptor: None | UniqueIdentifierRangeMap = None,
1215
+ ):
1216
+ """
1217
+ Same behaviour as get_data_between_dates_from_api,
1218
+ but calls the node-identifier endpoint and includes node_identifier in payload.
1219
+ """
1220
+ url = cls.get_object_url() + "/get_data_between_dates_from_node_identifier/"
1221
+
1222
+ return cls._get_data_between_dates_common(
1223
+ url=url,
1224
+ start_date=start_date,
1225
+ end_date=end_date,
1226
+ great_or_equal=great_or_equal,
1227
+ less_or_equal=less_or_equal,
1228
+ unique_identifier_list=unique_identifier_list,
1229
+ columns=columns,
1230
+ unique_identifier_range_map=unique_identifier_range_map,
1231
+ column_range_descriptor=column_range_descriptor,
1232
+ node_identifier=node_identifier,
1233
+ )
1234
+
1158
1235
 
1159
1236
  class Scheduler(BasePydanticModel, BaseObjectOrm):
1160
1237
  id: int | None = None
@@ -214,7 +214,7 @@ class UpdateRunner:
214
214
  # Check that the time index is a UTC datetime
215
215
  time_index = df.index.get_level_values(0)
216
216
  if not pd.api.types.is_datetime64_ns_dtype(time_index) or str(time_index.tz) != str(
217
- datetime.timezone.utc
217
+ datetime.UTC
218
218
  ):
219
219
  raise TypeError(f"Time index must be datetime64[ns, UTC], but found {time_index.dtype}")
220
220
 
@@ -249,11 +249,9 @@ class UpdateRunner:
249
249
  # 2. Execute the core data calculation
250
250
  with tracer.start_as_current_span("Update Calculation") as update_span:
251
251
 
252
- # Add specific log message for the initial run
253
- if not self.ts.update_statistics:
254
- self.logger.debug(f"Performing first-time update for {self.ts}...")
255
- else:
256
- self.logger.debug(f"Calculating update for {self.ts}...")
252
+
253
+
254
+ self.logger.debug(f"Calculating update for {self.ts}...")
257
255
 
258
256
  try:
259
257
  # Call the business logic defined on the DataNode class
@@ -295,7 +293,11 @@ class UpdateRunner:
295
293
  self.logger.exception("Failed during update calculation or persistence.")
296
294
  update_span.set_status(Status(StatusCode.ERROR, description=str(e)))
297
295
  raise e
298
- return tmp_df
296
+ finally:
297
+ self.ts.local_persist_manager.synchronize_data_node_update(None)
298
+ us = self.ts.local_persist_manager.get_update_statistics_for_table()
299
+ self.ts.update_statistics = us
300
+
299
301
 
300
302
  @tracer.start_as_current_span("UpdateRunner._verify_tree_is_updated")
301
303
  def _verify_tree_is_updated(
@@ -474,10 +476,6 @@ class UpdateRunner:
474
476
  raise e # Re-raise to halt the entire process on failure
475
477
 
476
478
  # refresh update statistics of direct dependencies
477
- # for edge case of multicolumn self update
478
- self.ts.local_persist_manager.synchronize_data_node_update(None)
479
- us = self.ts.local_persist_manager.get_update_statistics_for_table()
480
- self.ts.update_statistics = us
481
479
 
482
480
  refresh_update_statistics_of_deps(self.ts)
483
481
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.3.8
3
+ Version: 3.4.1
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -87,6 +87,7 @@ Requires-Dist: duckdb
87
87
  Requires-Dist: plotly
88
88
  Requires-Dist: typer
89
89
  Requires-Dist: QuantLib
90
+ Requires-Dist: streamlit
90
91
  Dynamic: license-file
91
92
 
92
93
  <p align="center">
@@ -97,12 +98,63 @@ Dynamic: license-file
97
98
 
98
99
 
99
100
 
100
- The **Main Sequence Python SDK** is a powerful set of client libraries designed to facilitate interaction with Main Sequence systems using Python.
101
+ The Main Sequence Python SDK is a high-performance client library that enables seamless integration with the Main Sequence platform.
102
+ It provides a unified and intuitive interface for interacting with data, compute, and intelligence services across the platform.
101
103
 
102
- **We strongly** encourage you to go through our examples.
103
- We have built the examples as individual Jupyter notebooks that explain the SDK through use cases.
104
- Since most platform usage involves a combination of operations, this is the most intuitive way to learn about Main Sequence.
104
+ Main Sequence functions as a centralized engine for data intelligence—integrating information from diverse data sources and systems
105
+ while abstracting away the complexity of underlying storage layers. This allows quants, researchers, analysts,
106
+ and engineers to focus on the data-generating process itself, while Main Sequence optimizes all CRUD operations and manages
107
+ the mapping between logical data structures and physical storage.
105
108
 
109
+ The Main Sequence SDK is also a foundational component of all Main Sequence Platform projects.
110
+ It acts as the backbone for automation, process orchestration, and the rapid development of dashboards,
111
+ data nodes, and agentic tools built on top of the platform.
106
112
 
113
+ ---
114
+
115
+ ## Developing with the Main Sequence SDK & Platform
116
+ To make it easy to work on Main Sequence projects from your local environment, you have two options:
117
+
118
+ 1. **Use the MainSequence CLI directly in your terminal**, or
119
+ 2. **Use the Main Sequence VS Code extension** (recommended if you already work in VS Code).
120
+
121
+ The VS Code extension provides a more visual, editor-integrated workflow on top of what the CLI offers.
122
+
123
+
124
+ ### Visual Studio Code Extension
125
+
126
+ 1. **Open the Extensions view in VS Code**
127
+
128
+ - **macOS:** Press `Cmd` + `Shift` + `X`
129
+ - **Windows/Linux:** Press `Ctrl` + `Shift` + `X`
130
+ - Or click the **Extensions** icon in the Activity Bar on the left side of the window.
131
+
132
+ 2. **Search for the extension**
133
+
134
+ In the Extensions search box, type Main Sequence and press Enter.:
135
+
136
+
137
+ ![img.png](/docs/img/vs_code_extension.png)
138
+
139
+ ### MainSequence CLI
140
+
141
+ MainSequence CLI is a small helper tool to:
142
+
143
+ - Authenticate against the Main Sequence backend
144
+ - Manage your local project checkouts (clone, open, delete)
145
+ - Set up SSH deploy keys for project repos
146
+ - Generate and maintain a `.env` file with project-specific tokens and endpoints
147
+ - Build & run your project in Docker (via `uv` + `docker`)
148
+ - Bundle and copy AI/LLM instruction markdowns to the clipboard
149
+
150
+ The CLI is implemented with [Typer](https://typer.tiangolo.com/) and exposes a `mainsequence` command.
107
151
 
108
152
  ---
153
+
154
+ ## Installation & Invocation
155
+
156
+ How you install the CLI depends on how this repository is packaged, but assuming it’s installed in your environment and provides the `mainsequence` entry point:
157
+
158
+ ```bash
159
+ # General form
160
+ mainsequence --help
@@ -33,3 +33,4 @@ duckdb
33
33
  plotly
34
34
  typer
35
35
  QuantLib
36
+ streamlit
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "3.3.8"
7
+ version = "3.4.1"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -56,6 +56,7 @@ dependencies = [
56
56
  "plotly",
57
57
  "typer",
58
58
  "QuantLib", # ← renamed from `quantlib`
59
+ "streamlit"
59
60
 
60
61
  ]
61
62
 
@@ -1,17 +0,0 @@
1
- <p align="center">
2
- <img src="https://main-sequence.app/static/media/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
3
- </p>
4
-
5
- # Main Sequence Python SDK
6
-
7
-
8
-
9
- The **Main Sequence Python SDK** is a powerful set of client libraries designed to facilitate interaction with Main Sequence systems using Python.
10
-
11
- **We strongly** encourage you to go through our examples.
12
- We have built the examples as individual Jupyter notebooks that explain the SDK through use cases.
13
- Since most platform usage involves a combination of operations, this is the most intuitive way to learn about Main Sequence.
14
-
15
-
16
-
17
- ---
File without changes
File without changes