PYield 0.8.2__tar.gz → 0.8.4__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 (32) hide show
  1. {pyield-0.8.2 → pyield-0.8.4}/PKG-INFO +1 -1
  2. pyield-0.8.4/pyield/__about__.py +1 -0
  3. pyield-0.8.2/pyield/tn_bonds.py → pyield-0.8.4/pyield/anbima.py +50 -42
  4. {pyield-0.8.2 → pyield-0.8.4}/pyield/data_access.py +7 -7
  5. {pyield-0.8.2 → pyield-0.8.4}/pyield/ntnb.py +42 -32
  6. {pyield-0.8.2 → pyield-0.8.4}/pyield/spreads.py +2 -2
  7. {pyield-0.8.2 → pyield-0.8.4}/pyproject.toml +4 -1
  8. pyield-0.8.2/pyield/__about__.py +0 -1
  9. {pyield-0.8.2 → pyield-0.8.4}/LICENSE +0 -0
  10. {pyield-0.8.2 → pyield-0.8.4}/README.md +0 -0
  11. {pyield-0.8.2 → pyield-0.8.4}/pyield/__init__.py +0 -0
  12. {pyield-0.8.2 → pyield-0.8.4}/pyield/bday.py +0 -0
  13. {pyield-0.8.2 → pyield-0.8.4}/pyield/date_validator.py +0 -0
  14. {pyield-0.8.2 → pyield-0.8.4}/pyield/futures/__init__.py +0 -0
  15. {pyield-0.8.2 → pyield-0.8.4}/pyield/futures/common.py +0 -0
  16. {pyield-0.8.2 → pyield-0.8.4}/pyield/futures/historical.py +0 -0
  17. {pyield-0.8.2 → pyield-0.8.4}/pyield/futures/intraday.py +0 -0
  18. {pyield-0.8.2 → pyield-0.8.4}/pyield/futures/xml.py +0 -0
  19. {pyield-0.8.2 → pyield-0.8.4}/pyield/holidays/__init__.py +0 -0
  20. {pyield-0.8.2 → pyield-0.8.4}/pyield/holidays/br_holidays_new.txt +0 -0
  21. {pyield-0.8.2 → pyield-0.8.4}/pyield/holidays/br_holidays_old.txt +0 -0
  22. {pyield-0.8.2 → pyield-0.8.4}/pyield/holidays/core.py +0 -0
  23. {pyield-0.8.2 → pyield-0.8.4}/pyield/indicators.py +0 -0
  24. {pyield-0.8.2 → pyield-0.8.4}/pyield/interpolator.py +0 -0
  25. {pyield-0.8.2 → pyield-0.8.4}/pyield/projections.py +0 -0
  26. {pyield-0.8.2 → pyield-0.8.4}/pyield/py.typed +0 -0
  27. {pyield-0.8.2 → pyield-0.8.4}/tests/__init__.py +0 -0
  28. {pyield-0.8.2 → pyield-0.8.4}/tests/data/SPRD231222.zip +0 -0
  29. {pyield-0.8.2 → pyield-0.8.4}/tests/data/SPRD240426.zip +0 -0
  30. {pyield-0.8.2 → pyield-0.8.4}/tests/test_bday.py +0 -0
  31. {pyield-0.8.2 → pyield-0.8.4}/tests/test_futures.py +0 -0
  32. {pyield-0.8.2 → pyield-0.8.4}/tests/test_futures_xml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PYield
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
5
  Keywords: fixed-income, brazil, finance, analysis, bonds
6
6
  Author-Email: Carlos Carvalho <cr.cj@outlook.com>
@@ -0,0 +1 @@
1
+ __version__ = "0.8.4"
@@ -8,14 +8,16 @@ ANBIMA_NON_MEMBER_URL = "https://www.anbima.com.br/informacoes/merc-sec/arqs/"
8
8
  ANBIMA_MEMBER_URL = "http://www.anbima.associados.rtm/merc_sec/arqs/"
9
9
 
10
10
 
11
- def _get_anbima_content(reference_date: pd.Timestamp) -> str:
11
+ def _get_file_content(reference_date: pd.Timestamp, headers: dict = None) -> str:
12
+ headers = headers or {} # Default empty headers
12
13
  url_date = reference_date.strftime("%y%m%d")
13
14
  member_url = f"{ANBIMA_MEMBER_URL}ms{url_date}.txt"
