mainsequence 3.4.2__tar.gz → 3.4.3__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 (120) hide show
  1. {mainsequence-3.4.2 → mainsequence-3.4.3}/PKG-INFO +1 -1
  2. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence.egg-info/PKG-INFO +1 -1
  3. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence.egg-info/SOURCES.txt +0 -1
  4. {mainsequence-3.4.2 → mainsequence-3.4.3}/pyproject.toml +1 -1
  5. mainsequence-3.4.2/mainsequence/client/models_report_studio.py +0 -373
  6. {mainsequence-3.4.2 → mainsequence-3.4.3}/LICENSE +0 -0
  7. {mainsequence-3.4.2 → mainsequence-3.4.3}/README.md +0 -0
  8. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/__init__.py +0 -0
  9. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/__main__.py +0 -0
  10. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/cli/__init__.py +0 -0
  11. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/cli/api.py +0 -0
  12. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/cli/cli.py +0 -0
  13. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/cli/config.py +0 -0
  14. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/cli/ssh_utils.py +0 -0
  15. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/__init__.py +0 -0
  16. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/base.py +0 -0
  17. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  18. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  19. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/data_sources_interfaces/timescale.py +0 -0
  20. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/exceptions.py +0 -0
  21. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/models_helpers.py +0 -0
  22. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/models_tdag.py +0 -0
  23. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/models_vam.py +0 -0
  24. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/client/utils.py +0 -0
  25. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/__init__.py +0 -0
  26. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/__init__.py +0 -0
  27. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/config.toml +0 -0
  28. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
  29. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/image_1_base64.txt +0 -0
  30. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/image_2_base64.txt +0 -0
  31. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/image_3_base64.txt +0 -0
  32. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/image_4_base64.txt +0 -0
  33. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/image_5_base64.txt +0 -0
  34. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/assets/logo.png +0 -0
  35. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/core/__init__.py +0 -0
  36. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/core/theme.py +0 -0
  37. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
  38. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/dashboards/streamlit/scaffold.py +0 -0
  39. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instrumentation/__init__.py +0 -0
  40. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instrumentation/utils.py +0 -0
  41. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/__init__.py +0 -0
  42. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/data_interface/__init__.py +0 -0
  43. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/data_interface/data_interface.py +0 -0
  44. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/__init__.py +0 -0
  45. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/base_instrument.py +0 -0
  46. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/bond.py +0 -0
  47. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/european_option.py +0 -0
  48. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/interest_rate_swap.py +0 -0
  49. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/json_codec.py +0 -0
  50. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/knockout_fx_option.py +0 -0
  51. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/position.py +0 -0
  52. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/ql_fields.py +0 -0
  53. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments/vanilla_fx_option.py +0 -0
  54. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/instruments.default.toml +0 -0
  55. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/__init__.py +0 -0
  56. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/black_scholes.py +0 -0
  57. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/bond_pricer.py +0 -0
  58. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/fx_option_pricer.py +0 -0
  59. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/indices.py +0 -0
  60. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/knockout_fx_pricer.py +0 -0
  61. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/pricing_models/swap_pricer.py +0 -0
  62. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/settings.py +0 -0
  63. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/instruments/utils.py +0 -0
  64. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/logconf.py +0 -0
  65. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/__init__.py +0 -0
  66. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/__main__.py +0 -0
  67. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/config.py +0 -0
  68. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/data_nodes/__init__.py +0 -0
  69. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/data_nodes/build_operations.py +0 -0
  70. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/data_nodes/data_nodes.py +0 -0
  71. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/data_nodes/persist_managers.py +0 -0
  72. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/data_nodes/run_operations.py +0 -0
  73. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/data_nodes/utils.py +0 -0
  74. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/future_registry.py +0 -0
  75. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/tdag/utils.py +0 -0
  76. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/__init__.py +0 -0
  77. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/agent_interface.py +0 -0
  78. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/config_handling.py +0 -0
  79. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
  80. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/__init__.py +0 -0
  81. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/etf_replicator_app.py +0 -0
  82. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/generate_report.py +0 -0
  83. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/load_external_portfolio.py +0 -0
  84. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/news_app.py +0 -0
  85. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/portfolio_report_app.py +0 -0
  86. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/portfolio_table.py +0 -0
  87. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/run_named_portfolio.py +0 -0
  88. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/run_portfolio.py +0 -0
  89. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/templates/base.html +0 -0
  90. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/apps/templates/report.html +0 -0
  91. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +0 -0
  92. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +0 -0
  93. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +0 -0
  94. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +0 -0
  95. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +0 -0
  96. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +0 -0
  97. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/prices/__init__.py +0 -0
  98. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +0 -0
  99. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/prices/utils.py +0 -0
  100. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +0 -0
  101. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +0 -0
  102. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/data_nodes.py +0 -0
  103. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/enums.py +0 -0
  104. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/models.py +0 -0
  105. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/notebook_handling.py +0 -0
  106. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/portfolio_interface.py +0 -0
  107. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
  108. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/resource_factory/app_factory.py +0 -0
  109. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/resource_factory/base_factory.py +0 -0
  110. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +0 -0
  111. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +0 -0
  112. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence/virtualfundbuilder/utils.py +0 -0
  113. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence.egg-info/dependency_links.txt +0 -0
  114. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence.egg-info/entry_points.txt +0 -0
  115. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence.egg-info/requires.txt +0 -0
  116. {mainsequence-3.4.2 → mainsequence-3.4.3}/mainsequence.egg-info/top_level.txt +0 -0
  117. {mainsequence-3.4.2 → mainsequence-3.4.3}/setup.cfg +0 -0
  118. {mainsequence-3.4.2 → mainsequence-3.4.3}/tests/test_agent.py +0 -0
  119. {mainsequence-3.4.2 → mainsequence-3.4.3}/tests/test_portfolio.py +0 -0
  120. {mainsequence-3.4.2 → mainsequence-3.4.3}/tests/test_replicator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.4.2
