finbrain-python 0.2.2__py3-none-any.whl → 0.2.4__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.
finbrain/aio/client.py CHANGED
@@ -24,6 +24,7 @@ from .endpoints.screener import AsyncScreenerAPI
24
24
  from .endpoints.recent import AsyncRecentAPI
25
25
  from .endpoints.corporate_lobbying import AsyncCorporateLobbyingAPI
26
26
  from .endpoints.reddit_mentions import AsyncRedditMentionsAPI
27
+ from .endpoints.government_contracts import AsyncGovernmentContractsAPI
27
28
 
28
29
 
29
30
  # Which status codes merit a retry
@@ -84,6 +85,7 @@ class AsyncFinBrainClient:
84
85
  self.recent = AsyncRecentAPI(self)
85
86
  self.corporate_lobbying = AsyncCorporateLobbyingAPI(self)
86
87
  self.reddit_mentions = AsyncRedditMentionsAPI(self)
88
+ self.government_contracts = AsyncGovernmentContractsAPI(self)
87
89
 
88
90
  async def __aenter__(self) -> "AsyncFinBrainClient":
89
91
  """Context manager entry."""
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+ import pandas as pd
3
+ import datetime as _dt
4
+ from typing import TYPE_CHECKING, Dict, Any, List
5
+
6
+ from ._utils import to_datestr
7
+
8
+ if TYPE_CHECKING:
9
+ from ..client import AsyncFinBrainClient
10
+
11
+
12
+ class AsyncGovernmentContractsAPI:
13
+ """Async wrapper for /government-contracts and /screener/government-contracts endpoints."""
14
+
15
+ def __init__(self, client: "AsyncFinBrainClient") -> None:
16
+ self._c = client
17
+
18
+ async def ticker(
19
+ self,
20
+ symbol: str,
21
+ *,
22
+ date_from: _dt.date | str | None = None,
23
+ date_to: _dt.date | str | None = None,
24
+ limit: int | None = None,
25
+ as_dataframe: bool = False,
26
+ ) -> Dict[str, Any] | pd.DataFrame:
27
+ """Fetch government contract awards for a symbol (async)."""
28
+ params: Dict[str, str] = {}
29
+ if date_from:
30
+ params["startDate"] = to_datestr(date_from)
31
+ if date_to:
32
+ params["endDate"] = to_datestr(date_to)
33
+ if limit is not None:
34
+ params["limit"] = str(limit)
35
+
36
+ path = f"government-contracts/{symbol.upper()}"
37
+
38
+ data: Dict[str, Any] = await self._c._request("GET", path, params=params)
39
+
40
+ if as_dataframe:
41
+ rows: List[Dict[str, Any]] = data.get("contracts", [])
42
+ df = pd.DataFrame(rows)
43
+ if not df.empty and "startDate" in df.columns:
44
+ df["startDate"] = pd.to_datetime(df["startDate"])
45
+ df.set_index("startDate", inplace=True)
46
+ return df
47
+
48
+ return data
@@ -46,34 +46,3 @@ class AsyncRedditMentionsAPI:
46
46
  return df
47
47
 
48
48
  return data
49
-
50
- async def screener(
51
- self,
52
- *,
53
- limit: int | None = None,
54
- market: str | None = None,
55
- region: str | None = None,
56
- as_dataframe: bool = False,
57
- ) -> Dict[str, Any] | pd.DataFrame:
58
- """Get recent Reddit mention counts across all tickers (async)."""
59
- params: Dict[str, str] = {}
60
- if limit is not None:
61
- params["limit"] = str(limit)
62
- if market:
63
- params["market"] = market
64
- if region:
65
- params["region"] = region
66
-
67
- data: Dict[str, Any] = await self._c._request(
68
- "GET", "screener/reddit-mentions", params=params
69
- )
70
-
71
- if as_dataframe:
72
- rows: List[Dict[str, Any]] = data.get("data", [])
73
- df = pd.DataFrame(rows)
74
- if not df.empty and "date" in df.columns:
75
- df["date"] = pd.to_datetime(df["date"])
76
- df.set_index("date", inplace=True)
77
- return df
78
-
79
- return data
@@ -208,3 +208,29 @@ class AsyncScreenerAPI:
208
208
  """Screen monthly (12-month) predictions across tickers."""