15
+ # Non member url example: https://www.anbima.com.br/informacoes/merc-sec/arqs/ms240614.txt
14
16
  non_member_url = f"{ANBIMA_NON_MEMBER_URL}ms{url_date}.txt"
15
17
 
16
18
  # Tries to access the member URL first
17
19
  try:
18
- response = requests.get(member_url, timeout=5)
20
+ response = requests.get(member_url, headers=headers, timeout=5)
19
21
  # Checks if the response was successful (status code 200)
20
22
  response.raise_for_status()
21
23
  return response.text
@@ -33,14 +35,9 @@ def _get_anbima_content(reference_date: pd.Timestamp) -> str:
33
35
  return ""
34
36
 
35
37
 
36
- def _get_raw_df(reference_date: pd.Timestamp) -> pd.DataFrame:
37
- url_content = _get_anbima_content(reference_date)
38
- if url_content == "":
39
- date_str = reference_date.strftime("%d-%m-%Y")
40
- raise ValueError(f"Could not fetch ANBIMA data for {date_str}.")
41
-
42
- df = pd.read_csv(
43
- io.StringIO(url_content),
38
+ def _read_raw_df(file_content: str) -> pd.DataFrame:
39
+ return pd.read_csv(
40
+ io.StringIO(file_content),
44
41
  sep="@",
45
42
  encoding="latin-1",
46
43
  skiprows=2,
@@ -49,45 +46,41 @@ def _get_raw_df(reference_date: pd.Timestamp) -> pd.DataFrame:
49
46
  na_values=["--"],
50
47
  dtype_backend="numpy_nullable",
51
48
  )
52
- return df
53
49
 
54
50
 
55
51
  def _process_raw_df(df_raw: pd.DataFrame) -> pd.DataFrame:
56
52
  """
57
- Process raw data from ANBIMA by filtering selected columns, renaming them and
58
- adjusting data formats.
53
+ Process raw data from ANBIMA by renaming columns and adjusting data formats.
59
54
 
60
55
  Parameters:
61
- - df (pd.DataFrame): Raw data DataFrame to process.
56
+ df (pd.DataFrame): Raw DataFrame to process.
62
57
 
63
58
  Returns:
64
- - pd.DataFrame: Processed DataFrame.
59
+ pd.DataFrame: Processed DataFrame.
65
60
  """
66
61
  # Filter selected columns and rename them
67
62
  selected_columns_dict = {
68
63
  "Titulo": "BondType",
69
64
  "Data Referencia": "ReferenceDate",
70
- # "Codigo SELIC": "SelicCode",
71
- # "Data Base/Emissao": "IssueBaseDate",
65
+ "Codigo SELIC": "SelicCode",
66
+ "Data Base/Emissao": "IssueBaseDate",
72
67
  "Data Vencimento": "MaturityDate",
73
68
  "Tx. Compra": "BidRate",
74
69
  "Tx. Venda": "AskRate",
75
70
  "Tx. Indicativas": "IndicativeRate",
76
71
  "PU": "Price",
77
- # "Desvio padrao": "StdDev",
78
- # "Interv. Ind. Inf. (D0)",
79
- # "Interv. Ind. Sup. (D0)",
80
- # "Interv. Ind. Inf. (D+1)",
81
- # "Interv. Ind. Sup. (D+1)",
82
- # "Criterio": "Criteria",
72
+ "Desvio padrao": "StdDev",
73
+ "Interv. Ind. Inf. (D0)": "LowerBoundRateD0",
74
+ "Interv. Ind. Sup. (D0)": "UpperBoundRateD0",
75
+ "Interv. Ind. Inf. (D+1)": "LowerBoundRateD1",
76
+ "Interv. Ind. Sup. (D+1)": "UpperBoundRateD1",
77
+ "Criterio": "Criteria",
83
78
  }
84
- select_columns = list(selected_columns_dict.keys())
85
- df = df_raw[select_columns].copy()
86
- df = df.rename(columns=selected_columns_dict)
79
+ df = df_raw.rename(columns=selected_columns_dict)
87
80
 
88
81
  # Remove percentage from rates
89
- rate_cols = ["BidRate", "AskRate", "IndicativeRate"]
90
- df[rate_cols] = df[rate_cols] / 100
82
+ rate_cols = [col for col in df.columns if "Rate" in col]
83
+ df[rate_cols] = (df[rate_cols] / 100).round(6)
91
84
 
92
85
  df["ReferenceDate"] = pd.to_datetime(df["ReferenceDate"], format="%Y%m%d")
93
86
  df["MaturityDate"] = pd.to_datetime(df["MaturityDate"], format="%Y%m%d")
@@ -95,31 +88,46 @@ def _process_raw_df(df_raw: pd.DataFrame) -> pd.DataFrame:
95
88
  return df.sort_values(["BondType", "MaturityDate"], ignore_index=True)
96
89
 
97
90
 
98
- def fetch_bonds(reference_date: pd.Timestamp, return_raw=False) -> pd.DataFrame:
91
+ def fetch_data(reference_date: pd.Timestamp, headers: dict = None) -> pd.DataFrame:
99
92
  """
100
93
  Fetches indicative treasury rates from ANBIMA for a specified reference date.
101
94
 
102
95
  This function retrieves the indicative rates for Brazilian treasury securities
103
96
  from ANBIMA, processing them into a structured pandas DataFrame.
104
- There is an option to return raw data directly from the source without processing.
105
97
 
106
98
  Parameters:
107
- reference_date (str | pd.Timestamp, optional): The date for which to fetch the
108
- indicative rates. If None or not provided, the function defaults to the
109
- previous business day.
110
- return_raw (bool, optional): Flag to return raw data without processing.
111
- Defaults to False.
99
+ reference_date (pd.Timestamp): The date for which to fetch the indicative rates.
112
100
 
113
101
  Returns:
114
102
  pd.DataFrame: A DataFrame containing the processed indicative rates for the
115
- given reference date, or raw data if `return_raw` is True. The processed
116
- data includes bond type, reference date, maturity date and various rates
117
- (bid, ask, indicative) among others, depending on the `return_raw` flag.
103
+ given reference date.
104
+
105
+ """
106
+ file_content = _get_file_content(reference_date, headers)
107
+
108
+ if file_content == "":
109
+ date_str = reference_date.strftime("%d-%m-%Y")
110
+ raise ValueError(f"Could not fetch ANBIMA data for {date_str}.")
111
+
112
+ df = _read_raw_df(file_content)
113
+
114
+ return _process_raw_df(df)
118
115
 
116
+
117
+ def fetch_rates(reference_date: pd.Timestamp, headers: dict = None) -> pd.DataFrame:
119
118
  """
120
- df = _get_raw_df(reference_date)
119
+ Fetches indicative treasury rates from ANBIMA for a specified reference date.
120
+
121
+ This function retrieves the indicative rates for Brazilian treasury securities
122
+ from ANBIMA, processing them into a structured pandas DataFrame.
121
123
 
122
- if not return_raw:
123
- df = _process_raw_df(df)
124
+ Parameters:
125
+ reference_date (pd.Timestamp): The date for which to fetch the indicative rates.
124
126
 
125
- return df
127
+ Returns:
128
+ pd.DataFrame: A DataFrame containing the processed indicative rates for the
129
+ given reference date.
130
+
131
+ """
132
+ df = fetch_data(reference_date, headers)
133
+ return df[["BondType", "MaturityDate", "IndicativeRate"]].copy()
@@ -1,11 +1,11 @@
1
1
  import pandas as pd
2
2
 
3
+ from . import anbima as an
3
4
  from . import date_validator as dv
4
5
  from . import futures as ft
5
6
  from . import indicators as it
6
7
  from . import projections as pr
7
8
  from . import spreads as sp
8
- from . import tn_bonds as tb
9
9
 
10
10
 
11
11
  def fetch_asset(
@@ -17,7 +17,7 @@ def fetch_asset(
17
17
  Args:
18
18
  asset_code (str): The asset code identifying the type of financial asset.
19
19
  Supported options:
20
- - "TRB": Treasury bonds (indicative rates from ANBIMA).
20
+ - "TRB": Brazilian treasury bonds (indicative rates from ANBIMA).
21
21
  - "LTN", "LFT", "NTN-F", "NTN-B": Specific types of Brazilian treasury bonds
22
22
  (indicative rates from ANBIMA).
23
23
  - "DI1": One-day Interbank Deposit Futures (Futuro de DI) from B3.
@@ -42,7 +42,7 @@ def fetch_asset(
42
42
  ValueError: If the asset code is not recognized or supported.
43
43
 
44
44
  Examples:
45
- >>> fetch_asset("TRB", "31-05-2024")
45
+ >>> fetch_asset("LTN", "31-05-2024")
46
46
  >>> fetch_asset("DI1", "31-05-2024")
47
47
  """
48
48
  SUPPORTED_BONDS = ["LTN", "LFT", "NTN-F", "NTN-B"]
@@ -55,13 +55,13 @@ def fetch_asset(
55
55
  return ft.fetch_intraday_df(future_code=asset_code.upper())
56
56
 
57
57
  if asset_code.upper() == "TRB":
58
- return tb.fetch_bonds(reference_date=normalized_date)
58
+ return an.fetch_data(reference_date=normalized_date)
59
59
 
60
60
  if asset_code.upper() in SUPPORTED_BONDS:
61
- df_bond = tb.fetch_bonds(reference_date=normalized_date)
61
+ df_bond = an.fetch_data(reference_date=normalized_date)
62
62
  df_bond.query(f"BondType == '{asset_code.upper()}'", inplace=True)
63
- # Return the DataFrame sorted by maturity date
64
- return df_bond.sort_values("MaturityDate", ignore_index=True)
63
+ # Return the DataFrame with the index reset
64
+ return df_bond.reset_index(drop=True)
65
65
 
66
66
  if asset_code.upper() in SUPPORTED_FUTURES:
67
67
  return ft.fetch_historical_df(
@@ -23,7 +23,7 @@ def anbima_data(reference_date: str | pd.Timestamp) -> pd.DataFrame:
23
23
  return da.fetch_asset(asset_code="NTN-B", reference_date=reference_date)
24
24
 
25
25
 
26
- def anbima_rates(reference_date: str | pd.Timestamp) -> pd.DataFrame:
26
+ def ytm_rates(reference_date: str | pd.Timestamp) -> pd.DataFrame:
27
27
  """
28
28
  Fetch NTN-B Anbima indicative rates for the given reference date.
29
29
 
@@ -33,10 +33,12 @@ def anbima_rates(reference_date: str | pd.Timestamp) -> pd.DataFrame:
33
33
  Returns:
34
34
  pd.DataFrame: A DataFrame containing the maturity dates and corresponding rates.
35
35
  """
36
- return anbima_data(reference_date)[["MaturityDate", "IndicativeRate"]]
36
+ df = anbima_data(reference_date)[["MaturityDate", "IndicativeRate"]]
37
+ # Rename IndicativeRate to YTM for consistency
38
+ return df.rename(columns={"IndicativeRate": "YTM"})
37
39
 
38
40
 
39
- def truncate(value, decimal_places):
41
+ def _truncate(value, decimal_places):
40
42
  """
41
43
  Truncate a float or a Pandas Series to the specified decimal place.
42
44
 
@@ -178,16 +180,16 @@ def quotation(
178
180
  cf = np.where(payment_dates == maturity_date, FINAL_PMT, INTER_PMT)
179
181
 
180
182
  # Calculate the number of periods truncated to 14 decimal places
181
- n = truncate(bdays / 252, 14)
183
+ n = _truncate(bdays / 252, 14)
182
184
 
183
185
  # Calculate the present value of each cash flow (DCF) rounded to 10 decimal places
184
186
  dcf = (cf / (1 + discount_rate) ** n).round(10)
185
187
 
186
188
  # Return the quotation (the dcf sum) truncated to 4 decimal places
187
- return truncate(dcf.sum(), 4)
189
+ return _truncate(dcf.sum(), 4)
188
190
 
189
191
 
190
- def prepare_interpolation_data(
192
+ def _prepare_interpolation_data(
191
193
  reference_date: pd.Timestamp, maturity_dates: pd.Series, rates: pd.Series
192
194
  ) -> tuple:
193
195
  """
@@ -242,7 +244,7 @@ def spot_rates(
242
244
  settlement_date = dv.normalize_date(settlement_date)
243
245
 
244
246
  # Prepare the data for interpolation
245
- ordered_bdays, ordered_ytms = prepare_interpolation_data(
247
+ ordered_bdays, ordered_ytms = _prepare_interpolation_data(
246
248
  settlement_date, maturity_dates, ytm_rates
247
249
  )
248
250
  # Generate coupon dates and initialize the main DataFrame
@@ -253,7 +255,7 @@ def spot_rates(
253
255
  # Add auxiliary columns for calculations
254
256
  df["BDays"] = bday.count_bdays(settlement_date, df["MaturityDate"])
255
257
  df["YTM"] = 0.0
256
- df["SpotRate"] = 0.0
258
+ df["RSR"] = 0.0
257
259
 
258
260
  # Main loop to calculate spot rates
259
261
  for index in df.index:
@@ -266,7 +268,7 @@ def spot_rates(
266
268
 
267
269
  # Create the Series that will be used to calculate the discounted cash flows
268
270
  cfs = pd.Series(COUPON, index=dfl.index)
269
- spot_rates = dfl["SpotRate"]
271
+ spot_rates = dfl["RSR"]
270
272
  periods = dfl["BDays"] / 252
271
273
 
272
274
  # Calculate the present value of the cash flows (discounted cash flows)
@@ -279,7 +281,7 @@ def spot_rates(
279
281
  spot_rate = ((COUPON + 1) / (ntnb_quotation - dcfs.sum())) ** (252 / bd) - 1
280
282
 
281
283
  # Update DataFrame with calculated values
282
- df.at[index, "SpotRate"] = spot_rate
284
+ df.at[index, "RSR"] = spot_rate
283
285
  df.at[index, "YTM"] = ytm
284
286
 
285
287
  # Drop the BDays column, remove intermediate cupon dates and reset the index.
@@ -290,7 +292,7 @@ def spot_rates(
290
292
  )
291
293
 
292
294
 
293
- def _get_nir_df(reference_date: pd.Timestamp) -> pd.DataFrame:
295
+ def _get_nsr_df(reference_date: pd.Timestamp) -> pd.DataFrame:
294
296
  """
295
297
  Fetch the Nominal Interest Rate (NIR) data for NTN-B bonds.
296
298
 
@@ -345,14 +347,14 @@ def _get_nir_df(reference_date: pd.Timestamp) -> pd.DataFrame:
345
347
  return df
346
348
 
347
349
 
348
- def breakeven_inflation(
350
+ def bei_rates(
349
351
  reference_date: str | pd.Timestamp,
350
352
  settlement_date: str | pd.Timestamp,
351
353
  maturity_dates: pd.Series,
352
354
  ytm_rates: pd.Series,
353
355
  ) -> pd.DataFrame:
354
356
  """
355
- Calculate the Breakeven Inflation (INF) for NTN-B bonds based on nominal and real
357
+ Calculate the Breakeven Inflation (BEI) for NTN-B bonds based on nominal and real
356
358
  interest rates.
357
359
 
358
360
  Args:
@@ -364,45 +366,53 @@ def breakeven_inflation(
364
366
  to the maturity dates.
365
367
 
366
368
  Returns:
367
- pd.DataFrame: DataFrame containing the maturity dates, business days to maturity
368
- (BDays), Yield to Maturity (YTM), real spot rates (RSR), nominal spot rates
369
- (NSR_DI and NSR_PRE), and breakeven inflation rates (INF_DI and INF_PRE).
369
+ pd.DataFrame: DataFrame containing the breakeven inflation rates.
370
+
371
+ Returned columns:
372
+ - MaturityDate: Maturity date of the bond.
373
+ - BDays: Number of business days from the settlement date to the maturity.
374
+ - YTM: Yield to Maturity rate for the bond.
375
+ - RSR: Real Spot Rate for the bond.
376
+ - NSR_DI: Nominal Spot Rate for the bond.
377
+ - NSR_PRE: Nominal Spot Rate for the bond with DI spread.
378
+ - BIR_DI: Breakeven Inflation Rate for the bond.
379
+ - BIR_PRE: Breakeven Inflation Rate for the bond adjusted for DI spread.
370
380
  """
371
381
  # Normalize input dates
372
382
  reference_date = dv.normalize_date(reference_date)
373
383
  settlement_date = dv.normalize_date(settlement_date)
374
384
 
375
385
  # Fetch Nominal Spot Rate (NSR) data
376
- df_nir = _get_nir_df(reference_date)
377
- known_bdays = df_nir["BDaysToExp"].to_list()
378
- known_rates = df_nir["NSR_DI"].to_list()
386
+ df_nsr = _get_nsr_df(reference_date)
387
+ known_bdays = df_nsr["BDaysToExp"].to_list()
388
+ known_rates = df_nsr["NSR_DI"].to_list()
379
389
 
380
390
  # Calculate Real Spot Rate (RSR)
381
- df_rir = spot_rates(settlement_date, maturity_dates, ytm_rates)
382
- df_rir = df_rir.rename(columns={"SpotRate": "RSR"})
383
- df_rir["BDays"] = bday.count_bdays(reference_date, df_rir["MaturityDate"])
384
- df_rir["NSR_DI"] = df_rir["BDays"].apply(
391
+ df = spot_rates(settlement_date, maturity_dates, ytm_rates)
392
+ df = df.rename(columns={"RSR": "RSR"})
393
+ df["BDays"] = bday.count_bdays(reference_date, df["MaturityDate"])
394
+ df["NSR_DI"] = df["BDays"].apply(
385
395
  lambda x: ip.find_and_interpolate_flat_forward(x, known_bdays, known_rates)
386
396
  )
387
397
 
388
- # Calculate Breakeven Inflation (INF)
389
- df_rir["INF_DI"] = ((df_rir["NSR_DI"] + 1) / (df_rir["RSR"] + 1)) - 1
398
+ # Calculate Breakeven Inflation Rate (BIR)
399
+ df["BIR_DI"] = ((df["NSR_DI"] + 1) / (df["RSR"] + 1)) - 1
390
400
 
391
401
  # Adjust BEI for DI spread in prefixed bonds
392
- known_rates = df_nir["NSR_PRE"].to_list()
393
- df_rir["NSR_PRE"] = df_rir["BDays"].apply(
402
+ known_rates = df_nsr["NSR_PRE"].to_list()
403
+ df["NSR_PRE"] = df["BDays"].apply(
394
404
  lambda x: ip.find_and_interpolate_flat_forward(x, known_bdays, known_rates)
395
405
  )
396
- df_rir["INF_PRE"] = ((df_rir["NSR_PRE"] + 1) / (df_rir["RSR"] + 1)) - 1
406
+ df["BIR_PRE"] = ((df["NSR_PRE"] + 1) / (df["RSR"] + 1)) - 1
397
407
 
398
- order_cols = [
408
+ cols_reordered = [
399
409
  "MaturityDate",
400
410
  "BDays",
401
411
  "YTM",
402
412
  "RSR",
403
413
  "NSR_DI",
404
414
  "NSR_PRE",
405
- "INF_DI",
406
- "INF_PRE",
415
+ "BIR_DI",
416
+ "BIR_PRE",
407
417
  ]
408
- return df_rir[order_cols].copy()
418
+ return df[cols_reordered].copy()
@@ -1,6 +1,6 @@
1
1
  import pandas as pd
2
2
 
3
- from . import tn_bonds as tb
3
+ from . import anbima as an
4
4
  from .futures import historical as fh
5
5
 
6
6
  # Constant for conversion to basis points
@@ -38,7 +38,7 @@ def calculate_di_spreads(reference_date: pd.Timestamp) -> pd.DataFrame:
38
38
  df_di["MaturityDate"] = df_di["MaturityDate"].dt.to_period("M").dt.to_timestamp()
39
39
 
40
40
  # Fetch bond rates, filtering for LTN and NTN-F types
41
- df_anbima = tb.fetch_bonds(reference_date, False)
41
+ df_anbima = an.fetch_data(reference_date, False)
42
42
  df_anbima.query("BondType in ['LTN', 'NTN-F']", inplace=True)
43
43
 
44
44
  # Merge bond and DI rates by maturity date to calculate spreads
@@ -32,7 +32,7 @@ dependencies = [
32
32
  "requests>=2.31.0",
33
33
  ]
34
34
  dynamic = []
35
- version = "0.8.2"
35
+ version = "0.8.4"
36
36
 
37
37
  [project.license]
38
38
  file = "LICENSE"
@@ -52,6 +52,9 @@ dev = [
52
52
  "ipykernel",
53
53
  "pytest",
54
54
  "mypy",
55
+ "mkdocs",
56
+ "mkdocs-material",
57
+ "mkdocstrings[python]",
55
58
  ]
56
59
 
57
60
  [tool.ruff]
@@ -1 +0,0 @@
1
- __version__ = "0.8.2"
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
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