openscour 0.3.1__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.
- openscour-0.3.1/.gitignore +19 -0
- openscour-0.3.1/CHANGELOG.md +83 -0
- openscour-0.3.1/LICENSE +21 -0
- openscour-0.3.1/PKG-INFO +649 -0
- openscour-0.3.1/README.md +613 -0
- openscour-0.3.1/openscour/__init__.py +38 -0
- openscour-0.3.1/openscour/client.py +267 -0
- openscour-0.3.1/openscour/errors.py +35 -0
- openscour-0.3.1/openscour/mcp_server.py +161 -0
- openscour-0.3.1/openscour/py.typed +0 -0
- openscour-0.3.1/openscour/server/__init__.py +0 -0
- openscour-0.3.1/openscour/server/answer.py +56 -0
- openscour-0.3.1/openscour/server/cache.py +33 -0
- openscour-0.3.1/openscour/server/config.py +59 -0
- openscour-0.3.1/openscour/server/fetcher.py +222 -0
- openscour-0.3.1/openscour/server/main.py +279 -0
- openscour-0.3.1/openscour/server/models.py +54 -0
- openscour-0.3.1/openscour/server/netguard.py +110 -0
- openscour-0.3.1/openscour/server/providers.py +138 -0
- openscour-0.3.1/openscour/server/ranker.py +419 -0
- openscour-0.3.1/openscour/server/ratelimit.py +41 -0
- openscour-0.3.1/openscour/server/robots.py +77 -0
- openscour-0.3.1/openscour/types.py +69 -0
- openscour-0.3.1/pyproject.toml +71 -0
- openscour-0.3.1/tests/test_client.py +222 -0
- openscour-0.3.1/tests/test_fetcher.py +151 -0
- openscour-0.3.1/tests/test_mcp_server.py +62 -0
- openscour-0.3.1/tests/test_netguard.py +82 -0
- openscour-0.3.1/tests/test_ranker.py +251 -0
- openscour-0.3.1/tests/test_ratelimit.py +22 -0
- openscour-0.3.1/tests/test_server.py +187 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
*.egg-info/
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
|
|
10
|
+
# Secrets and local config
|
|
11
|
+
.env
|
|
12
|
+
.env.*
|
|
13
|
+
!.env.example
|
|
14
|
+
.claude/settings.local.json
|
|
15
|
+
|
|
16
|
+
# OS / editors
|
|
17
|
+
.DS_Store
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to OpenScour are listed here. Versions follow [Semantic Versioning](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## [0.3.1] - 2026-10-30
|
|
6
|
+
|
|
7
|
+
### Packaging
|
|
8
|
+
- Published on [PyPI](https://pypi.org/project/openscour/): `pip install openscour`, and `uvx --from "openscour[mcp]==0.3.1" openscour-mcp` for the MCP server. New releases are published automatically from GitHub releases through PyPI trusted publishing.
|
|
9
|
+
- Package metadata (project links, classifiers, keywords) and a `py.typed` marker, so type checkers use the client's type hints.
|
|
10
|
+
- The package contains only an explicit list of files, so local files such as `.env` can never be published.
|
|
11
|
+
|
|
12
|
+
## [0.3.0] - 2026-10-29
|
|
13
|
+
|
|
14
|
+
Operations and client resilience (phase 2 of the enterprise roadmap).
|
|
15
|
+
|
|
16
|
+
### Server
|
|
17
|
+
- Rate limits: `RATE_LIMIT_PER_MINUTE` (default 60) requests a minute per API key, or per client IP when auth is off. Excess requests get `429` with a `Retry-After` header. `TRUST_FORWARDED_FOR` takes the client IP from a load balancer's `X-Forwarded-For`.
|
|
18
|
+
- `GET /health/ready` for load balancers: checks SearXNG, and reports "degraded" rather than failing while the DuckDuckGo fallback can serve searches.
|
|
19
|
+
- Request IDs: every response has an `X-Request-ID` header (the caller's own, or a generated one), and each request is logged on one line with its ID, status, duration, cache hit or miss, and pages read.
|
|
20
|
+
|
|
21
|
+
### Python client
|
|
22
|
+
- Retries transient failures (connection failures, `429`, `503`, `504`, and `502` from a proxy) with exponential backoff, honoring `Retry-After`. Set `max_retries` (default 2); `0` turns retries off.
|
|
23
|
+
- New `RateLimitError` with `retry_after`. A `502` that doesn't come from OpenScour is now an `APIStatusError` instead of `NoResultsError`.
|
|
24
|
+
|
|
25
|
+
### MCP server
|
|
26
|
+
- Reuses one client, and its connections, for all tool calls.
|
|
27
|
+
|
|
28
|
+
### Security
|
|
29
|
+
- The user agent follows the package version (`OpenScour/0.3.0`) instead of a fixed `OpenScour/0.2`.
|
|
30
|
+
- API keys are compared in constant time.
|
|
31
|
+
- robots.txt downloads stop at 512 KB instead of reading the whole response first.
|
|
32
|
+
|
|
33
|
+
### Reliability and performance
|
|
34
|
+
- The robots.txt cache holds at most 4,096 sites, dropping the least recently used, and also caches sites that have no robots.txt.
|
|
35
|
+
- robots.txt lookups time out after 1 second instead of 2, so a slow site can't use up a basic search's 2-second budget.
|
|
36
|
+
|
|
37
|
+
## [0.2.0] - 2026-10-29
|
|
38
|
+
|
|
39
|
+
Security and reliability hardening (phase 1 of the enterprise roadmap).
|
|
40
|
+
|
|
41
|
+
### Security
|
|
42
|
+
- Server-side request forgery (SSRF) protection: pages are only fetched from public addresses, checked on the address actually connected to, on every redirect. Requests for cloud metadata, localhost, private ranges or hostnames resolving to them return a `blocked:` error. `ALLOW_PRIVATE_NETWORK_FETCHES` opts out for trusted internal deployments.
|
|
43
|
+
- OpenScour identifies itself honestly (`OpenScour/0.2` user agent) instead of imitating a browser, and follows robots.txt (`RESPECT_ROBOTS_TXT`).
|
|
44
|
+
- The API container runs as an unprivileged user with a read-only filesystem, no capabilities, `no-new-privileges` and a health check. SearXNG is pinned to a release. Docker Compose publishes ports on `127.0.0.1` only.
|
|
45
|
+
|
|
46
|
+
### Reliability and performance
|
|
47
|
+
- One page-download limit shared by all requests (`FETCH_CONCURRENCY`), instead of one per request.
|
|
48
|
+
- Concurrent requests for the same page share one download (request coalescing).
|
|
49
|
+
- Background fetches are capped (`MAX_INFLIGHT_FETCHES`); beyond the cap, searches use search snippets.
|
|
50
|
+
- Ranking runs off the event loop, so it no longer delays other requests.
|
|
51
|
+
- Extraction workers are replaced after `EXTRACT_MAX_TASKS_PER_CHILD` pages to keep memory flat.
|
|
52
|
+
- The search cache treats domain lists in any order as the same search.
|
|
53
|
+
|
|
54
|
+
### Ranking
|
|
55
|
+
- Tokenization handles any script: accents, Cyrillic, and Chinese, Japanese and Korean (as character pairs).
|
|
56
|
+
- The current year is computed per request, so freshness stays correct across New Year.
|
|
57
|
+
|
|
58
|
+
### Testing
|
|
59
|
+
- 35 new tests: SSRF guard (including redirects), robots.txt, the shared page fetcher, and the server endpoints.
|
|
60
|
+
|
|
61
|
+
## [0.1.0] - 2026-10-29
|
|
62
|
+
|
|
63
|
+
First release.
|
|
64
|
+
|
|
65
|
+
### Server
|
|
66
|
+
- `POST /search`: searches the web through a self-hosted SearXNG instance, with a DuckDuckGo fallback, and returns the most relevant passage from each result page.
|
|
67
|
+
- `POST /extract`: returns the clean text of up to 20 URLs, or only the passages that match a `query`.
|
|
68
|
+
- Answer-aware ranking: dates for *when*, numbers for *how many*, names for *who*, version numbers for *latest release* questions, and the current holder for *who is* questions.
|
|
69
|
+
- Topic searches require the query's named terms in each passage, favor recent content for *latest/new/recent* queries, and rank tables of contents below explanatory passages.
|
|
70
|
+
- Basic searches answer as soon as enough pages are ready, capped at 2 seconds; text extraction runs in parallel worker processes.
|
|
71
|
+
- Optional AI answers with Claude, through Amazon Bedrock or the Claude API.
|
|
72
|
+
- API keys, in-memory caching, and a Docker Compose setup.
|
|
73
|
+
|
|
74
|
+
### Python client
|
|
75
|
+
- `OpenScour` and `AsyncOpenScour` with `search()` and `extract()`, typed results and typed errors. Only depends on `httpx`.
|
|
76
|
+
|
|
77
|
+
### MCP server
|
|
78
|
+
- `openscour-mcp` gives AI agents read-only `search` and `extract` tools, with setup instructions for Claude Code, Kiro, Cursor, Claude Desktop and VS Code.
|
|
79
|
+
|
|
80
|
+
[0.3.1]: https://github.com/ivipinmishra/openscour/releases/tag/v0.3.1
|
|
81
|
+
[0.3.0]: https://github.com/ivipinmishra/openscour/releases/tag/v0.3.0
|
|
82
|
+
[0.2.0]: https://github.com/ivipinmishra/openscour/releases/tag/v0.2.0
|
|
83
|
+
[0.1.0]: https://github.com/ivipinmishra/openscour/releases/tag/v0.1.0
|
openscour-0.3.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ivipinmishra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|