209
209
  params = self._build_params(limit=limit, market=market, region=region)
210
210
  return await self._get("screener/predictions/monthly", params, as_dataframe)
211
+
212
+ # ── reddit mentions ────────────────────────────────────────
213
+
214
+ async def reddit_mentions(
215
+ self,
216
+ *,
217
+ limit: int | None = None,
218
+ market: str | None = None,
219
+ region: str | None = None,
220
+ as_dataframe: bool = False,
221
+ ) -> List[Dict[str, Any]] | pd.DataFrame:
222
+ """Screen Reddit mention counts across tickers (async)."""
223
+ params = self._build_params(limit=limit, market=market, region=region)
224
+ return await self._get("screener/reddit-mentions", params, as_dataframe)
225
+
226
+ # ── government contracts ──────────────────────────────────
227
+
228
+ async def government_contracts(
229
+ self,
230
+ *,
231
+ limit: int | None = None,
232
+ as_dataframe: bool = False,
233
+ ) -> List[Dict[str, Any]] | pd.DataFrame:
234
+ """Screen government contracts across all tickers (async)."""
235
+ params = self._build_params(limit=limit)
236
+ return await self._get("screener/government-contracts", params, as_dataframe)
finbrain/client.py CHANGED
@@ -25,6 +25,7 @@ from .endpoints.screener import ScreenerAPI
25
25
  from .endpoints.recent import RecentAPI
26
26
  from .endpoints.corporate_lobbying import CorporateLobbyingAPI
27
27
  from .endpoints.reddit_mentions import RedditMentionsAPI
28
+ from .endpoints.government_contracts import GovernmentContractsAPI
28
29
 
29
30
 
30
31
  # Which status codes merit a retry
@@ -79,6 +80,7 @@ class FinBrainClient:
79
80
  self.recent = RecentAPI(self)
80
81
  self.corporate_lobbying = CorporateLobbyingAPI(self)
81
82
  self.reddit_mentions = RedditMentionsAPI(self)
83
+ self.government_contracts = GovernmentContractsAPI(self)
82
84
 
83
85
  # ---------- private helpers ----------
