lumis-ai 0.1.0a1__py3-none-any.whl → 0.1.1a2__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.
@@ -1,5 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
- from .models.chat_memory import ChatMemory
3
+ try:
4
+ from .models.chat_memory import ChatMemory
4
5
 
5
- __all__ = ["ChatMemory"]
6
+ __all__ = ["ChatMemory"]
7
+ except ImportError:
8
+ __all__ = []
@@ -1,9 +1,6 @@
1
- from typing import Optional, Set, Tuple
1
+ from __future__ import annotations
2
2
 
3
- import spacy
4
- from spacy.language import Language
5
- from spacy.matcher import Matcher
6
- from spacy.tokens import Doc, Span, Token
3
+ from typing import Optional, Set, Tuple
7
4
 
8
5
 
9
6
  # TODO: Convert this to a spacy factory
@@ -13,9 +10,19 @@ class FactExtractor:
13
10
  Initialize the FactExtractor with a spaCy NLP pipeline.
14
11
  :param model: The name of the spaCy model to load.
15
12
  """
13
+ try:
14
+ import spacy
15
+ from spacy.matcher import Matcher
16
+ from spacy.tokens import Doc
17
+ except ImportError:
18
+ raise ImportError(
19
+ "spacy is required for FactExtractor. "
20
+ "Install it with: pip install lumis-ai[spacy]"
21
+ )
22
+
16
23
  # spaCy handles caching and singleton behavior automatically
17
- self.nlp: Language = spacy.load(model)
18
- self.matcher: Matcher = Matcher(self.nlp.vocab)
24
+ self.nlp = spacy.load(model)
25
+ self.matcher = Matcher(self.nlp.vocab)
19
26
  self._init_patterns()
20
27
 
21
28
  # Register custom extension if not already registered
lumis/nlp/ner/ner.py CHANGED
@@ -1,13 +1,23 @@
1
+ from __future__ import annotations
2
+
1
3
  from pathlib import Path
4
+ from typing import TYPE_CHECKING
2
5
 
3
- from spacy.tokens import Doc
4
- from spacy_llm.util import assemble
6
+ if TYPE_CHECKING:
7
+ from spacy.tokens import Doc
5
8
 
6
9
  relative_path = Path(__file__).parent / "config" / "entity_rel_extraction.cfg"
7
10
 
8
11
 
9
12
  class Ner:
10
13
  def __init__(self, config: str = str(relative_path)):
14
+ try:
15
+ from spacy_llm.util import assemble
16
+ except ImportError:
17
+ raise ImportError(
18
+ "spacy and spacy-llm are required for Ner. "
19
+ "Install them with: pip install lumis-ai[spacy]"
20
+ )
11
21
  self.nlp = assemble(config)
12
22
 
13
23
  def get_entities(self, text: str) -> list[tuple[str, str]]:
lumis/tools/scraper.py CHANGED
@@ -278,16 +278,6 @@ class WebScrapper:
278
278
  raise e
279
279
 
280
280
  return None
281
-
282
- # async def from_gotenberg(self, url: str, metadata: Optional[dict]) -> Optional[Document]:
283
- # # Same logic as before, but uses injected gb_client
284
- # try:
285
- # response = await self.gb_client.afrom_url(url)
286
- # return await self.parse_pdf(response.content, metadata)
287
- # except Exception as e:
288
- # logger.debug(f"Gotenberg failed for {url}: {e}")
289
- # return None
290
-
291
281
  def _url_with_protocol(self, url: str):
292
282
  if not url.startswith("http://") and not url.startswith("https://"):
293
283
  url = "https://" + url
@@ -7,12 +7,15 @@ import logging
7
7
  from typing import Any, Dict, Optional
8
8
  import xml.etree.ElementTree as ET
9
9
 
10
- import arxiv
11
- from arxiv import Client, SortCriterion, SortOrder
10
+ from typing import TYPE_CHECKING
11
+
12
12
  import httpx
13
13
  from lumis.core.document import Document
14
14
  import pymupdf
15
15
 
16
+ if TYPE_CHECKING:
17
+ from arxiv import SortCriterion, SortOrder
18
+
16
19
  logger = logging.getLogger(__name__)
17
20
 
18
21
 
@@ -36,8 +39,16 @@ class ArxivResult:
36
39
 
37
40
  class ArxivSearcher:
38
41
  def __init__(self, max_results: int = 10, max_concurrent_pdfs: int = 5) -> None:
42
+ try:
43
+ import arxiv
44
+ except ImportError:
45
+ raise ImportError(
46
+ "arxiv is required for ArxivSearcher. "
47
+ "Install it with: pip install lumis-ai[search]"
48
+ )
49
+ self._arxiv = arxiv
39
50
  self.max_results: int = max_results
40
- self.client = Client()
51
+ self.client = arxiv.Client()
41
52
  self._http_client = httpx.AsyncClient()
42
53
  self._result_cache: dict[str, ArxivResult] = {} # Cache for results by arxiv_id
43
54
  self._pdf_semaphore = asyncio.Semaphore(max_concurrent_pdfs)
@@ -46,8 +57,8 @@ class ArxivSearcher:
46
57
  self,
47
58
  query: str,
48
59
  max_results: Optional[int] = None,
49
- sort_by: SortCriterion = SortCriterion.SubmittedDate,
50
- sort_order: SortOrder = SortOrder.Descending,
60
+ sort_by: SortCriterion | None = None,
61
+ sort_order: SortOrder | None = None,
51
62
  id_list: Optional[list[str]] = None,
52
63
  read_pdfs: bool = False,
53
64
  ) -> list[ArxivResult]:
@@ -65,8 +76,13 @@ class ArxivSearcher:
65
76
  Returns:
66
77
  list of ArxivResult objects
67
78
  """
