symbolicai 1.5.0__py3-none-any.whl → 1.7.0__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.
Files changed (52) hide show
  1. symai/__init__.py +21 -71
  2. symai/backend/base.py +0 -26
  3. symai/backend/engines/drawing/engine_gemini_image.py +101 -0
  4. symai/backend/engines/embedding/engine_openai.py +11 -8
  5. symai/backend/engines/neurosymbolic/__init__.py +8 -0
  6. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +1 -0
  7. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +48 -1
  8. symai/backend/engines/neurosymbolic/engine_cerebras.py +1 -0
  9. symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +14 -1
  10. symai/backend/engines/neurosymbolic/engine_openrouter.py +294 -0
  11. symai/backend/mixin/__init__.py +4 -0
  12. symai/backend/mixin/anthropic.py +37 -16
  13. symai/backend/mixin/openrouter.py +2 -0
  14. symai/components.py +203 -13
  15. symai/extended/interfaces/nanobanana.py +23 -0
  16. symai/interfaces.py +2 -0
  17. symai/ops/primitives.py +0 -18
  18. symai/shellsv.py +2 -7
  19. symai/strategy.py +44 -4
  20. {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/METADATA +3 -10
  21. {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/RECORD +25 -48
  22. {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/WHEEL +1 -1
  23. symai/backend/driver/webclient.py +0 -217
  24. symai/backend/engines/crawler/engine_selenium.py +0 -94
  25. symai/backend/engines/drawing/engine_dall_e.py +0 -131
  26. symai/backend/engines/embedding/engine_plugin_embeddings.py +0 -12
  27. symai/backend/engines/experiments/engine_bard_wrapper.py +0 -131
  28. symai/backend/engines/experiments/engine_gptfinetuner.py +0 -32
  29. symai/backend/engines/experiments/engine_llamacpp_completion.py +0 -142
  30. symai/backend/engines/neurosymbolic/engine_openai_gptX_completion.py +0 -277
  31. symai/collect/__init__.py +0 -8
  32. symai/collect/dynamic.py +0 -117
  33. symai/collect/pipeline.py +0 -156
  34. symai/collect/stats.py +0 -434
  35. symai/extended/crawler.py +0 -21
  36. symai/extended/interfaces/selenium.py +0 -18
  37. symai/extended/interfaces/vectordb.py +0 -21
  38. symai/extended/personas/__init__.py +0 -3
  39. symai/extended/personas/builder.py +0 -105
  40. symai/extended/personas/dialogue.py +0 -126
  41. symai/extended/personas/persona.py +0 -154
  42. symai/extended/personas/research/__init__.py +0 -1
  43. symai/extended/personas/research/yann_lecun.py +0 -62
  44. symai/extended/personas/sales/__init__.py +0 -1
  45. symai/extended/personas/sales/erik_james.py +0 -62
  46. symai/extended/personas/student/__init__.py +0 -1
  47. symai/extended/personas/student/max_tenner.py +0 -51
  48. symai/extended/strategies/__init__.py +0 -1
  49. symai/extended/strategies/cot.py +0 -40
  50. {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/entry_points.txt +0 -0
  51. {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/licenses/LICENSE +0 -0
  52. {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/top_level.txt +0 -0
symai/interfaces.py CHANGED
@@ -42,6 +42,8 @@ def _add_symbolic_interface(mapping):
42
42
  def _resolve_drawing_interface_name(drawing_engine_model):
43
43
  if drawing_engine_model.startswith("flux"):
44
44
  return "flux"
45
+ if drawing_engine_model.startswith(("gemini-2.5-flash-image", "gemini-3-pro-image-preview")):
46
+ return "nanobanana"
45
47
  if drawing_engine_model.startswith("dall-e-"):
46
48
  return "dall_e"
47
49
  if drawing_engine_model.startswith("gpt-image-"):
symai/ops/primitives.py CHANGED
@@ -745,12 +745,6 @@ class OperatorPrimitives(Primitive):
745
745
  Returns:
746
746
  Symbol: A new symbol with the result of the OR operation.
747
747
  """
748
- # Exclude the evaluation for the Aggregator class; keep import local to avoid ops.primitives <-> collect.stats cycle.
749
- from ..collect.stats import Aggregator # noqa
750
-
751
- if isinstance(other, Aggregator):
752
- return NotImplemented
753
-
754
748
  result = self.__try_type_specific_func(
755
749
  other, lambda self, other: self.value | other.value, op="|"
756
750
  )
@@ -777,12 +771,6 @@ class OperatorPrimitives(Primitive):
777
771
  Returns:
778
772
  Symbol: A new Symbol object with the concatenated value.
779
773
  """
780
- # Exclude the evaluation for the Aggregator class; keep import local to avoid ops.primitives <-> collect.stats cycle.
781
- from ..collect.stats import Aggregator # noqa
782
-
783
- if isinstance(other, Aggregator):
784
- return NotImplemented
785
-
786
774
  result = self.__try_type_specific_func(
787
775
  other, lambda self, other: self.value | other.value, op="|"
788
776
  )
@@ -811,12 +799,6 @@ class OperatorPrimitives(Primitive):
811
799
  Returns:
812
800
  Symbol: A new Symbol object with the concatenated value.
813
801
  """
814
- # Exclude the evaluation for the Aggregator class; keep import local to avoid ops.primitives <-> collect.stats cycle.
815
- from ..collect.stats import Aggregator # noqa
816
-
817
- if isinstance(other, Aggregator):
818
- return NotImplemented
819
-
820
802
  result = self.__try_type_specific_func(
821
803
  other, lambda self, other: self.value | other.value, op="|="
822
804
  )
symai/shellsv.py CHANGED
@@ -1070,14 +1070,9 @@ def run(auto_query_on_error=False, conversation_style=None, verbose=False):
1070
1070
  ) = styles_
1071
1071
  state.use_styles = True
1072
1072
 
1073
- if SYMSH_CONFIG["show-splash-screen"]:
1073
+ if SYMSH_CONFIG.get("show-splash-screen", True):
1074
1074
  show_intro_menu()
1075
- # set show splash screen to false
1076
- SYMSH_CONFIG["show-splash-screen"] = False
1077
- # save config
1078
- _config_path = HOME_PATH / "symsh.config.json"
1079
- with _config_path.open("w") as f:
1080
- json.dump(SYMSH_CONFIG, f, indent=4)
1075
+
1081
1076
  if "plugin_prefix" not in SYMSH_CONFIG:
1082
1077
  SYMSH_CONFIG["plugin_prefix"] = None
1083
1078
 
symai/strategy.py CHANGED
@@ -3,9 +3,11 @@ import logging
3
3
  import time
4
4
  from collections import defaultdict
5
5
  from collections.abc import Callable
6
+ from contextlib import nullcontext
6
7
  from typing import Any, ClassVar
7
8
 
8
9
  import numpy as np
10
+ from anthropic import transform_schema
9
11
  from beartype import beartype
10
12
  from loguru import logger
11
13
  from pydantic import BaseModel, ValidationError
@@ -14,7 +16,9 @@ from rich.markup import escape
14
16
  from rich.panel import Panel
15
17
  from rich.table import Table
16
18
 
19
+ from .backend.settings import SYMAI_CONFIG
17
20
  from .components import Function
21
+ from .context import CURRENT_ENGINE_VAR
18
22
  from .models import LLMDataModel, TypeValidationError, build_dynamic_llm_datamodel
19
23
  from .symbol import Expression
20
24
  from .utils import UserMessage
@@ -182,6 +186,7 @@ class TypeValidationFunction(ValidationFunction):
182
186
  self.output_data_model = None
183
187
  self.accumulate_errors = accumulate_errors
184
188
  self.verbose = verbose
189
+ self.dynamic_engine = self.retry_params.get("dynamic_engine")
185
190
 
186
191
  def register_expected_data_model(
187
192
  self, data_model: LLMDataModel, attach_to: str, override: bool = False
@@ -361,7 +366,8 @@ Important guidelines:
361
366
  if self.verbose:
362
367
  self.display_panel(self.remedy_function.dynamic_context, title="New Context")
363
368
 
364
- json_str = self.remedy_function(seed=remedy_seeds[attempt_index], **kwargs).value
369
+ with (self.dynamic_engine if self.dynamic_engine is not None else nullcontext()):
370
+ json_str = self.remedy_function(seed=remedy_seeds[attempt_index], **kwargs).value
365
371
  logger.info("Applied remedy function with updated context!")
366
372
  return json_str
367
373
 
@@ -418,17 +424,51 @@ Important guidelines:
418
424
  violations=errors,
419
425
  )
420
426
 
427
+ def _build_response_format(self, kwargs: dict) -> dict:
428
+ response_format = kwargs.get("response_format")
429
+ if response_format is None:
430
+ response_format = {"type": "json_object"}
431
+ # Resolve the effective model from the most specific runtime source first.
432
+ # This keeps contracts working when engines are swapped dynamically and no static
433
+ # model is registered in config.
434
+ selected_model = kwargs.get("model")
435
+ if selected_model is None:
436
+ active_engine = CURRENT_ENGINE_VAR.get()
437
+ if active_engine is not None:
438
+ selected_model = getattr(active_engine, "model", None)
439
+ if selected_model is None:
440
+ selected_model = SYMAI_CONFIG.get("NEUROSYMBOLIC_ENGINE_MODEL", "")
441
+
442
+ if "claude-opus" not in selected_model:
443
+ return response_format
444
+
445
+ if response_format.get("type") != "json_object":
446
+ return response_format
447
+
448
+ # At the contract layer, `json_object` stays the generic trigger for structured output.
449
+ # Opus requires a concrete JSON Schema payload, so we derive it from the output model.
450
+ return {"type": "json_schema", "schema": transform_schema(self.output_data_model)}
451
+
421
452
  def forward(
422
453
  self, prompt: str, f_semantic_conditions: list[Callable] | None = None, *args, **kwargs
423
454
  ):
424
455
  self._ensure_output_model()
425
456
  validation_context = kwargs.pop("validation_context", {})
426
- kwargs["response_format"] = {"type": "json_object"}
457
+ kwargs["response_format"] = self._build_response_format(kwargs)
427
458
  logger.info("Initializing validation…")
428
459
  self._display_verbose_panels(prompt)
429
460
 
430
461
  context = self.zero_shot_prompt(prompt=prompt)
431
- json_str = super().forward(context, *args, **kwargs).value
462
+
463
+ # Zero-shot attempt; fall back to dynamic engine on failure
464
+ try:
465
+ json_str = super().forward(context, *args, **kwargs).value
466
+ except Exception:
467
+ if self.dynamic_engine is None:
468
+ raise
469
+ logger.info("Zero-shot failed; retrying with dynamic engine…")
470
+ with self.dynamic_engine:
471
+ json_str = super().forward(context, *args, **kwargs).value
432
472
 
433
473
  remedy_seeds = self.prepare_seeds(self.retry_params["tries"] + 1, **kwargs)
434
474
  logger.info(f"Prepared {len(remedy_seeds)} remedy seeds for validation attempts…")
@@ -468,7 +508,7 @@ class contract:
468
508
  post_remedy: bool = False,
469
509
  accumulate_errors: bool = False,
470
510
  verbose: bool = False,
471
- remedy_retry_params: dict[str, int | float | bool] = _default_remedy_retry_params,
511
+ remedy_retry_params: dict[str, Any] = _default_remedy_retry_params,
472
512
  ):
473
513
  """
474
514
  A contract class decorator inspired by DbC principles. It ensures that the function's input and output
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: symbolicai
3
- Version: 1.5.0
3
+ Version: 1.7.0
4
4
  Summary: A Neurosymbolic Perspective on Large Language Models
5
5
  Author-email: Marius-Constantin Dinu <marius@extensity.ai>, Leoveanu-Condrei Claudiu <leo@extensity.ai>
6
6
  License: BSD 3-Clause License
@@ -52,7 +52,7 @@ Requires-Dist: tqdm>=4.66.3
52
52
  Requires-Dist: python-box>=7.1.1
53
53
  Requires-Dist: pandas>=2.2.2
54
54
  Requires-Dist: scikit-learn>=1.5.0
55
- Requires-Dist: torch>=2.2.2
55
+ Requires-Dist: torch<2.10.0
56
56
  Requires-Dist: torchaudio>=2.2.2
57
57
  Requires-Dist: torchvision>=0.17.2
58
58
  Requires-Dist: PyYAML>=6.0.1
@@ -88,10 +88,6 @@ Requires-Dist: llvmlite>=0.45.1
88
88
  Requires-Dist: cerebras-cloud-sdk>=1.59.0
89
89
  Provides-Extra: bitsandbytes
90
90
  Requires-Dist: bitsandbytes>=0.43.1; extra == "bitsandbytes"
91
- Provides-Extra: blip2
92
- Requires-Dist: decord>=0.6.0; extra == "blip2"
93
- Requires-Dist: salesforce-lavis>=1.0.0; extra == "blip2"
94
- Requires-Dist: opencv-python-headless>=4.5.5.64; extra == "blip2"
95
91
  Provides-Extra: hf
96
92
  Requires-Dist: transformers>=4.45.2; extra == "hf"
97
93
  Requires-Dist: accelerate>=0.33.0; extra == "hf"
@@ -425,15 +421,12 @@ Example of a configuration file with all engines enabled:
425
421
  "VISION_ENGINE_MODEL": "openai/clip-vit-base-patch32",
426
422
  "OCR_ENGINE_API_KEY": "<APILAYER_API_KEY>",
427
423
  "SPEECH_TO_TEXT_ENGINE_MODEL": "turbo",
428
- "SPEECH_TO_TEXT_API_KEY": "",
429
- "SUPPORT_COMMUNITY": true
424
+ "SPEECH_TO_TEXT_API_KEY": ""
430
425
  }
431
426
  ```
432
427
 
433
428
  With these steps completed, you should be ready to start using SymbolicAI in your projects.
434
429
 
435
- > ❗️**NOTE**❗️Our framework allows you to support us train models for local usage by enabling the data collection feature. On application startup we show the terms of services and you can activate or disable this community feature. We do not share or sell your data to 3rd parties and only use the data for research purposes and to improve your user experience. To change this setting open the `symai.config.json` and turn it on/off by setting the `SUPPORT_COMMUNITY` property to `True/False` via the config file or the respective environment variable.
436
-
437
430
  > ❗️**NOTE**❗️By default, the user warnings are enabled. To disable them, export `SYMAI_WARNINGS=0` in your environment variables.
438
431
 
439
432
  ### Running tests
@@ -1,7 +1,7 @@
1
1
  symai/TERMS_OF_SERVICE.md,sha256=HN42UXVI_wAVDHjMShzy_k7xAsbjXaATNeMKcIte_eg,91409
2
- symai/__init__.py,sha256=qlqkm2OjRqXtKhIBltfB9zx0kBf4V4ygckH1RHVPAVE,18530
2
+ symai/__init__.py,sha256=j5bwtmnvxtMH6h5LsdMB5hgynMwXRVH5tWJ5rp49Am0,15612
3
3
  symai/chat.py,sha256=DCEbmZ96wv-eitAVt6-oF6PT3JM3cT59Iy3r2Hucd_M,14100
4
- symai/components.py,sha256=XL1whwdZd6HCl0viUuXca_7d8no_xxfTGZsqE1hhwqI,64845
4
+ symai/components.py,sha256=SsGl8Cs-AQcPZjFyTv4IB3ATz8evRiVwTBH7k2umVSo,75391
5
5
  symai/constraints.py,sha256=ljjB9p0qK4DrDl_u5G_Y-Y6WAH5ZHANIqLLxRtwcORs,1980
6
6
  symai/context.py,sha256=4M69MJOeWSdPTr2Y9teoNTs-nEvpzcAcr7900UgORXA,189
7
7
  symai/core.py,sha256=gI9qvTT0Skq2D0izdhAoN3RdwBtWei59KO52mKN1Sos,70420
@@ -9,34 +9,28 @@ symai/core_ext.py,sha256=lS_BZNeUGmNhhXR-F3dFLF26_nZHq3NVaAwa4vAbkTQ,8937
9
9
  symai/exceptions.py,sha256=BxpxI8q3-7Uh_Kg9Xi2PhF6RR6CofxV1h8R07j4v47U,165
10
10
  symai/functional.py,sha256=GqBs5FZPVZ3iVJ-MlO0Zvkf7cNSDgVhkt3tsL82kFrM,21457
11
11
  symai/imports.py,sha256=P5WsamkfKxsK3fs8vlrFpC6CIv5WVpMIMNue9DKJGnE,16126
12
- symai/interfaces.py,sha256=Z8CDdarnOVa67GCLljKjxQojDH9MhhPKBQFb0pi2WfY,3458
12
+ symai/interfaces.py,sha256=M84QPVXABh0Pt7WlG3hxB6Rw8lSceuABKdUqbR_98Ok,3584
13
13
  symai/memory.py,sha256=Cd60UyeJk7SHNBWEYOLrmUXQy54GzQsu3Mjh0lfNQOY,3716
14
14
  symai/post_processors.py,sha256=_GK53qpc2SyjecmEO5bWr162mWZcK_jUDPOcPvlwrHY,7818
15
15
  symai/pre_processors.py,sha256=9YwhNajIUux7B5usl0To9Az3J2teuDLxPsMsTBShqwI,16763
16
16
  symai/processor.py,sha256=FsR7rIjm6NlestgX3dVOLtvQJcGNpJaogtPyi3I1PR4,1648
17
17
  symai/prompts.py,sha256=cF3FauHfl0ZiBW-6DEE50wx_elNN7PBTbbmlVCr7nzQ,93743
18
18
  symai/shell.py,sha256=iEQ-dGGPSm7ZDaaC3I7RwnzgA8X9yHBzPD0TouBk3AU,6487
19
- symai/shellsv.py,sha256=rwTUcgaNdUm4_SRM7u4aMndMaEAaM6jBvWbEQzWoI0c,39831
20
- symai/strategy.py,sha256=BQTXRnBv57fYO47A--WA6KK1oqGmf9Aijm0p4a_vvqY,45004
19
+ symai/shellsv.py,sha256=rdKwBRqTT0k81LgMi0qshD4z8ucYL5iDCN4MOCgvEa8,39581
20
+ symai/strategy.py,sha256=8-BlvTQ-o1XlVbHiu5LE7wtYRyqwAJPv3qgN6UHnuN0,46932
21
21
  symai/symbol.py,sha256=s5CYwP5SGcRUzZ7TlakZFpKBX_Q0mwPQKRbv4pC3sxM,40443
22
22
  symai/symsh.md,sha256=QwY_-fX0Ge7Aazul0xde2DuF2FZLw_elxrkXR3kuKDQ,1245
23
23
  symai/utils.py,sha256=m4iQzxclkPAUSDderTO_OK2fKznJ69pLfbBcTYq4p70,10824
24
24
  symai/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- symai/backend/base.py,sha256=28kIR0NrTL-BgmjpP31JXNlRH4u1TF9qarOXqlCFbVI,7296
25
+ symai/backend/base.py,sha256=z60M_4Hmg_0afCv8l6iQJ1bOTO_HCPbJze16GPNDpJo,6420
26
26
  symai/backend/settings.py,sha256=T5iUAV8aGLnQy9iRTvUDJq49LGobiSHPGV1HqBHjkEg,6181
27
- symai/backend/driver/webclient.py,sha256=VDFb0KACENTyZuZTLkPMYHUSlpyDeqzJS2ydV7l4_9A,7854
28
27
  symai/backend/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- symai/backend/engines/crawler/engine_selenium.py,sha256=daCEXYh7WSlwbJypM-51rrOmjm4tjOYz2trmSL9iJ28,3267
30
28
  symai/backend/engines/drawing/engine_bfl.py,sha256=7ccDpnjld5G3qIA8k6OafSm6c_WHrcCW1RfNsKbKKXs,4419
31
- symai/backend/engines/drawing/engine_dall_e.py,sha256=CKcMfy69kXSs2I92PqNfgRoz5LZYH-1nMhEVIRZKLFk,4896
29
+ symai/backend/engines/drawing/engine_gemini_image.py,sha256=GE4dSE0zmhLOrs5HBhwaS6wbYVL_xLrJ4475oasxEVw,3840
32
30
  symai/backend/engines/drawing/engine_gpt_image.py,sha256=aXaHQrug-_SuQ9A2CqOS8WVm9r6CifnxnMaXTAJl9g8,8049
33
31
  symai/backend/engines/embedding/engine_llama_cpp.py,sha256=wKWe1hEpNKFiKaDo8-p5mAq1JbFQXpE8iDAWHGimHEk,5438
34
- symai/backend/engines/embedding/engine_openai.py,sha256=v5EpbKBobIs-lphC0K4epCVBtlbpj9qdnQyd473gGEQ,3346
35
- symai/backend/engines/embedding/engine_plugin_embeddings.py,sha256=TLOaYAw_1AWMwqcHydP41aWIYSGhguOJgI0rMu1Fl00,623
32
+ symai/backend/engines/embedding/engine_openai.py,sha256=BwKpwmsE7xUvuutRInxZ1anBk7W8jltIMNC6qBbtH5g,3543
36
33
  symai/backend/engines/execute/engine_python.py,sha256=WaB4rx9CMnqd88FfZUTRDLOju9IB9hKxnQ88lBwq_2s,3576
37
- symai/backend/engines/experiments/engine_bard_wrapper.py,sha256=RTRLg5kAq1yKMkgNC8xj9kzOtkeoOANrXzHejKp2haM,5276
38
- symai/backend/engines/experiments/engine_gptfinetuner.py,sha256=POQwYj_NKjOBLc83FM1S_WBqHudZyYlDENjNFak6ocY,804
39
- symai/backend/engines/experiments/engine_llamacpp_completion.py,sha256=Wgq56wH9ZoV-FwdWfok90Yv48Zu4kXHMNDdzFe4mmjc,5268
40
34
  symai/backend/engines/files/engine_io.py,sha256=4eYBz44rQYWD7VO6Pn7hVF_cOnqNuolo4O0SYHR1NzI,7424
41
35
  symai/backend/engines/imagecaptioning/engine_blip2.py,sha256=8lTzc8sQpuNY4AUb_ZweRKr95v-sFtTykT5ennVf6g0,2915
42
36
  symai/backend/engines/imagecaptioning/engine_llavacpp_client.py,sha256=jBsLZv0Laa4tuPyX0VQ7uwyldyO3aYIbbj73WjTbceM,6793
@@ -44,19 +38,19 @@ symai/backend/engines/index/engine_pinecone.py,sha256=fxCew1ldUdjd9UtqnMuWFDiVz5
44
38
  symai/backend/engines/index/engine_qdrant.py,sha256=U9p0kzYvHE4DjFgxnvnG_8xfEoP_W4dpaBGY5gTFMF4,50994
45
39
  symai/backend/engines/index/engine_vectordb.py,sha256=xXU8QaC2BX9O4dDjDCVYgWO4PxQMpmNlhtal6UVtV0o,8541
46
40
  symai/backend/engines/lean/engine_lean4.py,sha256=ln5nbQn5szq8nRulbREPLCPQ5bwjM_A5XAGMkfzPdT8,10102
47
- symai/backend/engines/neurosymbolic/__init__.py,sha256=o7HUmxcYSrIkutGYB-6_Qur3adHyrkVeWroDtqEK-YE,2279
48
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py,sha256=WyuskobMjf9ynxRWUnXk55DUMUN7qv7jT1nbZP3Bx9o,21054
49
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py,sha256=thEPDh8H-5XrsADF0mVTWB6m_dJgKeTT49HvyCGJcQM,21291
50
- symai/backend/engines/neurosymbolic/engine_cerebras.py,sha256=ki84Qh7hdxaKn--UgMMUvAEoqJos7VeKtkka6XpHI3g,13336
41
+ symai/backend/engines/neurosymbolic/__init__.py,sha256=zEjkuxtzBQdxx-b1aXzooCatA43Rrlo9jAyZZfRYNzM,2608
42
+ symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py,sha256=Y5AOCmJgL51QgrVbezSd0pe8GgMYNCuWWDIDES1_eaM,21133
43
+ symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py,sha256=PaIN_C6xMhAUw51vGkI774q-PMnq30mofWsOtwYrIc8,23393
44
+ symai/backend/engines/neurosymbolic/engine_cerebras.py,sha256=zFnKKd_9iEL2S-4hKFMG4vPAK-fkSOkaUMJlZ5EvoF4,13387
51
45
  symai/backend/engines/neurosymbolic/engine_deepseekX_reasoning.py,sha256=_k0hy5dUxkbNP9vgF4R780A6THtjfcCJ_xUnkPvPRNw,9299
52
- symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py,sha256=3GGbAJh1hnx0YZLwvXJI-YDyGuVQe4o1nNEiKgDWtBY,27846
46
+ symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py,sha256=pvsUNtWYwvFXt8EEy5ed0V4xE4EE0IZ4f7Uw5jV3OF0,28333
53
47
  symai/backend/engines/neurosymbolic/engine_groq.py,sha256=pliezi4X1LP-XdnJirjlI2nCXC8S2pex8fZalNlkKWw,13122
54
48
  symai/backend/engines/neurosymbolic/engine_huggingface.py,sha256=dLKFPoNpnFgS_uQJJ2bXPEBtnMR_sLcYYtqgILzbLcg,8208
55
49
  symai/backend/engines/neurosymbolic/engine_llama_cpp.py,sha256=CWy1aqqV-NFey0b9sr_uKDEYt16pSuP831IFuN4PhrU,14144
56
50
  symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py,sha256=FfNkesV64d3gf7MWKf2PoK5nUjetS2MndTbWhE1KieE,28267
57
- symai/backend/engines/neurosymbolic/engine_openai_gptX_completion.py,sha256=YgxRoitmDz2de_W7rkhVXYEkDqTJQlgxK4f8tWlt88Q,13840
58
51
  symai/backend/engines/neurosymbolic/engine_openai_gptX_reasoning.py,sha256=yWiCT_jHHQGs2_YqRhSRvVFxQFXGb1TwvXf2zZWoStU,27171
59
52
  symai/backend/engines/neurosymbolic/engine_openai_responses.py,sha256=J3P7WcQhxWSPK99uZuLClpIDlLRqLJFWYwDJHrBKox4,17830
53
+ symai/backend/engines/neurosymbolic/engine_openrouter.py,sha256=Kmmx_9ifE-uP_Pua2saegcCQs3gkU4J7er12qiWxKjI,11991
60
54
  symai/backend/engines/ocr/engine_apilayer.py,sha256=UpC3oHBdSM6wlPVqxwMkemBd-Y0ReVwc270O_EVbRD0,2267
61
55
  symai/backend/engines/output/engine_stdout.py,sha256=BWNXACl5U-WYIJnT1pZNwZsTRMzP1XzA0A7o693mmyQ,899
62
56
  symai/backend/engines/scrape/engine_requests.py,sha256=uXQ8PGeRN2OyM0_ioEI61rkv5PqSBE0wayAJNS7s8ZA,15819
@@ -71,17 +65,14 @@ symai/backend/engines/symbolic/engine_wolframalpha.py,sha256=mTH0N4rA0gMffSBLjf2
71
65
  symai/backend/engines/text_to_speech/engine_openai.py,sha256=AtY0mDvIM_yZQ6AgYNXuyinZr_OaMK7XiPLQ6fe6RBo,2013
72
66
  symai/backend/engines/text_vision/engine_clip.py,sha256=hU9vsHtKPpQYEoESyjuGXOzMhUNhvspYMCNkCAqn2x8,3648
73
67
  symai/backend/engines/userinput/engine_console.py,sha256=fDO6PRQI3NYZ_nHVXDFIsS9cFDRv3aTOfv8h5a360jc,743
74
- symai/backend/mixin/__init__.py,sha256=rJjz7OSR2Qp_gl9KCL6ILuUh1BduKRPLSiWYIQuBIv4,1320
75
- symai/backend/mixin/anthropic.py,sha256=GdHimGqiJcA21Jo797ZEeFzotRpCOJdBJQIChl_6NJI,2403
68
+ symai/backend/mixin/__init__.py,sha256=LMeNSxy0Uwn3CSSImgGcRal7JpZqIxP9I1lw0C4sLJ0,1539
69
+ symai/backend/mixin/anthropic.py,sha256=b06RGsEa_lvn1VBKRtLt1BPROCnR6g_lPO0BQtU2s0o,3213
76
70
  symai/backend/mixin/cerebras.py,sha256=MEc9vQ6G4KWWrt0NFjdt2y0rojhtBidwa_n4M8Z5EKI,215
77
71
  symai/backend/mixin/deepseek.py,sha256=7TnyqXQb2t6r6-hzOClPzxfO2d7TShYC989Lmn_YTzM,414
78
72
  symai/backend/mixin/google.py,sha256=N1xxrrTcQkcKJtdPbRorev6dfJ1F65I5XavrGR06GN4,494
79
73
  symai/backend/mixin/groq.py,sha256=at6yFLa35Js8o7D8p_-Y4NjOPJI-lH8yx6tsCDrEy6M,227
80
74
  symai/backend/mixin/openai.py,sha256=7uFu-cRYvWPWGK0fxLh-wzW0FwNTvfWUde68yngXPtw,5810
81
- symai/collect/__init__.py,sha256=YD1UQoD4Z-_AodqTp48Vv-3UHYUa1g4lZnhm2AsjCd0,202
82
- symai/collect/dynamic.py,sha256=72oEdshjue3t_Zs_3D08bhHPKN5mKAw0HEucWAFlqVI,3833
83
- symai/collect/pipeline.py,sha256=eyxqqNpa1P5xEL50WgUZT6Z-MRocuLRBqexkVIqWqv8,5360
84
- symai/collect/stats.py,sha256=iqawGMul_ltSKvE9oAMafy1cC2ZxwiP3THEmzpmo7JU,15040
75
+ symai/backend/mixin/openrouter.py,sha256=LOnY6OwueynvLPbtWekvbTDxFElmljTzuDX3ZHppXOA,92
85
76
  symai/endpoints/__init__py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
77
  symai/endpoints/api.py,sha256=jW_gcYcSoEUNy-Qbpt4OEL0PxWMInvdirYW9DSyPoAY,19826
87
78
  symai/extended/.DS_Store,sha256=0W9Q0cbPawSN2y5DkK995aaAclHC732Z53ARDbUN21k,6148
@@ -90,7 +81,6 @@ symai/extended/api_builder.py,sha256=0meiKYt3IBbPsRxiDDwXETG-wL0W9IAIBOydJ-XkO5g
90
81
  symai/extended/arxiv_pdf_parser.py,sha256=w_EWssS75g9hHYGwP3P1QVu-osPEq5KLSjPtk2Wwx8I,2297
91
82
  symai/extended/bibtex_parser.py,sha256=j3HNe3-wPMUCtV8_1DXnRswEnvG9elWqozxqTMRaBIg,3749
92
83
  symai/extended/conversation.py,sha256=OXE8j27Qg0wQ181ZkqQcWurS0CQzi9r_xZbeoDd1HrY,14100
93
- symai/extended/crawler.py,sha256=DcnXbCmCjh-TPdc6NxOw9f-SMEaE5HkekiciIxuM5fo,734
94
84
  symai/extended/document.py,sha256=RoPCqPq2ETaaLlG7S0Lj8-GpQLWb3HFklmJAtrc3yTU,3571
95
85
  symai/extended/file_merger.py,sha256=Sb0Y0rbLTyxH3n2-tqVZbkSyGe6A20_QqGcelHg58l4,3736
96
86
  symai/extended/graph.py,sha256=mKR-aJWWqUZBi-X8AIn1CMpOWZXymmKrXFJC4E2SPdQ,3666
@@ -116,17 +106,16 @@ symai/extended/interfaces/llava.py,sha256=yCItfGYSk35RazhEfHR4R324h-R6W5DjZYeJBo
116
106
  symai/extended/interfaces/local_search.py,sha256=AHHRsYCUm4VttGSl_HAk5kpH34e0x_uzvgy1OXSubSs,2408
117
107
  symai/extended/interfaces/naive_scrape.py,sha256=KPjTSBXSCr5zwHwIPgF-VwLSTD2OjVcL4xALNX4l9-4,682
118
108
  symai/extended/interfaces/naive_vectordb.py,sha256=fm7DBMYYnSx7Ma7eNnCmuOVyQwNGnkiDR31oV-qNrJA,1348
109
+ symai/extended/interfaces/nanobanana.py,sha256=nqMCuYG5Cw1xbhSTQTPqvJ6moexsR9Au0LKWYJgae6g,614
119
110
  symai/extended/interfaces/ocr.py,sha256=MMxgp8ZKoM44doJPZzzrBVh2VxChs6faFu2uFYnbzfU,563
120
111
  symai/extended/interfaces/openai_search.py,sha256=UvnSihdfIwybrLDz2A-yt92aklHEHIvh0pt0hp1Dpis,528
121
112
  symai/extended/interfaces/parallel.py,sha256=kWRcrs_vTPvZDDhKjl1Hp94ltZeiYH7K8l9zOy5jd-I,947
122
113
  symai/extended/interfaces/perplexity.py,sha256=vSUl8CfBsFhFrzxws9Lf8WgfhsoPatJf7eYRfihKRG4,529
123
114
  symai/extended/interfaces/pinecone.py,sha256=NA2t1pNQf-G-HSeewEO8jqGnitD3huBV5bucIM9vgi4,1075
124
115
  symai/extended/interfaces/python.py,sha256=EcxXQwrlhjGOS5SkRoa_cVt069vu_INDD9DIfbnUses,418
125
- symai/extended/interfaces/selenium.py,sha256=nAhIZZjhmz2fsFIXytk9WNfGLy1OqlVytA-ipHZj3JM,660
126
116
  symai/extended/interfaces/serpapi.py,sha256=wbUisiYof-y5660dMU5DDTmbiUSd3rvDaYEvMkPTgwM,523
127
117
  symai/extended/interfaces/terminal.py,sha256=U-uXJc320wGEMWwsByVAyIzB3Puioeshcr9oKhtTV6Q,378
128
118
  symai/extended/interfaces/tts.py,sha256=uVTMXzkpOEdxSknXCihhfXvBnvadrMwIubeBB2_VVck,475
129
- symai/extended/interfaces/vectordb.py,sha256=Lou8XPScqDWPXEpxhIOzdRqonGVAJ2kriedVjSNSbo8,1022
130
119
  symai/extended/interfaces/whisper.py,sha256=sk2D6gAYREOe6nRMp7ArcnO-ENOp4GV97AsyZrm65mI,546
131
120
  symai/extended/interfaces/wolframalpha.py,sha256=6Q9X8OGokHeMphhZf3ZT0RuSFivx5fwwLxU9bH0xe00,488
132
121
  symai/extended/metrics/__init__.py,sha256=HuHm0ZSF7SidYgZTAu8ZbZ05i5BgspoiCeELtapP-Ig,296
@@ -135,18 +124,6 @@ symai/extended/packages/__init__.py,sha256=_SzkRPEiIxP3kAW-I5mve7o7UMJsIFavLTKQm
135
124
  symai/extended/packages/symdev.py,sha256=aVcqRLOZRf9awAClBlg_0cPVjAqTnWhmSPGWGCeQO1g,3826
136
125
  symai/extended/packages/sympkg.py,sha256=EFNrpvNJwYun0ridPcqK_LXHZOdsugKu5P6cJUBDvbk,3951
137
126
  symai/extended/packages/symrun.py,sha256=39QEDCJJWaeBT7NGf_qre-ij2BVRmjy06o1PCDhqyQU,6338
138
- symai/extended/personas/__init__.py,sha256=XoP39SRSxXiyiAI3frj6hFb3wzc9Vu5gRcIJBqzIlEo,95
139
- symai/extended/personas/builder.py,sha256=VvTPB4ar93ESRSbhOtfODMuQOAed7pvdLeX1HOJlGUs,3248
140
- symai/extended/personas/dialogue.py,sha256=zci4X6ksGHSc49KPUCaoLeLJYyhG8ibacsGOwnZpcJA,6404
141
- symai/extended/personas/persona.py,sha256=uy0B0R6OsvG9LTOe-vL06OfiDxZgN01tnvJiIMU_rHk,6612
142
- symai/extended/personas/research/__init__.py,sha256=3slSnilDyPcyXfSEoyYEatGnkjt4AkRgyUvSjaNNhO4,33
143
- symai/extended/personas/research/yann_lecun.py,sha256=lhhOX8MOX3DqU-1o2YDYo5GYaz9A_r_rI9gfw1Z3uuA,3876
144
- symai/extended/personas/sales/__init__.py,sha256=g2G5ove8tntwhBxoGQaE4J1C69thTBS5lbrqj-z3Wfc,33
145
- symai/extended/personas/sales/erik_james.py,sha256=n0D-bKZF1QxeS2XXQ7bOlRv_P60tIK8D6zBr8TsvYMg,5273
146
- symai/extended/personas/student/__init__.py,sha256=vn9SviFVdrNqLpln1lu5QUeQf-oE7LDwuTKaPsBkIJU,33
147
- symai/extended/personas/student/max_tenner.py,sha256=rp10Ijim6upo5s_DHj9tzsSfZWgDUaf2HgsgUeCRkT4,3422
148
- symai/extended/strategies/__init__.py,sha256=L_FSTzP4jCDjh8lvUBMk9fhc14W7_HwiOLRIQM7Gjzk,31
149
- symai/extended/strategies/cot.py,sha256=sOf3KrmG3M2IL1kpmS1FislbmnWWwyh9GzgHrkmYWgw,1800
150
127
  symai/formatter/__init__.py,sha256=CKr_aAmIwqaKPi4kvS9MCF3ghe68QMeGBVvOyB1qlD4,269
151
128
  symai/formatter/emoji.pytxt,sha256=D7FMnAar7UMBZnVoPIa_drnv8thIM8r0KNq_BkQ0k8k,13498
152
129
  symai/formatter/formatter.py,sha256=f0JDbxctzvSwWi8gYUrMj7Buo93x2cV4k1T-4PHuEIQ,8451
@@ -161,14 +138,14 @@ symai/models/base.py,sha256=NZ9fjkoQlMA1fN9YroSwImm7RqpH0mQ7zTaJAsPYzgE,44741
161
138
  symai/models/errors.py,sha256=nEbViXJ7RoVgs6nU3nbfz6Esy_pd4IB5MaggcLLOcdI,910
162
139
  symai/ops/__init__.py,sha256=bQneuCvcJkRF_VoM-uJXHeSbmGS2ewfNJP6zRO49e2s,1155
163
140
  symai/ops/measures.py,sha256=HAr5rMCKCcKErmwaPa751vM35L_KJ3fL86Pn6x47GmY,3651
164
- symai/ops/primitives.py,sha256=c0GT8rGL2p7dIL-yNoAydpwSZWx__8Ep8T2jj9Q5Eqw,116361
141
+ symai/ops/primitives.py,sha256=1G3tvY9t0T6OIkwh9kU9N7veYWugFZCIrNxHLbz9_tY,115584
165
142
  symai/server/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
166
143
  symai/server/huggingface_server.py,sha256=wSAVqFiKQsCu5UB2YYVpxJBhJ7GgQBBfePxNi265yP8,9039
167
144
  symai/server/llama_cpp_server.py,sha256=-WPTNB2cbnwtnpES4AtPM__MCasDKl83jr94JGS9tmI,2144
168
145
  symai/server/qdrant_server.py,sha256=l4r4rz29c7cO1dapXO0LQ4sHW4WF44keuz7j8v5azMc,9854
169
- symbolicai-1.5.0.dist-info/licenses/LICENSE,sha256=9vRFudlJ1ghVfra5lcCUIYQCqnZSYcBLjLHbGRsrQCs,1505
170
- symbolicai-1.5.0.dist-info/METADATA,sha256=gQLPEUb1pW2VPNqCtgN-WcXeSQnfUJAWx0KTAN3vnJw,23731
171
- symbolicai-1.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
172
- symbolicai-1.5.0.dist-info/entry_points.txt,sha256=JV5sdydIfUZdDF6QBEQHiZHod6XNPjCjpWQrXh7gTAw,261
173
- symbolicai-1.5.0.dist-info/top_level.txt,sha256=bOoIDfpDIvCQtQgXcwVKJvxAKwsxpxo2IL4z92rNJjw,6
174
- symbolicai-1.5.0.dist-info/RECORD,,
146
+ symbolicai-1.7.0.dist-info/licenses/LICENSE,sha256=9vRFudlJ1ghVfra5lcCUIYQCqnZSYcBLjLHbGRsrQCs,1505
147
+ symbolicai-1.7.0.dist-info/METADATA,sha256=leIkcs9g6yfwn3e7qqRGnZHUL_Co6M9G5W9YddvE1QM,22946
148
+ symbolicai-1.7.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
149
+ symbolicai-1.7.0.dist-info/entry_points.txt,sha256=JV5sdydIfUZdDF6QBEQHiZHod6XNPjCjpWQrXh7gTAw,261
150
+ symbolicai-1.7.0.dist-info/top_level.txt,sha256=bOoIDfpDIvCQtQgXcwVKJvxAKwsxpxo2IL4z92rNJjw,6
151
+ symbolicai-1.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,217 +0,0 @@
1
- import os
2
-
3
- os.environ['WDM_LOG'] = 'false' # disable webdriver-manager logging
4
-
5
- import logging
6
-
7
- logging.getLogger('WDM').setLevel(logging.NOTSET)
8
-
9
- import random
10
- import re
11
- import sys
12
- import time
13
- import urllib.request
14
- import warnings
15
-
16
- from random import choice
17
-
18
- try:
19
- warnings.filterwarnings('ignore', module='chromedriver')
20
- warnings.filterwarnings('ignore', module='selenium')
21
- from selenium import webdriver
22
- from selenium.webdriver.remote.remote_connection import LOGGER
23
- from webdriver_manager.firefox import GeckoDriverManager
24
- from selenium.webdriver.firefox.options import Options as FirefoxOptions
25
- from selenium.webdriver.firefox.service import Service as FirefoxService
26
- from webdriver_manager.chrome import ChromeDriverManager
27
- from selenium.webdriver.chrome.options import Options as ChromeOptions
28
- from selenium.webdriver.chrome.service import Service as ChromeService
29
- from webdriver_manager.microsoft import EdgeChromiumDriverManager
30
- from selenium.webdriver.edge.options import Options as EdgeOptions
31
- from selenium.webdriver.edge.service import Service as EdgeService
32
- from selenium.common.exceptions import WebDriverException
33
-
34
- LOGGER.setLevel(logging.ERROR)
35
-
36
- except Exception as e:
37
- webdriver = None
38
- if "No module named 'selenium'" in str(e):
39
- print(f"ERROR: {e}")
40
- print(f"ERROR: Please install selenium with `pip install selenium`")
41
- else:
42
- print(f"ERROR: {e}")
43
-
44
- from ... import __root_dir__
45
-
46
-
47
- class Proxy(object):
48
- def __init__(self, host, port):
49
- self.host = host
50
- self.port = port
51
-
52
-
53
- class add_path():
54
- def __init__(self, path):
55
- self.path = path
56
-
57
- def __enter__(self):
58
- sys.path.insert(0, self.path)
59
-
60
- def __exit__(self, exc_type, exc_value, traceback):
61
- try:
62
- sys.path.remove(self.path)
63
- except ValueError:
64
- pass
65
-
66
-
67
- def wait_for(condition_function, timeout):
68
- start_time = time.time()
69
- while time.time() < start_time + timeout:
70
- if condition_function():
71
- return True
72
- else:
73
- time.sleep(0.1)
74
- raise Exception(f'Server does not respond to request with appropriate content. Check link or script.')
75
-
76
-
77
- class page_loaded(object):
78
- def __init__(self, driver, check_pattern, timeout=3, debug=False):
79
- self.check_pattern = check_pattern
80
- self.driver = driver
81
- self.timeout = timeout
82
- self.debug = debug
83
-
84
- def __enter__(self):
85
- pass
86
-
87
- def page_has_loaded(self):
88
- if self.debug: print(self.driver.page_source)
89
- return re.search(self.check_pattern, self.driver.page_source)
90
-
91
- def __exit__(self, *_):
92
- wait_for(self.page_has_loaded, timeout=self.timeout)
93
-
94
-
95
- def add_options(options, proxy):
96
- if proxy: options.add_argument(f"--proxy-server=socks5://{proxy.host}:{proxy.port}")
97
- options.add_argument('--ignore-certificate-errors')
98
- options.add_argument('--incognito')
99
- options.add_argument("--headless")
100
- options.add_argument("--log-level=3")
101
-
102
-
103
- def _connect_brower(debug, proxy=None):
104
- assert webdriver is not None, "selenium is not installed"
105
-
106
- try:
107
- options = ChromeOptions()
108
- add_options(options, proxy)
109
- driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options)
110
- except Exception as e1:
111
- try:
112
- print(f"ERROR REMEDY: Trying to use Chrome as an alternative.")
113
- options = FirefoxOptions()
114
- add_options(options, proxy)
115
- driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()), options=options)
116
- except Exception as e2:
117
- print(f"Issue with finding an appropriate driver version. Your current browser might be newer than the driver. Please either downgrade Chrome or try to install a proper chromedriver manually.\nOriginal error: {e1}; Remedy attempt error: {e2}")
118
- try:
119
- print(f"ERROR REMEDY: Trying to use Edge as an alternative.")
120
- options = EdgeOptions()
121
- if proxy: options.add_argument(f"--proxy-server=socks5://{proxy.host}:{proxy.port}")
122
- add_options(options, proxy)
123
- driver = webdriver.Edge(service=EdgeService(EdgeChromiumDriverManager().install()), options=options)
124
- except Exception as e3:
125
- print(f"Issue with finding an appropriate driver version. Your current browser might be newer than the driver. Please either downgrade Chrome or try to install a proper chromedriver manually.\nOriginal error: {e1}; Remedy attempt error: {e2}; Second remedy attempt error: {e3}")
126
- raise e3 from e2
127
- if debug: print("Chrome Headless Browser Invoked")
128
-
129
- return driver
130
-
131
-
132
- def connect_browsers(debug, proxy):
133
- assert webdriver is not None, "selenium is not installed"
134
- class BrowserHandler(object):
135
- def __init__(self, debug):
136
- self.browsers = [_connect_brower(debug, proxy=proxy)]
137
- def __call__(self):
138
- return choice(self.browsers)
139
- return BrowserHandler(debug)
140
-
141
-
142
- def dump_page_source(driver, file_path="dump.log"):
143
- with open(file_path, "wb") as err_file:
144
- err_file.write(driver.page_source.encode("utf-8"))
145
-
146
-
147
-
148
- def contains_text(check_pattern, search_pattern, link, driver_handler, script=None, debug=False, args=None):
149
- driver = driver_handler()
150
- try:
151
- driver.get(link)
152
- except WebDriverException as e:
153
- print(f"ERROR: {e}")
154
- print(f"ERROR: Please install a proper driver for your browser. You can find the appropriate driver here: https://selenium-python.readthedocs.io/installation.html#drivers")
155
- return False
156
- with page_loaded(driver, check_pattern, debug=debug):
157
- if script is not None: script(driver, args)
158
- rsp = re.search(search_pattern, driver.page_source)
159
- return True if rsp else False
160
-
161
-
162
- def download_images(driver, args):
163
- src = driver.find_element_by_xpath("//div[@class='bRMDJf islir']/descendant-or-self::*[img]").get_attribute("src")
164
- imgs = driver.find_elements_by_tag_name('img')
165
- p = args[0]
166
- uri = []
167
- for i in imgs:
168
- data = i.get_attribute("src")
169
- if data and data.startswith('data'):
170
- response = urllib.request.urlopen(data)
171
- n = i.get_attribute("data-iml")
172
- if n:
173
- if not os.path.exists(f'data/{p}'):
174
- os.makedirs(f'data/{p}')
175
- with open(f'data/{p}/{n}.jpg', 'wb') as f:
176
- f.write(response.file.read())
177
-
178
-
179
- def run_selenium_test(debug=False):
180
- proxy = Proxy(host="localhost", port=9050)
181
- driver_handler = connect_browsers(debug, proxy)
182
-
183
- max_cnt = 5
184
- cnt = 0
185
- now = time.time()
186
-
187
- with open('data/text_demo.txt', 'r') as f:
188
- text = f.read().replace('\n', '')\
189
- .replace('.', '')\
190
- .replace(',', '')
191
-
192
- print(text)
193
- #text = "women sitting in the park" #names.get_full_name()
194
-
195
- # input String
196
- lst = text.split(' ')
197
-
198
- while cnt < max_cnt:
199
- start_pos = random.randint(0, len(lst)-1)
200
- len_ = random.randint(1, 6)
201
- seq = lst[start_pos:start_pos+len_]
202
- pattern = " ".join(seq)
203
- result = contains_text(check_pattern="Images",
204
- search_pattern=pattern,
205
- link=f"https://www.google.com/search?tbm=isch&as_q={pattern}&tbs=isz:lt,islt:4mp,sur:fmc",
206
- driver_handler=driver_handler,
207
- debug=True,
208
- script=download_images,
209
- args=[pattern])
210
- timestamp = time.time() - now
211
- now = time.time()
212
- print(f"{result} - time: {timestamp}")
213
- cnt += 1
214
-
215
-
216
- if __name__ == "__main__":
217
- run_selenium_test(debug=True)