unique-search-proxy 2026.42.0.dev1__tar.gz → 2026.42.0.dev2__tar.gz

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 (114) hide show
  1. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/PKG-INFO +3 -3
  2. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/pyproject.toml +3 -3
  3. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/service.py +19 -9
  4. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/README.md +0 -0
  5. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/__init__.py +0 -0
  6. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/__init__.py +0 -0
  7. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/__init__.py +0 -0
  8. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/health.py +0 -0
  9. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/__init__.py +0 -0
  10. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/agent_search.py +0 -0
  11. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/configuration.py +0 -0
  12. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/context_headers.py +0 -0
  13. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/crawl.py +0 -0
  14. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/openapi_examples.py +0 -0
  15. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/api/v1/search.py +0 -0
  16. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/app.py +0 -0
  17. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/context.py +0 -0
  18. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/__init__.py +0 -0
  19. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/__init__.py +0 -0
  20. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/cleanup.py +0 -0
  21. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/client.py +0 -0
  22. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/runner.py +0 -0
  23. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/service.py +0 -0
  24. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/factory.py +0 -0
  25. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/service_base.py +0 -0
  26. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/structured_output.py +0 -0
  27. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/vertexai/client.py +0 -0
  28. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/vertexai/gemini.py +0 -0
  29. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/agent_engines/vertexai/service.py +0 -0
  30. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/client/__init__.py +0 -0
  31. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/client/credentials.py +0 -0
  32. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/client/service.py +0 -0
  33. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/__init__.py +0 -0
  34. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/__init__.py +0 -0
  35. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/__init__.py +0 -0
  36. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/errors.py +0 -0
  37. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/html_markdown.py +0 -0
  38. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/__init__.py +0 -0
  39. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/html.py +0 -0
  40. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/pdf.py +0 -0
  41. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/plain_text.py +0 -0
  42. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/registry.py +0 -0
  43. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/settings.py +0 -0
  44. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/user_agent.py +0 -0
  45. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/factory.py +0 -0
  46. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/firecrawl/polling.py +0 -0
  47. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/firecrawl/request_body.py +0 -0
  48. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/firecrawl/service.py +0 -0
  49. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/jina/request_body.py +0 -0
  50. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/jina/service.py +0 -0
  51. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/pinned_egress.py +0 -0
  52. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/tavily/request_body.py +0 -0
  53. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/crawlers/tavily/service.py +0 -0
  54. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/provider_response.py +0 -0
  55. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/providers.py +0 -0
  56. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/registry.py +0 -0
  57. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/__init__.py +0 -0
  58. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/__init__.py +0 -0
  59. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/pagination.py +0 -0
  60. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/query_params.py +0 -0
  61. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/service.py +0 -0
  62. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/descriptor.py +0 -0
  63. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/factory.py +0 -0
  64. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/__init__.py +0 -0
  65. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/pagination.py +0 -0
  66. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/query_params.py +0 -0
  67. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/service.py +0 -0
  68. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/pagination.py +0 -0
  69. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/perplexity/__init__.py +0 -0
  70. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/perplexity/request_body.py +0 -0
  71. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/perplexity/service.py +0 -0
  72. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/search_engines/service_base.py +0 -0
  73. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/url_safety/__init__.py +0 -0
  74. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/core/url_safety/gate.py +0 -0
  75. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/error_handlers.py +0 -0
  76. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/__init__.py +0 -0
  77. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/generator/__init__.py +0 -0
  78. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/generator/introspect.py +0 -0
  79. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/generator/schema.py +0 -0
  80. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/generator/template.py +0 -0
  81. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/generator/templates/provider_values_yaml.j2 +0 -0
  82. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/generator/values_yaml.py +0 -0
  83. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/metadata.py +0 -0
  84. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/registry.py +0 -0
  85. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/helm/url_safety_registration.py +0 -0
  86. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/logging_config.py +0 -0
  87. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/middleware/context.py +0 -0
  88. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/monitoring/__init__.py +0 -0
  89. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/monitoring/metrics.py +0 -0
  90. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/monitoring/setup.py +0 -0
  91. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/presets/__init__.py +0 -0
  92. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/presets/common.py +0 -0
  93. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/presets/crawl.py +0 -0
  94. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/presets/search.py +0 -0
  95. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/presets/types.py +0 -0
  96. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/__init__.py +0 -0
  97. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/app.py +0 -0
  98. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/base.py +0 -0
  99. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/client.py +0 -0
  100. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/monitoring.py +0 -0
  101. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/__init__.py +0 -0
  102. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/base.py +0 -0
  103. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/bing_agent.py +0 -0
  104. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/brave.py +0 -0
  105. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/firecrawl.py +0 -0
  106. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/google.py +0 -0
  107. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/jina.py +0 -0
  108. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/perplexity.py +0 -0
  109. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/tavily.py +0 -0
  110. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/providers/vertexai_agent.py +0 -0
  111. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/settings/secret_str.py +0 -0
  112. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/startup_report.py +0 -0
  113. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/utils/__init__.py +0 -0
  114. {unique_search_proxy-2026.42.0.dev1 → unique_search_proxy-2026.42.0.dev2}/unique_search_proxy_client/web/utils/url.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-search-proxy