79
+ if sort_by is None:
80
+ sort_by = self._arxiv.SortCriterion.SubmittedDate
81
+ if sort_order is None:
82
+ sort_order = self._arxiv.SortOrder.Descending
83
+
68
84
  # Create search object with all available options
69
- search = arxiv.Search(query=query, max_results=max_results or self.max_results, sort_by=sort_by, sort_order=sort_order, id_list=id_list or [])
85
+ search = self._arxiv.Search(query=query, max_results=max_results or self.max_results, sort_by=sort_by, sort_order=sort_order, id_list=id_list or [])
70
86
 
71
87
  results: list[ArxivResult] = []
72
88
  pdf_tasks = []
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  from typing import Any, Dict, List
4
4
 
5
5
  from asgiref.sync import sync_to_async
6
- from pytrends.request import TrendReq
7
6
 
8
7
 
9
8
  class PyTrends:
@@ -12,6 +11,13 @@ class PyTrends:
12
11
  """
13
12
 
14
13
  def __init__(self, tz: int = 0, retries: int = 3, backoff: float = 0.1):
14
+ try:
15
+ from pytrends.request import TrendReq
16
+ except ImportError:
17
+ raise ImportError(
18
+ "pytrends is required for PyTrends. "
19
+ "Install it with: pip install lumis-ai[search]"
20
+ )
15
21
  self.pytrends = TrendReq(retries=retries, backoff_factor=backoff, tz=tz) # type: ignore
16
22
 
17
23
  @sync_to_async
@@ -7,7 +7,6 @@ from typing import Any, cast, Optional
7
7
  from asgiref.sync import sync_to_async
8
8
  import pandas as pd
9
9
  from pydantic import BaseModel, Field
10
- import yfinance as yf
11
10
 
12
11
  logger = logging.getLogger(__name__)
13
12
 
@@ -53,6 +52,16 @@ class YahooFinance:
53
52
  with async codebases.
54
53
  """
55
54
 
55
+ def __init__(self):
56
+ try:
57
+ import yfinance as yf
58
+ except ImportError:
59
+ raise ImportError(
60
+ "yfinance is required for YahooFinance. "
61
+ "Install it with: pip install lumis-ai[search]"
62
+ )
63
+ self._yf = yf
64
+
56
65
  @sync_to_async
57
66
  def get_quote(self, ticker: str) -> QuoteData:
58
67
  """
@@ -70,7 +79,7 @@ class YahooFinance:
70
79
  """
71
80
  try:
72
81
  logger.debug(f"Fetching quote data for ticker: {ticker}")
73
- t = yf.Ticker(ticker)
82
+ t = self._yf.Ticker(ticker)
74
83
  info = t.info
75
84
 
