38 Commits

Author SHA1 Message Date
Karim shoair e7f9adb40a feat(security): default follow_redirects to "safe" for SSRF protection
curl_cffi v0.15.0 introduced CurlFollow.SAFE, which follows redirects but rejects those targeting internal/private IPs (loopback, private networks, link-local). This is now the default for all HTTP fetchers, the MCP server, and the shell curl converter.

Added FollowRedirects type alias supporting all curl_cffi redirect
modes: bool, "safe", "all", "obeycode", "firstonly".
2026-04-05 18:41:50 +02:00
Karim shoair 4efbffa1dc feat(cli): Add an option to make content safe/targets AI 2026-03-30 02:44:14 +02:00
Karim shoair 375951bd49 feat(mcp): Protect from Prompt Injection by removing hidden content
Solves #214 as well
2026-03-30 02:31:14 +02:00
Karim shoair b50e8f050f fix(mcp): make mcp use less tokens by striping useless tags 2026-02-27 03:39:48 +02:00
Karim shoair 5ec929435b style: Fix all mypy errors and add type hints to untyped function bodies
**Resolved all 65 mypy errors across 14 files and added type annotations to all previously untyped function bodies. Final result: 0 errors with --check-untyped-defs enabled, all 454 tests pass.**

`scrapling/core/_types.py`

  - Removed broken Self = object fallback — now requires typing_extensions for Python < 3.11

`scrapling/core/storage.py`

  - Fixed str/bytes mismatch in _get_hash() — used separate _identifier_bytes variable instead of reassigning from str to bytes

`scrapling/core/custom_types.py`

  - split() return type: Union[List, "TextHandlers"] → list[Any] (avoids LSP violation with parent list[str])
  - format() kwargs: **kwargs: str → **kwargs: object (matches parent str.format signature)
  - AttributesHandler.__init__: Added mapping: Any = None, **kwargs: Any and -> None
  - json_string property: Added -> bytes return type

