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.
- symai/__init__.py +21 -71
- symai/backend/base.py +0 -26
- symai/backend/engines/drawing/engine_gemini_image.py +101 -0
- symai/backend/engines/embedding/engine_openai.py +11 -8
- symai/backend/engines/neurosymbolic/__init__.py +8 -0
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +1 -0
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +48 -1
- symai/backend/engines/neurosymbolic/engine_cerebras.py +1 -0
- symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +14 -1
- symai/backend/engines/neurosymbolic/engine_openrouter.py +294 -0
- symai/backend/mixin/__init__.py +4 -0
- symai/backend/mixin/anthropic.py +37 -16
- symai/backend/mixin/openrouter.py +2 -0
- symai/components.py +203 -13
- symai/extended/interfaces/nanobanana.py +23 -0
- symai/interfaces.py +2 -0
- symai/ops/primitives.py +0 -18
- symai/shellsv.py +2 -7
- symai/strategy.py +44 -4
- {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/METADATA +3 -10
- {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/RECORD +25 -48
- {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/WHEEL +1 -1
- symai/backend/driver/webclient.py +0 -217
- symai/backend/engines/crawler/engine_selenium.py +0 -94
- symai/backend/engines/drawing/engine_dall_e.py +0 -131
- symai/backend/engines/embedding/engine_plugin_embeddings.py +0 -12
- symai/backend/engines/experiments/engine_bard_wrapper.py +0 -131
- symai/backend/engines/experiments/engine_gptfinetuner.py +0 -32
- symai/backend/engines/experiments/engine_llamacpp_completion.py +0 -142
- symai/backend/engines/neurosymbolic/engine_openai_gptX_completion.py +0 -277
- symai/collect/__init__.py +0 -8
- symai/collect/dynamic.py +0 -117
- symai/collect/pipeline.py +0 -156
- symai/collect/stats.py +0 -434
- symai/extended/crawler.py +0 -21
- symai/extended/interfaces/selenium.py +0 -18
- symai/extended/interfaces/vectordb.py +0 -21
- symai/extended/personas/__init__.py +0 -3
- symai/extended/personas/builder.py +0 -105
- symai/extended/personas/dialogue.py +0 -126
- symai/extended/personas/persona.py +0 -154
- symai/extended/personas/research/__init__.py +0 -1
- symai/extended/personas/research/yann_lecun.py +0 -62
- symai/extended/personas/sales/__init__.py +0 -1
- symai/extended/personas/sales/erik_james.py +0 -62
- symai/extended/personas/student/__init__.py +0 -1
- symai/extended/personas/student/max_tenner.py +0 -51
- symai/extended/strategies/__init__.py +0 -1
- symai/extended/strategies/cot.py +0 -40
- {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/entry_points.txt +0 -0
- {symbolicai-1.5.0.dist-info → symbolicai-1.7.0.dist-info}/licenses/LICENSE +0 -0
- {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
|
|
1073
|
+
if SYMSH_CONFIG.get("show-splash-screen", True):
|
|
1074
1074
|
show_intro_menu()
|
|
1075
|
-
|
|
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
|
-
|
|
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"] =
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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
|
|
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=
|
|
2
|
+
symai/__init__.py,sha256=j5bwtmnvxtMH6h5LsdMB5hgynMwXRVH5tWJ5rp49Am0,15612
|
|
3
3
|
symai/chat.py,sha256=DCEbmZ96wv-eitAVt6-oF6PT3JM3cT59Iy3r2Hucd_M,14100
|
|
4
|
-
symai/components.py,sha256=
|
|
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=
|
|
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=
|
|
20
|
-
symai/strategy.py,sha256=
|
|
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=
|
|
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/
|
|
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=
|
|
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=
|
|
48
|
-
symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py,sha256=
|
|
49
|
-
symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py,sha256=
|
|
50
|
-
symai/backend/engines/neurosymbolic/engine_cerebras.py,sha256=
|
|
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=
|
|
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=
|
|
75
|
-
symai/backend/mixin/anthropic.py,sha256=
|
|
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/
|
|
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=
|
|
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.
|
|
170
|
-
symbolicai-1.
|
|
171
|
-
symbolicai-1.
|
|
172
|
-
symbolicai-1.
|
|
173
|
-
symbolicai-1.
|
|
174
|
-
symbolicai-1.
|
|
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,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)
|