84
86
  def _request(
@@ -0,0 +1,73 @@
1
+ from __future__ import annotations
2
+ import pandas as pd
3
+ import datetime as _dt
4
+ from typing import TYPE_CHECKING, Dict, Any, List
5
+
6
+ from ._utils import to_datestr
7
+
8
+ if TYPE_CHECKING: # imported only by type-checkers
9
+ from ..client import FinBrainClient
10
+
11
+
12
+ class GovernmentContractsAPI:
13
+ """
14
+ Endpoints
15
+ ---------
16
+ ``/government-contracts/<TICKER>`` - U.S. government contract awards.
17
+ ``/screener/government-contracts`` - cross-ticker government contracts screener.
18
+ """
19
+
20
+ # ------------------------------------------------------------------ #
21
+ def __init__(self, client: "FinBrainClient") -> None:
22
+ self._c = client # reference to the parent client
23
+
24
+ # ------------------------------------------------------------------ #
25
+ def ticker(
26
+ self,
27
+ symbol: str,
28
+ *,
29
+ date_from: _dt.date | str | None = None,
30
+ date_to: _dt.date | str | None = None,
31
+ limit: int | None = None,
32
+ as_dataframe: bool = False,
33
+ ) -> Dict[str, Any] | pd.DataFrame:
34
+ """
35
+ Fetch government contract awards for *symbol*.
36
+
37
+ Parameters
38
+ ----------
39
+ symbol :
40
+ Ticker symbol; auto-upper-cased.
41
+ date_from, date_to :
42
+ Optional ISO dates (``YYYY-MM-DD``) bounding the returned rows.
43
+ limit :
44
+ Maximum number of records to return (1-500).
45
+ as_dataframe :
46
+ If *True*, return a **pandas.DataFrame** indexed by ``startDate``;
47
+ otherwise return the raw JSON dict.
48
+
49
+ Returns
50
+ -------
51
+ dict | pandas.DataFrame
52
+ """
53
+ params: Dict[str, str] = {}
54
+ if date_from:
55
+ params["startDate"] = to_datestr(date_from)
56
+ if date_to:
57
+ params["endDate"] = to_datestr(date_to)
58
+ if limit is not None:
59
+ params["limit"] = str(limit)
60
+
61
+ path = f"government-contracts/{symbol.upper()}"
62
+
63
+ data: Dict[str, Any] = self._c._request("GET", path, params=params)
64
+
65
+ if as_dataframe:
66
+ rows: List[Dict[str, Any]] = data.get("contracts", [])
67
+ df = pd.DataFrame(rows)
68
+ if not df.empty and "startDate" in df.columns:
69
+ df["startDate"] = pd.to_datetime(df["startDate"])
70
+ df.set_index("startDate", inplace=True)
71
+ return df
72
+
73
+ return data
@@ -71,53 +71,3 @@ class RedditMentionsAPI:
71
71
  return df
72
72
 
73
73
  return data
74
-
75
- # ------------------------------------------------------------------ #
76
- def screener(
77
- self,
78
- *,
79
- limit: int | None = None,
80
- market: str | None = None,
81
- region: str | None = None,
82
- as_dataframe: bool = False,
83
- ) -> Dict[str, Any] | pd.DataFrame:
84
- """
85
- Get recent Reddit mention counts across all tickers.
86
-
87
- Parameters
88
- ----------
89
- limit :
90
- Maximum number of records to return (1-20000).
91
- market :
92
- Filter by market name (e.g. ``"S&P 500"``, ``"NASDAQ"``).
93
- region :
94
- Filter by region (e.g. ``"US"``, ``"Europe"``).
95
- as_dataframe :
96
- If *True*, return a **pandas.DataFrame** indexed by ``date``;
97
- otherwise return the raw JSON dict.
98
-
99
- Returns
100
- -------
101
- dict | pandas.DataFrame
102
- """
103
- params: Dict[str, str] = {}
104
- if limit is not None:
105
- params["limit"] = str(limit)
106
- if market:
107
- params["market"] = market
108
- if region:
109
- params["region"] = region
110
-
111
- data: Dict[str, Any] = self._c._request(
112
- "GET", "screener/reddit-mentions", params=params
113
- )
114
-
115
- if as_dataframe:
116
- rows: List[Dict[str, Any]] = data.get("data", [])
117
- df = pd.DataFrame(rows)
118
- if not df.empty and "date" in df.columns:
119
- df["date"] = pd.to_datetime(df["date"])
120
- df.set_index("date", inplace=True)
121
- return df
122
-
123
- return data
@@ -213,3 +213,29 @@ class ScreenerAPI:
213
213
  """Screen monthly (12-month) predictions across tickers."""
214
214
  params = self._build_params(limit=limit, market=market, region=region)
215
215
  return self._get("screener/predictions/monthly", params, as_dataframe)
216
+
217
+ # ── reddit mentions ────────────────────────────────────────
218
+
219
+ def reddit_mentions(
220
+ self,
221
+ *,
222
+ limit: int | None = None,
223
+ market: str | None = None,
224
+ region: str | None = None,
225
+ as_dataframe: bool = False,
226
+ ) -> List[Dict[str, Any]] | pd.DataFrame:
227
+ """Screen Reddit mention counts across tickers."""
228
+ params = self._build_params(limit=limit, market=market, region=region)
229
+ return self._get("screener/reddit-mentions", params, as_dataframe)
230
+
231
+ # ── government contracts ──────────────────────────────────
232
+
233
+ def government_contracts(
234
+ self,
235
+ *,
236
+ limit: int | None = None,
237
+ as_dataframe: bool = False,
238
+ ) -> List[Dict[str, Any]] | pd.DataFrame:
239
+ """Screen government contracts across all tickers."""
240
+ params = self._build_params(limit=limit)
241
+ return self._get("screener/government-contracts", params, as_dataframe)
finbrain/plotting.py CHANGED
@@ -1057,7 +1057,7 @@ class _PlotNamespace:
1057
1057
  # --------------------------------------------------------------------- #
1058
1058
  # Reddit Mentions Screener → stacked horizontal bars (top N tickers) #
1059
1059
  # --------------------------------------------------------------------- #
1060
- def reddit_mentions_screener(
1060
+ def reddit_mentions_top(
1061
1061
  self,
1062
1062
  *,
1063
1063
  top_n: int = 15,
@@ -1091,20 +1091,20 @@ class _PlotNamespace:
1091
1091
  Plotly template name.
1092
1092
  **kwargs
1093
1093
  Additional arguments passed to
1094
- :meth:`FinBrainClient.reddit_mentions.screener`.
1094
+ :meth:`FinBrainClient.screener.reddit_mentions`.
1095
1095
 
1096
1096
  Returns
1097
1097
  -------
1098
1098
  plotly.graph_objects.Figure or str or None
1099
1099
  """
1100
- data = self._fb.reddit_mentions.screener(
1100
+ data = self._fb.screener.reddit_mentions(
1101
1101
  market=market,
1102
1102
  region=region,
1103
1103
  limit=limit,
1104
1104
  **kwargs,
1105
1105
  )
1106
1106
 
1107
- rows = data.get("data", [])
1107
+ rows = data if isinstance(data, list) else data.get("data", [])
1108
1108
  if not rows:
1109
1109
  raise ValueError("No screener data returned")
1110
1110
 
@@ -1154,6 +1154,160 @@ class _PlotNamespace:
1154
1154
  return None
1155
1155
  return fig.to_json() if as_json else fig
1156
1156
 
1157
+ # --------------------------------------------------------------------- #
1158
+ # Government Contracts → bars on price chart #
1159
+ # --------------------------------------------------------------------- #
1160
+ def government_contracts(
1161
+ self,
1162
+ ticker: str,
1163
+ price_data: pd.DataFrame,
1164
+ *,
1165
+ date_from: str | None = None,
1166
+ date_to: str | None = None,
1167
+ as_json: bool = False,
1168
+ show: bool = True,
1169
+ template: str = "plotly_dark",
1170
+ **kwargs,
1171
+ ):
1172
+ """
1173
+ Plot government contract awards overlaid on a price chart.
1174
+
1175
+ This method requires user-provided historical price data, as FinBrain
1176
+ does not currently offer a price history endpoint.
1177
+
1178
+ Parameters
1179
+ ----------
1180
+ ticker : str
1181
+ Ticker symbol (e.g. ``"LMT"``).
1182
+ price_data : pandas.DataFrame
1183
+ **User-provided** price history with a DatetimeIndex and a column
1184
+ containing prices (e.g. ``"close"``, ``"Close"``, or ``"price"``).
1185
+ The index must be timezone-naive or UTC.
1186
+ date_from, date_to : str or None, optional
1187
+ Date range for contracts in ``YYYY-MM-DD`` format.
1188
+ as_json : bool, default False
1189
+ If ``True``, return JSON string instead of Figure object.
1190
+ show : bool, default True
1191
+ If ``True`` and ``as_json=False``, display the figure immediately.
1192
+ template : str, default "plotly_dark"
1193
+ Plotly template name.
1194
+ **kwargs
1195
+ Additional arguments passed to
1196
+ :meth:`FinBrainClient.government_contracts.ticker`.
1197
+
1198
+ Returns
1199
+ -------
1200
+ plotly.graph_objects.Figure or str or None
1201
+ Figure object, JSON string, or None (when shown).
1202
+
1203
+ Raises
1204
+ ------
1205
+ ValueError
1206
+ If ``price_data`` is empty or missing required price column.
1207
+ """
1208
+ # Validate price_data
1209
+ if price_data.empty:
1210
+ raise ValueError("price_data cannot be empty")
1211
+
1212
+ # Flatten MultiIndex columns if present (e.g., from yf.download())
1213
+ if isinstance(price_data.columns, pd.MultiIndex):
1214
+ price_data = price_data.copy()
1215
+ price_data.columns = price_data.columns.get_level_values(0)
1216
+
1217
+ # Find price column (case-insensitive search)
1218
+ price_col = None
1219
+ for col in ["close", "Close", "price", "Price", "adj_close", "Adj Close"]:
1220
+ if col in price_data.columns:
1221
+ price_col = col
1222
+ break
1223
+ if price_col is None:
1224
+ raise ValueError(
1225
+ f"price_data must contain a price column (e.g. 'close', 'Close', 'price'). "
1226
+ f"Found columns: {price_data.columns.tolist()}"
1227
+ )
1228
+
1229
+ # Fetch government contracts
1230
+ contracts_df = self._fb.government_contracts.ticker(
1231
+ ticker,
1232
+ date_from=date_from,
1233
+ date_to=date_to,
1234
+ as_dataframe=True,
1235
+ **kwargs,
1236
+ )
1237
+
1238
+ # Normalize timezones
1239
+ price_data_normalized = price_data.copy()
1240
+ if price_data_normalized.index.tz is not None:
1241
+ price_data_normalized.index = price_data_normalized.index.tz_localize(None)
1242
+
1243
+ fig = go.Figure(
1244
+ layout=dict(
1245
+ template=template,
1246
+ title=f"Government Contracts · {ticker}",
1247
+ xaxis_title="Date",
1248
+ hovermode="x unified",
1249
+ )
1250
+ )
1251
+
1252
+ # Plot price line on primary y-axis
1253
+ fig.add_scatter(
1254
+ name="Price",
1255
+ x=price_data_normalized.index,
1256
+ y=price_data_normalized[price_col],
1257
+ mode="lines",
1258
+ line=dict(width=2, color="#02d2ff"),
1259
+ hovertemplate="<b>%{x|%Y-%m-%d}</b><br>Price: $%{y:.2f}<extra></extra>",
1260
+ )
1261
+
1262
+ if not contracts_df.empty:
1263
+ contracts_normalized = contracts_df.copy()
1264
+ if contracts_normalized.index.tz is not None:
1265
+ contracts_normalized.index = contracts_normalized.index.tz_localize(None)
1266
+
1267
+ amounts = contracts_normalized.get("awardAmount", pd.Series(dtype=float))
1268
+
1269
+ hover_text = []
1270
+ for _, row in contracts_normalized.iterrows():
1271
+ agency = row.get("awardingAgency", "N/A")
1272
+ desc = row.get("description", "")
1273
+ if len(str(desc)) > 80:
1274
+ desc = str(desc)[:80] + "…"
1275
+ naics = row.get("naicsDescription", "")
1276
+ amount = row.get("awardAmount", 0)
1277
+ hover_text.append(
1278
+ f"Agency: {agency}<br>"
1279
+ f"Amount: ${amount:,.0f}<br>"
1280
+ f"NAICS: {naics}<br>"
1281
+ f"Desc: {desc}"
1282
+ )
1283
+
1284
+ fig.add_bar(
1285
+ name="Contract Award",
1286
+ x=contracts_normalized.index,
1287
+ y=amounts,
1288
+ marker_color="rgba(249,200,14,0.6)",
1289
+ yaxis="y2",
1290
+ hovertext=hover_text,
1291
+ hovertemplate="<b>%{x|%Y-%m-%d}</b><br>%{hovertext}<extra></extra>",
1292
+ )
1293
+
1294
+ fig.update_layout(
1295
+ yaxis=dict(title="Price", showgrid=True),
1296
+ yaxis2=dict(
1297
+ title="Award Amount ($)",
1298
+ overlaying="y",
1299
+ side="right",
1300
+ showgrid=False,
1301
+ zeroline=False,
1302
+ rangemode="tozero",
1303
+ ),
1304
+ )
1305
+
1306
+ if show and not as_json:
1307
+ fig.show()
1308
+ return None
1309
+ return fig.to_json() if as_json else fig
1310
+
1157
1311
  # --------------------------------------------------------------------- #
1158
1312
  # Helper methods #
1159
1313
  # --------------------------------------------------------------------- #
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: finbrain-python
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Official Python client for the FinBrain API
5
5
  Author-email: Ahmet Salim Bilgin <ahmet@finbrain.tech>
6
6
  License-Expression: MIT
@@ -105,8 +105,12 @@ fb.reddit_mentions.ticker("TSLA",
105
105
  date_to="2026-03-17",
106
106
  as_dataframe=True)
107
107
 
108
- # screener cross-ticker Reddit mentions
109
- fb.reddit_mentions.screener(market="S&P 500", limit=100, as_dataframe=True)
108
+ # ---------- government contracts ----------
109
+ fb.government_contracts.ticker("LMT",
110
+ date_from="2025-01-01",
111
+ date_to="2025-12-31",
112
+ limit=50,
113
+ as_dataframe=True)
110
114
 
111
115
  # ---------- insider transactions ----------
112
116
  fb.insider_transactions.ticker("AMZN", as_dataframe=True)
@@ -139,6 +143,8 @@ fb.news.ticker("AMZN", limit=20, as_dataframe=True)
139
143
  fb.screener.sentiment(market="S&P 500", as_dataframe=True)
140
144
  fb.screener.predictions_daily(limit=100, as_dataframe=True)
141
145
  fb.screener.insider_trading(limit=50)
146
+ fb.screener.reddit_mentions(limit=100, as_dataframe=True)
147
+ fb.screener.government_contracts(limit=100, as_dataframe=True)
142
148
 
143
149
  # ---------- recent data ----------
144
150
  fb.recent.news(limit=100, as_dataframe=True)
@@ -264,10 +270,10 @@ fb.plot.reddit_mentions("TSLA",
264
270
  ```python
265
271
  # ---------- Reddit Mentions Screener Chart (no price data needed) ----------
266
272
  # Stacked horizontal bar chart of top 15 most mentioned tickers
267
- fb.plot.reddit_mentions_screener(market="S&P 500")
273
+ fb.plot.reddit_mentions_top(market="S&P 500")
268
274
 
269
275
  # Customize the number of tickers shown
270
- fb.plot.reddit_mentions_screener(top_n=10, region="US")
276
+ fb.plot.reddit_mentions_top(top_n=10, region="US")
271
277
  ```
272
278
 
273
279
  **Price Data Requirements:**
@@ -314,13 +320,15 @@ fb = FinBrainClient() # reads from FINBRAIN_API_KEY env var
314
320
  | Senate trades | `client.senate_trades.ticker()` | `/congress/senate/{SYMBOL}` |
315
321
  | Corporate lobbying | `client.corporate_lobbying.ticker()` | `/lobbying/{SYMBOL}` |
316
322
  | Reddit mentions | `client.reddit_mentions.ticker()` | `/reddit-mentions/{SYMBOL}` |
317
- | | `client.reddit_mentions.screener()` | `/screener/reddit-mentions` |
323
+ | Gov. contracts | `client.government_contracts.ticker()` | `/government-contracts/{SYMBOL}` |
318
324
  | Insider transactions | `client.insider_transactions.ticker()` | `/insider-trading/{SYMBOL}` |
319
325
  | LinkedIn | `client.linkedin_data.ticker()` | `/linkedin/{SYMBOL}` |
320
326
  | Options – Put/Call | `client.options.put_call()` | `/put-call-ratio/{SYMBOL}` |
321
327
  | Screener | `client.screener.sentiment()` | `/screener/sentiment` |
322
328
  | | `client.screener.predictions_daily()` | `/screener/predictions/daily` |
323
329
  | | `client.screener.insider_trading()` | `/screener/insider-trading` |
330
+ | | `client.screener.reddit_mentions()` | `/screener/reddit-mentions` |
331
+ | | `client.screener.government_contracts()` | `/screener/government-contracts` |
324
332
  | | ... and 8 more screener methods | |
325
333
  | Recent | `client.recent.news()` | `/recent/news` |
326
334
  | | `client.recent.analyst_ratings()` | `/recent/analyst-ratings` |
@@ -1,16 +1,17 @@
1
1
  finbrain/__init__.py,sha256=ULIgwHkWbj5sT0udC3SlTROhZCgm2y9BtPox-4joNn4,416
2
- finbrain/client.py,sha256=tk-CzppuN8U1AJ4lR1XfvHs_ymSpn86EP8776nwYmYs,5120
2
+ finbrain/client.py,sha256=7ytNARm22V9ePOIPv6hq-UGvphSC9fsIuxQqTfL313I,5252
3
3
  finbrain/exceptions.py,sha256=ZkuhWfaMAqoEfhrN_6V2XPq0eY7vPCINM9S__tfgqYI,6249
4
- finbrain/plotting.py,sha256=DU2fvZ_iPXInDIYSL3Jh2xTq-MNtDQ9K_M-4iPsCBvY,47940
4
+ finbrain/plotting.py,sha256=ZDswlMAGfQzjCYNmKmcfpkljs9FYl4kOKJyy9vl1z2w,53596
5
5
  finbrain/py.typed,sha256=INFR1qO3jdMrtVPs0N0SAVKVbjKV80HQPoPshwGEpGo,27
6
6
  finbrain/aio/__init__.py,sha256=eJra9SqvLMkq5zoZfG6WFw7kd1jGpf9l-ovuPMeWvdw,125
7
- finbrain/aio/client.py,sha256=-MIJBKUfe_dGIDMAmJPlx2mQaq-XLToWWUe6owsbVqE,7029
7
+ finbrain/aio/client.py,sha256=aiYDmukVDoCw9MmrPdxMyLOoPlR77il_nZO9CvP3ZHk,7171
8
8
  finbrain/aio/endpoints/__init__.py,sha256=zdNSU1jzvnK6JnHxrvb3ye9KFCkA86xDTu9bBzmwrEQ,48
9
9
  finbrain/aio/endpoints/_utils.py,sha256=4ElYWGCcJ7t_lx02e49NvFHMt2g6DTcnwx3Mvwf3KyY,908
10
10
  finbrain/aio/endpoints/analyst_ratings.py,sha256=IYG-PU8HDOZoyyMcb_2KRxhiMVicYyaU_TOCVZPWroo,1451
11
11
  finbrain/aio/endpoints/app_ratings.py,sha256=QrJoLc7roTPRfInAEMwlr9vtxzruFJulGdB6msz7Eg0,2177
12
12
  finbrain/aio/endpoints/available.py,sha256=rQuffHowNF7FrVV5Ds-KE5iFjdz0I_vD7Qk2_zY2WLo,2315
13
13
  finbrain/aio/endpoints/corporate_lobbying.py,sha256=4rILB9-W91n6v2UwOnlVeH-ulk4D8onamzdEJf--wko,1429
14
+ finbrain/aio/endpoints/government_contracts.py,sha256=-jKXMHWrdG-4PszBSTQpK-i4SHpVZufPDBABMDB56Gk,1540
14
15
  finbrain/aio/endpoints/house_trades.py,sha256=HQVFnCI_rn9mdYWUTiU10iRoFxYdIeR7AhmqKrItndU,1427
15
16
  finbrain/aio/endpoints/insider_transactions.py,sha256=EBqHdvapYWvI53PM_sQy0caN2rbl7Qul4OmqzItMUR0,1437
16
17
  finbrain/aio/endpoints/linkedin_data.py,sha256=ucnkyNc1waiFHLxas1onPhxh9Y7ekcI_gOfUJ5gu1hI,1469
@@ -18,8 +19,8 @@ finbrain/aio/endpoints/news.py,sha256=NJkcpoP8ngNsJdCzQab8yaXJzNe5ypYstzq3-mEHfq
18
19
  finbrain/aio/endpoints/options.py,sha256=k1XL3ktoFL2Exw6UE2XfU-EcS1Xw8BPXQzABLYXmfxk,1442
19
20
  finbrain/aio/endpoints/predictions.py,sha256=BrUSmqy0v7ngXyoE_UHgqdght8qtJ8IRxAhk_s9UeR0,1285
20
21
  finbrain/aio/endpoints/recent.py,sha256=TSaAwf5w86O1plSmm4eg_gKSjSap2Z8rd2i7FAvgm90,2302
21
- finbrain/aio/endpoints/reddit_mentions.py,sha256=4jR6bYVRRZSVfuiVFPflR-GHcnHwOypm8apsJdQ1Nyo,2489
22
- finbrain/aio/endpoints/screener.py,sha256=JhQ3tMLFsp8ljNzPDzUrhI0LEy3mMzbBuOAQn6nvTzc,8609
22
+ finbrain/aio/endpoints/reddit_mentions.py,sha256=P9ToZRaRN521RJ9W2J8cBCySUsNT47ROe-8TTdVtlqA,1508
23
+ finbrain/aio/endpoints/screener.py,sha256=MYkIIZ6ocyx9khkxYjJnMQeg098-uZpdoSVbkUUj8Z4,9751
23
24
  finbrain/aio/endpoints/senate_trades.py,sha256=nhZd8R7Tclxzn-J4-ZWZ5onvBBd8pVOtiLfhKFtFBHw,1431
24
25
  finbrain/aio/endpoints/sentiments.py,sha256=BXFT0jr5j0MnB65MXGxZK36BJLXMTuggkFF9A9eenEQ,1532
25
26
  finbrain/endpoints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -28,6 +29,7 @@ finbrain/endpoints/analyst_ratings.py,sha256=6q_tecgnbzXn2wLSWqHNUa9MbLcybTD7xEB
28
29
  finbrain/endpoints/app_ratings.py,sha256=mbeKiJ87nNibnz9AT2kmH4fVFA4goEcld910abm3tFs,3597
29
30
  finbrain/endpoints/available.py,sha256=3cXjDK1qE38RHAfQ2C14oD7l7dR8mhDtUcva3LzlK5s,3911
30
31
  finbrain/endpoints/corporate_lobbying.py,sha256=K4jFcgx2_PqxFSlSm2E0rxuunl7FjWEwk_S4nfjsMuw,2213
32
+ finbrain/endpoints/government_contracts.py,sha256=jb96byPNK32AsEQWgCHMU7kAue9BFC539TH10JGfY7I,2343
31
33
  finbrain/endpoints/house_trades.py,sha256=x_C5Xc-Cj9CKdR2014XcP6G_zeXSWChwR8bKbkLzuGM,2235
32
34
  finbrain/endpoints/insider_transactions.py,sha256=TU6EsSHIeams4OLJ9s8BpNuXeBnWPHghlp4enqkEFe8,2244
33
35
  finbrain/endpoints/linkedin_data.py,sha256=zcNboQ-Ejt_7Ncu3p9WCd-PsjEBFbojVaJZdkbaGT8Q,2215
@@ -35,12 +37,12 @@ finbrain/endpoints/news.py,sha256=q4aaEiunrUbl1FF0JZuX9__cZWxm2r1-B9x-c8g4Ia8,19
35
37
  finbrain/endpoints/options.py,sha256=_TYWPcJ-gmPTQRg_kEVQl6Oj6fAirtZJ8QrfqFA2cMU,2611
36
38
  finbrain/endpoints/predictions.py,sha256=og1RY68p4O71smogrx-M5FyGk8FVclBGP18BvttzbZk,2026
37
39
  finbrain/endpoints/recent.py,sha256=7D36oVRJKF5hkR42y6M6CiEMYksuFleZou1v86SbEfA,3004
38
- finbrain/endpoints/reddit_mentions.py,sha256=2OJYR-5RaRaAv8uExuOjdy7aQV0ybxDfdLvNIVlHuxI,3847
39
- finbrain/endpoints/screener.py,sha256=tuqBBrUSgYltFORgkG0sCOUIrUh1y8pmWbemq7GV0UM,8563
40
+ finbrain/endpoints/reddit_mentions.py,sha256=WiePVAyUbA0VpWOd22M2YTlDWOQITp8qUBraI29y6d4,2305
41
+ finbrain/endpoints/screener.py,sha256=jBPUvmfj0Zfj5aoDLBtfXlYIR0UynIG613duSkck3NY,9665
40
42
  finbrain/endpoints/senate_trades.py,sha256=K6r_-Wt1HOs0dDXngHdj6Eo_UUJXAy5yE4EmmQbGaiU,2226
41
43
  finbrain/endpoints/sentiments.py,sha256=sGGPaxzGGFvMOaYv3VSCmnG7H9v7OVlX7Vsndct8jhA,2606
42
- finbrain_python-0.2.2.dist-info/licenses/LICENSE,sha256=x71LjIUPbK7Y8YBulH_AXzEIX7BK90dgFL2zA6LBT-A,1069
43
- finbrain_python-0.2.2.dist-info/METADATA,sha256=H2Dd6A3Xtw_QA77k5yNq9snLwbVoMR9jH8Aw32M06MU,14901
44
- finbrain_python-0.2.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
45
- finbrain_python-0.2.2.dist-info/top_level.txt,sha256=dCiQtTx3z2TtO_yQI6q3yODcdb-pABB-iEReJegVAv0,9
46
- finbrain_python-0.2.2.dist-info/RECORD,,
44
+ finbrain_python-0.2.4.dist-info/licenses/LICENSE,sha256=x71LjIUPbK7Y8YBulH_AXzEIX7BK90dgFL2zA6LBT-A,1069
45
+ finbrain_python-0.2.4.dist-info/METADATA,sha256=qLUp9VxSkq5FRsYFAgpI5rLxClH-uUfcy2auc8bNLno,15402
46
+ finbrain_python-0.2.4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
47
+ finbrain_python-0.2.4.dist-info/top_level.txt,sha256=dCiQtTx3z2TtO_yQI6q3yODcdb-pABB-iEReJegVAv0,9
48
+ finbrain_python-0.2.4.dist-info/RECORD,,