`scrapling/core/mixins.py`

  - Changed self: "Selector" to self: Any on all mixin methods (mypy can't handle forward-reference self types on non-subclass mixins)
  - Added Dict[str, int] annotation for counter variable
  - Removed unused TYPE_CHECKING / Selector imports

`scrapling/parser.py (~30 errors)`

  - Added body: str | bytes pre-annotation for dual-type if/elif assignment
  - Used Dict[str, Any] kwargs dict for HTMLParser(...) to bypass incomplete lxml stubs missing default_doctype
  - Changed base_url=url or None → base_url=url or "" (avoids str | None vs str | bytes)
  - bool(adaptive) to guarantee bool type for __adaptive_enabled
  - Declared __text: Optional[TextHandler], __tag: Optional[str], __attributes: Optional[AttributesHandler] at top of __init__
  - cast(List, ...) for all XPath() call results (_find_all_elements, _find_all_elements_with_spaces)
  - Added Dict[float, List[Any]] for score_table, Dict[str, Any] for attributes
  - Changed score, checks = 0, 0 → score: float = 0; checks: int = 0 (two locations)
  - Renamed target → target_element in save() to avoid variable redefinition with different types
  - Wrapped node_text.clean() / .lower() in TextHandler(...) to preserve type

`scrapling/engines/_browsers/_page.py`

  - Added PageInfo[SyncPage] | PageInfo[AsyncPage] union type annotation to page_info variable

`scrapling/engines/_browsers/_validators.py`

  - Convert method_kwargs (TypedDict) to plain Dict[str, Any] before dynamic key access

`scrapling/engines/_browsers/_base.py`

  - Added _config declaration to BaseSessionMixin
  - Used cast(StealthConfig, self._config) in __generate_stealth_options to access stealth-only attributes
  - Added Tuple[str, ...] annotation for flags
  - Removed redundant narrower StealthConfig type annotation on self._config in StealthySessionMixin.__validate__
  - Widened SyncSession and AsyncSession fields (playwright, context, browser) to Any to support both playwright and patchright types
  - Added -> None to both start() methods

`scrapling/engines/_browsers/_stealth.py`

  - Added Optional, ProxyType imports
  - Annotated proxy: Optional[ProxyType] in both sync/async fetch loops
  - Annotated outer_box: Any at first declaration, removed duplicate type annotations in subsequent branches
  - Added -> None to sync and async start()
  - Added config: Any parameter type to _initialize_context
  - Removed redundant self.context: AsyncBrowserContext re-annotations in conditional branches

`scrapling/engines/_browsers/_controllers.py`

  - Added Optional, ProxyType imports
  - Annotated proxy: Optional[ProxyType] in both sync/async fetch loops
  - Added -> None to async start()
  - Removed redundant self.context: AsyncBrowserContext re-annotations

`scrapling/spiders/request.py`

  - Added Optional import, typed _fp: Optional[bytes] = None
  - Removed redundant body: bytes re-annotation

`scrapling/spiders/session.py`

  - Used separate client variable instead of reassigning session = session._client (avoids type incompatibility and fixes a bug where session._make_request was called instead of client._make_request)
  - Added -> None to SessionManager.__init__

`scrapling/engines/toolbelt/convertor.py`

  - Added list[Response] annotation for history in both sync/async methods

`scrapling/engines/static.py`

  - FetcherClient.__init__ and AsyncFetcherClient.__init__: Added **kwargs: Any and -> None

`scrapling/core/shell.py`

  - Wrapped re_sub(...) result in TextHandler(...) to maintain correct type
  - Added -> None to CurlParser.__init__
  - Added full type signature to create_wrapper, replaced wrapper.__signature__ = ... with setattr(wrapper, "__signature__", ...) to satisfy mypy
  - Added Callable to imports
2026-02-07 16:30:00 +02:00
Karim shoair aa7a95fb70 feat(parser)!: Make all selection return selector objects by default
- The strings/Texthandlers are only returned by `get`/`getall`/`extract`/`extract_first`. This makes the type checking/autocompletion experience consistent.
- Removed `css_first` and `xpath_first` since it doesn't make sense to leave them now.
- Made the type hints more accurate in multiple places.
2026-02-06 02:43:51 +02:00
Karim shoair ac2d4d3833 fix: use the correct signature for the stealthy_fetch shortcut 2025-12-02 02:15:42 +02:00
Karim shoair 8940bdeb55 fix(shell): dynamically build the signature of shortcuts after last changes 2025-11-25 21:23:06 +02:00
Karim shoair 5376c97996 fix(fetcher): Remove non-keywords arguments 2025-11-25 20:25:09 +02:00
Karim shoair debe03256b refactor: Making all the codebase acceptable by PyRight
Also fixes #97
2025-10-05 04:03:39 +03:00
Karim shoair 3da806210b perf: General code restructure to not use more than needed memory 2025-09-23 18:34:54 +03:00
Karim shoair 2d704b2a8b fix(shell): Fixing a bug with content converting 2025-09-19 04:50:15 +03:00
Karim shoair bf5fe6d451 fix(shell): Fix view command edge case 2025-09-19 04:21:15 +03:00
Karim shoair 504ecdf7dc fix(shell): Fix parsing curl --data-raw 2025-09-19 04:20:16 +03:00
Karim shoair 05c2d9aa00 feat(CLI): Make the session classes available in the shell 2025-09-15 23:34:36 +03:00
Karim shoair 1547366c85 fix: fixing body issue with cli view command 2025-09-15 21:32:57 +03:00
Karim shoair 67ca139ff9 fix: Fixes for multiple encoding issues (#80 & #81 ) 2025-09-14 20:20:29 +03:00
Karim shoair 0b3509a295 fix(shell): Fix a small typo 2025-09-14 05:05:55 +03:00
Karim shoair 13d7e70cb7 refactor: Make all fetchers as an optional dependency group
+ Removing some dead code
2025-09-13 16:07:48 +03:00
Karim shoair 330d03559c style: applying the new ruff rules to all files 2025-09-13 03:22:53 +03:00
Karim shoair af9a62a539 fix: fix for shell imported by mistake issue (#76) 2025-09-02 15:23:15 +03:00
Karim shoair 2f402f4835 style: add flags for tests coverage
- Some are already tested but the coverage report can't see it.
- Some are not necessary to test or too hard to test on GitHub's CI
2025-08-17 01:02:14 +03:00
Karim shoair 13700e2692 fix: improve error handling 2025-08-15 04:52:11 +03:00
Karim shoair ae9ccaec79 style: A lot of type hints correction
Since we are using Py3.10 as minimum version now, we remove Union when possible
2025-07-30 02:46:57 +03:00
Karim shoair e7cdd39695 style: replacing os with Pathlib and small optimizations 2025-07-30 01:15:28 +03:00
Karim shoair 18660f8132 style: type hints corrections and docstrings 2025-07-30 00:32:39 +03:00
Karim shoair 264ae02aa7 refactor: huge change, many features/class got a better naming
- `Adaptor` became `Selector`
- `Adaptors` became `Selectors`
- `auto_match` argument/feature became `adaptive`
- `adaptor_arguments` argument became `selector_config`
- `automatch_domain` argument became `adaptive_domain`
- `additional_arguments` argument became `additional_args`
- `storage_adaptors` file became just `storage`
2025-07-29 04:20:23 +03:00
Karim shoair 172a5b4a0a feat: Add an mcp server 2025-07-26 22:57:08 +03:00
Karim shoair 1076001e29 refactor: changes to be used by the mcp server 2025-07-14 05:38:29 +03:00
Karim shoair 29e485bdf2 refactor: Optimizations to CLI 2025-06-29 19:10:52 +03:00
Karim shoair 1c9e48b1c6 feat(extract): Adding new command to CLI options + Optimizations
Users can now fetch websites directly without code and extract full/selected HTML content as HTML, Markdown, or extract text content.
2025-06-29 18:56:09 +03:00
Karim shoair a41be48047 refactor: optimize imports and docstrings correction 2025-06-25 21:36:53 +03:00
Karim shoair 8a272cf19b feat/refactor(fetchers): Replacing PlayWrightFetcher with DynamicFetcher and adding session classes 2025-06-22 02:10:45 +03:00
Karim shoair 3e63fa2523 fix(shell): Hide the automatic tips and solve the namespace issue 2025-06-19 04:03:13 +03:00
Karim shoair 74fa1bfbed feat(shell): Add support to curl -b argument 2025-04-30 04:23:05 +03:00
Karim shoair 8f3b2092c2 fix(cli): Update page object after curl request 2025-04-29 03:14:41 +03:00
Karim shoair 98ad50d5aa feat(cli): Adding two new commands (uncurl/curl2fetcher) 2025-04-29 02:45:50 +03:00
Karim shoair 49b7ae13f6 feat(cli): Adding Scrapling Shell feature 2025-04-22 05:15:57 +02:00