76
85
  return QuoteData(
@@ -114,7 +123,7 @@ class YahooFinance:
114
123
  """
115
124
  try:
116
125
  logger.debug(f"Fetching historical data for {ticker} with period={period}, interval={interval}")
117
- t = yf.Ticker(ticker)
126
+ t = self._yf.Ticker(ticker)
118
127
  hist = t.history(period=period, interval=interval, start=start, end=end)
119
128
 
120
129
  return [
@@ -149,8 +158,8 @@ class YahooFinance:
149
158
  """
150
159
  try:
151
160
  logger.debug(f"Searching for tickers matching: {query}")
152
- # Using yf.Tickers() as get_tickers_by_search is deprecated
153
- tickers = yf.Tickers(query)
161
+ # Using self._yf.Tickers() as get_tickers_by_search is deprecated
162
+ tickers = self._yf.Tickers(query)
154
163
  return [{"symbol": symbol, "name": ticker.info.get("shortName", symbol)} for symbol, ticker in tickers.tickers.items()]
155
164
  except Exception as e:
156
165
  logger.error(f"Error searching tickers for {query}: {str(e)}")
@@ -172,7 +181,7 @@ class YahooFinance:
172
181
  """
173
182
  try:
174
183
  logger.debug(f"Fetching recommendations for {ticker}")
175
- t = yf.Ticker(ticker)
184
+ t = self._yf.Ticker(ticker)
176
185
  if t.recommendations is None:
177
186
  return []
178
187
  df = cast(pd.DataFrame, t.recommendations)
@@ -197,7 +206,7 @@ class YahooFinance:
197
206
  """
198
207
  try:
199
208
  logger.debug(f"Fetching major holders for {ticker}")
200
- t = yf.Ticker(ticker)
209
+ t = self._yf.Ticker(ticker)
201
210
  if t.major_holders is None:
202
211
  return {}
203
212
  df = cast(pd.DataFrame, t.major_holders)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lumis-ai
3
- Version: 0.1.0a1
3
+ Version: 0.1.1a2
4
4
  Summary: An AI agent framework for building LLM-powered applications
5
5
  Project-URL: Homepage, https://github.com/tareksanger/lumis
6
6
  Project-URL: Repository, https://github.com/tareksanger/lumis
@@ -20,15 +20,9 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
20
  Classifier: Topic :: Software Development :: Libraries
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Requires-Python: >=3.11
23
- Requires-Dist: arxiv>=0.5.0
24
23
  Requires-Dist: asgiref>=3.8.1
25
24
  Requires-Dist: beautifulsoup4>=4.12.0
26
- Requires-Dist: coreferee-model-en>=1.0.0
27
- Requires-Dist: coreferee>=1.3.0
28
25
  Requires-Dist: deepmerge>=2.0.0
29
- Requires-Dist: django>=4.2
30
- Requires-Dist: en-core-web-lg<3.8.0,>=3.7.0
31
- Requires-Dist: en-core-web-trf<3.8.0,>=3.7.0
32
26
  Requires-Dist: faiss-cpu>=1.7.0
33
27
  Requires-Dist: googlesearch-python>=1.2.0
34
28
  Requires-Dist: httpx>=0.27.0
@@ -47,15 +41,12 @@ Requires-Dist: pydantic>=2.9.2
47
41
  Requires-Dist: pymupdf>=1.22.0
48
42
  Requires-Dist: pypdf2>=3.0.0
49
43
  Requires-Dist: python-dateutil>=2.8.0
50
- Requires-Dist: pytrends>=5.1.0
51
44
  Requires-Dist: pyvis>=0.3.0
52
45
  Requires-Dist: readability-lxml>=3.3.0
53
46
  Requires-Dist: redis>=5.0.0
54
47
  Requires-Dist: requests>=2.28.0
55
48
  Requires-Dist: scikit-learn>=1.0.0
56
49
  Requires-Dist: sentence-transformers>=2.2.2
57
- Requires-Dist: spacy-llm>=0.7.2
58
- Requires-Dist: spacy<3.8.0,>=3.7.0
59
50
  Requires-Dist: tavily-python>=0.3.0
60
51
  Requires-Dist: tenacity>=9.0.0
61
52
  Requires-Dist: textstat>=0.7.0
@@ -64,7 +55,19 @@ Requires-Dist: torch>=2.5.0
64
55
  Requires-Dist: transformers>=4.0.0
65
56
  Requires-Dist: typing-extensions>=4.0.0
66
57
  Requires-Dist: wikipedia>=1.4.0
67
- Requires-Dist: yfinance>=0.2.0
58
+ Provides-Extra: django
59
+ Requires-Dist: django>=4.2; extra == 'django'
60
+ Provides-Extra: search
61
+ Requires-Dist: arxiv>=0.5.0; extra == 'search'
62
+ Requires-Dist: pytrends>=5.1.0; extra == 'search'
63
+ Requires-Dist: yfinance>=0.2.0; extra == 'search'
64
+ Provides-Extra: spacy
65
+ Requires-Dist: coreferee-model-en>=1.0.0; extra == 'spacy'
66
+ Requires-Dist: coreferee>=1.3.0; extra == 'spacy'
67
+ Requires-Dist: en-core-web-lg<3.8.0,>=3.7.0; extra == 'spacy'
68
+ Requires-Dist: en-core-web-trf<3.8.0,>=3.7.0; extra == 'spacy'
69
+ Requires-Dist: spacy-llm>=0.7.2; extra == 'spacy'
70
+ Requires-Dist: spacy<3.8.0,>=3.7.0; extra == 'spacy'
68
71
  Description-Content-Type: text/markdown
69
72
 
70
73
  # lumis
@@ -88,7 +91,17 @@ An AI agent framework for building LLM-powered applications with multi-provider
88
91
  pip install lumis-ai
89
92
  ```
90
93
 
91
- After installing, download the required spaCy language models:
94
+ ### Optional extras
95
+
96
+ Some integrations are opt-in to keep the base install lighter:
97
+
98
+ | Extra | What it adds | Install |
99
+ |------------|-----------------------------------------------|-----------------------------------|
100
+ | `spacy` | NER, fact extraction, coreference resolution | `pip install lumis-ai[spacy]` |
101
+ | `search` | arXiv, Google Trends, Yahoo Finance | `pip install lumis-ai[search]` |
102
+ | `django` | Django ORM memory backend | `pip install lumis-ai[django]` |
103
+
104
+ The `spacy` extra requires language models. After installing, download them:
92
105
 
93
106
  ```bash
94
107
  python -m spacy download en_core_web_lg
@@ -24,7 +24,7 @@ lumis/core/document.py,sha256=bat9TjbHigFf5TLVy9r0Ft67zjIMPJMwmQrsE4gP-IA,1080
24
24
  lumis/core/event_emitter.py,sha256=2LwAo0gLIIKMqKocjrZ3g86BRjrtnplTQth0S8iDw_U,2094
25
25
  lumis/core/common/coloured_logger.py,sha256=Pc_WcpPXfMIGHagrnJQ2MjY6x8MI1U5ZbTt5xtb8mgg,943
26
26
  lumis/core/common/logger_mixin.py,sha256=TmswwCfgEi8BeatoWsa3gMk3qhCEMEmZyLK4rkZWLUU,1013
27
- lumis/core/django/__init__.py,sha256=1eLq5GHCa7iCrlb3eg85Ifx9TtnnsYgMeZ6rakyzkWY,105
27
+ lumis/core/django/__init__.py,sha256=yOr6iSaA7VSlIpSwryrwtL5zIHuv5HcY-9Fa9czoyRI,155
28
28
  lumis/core/django/models/chat_memory.py,sha256=j5E36hza2nbIKjVlv0j0WjttmRvOLjvTnoMFgNyUVVQ,6612
29
29
  lumis/core/utils/__init__.py,sha256=2hfqwepX9pCGlsPHZ3P1Zv_7jW0BCuW5r9P0aCu-xvU,246
30
30
  lumis/core/utils/coroutine.py,sha256=B_KQfwa6_wWI7a3hVPWv8GLAyuDPQywPgBYDd0iI4cI,665
@@ -65,8 +65,8 @@ lumis/nlp/semantic_parser.py,sha256=ydJjGy5h-gzaG0AJkBZOwj8JagoPxefm8RZx9D9FnsM,
65
65
  lumis/nlp/spacy_summarizer.py,sha256=6_ZMOYJ0gs7bcsef-x6GEhzsssitlpf4Ovw58SfEllw,2762
66
66
  lumis/nlp/summarizer.py,sha256=R-oTjtS86TnySTXjVhNf_NaTNJNbrfX8p964V5YfEIA,6920
67
67
  lumis/nlp/vector_similarity_retriever.py,sha256=mR2FjISAkAgS5bzSBwZIdnSr3q9s_r0GhCgrt5PlMAA,1714
68
- lumis/nlp/information_extraction/FactExtractor.py,sha256=3gA2LbAO9xOdcguoZQVssQYfDCOT6O9glWqBCUWxu_o,9355
69
- lumis/nlp/ner/ner.py,sha256=Dfxz2fuDedrd5kwLTHnpQQ5KnFOsmHEe1IfmvgQMYcI,504
68
+ lumis/nlp/information_extraction/FactExtractor.py,sha256=Chu-fMoyBJe0axM-aH6T_LWcWCVyh_lzZOSRzePszJY,9564
69
+ lumis/nlp/ner/ner.py,sha256=CVTft8EKgl3kvy9gzM0I2ANnLNmAGnYz0SdXXdf34II,819
70
70
  lumis/nlp/ner/config/entity_rel_extraction.cfg,sha256=rQKm-Agl_qse0EwI9XgLy0kjU4hdLe4B15bvspny5qY,923
71
71
  lumis/nlp/ner/config/fill-config.cfg,sha256=iMhF-QfZs15UtDHTBC3OPAhfaqyHMpnvqRAcWVAMU6U,4130
72
72
  lumis/reader/__init__.py,sha256=707frfd3cLTb7LTjhsWyFhb-u21YqaifWcyiCpVgYvg,52
@@ -76,15 +76,15 @@ lumis/storage/base_vector_db.py,sha256=ab4FyHzD6vYfyjuxPX19Vj10FGncndnRYWAzFiafR
76
76
  lumis/storage/chroma_vector_db.py,sha256=NPh5sYC_cdWWqWyACS4cLIrOjmJjKpDo7D2rS8WTmjw,5862
77
77
  lumis/storage/faiss_vector_db.py,sha256=Fkh3cFGcl6CFJ_Mja_ou9B2isXGvONRUx44qhco-YeY,12790
78
78
  lumis/tools/__init__.py,sha256=pzYG4pj-lNA1HtZ8ySDHhl1wjeDWJXWJyQje3zUTpPk,183
79
- lumis/tools/scraper.py,sha256=2aYyx5L0V3sKD_HHwIeiOq_ZlrRdcCKd7gyszOltwnY,14098
79
+ lumis/tools/scraper.py,sha256=0iNQS2jptT093ZkOSKamvNDOQuJRBaAwM2_ztmS1w6U,13670
80
80
  lumis/tools/search/__init__.py,sha256=_MGFJAeizjcX0oI9Cr0B9efTfolRbL_3QQo2ZcNUklE,283
81
- lumis/tools/search/arxiv.py,sha256=wjgTKZSefC98Zt7cwiFNR3eRmFYrQoaU8Fa4ABlhvqs,9783
82
- lumis/tools/search/pytrends.py,sha256=yY5c4hlflqgvanWRAO4C1PtzBMx1rVPZfbqMaEukpm4,1764
81
+ lumis/tools/search/arxiv.py,sha256=ldRHo_SSyhKm7CwjCuOjxZlIhkutwu85_UD8YcXCAtI,10245
82
+ lumis/tools/search/pytrends.py,sha256=_tTmGMNNqSUbN3s7Scrx771KzX9nLHuYQrxFPC_nXIo,1980
83
83
  lumis/tools/search/search_engine_client.py,sha256=5Q0nb7Lztj0mjaN3EwZQfpRMNUbxcHyhp-wGbmOZdiA,11766
84
84
  lumis/tools/search/vector_search_retrieval_engine.py,sha256=RGZyFah2F-ojFzH9xiApILK5oQWWZEuihV2EN3Ae0cc,7889
85
85
  lumis/tools/search/wiki.py,sha256=gGm6I273KOLvDN0E7boAezjPq6cywRhbZEBqB_Pem4U,7864
86
- lumis/tools/search/yahoofinance.py,sha256=xQTTMJU7IDfH2WkzIWPjWwwLao0unfMHGrbhVEJJSJg,7548
87
- lumis_ai-0.1.0a1.dist-info/METADATA,sha256=bVQmNhCCxjia24iGCDc-brqlxqfrp2Poy74ubstINpU,3783
88
- lumis_ai-0.1.0a1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
89
- lumis_ai-0.1.0a1.dist-info/licenses/LICENSE,sha256=cKZn_mblbydX1fOrVMvUIrelUE9AElKLAR_7-VYRDow,1068
90
- lumis_ai-0.1.0a1.dist-info/RECORD,,
86
+ lumis/tools/search/yahoofinance.py,sha256=0Oz7kfdWI2ehllo9NM2wKS0WSAUeGnPyuVnfobyBXHA,7851
87
+ lumis_ai-0.1.1a2.dist-info/METADATA,sha256=Z0Ajv1lr3HYpO6izksSyOIU-79wK1KGzMgG5l0-6K4Y,4630
88
+ lumis_ai-0.1.1a2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
89
+ lumis_ai-0.1.1a2.dist-info/licenses/LICENSE,sha256=cKZn_mblbydX1fOrVMvUIrelUE9AElKLAR_7-VYRDow,1068
90
+ lumis_ai-0.1.1a2.dist-info/RECORD,,