luxorasap 0.2.11__py3-none-any.whl → 0.2.13__py3-none-any.whl

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.
luxorasap/__init__.py CHANGED
@@ -13,7 +13,7 @@ from types import ModuleType
13
13
  try:
14
14
  __version__: str = metadata.version(__name__)
15
15
  except metadata.PackageNotFoundError: # editable install
16
- __version__ = "0.2.11"
16
+ __version__ = "0.2.13"
17
17
 
18
18
  # ─── Lazy loader ─────────────────────────────────────────────────
19
19
  def __getattr__(name: str) -> ModuleType:
@@ -2247,10 +2247,12 @@ class LuxorQuery:
2247
2247
  # Racional: Resgates rentabilizam no dia (ja estao no inicial)
2248
2248
  # Aportes rentabilizam no dia (nao estano no inicial)
2249
2249
  df["Open_AUM"] = df.reset_index().groupby("Today")["Open_Mkt_Value"].sum()
2250
- df["Open_AUM_Adjusted"] = (df["Open_AUM"] +
2250
+ df["Open_AUM_Adjusted"] = (df["Open_AUM"] +
2251
+
2251
2252
  df["Net_Subscriptions_Redemptions"]*(df["Net_Subscriptions_Redemptions"] > 0)
2252
2253
  )
2253
2254
 
2255
+ df["Open_AUM_Adjusted"] = df["Open_AUM_Adjusted"].fillna(0)
2254
2256
  df["Daily_Attribution"] = np.where(df["Open_AUM_Adjusted"] == 0,0, df["Daily_Pnl"] / df["Open_AUM_Adjusted"])
2255
2257
  df["Daily_Return"] = df.reset_index().groupby("Today")["Daily_Attribution"].sum()
2256
2258
 
@@ -157,6 +157,51 @@ class BlobExcelClient:
157
157
  self._container.upload_blob(name=blob_name, data=buf, overwrite=True)
158
158
 
159
159
 
160
+ def write_excel_multiple_sheets(
161
+ self,
162
+ sheets: dict[str, pd.DataFrame],
163
+ blob_name: str,
164
+ *,
165
+ index: bool = False,
166
+ engine: str = "openpyxl",
167
+ **to_excel_kwargs,
168
+ ) -> None:
169
+ """
170
+ Salva várias abas de uma planilha Excel no blob, a partir de um dicionário
171
+ {nome_aba: DataFrame}.
172
+
173
+ Args:
174
+ sheets: Mapa de nome da aba -> DataFrame.
175
+ blob_name: Caminho/nome do blob (ex.: "reports/minha_planilha.xlsx").
176
+ index: Se True, escreve o índice dos DataFrames.
177
+ engine: Engine do pandas.ExcelWriter (default "openpyxl").
178
+ **to_excel_kwargs: repassado a `DataFrame.to_excel` (ex.: na_format, float_format).
179
+ """
180
+
181
+ def _sanitize_sheet_name(name: str) -> str:
182
+ # Excel limita a 31 chars e proíbe alguns caracteres
183
+ s = str(name)[:31]
184
+ for ch, repl in {":": "_", "/": "_", "\\": "_", "?": "_", "*": "_", "[": "(", "]": ")"}.items():
185
+ s = s.replace(ch, repl)
186
+ return s
187
+
188
+ if not isinstance(sheets, dict) or not sheets:
189
+ raise ValueError("`sheets` deve ser um dicionário não vazio 'aba': 'DataFrame'.")
190
+
191
+ buf = io.BytesIO()
192
+ with pd.ExcelWriter(buf, engine=engine) as writer:
193
+ for sheet_name, df in sheets.items():
194
+ sanitized = _sanitize_sheet_name(sheet_name)
195
+ if not isinstance(df, pd.DataFrame):
196
+ # tenta converter objetos "tabelares" em DataFrame
197
+ df = pd.DataFrame(df)
198
+ df.to_excel(writer, sheet_name=sanitized, index=index, **to_excel_kwargs)
199
+
200
+ buf.seek(0)
201
+ self._container.upload_blob(name=blob_name, data=buf, overwrite=True)
202
+
203
+
204
+
160
205
  def read_excel(self, blob_name: str, **kwargs) -> pd.DataFrame:
161
206
  """
162
207
  Lê um arquivo Excel do blob e retorna um DataFrame.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: luxorasap
3
- Version: 0.2.11
3
+ Version: 0.2.13
4
4
  Summary: Toolbox da Luxor para ingestão, análise e automação de dados financeiros.
5
5
  Author-email: Luxor Group <backoffice@luxor.com.br>
6
6
  License: Proprietary – All rights reserved
@@ -1,10 +1,10 @@
1
- luxorasap/__init__.py,sha256=2oaOQ9biubY-DQ-DhpQEpPoip4s_RqAn4rvb3fE8y1A,1356
1
+ luxorasap/__init__.py,sha256=GkQbqhp8X0INL0fX6QVBw8-ig3E5TY1M4_2EuysCVrc,1356
2
2
  luxorasap/btgapi/__init__.py,sha256=QUlfb5oiBY6K1Q5x4-a-x2wECe1At5wc2962I5odOJk,620
3
3
  luxorasap/btgapi/auth.py,sha256=PvyCtbEyBO2B1CIeAlNXWugKW1OgiKfPcVzS6K5FBnQ,1872
4
4
  luxorasap/btgapi/reports.py,sha256=ZVEMLoJPXc0r3XjPJPMsKQN0zZd1Npd7umNpAj1bncs,8040
5
5
  luxorasap/btgapi/trades.py,sha256=956HZ9BvN9C_VQvKTyBLN0x6ZygwVqBZN11F7OnNbDI,5985
6
6
  luxorasap/datareader/__init__.py,sha256=41RAvbrQ4R6oj67S32CrKqolx0CJ2W8cbOF6g5Cqm2g,120
7
- luxorasap/datareader/core.py,sha256=VyUmD9DsFG6pemdotWZdjVIxpzkNqfhIl10elCZrh88,158680
7
+ luxorasap/datareader/core.py,sha256=D7nNdKiu5VAii4xWnoqO1PR0qaYi3YEfKyxhkVGZ1j8,158784
8
8
  luxorasap/ingest/__init__.py,sha256=gHkw8FU8TuRL5tfHkACxwsLHwLYX8SgX9xHkB8uTjww,831
9
9
  luxorasap/ingest/cloud/__init__.py,sha256=I0JZh9FbGnIVxu7VmiTXe8rKN_w5OWLULvkVkVZNeUk,7242
10
10
  luxorasap/ingest/legacy_local/dataloader.py,sha256=DF3CvojDAi0itVDZPsQbmpl5pqMTNwOOpxTz4Ju8mho,12419
@@ -13,12 +13,12 @@ luxorasap/utils/dataframe/__init__.py,sha256=heKpmq58FmX35syzzwrHqlOWKYBkH2Z1jyq
13
13
  luxorasap/utils/dataframe/reader.py,sha256=Vzjdw-AeS1lnWEHQ8RZNh0kK93NWTp0NWVi_B6mN5N0,616
14
14
  luxorasap/utils/dataframe/transforms.py,sha256=OIvlTTcjFX6bUhuQp_syEp7ssm4sLzwvgsag6n2Wl3k,2438
15
15
  luxorasap/utils/storage/__init__.py,sha256=461GYJcPMXGjHuJ9y9D3BHOC_oUS9Re32nVu1AwKyIA,334
16
- luxorasap/utils/storage/blob.py,sha256=vgCKMOiVgP-V1A2xZRhG3kJhPFU-LA9E9kddOQTxYD8,9443
16
+ luxorasap/utils/storage/blob.py,sha256=28bsUbEUjg_LapDZ4P3kWkxHDQGNXv_Jik49RfXbwME,11223
17
17
  luxorasap/utils/storage/change_tracker.py,sha256=HkeKc62UyD2BtP2gqafnJHZSBvYreH_7SQI1CYhn3Us,11709
18
18
  luxorasap/utils/tools/__init__.py,sha256=dvK7Z4xnNQAuEiObVN7qjeLWAvP49JeFn2Oq9GdgmXs,76
19
19
  luxorasap/utils/tools/excel.py,sha256=SfeTcbJWsWq3uKruwKSjJ4aWgMovITzlNXjP2bhdMjI,1246
20
- luxorasap-0.2.11.dist-info/METADATA,sha256=VxmpijHTlDCIgqzDQj-D1Uz0Bng9_6R7O1sw-7rZg-c,3804
21
- luxorasap-0.2.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- luxorasap-0.2.11.dist-info/entry_points.txt,sha256=XFh-dOwUhlya9DmGvgookMI0ezyUJjcOvTIHDEYS44g,52
23
- luxorasap-0.2.11.dist-info/top_level.txt,sha256=9YOL6bUIpzY06XFBRkUW1e4rgB32Ds91fQPGwUEjxzU,10
24
- luxorasap-0.2.11.dist-info/RECORD,,
20
+ luxorasap-0.2.13.dist-info/METADATA,sha256=PYZaklSt38Ed1ku0gR0ifcgHl4rcbw49LNd-Yf8TDlA,3804
21
+ luxorasap-0.2.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ luxorasap-0.2.13.dist-info/entry_points.txt,sha256=XFh-dOwUhlya9DmGvgookMI0ezyUJjcOvTIHDEYS44g,52
23
+ luxorasap-0.2.13.dist-info/top_level.txt,sha256=9YOL6bUIpzY06XFBRkUW1e4rgB32Ds91fQPGwUEjxzU,10
24
+ luxorasap-0.2.13.dist-info/RECORD,,