3
+ Version: 3.4.3
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.4.2
3
+ Version: 3.4.3
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
@@ -19,7 +19,6 @@ mainsequence/client/__init__.py
19
19
  mainsequence/client/base.py
20
20
  mainsequence/client/exceptions.py
21
21
  mainsequence/client/models_helpers.py
22
- mainsequence/client/models_report_studio.py
23
22
  mainsequence/client/models_tdag.py
24
23
  mainsequence/client/models_vam.py
25
24
  mainsequence/client/utils.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "3.4.2"
7
+ version = "3.4.3"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,373 +0,0 @@
1
- import datetime
2
- from typing import Annotated, Literal
3
-
4
- from pydantic import BaseModel, Field, conint, constr
5
-
6
- from .base import BaseObjectOrm, BasePydanticModel
7
- from .utils import make_request
8
-
9
- # Define a reusable HexColor annotated type
10
- HexColor = Annotated[
11
- str,
12
- Field(
13
- pattern=r"^#[0-9A-Fa-f]{6}$",
14
- description="HEX color in format #RRGGBB",
15
- min_length=7,
16
- max_length=7,
17
- ),
18
- ]
19
-
20
-
21
- class Theme(BasePydanticModel, BaseObjectOrm):
22
- id: int
23
- theme_type: constr(max_length=15) = Field(..., description="‘standard’ or ‘custom’")
24
- name: constr(max_length=100)
25
- created: datetime.datetime
26
- updated: datetime.datetime
27
-
28
- mode: constr(max_length=5) = Field(..., description="‘light’ or ‘dark’")
29
- editor_background: dict | None = Field(None, description="FK to Background.id")
30
-
31
- font_family_headings: constr(max_length=100) | None = Field(
32
- "", description="--font-family-headings"
33
- )
34
- font_family_paragraphs: constr(max_length=100) | None = Field(
35
- "", description="--font-family-paragraphs"
36
- )
37
-
38
- font_size_h1: conint(ge=1) = Field(48, description="--font-size-h1 (px)")
39
- font_size_h2: conint(ge=1) = Field(40, description="--font-size-h2 (px)")
40
- font_size_h3: conint(ge=1) = Field(32, description="--font-size-h3 (px)")
41
- font_size_h4: conint(ge=1) = Field(24, description="--font-size-h4 (px)")
42
- font_size_h5: conint(ge=1) = Field(20, description="--font-size-h5 (px)")
43
- font_size_h6: conint(ge=1) = Field(16, description="--font-size-h6 (px)")
44
- font_size_p: conint(ge=1) = Field(14, description="--font-size-p (px)")
45
-
46
- primary_color: HexColor = Field("#0d6efd")
47
- secondary_color: HexColor = Field("#6c757d")
48
- accent_color_1: HexColor = Field("#198754")
49
- accent_color_2: HexColor = Field("#ffc107")
50
- heading_color: HexColor = Field("#212529")
51
- paragraph_color: HexColor = Field("#495057")
52
- light_paragraph_color: HexColor = Field("#6c757d")
53
- background_color: HexColor = Field("#ffffff")
54
-
55
- title_column_width: constr(max_length=15) = Field("150px", description="--title-column-width")
56
- chart_label_font_size: conint(ge=1) = Field(12, description="--chart-label-font-size (px)")
57
-
58
- chart_palette_sequential: list[HexColor] = Field(
59
- default_factory=list,
60
- description="List of 5 HEX colours for sequential palettes",
61
- )
62
- chart_palette_diverging: list[HexColor] = Field(
63
- default_factory=list,
64
- description="List of 5 HEX colours for diverging palettes",
65
- )
66
- chart_palette_categorical: list[HexColor] = Field(
67
- default_factory=list,
68
- description="List of 6 HEX colours for categorical palettes",
69
- )
70
-
71
- def set_plotly_theme(self):
72
- import plotly.graph_objects as go
73
- import plotly.io as pio
74
-
75
- try:
76
- import plotly.express as px
77
- except ImportError:
78
- px = None
79
-
80
- # --------------------- derive colours and fonts --------------------------
81
- base_font = dict(
82
- family=self.font_family_paragraphs or "Inter, Arial, sans-serif",
83
- size=self.font_size_p,
84
- color=self.paragraph_color,
85
- )
86
- title_font = dict(
87
- family=self.font_family_headings or base_font["family"],
88
- size=self.font_size_h4,
89
- color=self.heading_color,
90
- )
91
-
92
- # categorical palette
93
- colorway = (
94
- self.chart_palette_categorical[:]
95
- if len(self.chart_palette_categorical) >= 3
96
- else [
97
- self.primary_color,
98
- self.secondary_color,
99
- self.accent_color_1,
100
- self.accent_color_2,
101
- self.heading_color,
102
- self.paragraph_color,
103
- ]
104
- )
105
-
106
- sequential = (
107
- self.chart_palette_sequential[:]
108
- if len(self.chart_palette_sequential) >= 3
109
- else colorway
110
- )
111
- diverging = (
112
- self.chart_palette_diverging[:]
113
- if len(self.chart_palette_diverging) >= 3
114
- else colorway[::-1]
115
- )
116
-
117
- paper_bg = plot_bg = self.background_color
118
- if self.mode.lower() == "dark" and paper_bg.lower() == "#ffffff":
119
- paper_bg = plot_bg = "#111111"
120
-
121
- # --------------------------- build template ------------------------------
122
- template = go.layout.Template(
123
- layout=dict(
124
- font=base_font,
125
- title_font=title_font,
126
- paper_bgcolor=paper_bg,
127
- plot_bgcolor=plot_bg,
128
- colorway=colorway,
129
- # ↓↓↓ **correct spot for continuous scales** ↓↓↓
130
- colorscale=dict(
131
- sequential=sequential,
132
- diverging=diverging,
133
- ),
134
- xaxis=dict(showgrid=False, zeroline=False),
135
- yaxis=dict(showgrid=True, zeroline=False),
136
- )
137
- )
138
-
139
- # ---------------------- register & activate ------------------------------
140
- tpl_name = f"theme_{self.id}_{self.name}"
141
- pio.templates[tpl_name] = template
142
- pio.templates.default = tpl_name
143
- if px:
144
- px.defaults.template = tpl_name
145
- px.defaults.color_discrete_sequence = colorway
146
- px.defaults.color_continuous_scale = sequential
147
-
148
-
149
- class Folder(BasePydanticModel, BaseObjectOrm):
150
- id: int | None = None
151
- name: str
152
- slug: str
153
-
154
- @classmethod
155
- def get_or_create(cls, *args, **kwargs):
156
- url = f"{cls.get_object_url()}/get-or-create/"
157
- payload = {"json": kwargs}
158
- r = make_request(
159
- s=cls.build_session(), loaders=cls.LOADERS, r_type="POST", url=url, payload=payload
160
- )
161
- if r.status_code not in [200, 201]:
162
- raise Exception(f"Error appending creating: {r.text}")
163
- # Return a new instance of AssetCategory built from the response JSON.
164
- return cls(**r.json())
165
-
166
-
167
- class Slide(BasePydanticModel, BaseObjectOrm):
168
- id: int | None = None
169
- number: int = Field(..., ge=0, description="Number of the slide in presentation order")
170
- body: str = Field(
171
- ...,
172
- description=(
173
- "Tiptap rich-text document for the main content, serialized as JSON. "
174
- "Must follow the Tiptap ‘doc’ schema, e.g.: "
175
- '{"type":"doc","content":[{"type":"paragraph","attrs":{"textAlign":null}}]}'
176
- ),
177
- example='{"type":"doc","content":[{"type":"paragraph","attrs":{"textAlign":null}}]}',
178
- )
179
- header: str | None = Field(
180
- None,
181
- description=(
182
- "Optional Tiptap rich-text document for the header, serialized as JSON. "
183
- "If present, should follow the Tiptap ‘doc’ schema, e.g.: "
184
- '{"type":"doc","content":[{"type":"paragraph","attrs":{"textAlign":null}}]}'
185
- ),
186
- example='{"type":"doc","content":[{"type":"paragraph","attrs":{"textAlign":null}}]}',
187
- )
188
- footer: str | None = Field(
189
- None,
190
- description=(
191
- "Optional Tiptap rich-text document for the footer, serialized as JSON. "
192
- "If present, should follow the Tiptap ‘doc’ schema, e.g.: "
193
- '{"type":"doc","content":[{"type":"paragraph","attrs":{"textAlign":null}}]}'
194
- ),
195
- example='{"type":"doc","content":[{"type":"paragraph","attrs":{"textAlign":null}}]}',
196
- )
197
- created_at: datetime.datetime = Field(
198
- default_factory=datetime.datetime.utcnow,
199
- description="Timestamp when the record was created",
200
- )
201
- updated_at: datetime.datetime = Field(
202
- default_factory=datetime.datetime.utcnow,
203
- description="Timestamp when the record was last updated",
204
- )
205
- custom_format: dict | None = Field(
206
- description="Extra configuration for different type of slides"
207
- )
208
-
209
-
210
- class Presentation(BasePydanticModel, BaseObjectOrm):
211
- id: int
212
- folder: int
213
- title: str = Field(..., max_length=255)
214
- description: str | None = Field("", description="Optional text")
215
- created_at: datetime.datetime
216
- updated_at: datetime.datetime
217
- theme: int | Theme
218
- slides: list[Slide]
219
-
220
- @classmethod
221
- def get_or_create_by_title(cls, *args, **kwargs):
222
- url = f"{cls.get_object_url()}/get_or_create_by_title/"
223
- payload = {"json": kwargs}
224
- r = make_request(
225
- s=cls.build_session(), loaders=cls.LOADERS, r_type="POST", url=url, payload=payload
226
- )
227
- if r.status_code not in [200, 201]:
228
- raise Exception(f"Error appending creating: {r.text}")
229
- # Return a new instance of AssetCategory built from the response JSON.
230
- return cls(**r.json())
231
-
232
- def add_slide(self, *args, **kwargs) -> Slide:
233
- url = f"{self.get_object_url()}/{self.id}/add_slide/"
234
-
235
- r = make_request(
236
- s=self.build_session(),
237
- loaders=self.LOADERS,
238
- r_type="POST",
239
- url=url,
240
- payload={"json": {}},
241
- )
242
- if r.status_code not in [201]:
243
- raise Exception(f"Error appending creating: {r.text}")
244
- # Return a new instance of AssetCategory built from the response JSON.
245
- return Slide(**r.json())
246
-
247
-
248
- ##########
249
-
250
-
251
- class TextNode(BaseModel):
252
- type: Literal["text"] = Field(..., description="Inline text node")
253
- text: str = Field(..., description="Text content")
254
-
255
-
256
- class TextParagraphAttrs(BaseModel):
257
- textAlign: Literal["left", "right", "center", "justify"] | None = Field(
258
- None, description="Text alignment within the block"
259
- )
260
- level: int | None = Field(
261
- None, ge=1, le=6, description="Heading level (1–6); only set when `type` == 'heading'"
262
- )
263
-
264
-
265
- class TextParagraph(BaseModel):
266
- """
267
- Tiptap 'paragraph' or 'heading' block with inline text content.
268
- """
269
-
270
- type: Literal["paragraph", "heading"] = Field(
271
- ..., description="Block type: 'paragraph' or 'heading'"
272
- )
273
- attrs: TextParagraphAttrs = Field(
274
- default_factory=TextParagraphAttrs,
275
- description="Block attributes (alignment and optional heading level)",
276
- )
277
- content: list[TextNode] = Field(..., description="Inline text nodes")
278
-
279
- @classmethod
280
- def paragraph(
281
- cls, text: str, text_align: Literal["left", "right", "center", "justify"] | None = None
282
- ) -> "TextParagraph":
283
- """
284
- Build a simple paragraph block:
285
-
286
- TextParagraph.paragraph("Hello world", text_align="center")
287
- """
288
- return cls(
289
- type="paragraph",
290
- attrs=TextParagraphAttrs(textAlign=text_align),
291
- content=[TextNode(type="text", text=text)],
292
- )
293
-
294
- @classmethod
295
- def heading(
296
- cls,
297
- text: str,
298
- level: int = 1,
299
- text_align: Literal["left", "right", "center", "justify"] | None = None,
300
- ) -> "TextParagraph":
301
- """
302
- Build a heading block of the given level (1–6):
303
-
304
- TextParagraph.heading("Title", level=2, text_align="center")
305
- """
306
- return cls(
307
- type="heading",
308
- attrs=TextParagraphAttrs(textAlign=text_align, level=level),
309
- content=[TextNode(type="text", text=text)],
310
- )
311
-
312
- class Config:
313
- json_schema_extra = {
314
- "examples": {
315
- "paragraph": {
316
- "summary": "Basic paragraph",
317
- "value": {
318
- "type": "paragraph",
319
- "attrs": {"textAlign": None},
320
- "content": [{"type": "text", "text": "This is a body paragraph."}],
321
- },
322
- },
323
- "heading": {
324
- "summary": "Centered H1 heading",
325
- "value": {
326
- "type": "heading",
327
- "attrs": {"textAlign": "center", "level": 1},
328
- "content": [{"type": "text", "text": "This is a heading"}],
329
- },
330
- },
331
- }
332
- }
333
-
334
-
335
- ### App Nodes
336
- class EndpointProps(BaseModel):
337
- props: dict[str, int] = Field(
338
- ...,
339
- description="Dictionary of props to send to the endpoint, e.g. {'id': 33}",
340
- example={"id": 33},
341
- )
342
- url: str = Field(
343
- ...,
344
- description="Relative or absolute URL for the API endpoint",
345
- example="/orm/api/reports/run-function/",
346
- )
347
-
348
-
349
- class AppNodeAttrs(BaseModel):
350
- endpointProps: EndpointProps = Field(..., description="Configuration for the endpoint call")
351
-
352
-
353
- class AppNode(BaseModel):
354
- """
355
- Represents a custom Tiptap node of type 'appNode' that invokes an API.
356
- """
357
-
358
- type: Literal["appNode"] = Field("appNode", description="Node type identifier")
359
- attrs: AppNodeAttrs = Field(..., description="Node attributes")
360
-
361
- class Config:
362
- json_schema_extra = {
363
- "example": {
364
- "type": "appNode",
365
- "attrs": {
366
- "endpointProps": {"props": {"id": 33}, "url": "/orm/api/reports/run-function/"}
367
- },
368
- }
369
- }
370
-
371
- @classmethod
372
- def make_app_node(cls, id: int, url: str = "/orm/api/reports/run-function/") -> "AppNode":
373
- return cls(attrs=AppNodeAttrs(endpointProps=EndpointProps(props={"id": id}, url=url)))
File without changes
File without changes
File without changes