3
- Version: 2026.42.0.dev1
3
+ Version: 2026.42.0.dev2
4
4
  Summary: Web Search Proxy implementation
5
5
  Author: ThePhilAz
6
6
  Author-email: ThePhilAz <rami.azouz@philico.com>
@@ -19,8 +19,8 @@ Requires-Dist: certifi>=2025.11.12,<2027
19
19
  Requires-Dist: google-genai>=1.73.0,<2
20
20
  Requires-Dist: google-auth>=2.43.0,<3
21
21
  Requires-Dist: jinja2>=3.1.6,<4
22
- Requires-Dist: unique-toolkit[monitoring]>=2026.42.0.dev9,<2026.42.0rc0
23
- Requires-Dist: unique-search-proxy-core>=2026.42.0.dev1,<2026.42.0rc0
22
+ Requires-Dist: unique-toolkit[monitoring]>=2026.42.0.dev13,<2026.42.0rc0
23
+ Requires-Dist: unique-search-proxy-core>=2026.42.0.dev2,<2026.42.0rc0
24
24
  Requires-Dist: openai>=1.105.0,<3
25
25
  Requires-Python: >=3.12
26
26
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique-search-proxy"
3
- version = "2026.42.0.dev1"
3
+ version = "2026.42.0.dev2"
4
4
  description = "Web Search Proxy implementation"
5
5
  authors = [{ name = "ThePhilAz", email = "rami.azouz@philico.com" }]
6
6
  readme = "README.md"
@@ -21,8 +21,8 @@ dependencies = [
21
21
  "google-genai>=1.73.0,<2",
22
22
  "google-auth>=2.43.0,<3",
23
23
  "jinja2>=3.1.6,<4",
24
- "unique-toolkit[monitoring]>=2026.42.0.dev9,<2026.42.0rc0",
25
- "unique-search-proxy-core>=2026.42.0.dev1,<2026.42.0rc0",
24
+ "unique-toolkit[monitoring]>=2026.42.0.dev13,<2026.42.0rc0",
25
+ "unique-search-proxy-core>=2026.42.0.dev2,<2026.42.0rc0",
26
26
  "openai>=1.105.0,<3",
27
27
  ]
28
28
 
@@ -15,9 +15,11 @@ from unique_search_proxy_core.schema import (
15
15
  ProxyErrorCode,
16
16
  )
17
17
  from unique_search_proxy_core.url_safety import (
18
+ CrawlTargetValidationError,
18
19
  ResolvedCrawlTarget,
19
20
  bypass_crawl_target,
20
- pinned_httpx_get_args,
21
+ safe_pinned_httpx_get,
22
+ url_safety_settings,
21
23
  )
22
24
 
23
25
  from unique_search_proxy_client.web.core.crawlers.basic.processing import (
@@ -29,10 +31,12 @@ from unique_search_proxy_client.web.core.crawlers.basic.user_agent import (
29
31
  random_user_agent,
30
32
  )
31
33
  from unique_search_proxy_client.web.core.provider_response import (
34
+ crawl_forbidden_target,
32
35
  crawl_upstream_error,
33
36
  transport_error_raw,
34
37
  )
35
38
  from unique_search_proxy_client.web.core.url_safety.gate import AllowedCrawlTarget
39
+ from unique_search_proxy_client.web.monitoring.metrics import record_crawl_blocked
36
40
 
37
41
  _LOGGER = logging.getLogger(__name__)
38
42
 
@@ -101,18 +105,24 @@ class BasicCrawlerService(BaseCrawler[BasicCrawlRequest]):
101
105
  semaphore: asyncio.Semaphore,
102
106
  content_type_handlers: dict[str, ContentTypeHandlerPolicy],
103
107
  ) -> CrawlUrlResult:
104
- request_url, pin_headers, extensions = pinned_httpx_get_args(resolved_target)
105
108
  async with semaphore:
106
- headers = {"User-Agent": random_user_agent(), **pin_headers}
107
-
108
109
  try:
109
- response = await client.get(
110
- request_url,
111
- headers=headers,
112
- extensions=extensions or None,
110
+ response = await safe_pinned_httpx_get(
111
+ client,
112
+ resolved_target,
113
+ headers={"User-Agent": random_user_agent()},
113
114
  timeout=Timeout(timeout),
114
- follow_redirects=True,
115
+ max_redirect_hops=url_safety_settings.max_redirect_hops,
116
+ enforce_url_safety=url_safety_settings.enabled,
117
+ )
118
+ except CrawlTargetValidationError as exc:
119
+ blocked = exc.blocked_targets[0]
120
+ record_crawl_blocked(blocked.category)
121
+ _LOGGER.warning(
122
+ "Basic crawl blocked redirect: %s",
123
+ blocked.category,
115
124
  )
125
+ return crawl_forbidden_target(display_url, blocked.reason)
116
126
  except httpx.TimeoutException as exc:
117
127
  _LOGGER.warning("Basic crawl timed out for %s: %s", display_url, exc)
118
128
  return crawl_upstream_error(