Ollama Python library
This report summarizes scanner evidence for ollama/ollama-python, a Python project with 10,589 GitHub stars. SynthScan examined 6,967 lines of code across 51 source files, recording 153 pattern matches distributed across 12 syntactic categories. The legacy adjusted pattern signal is 26.1 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 102 finding(s).
Are imports declared and package/API names verified? 38 finding(s).
Are wrappers, guards, and repeated structures necessary? 108 finding(s).
Which changes need focused human review? 153 finding(s).
Run additional scans to build a history of the legacy pattern signal. Score changes are not a measure of AI adoption or code quality.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 153 distinct pattern matches across 12 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_utils.py | 8 | def test_function_to_tool_conversion(): | CODE |
| LOW | tests/test_utils.py | 31 | def test_function_with_no_args(): | CODE |
| LOW | tests/test_utils.py | 47 | def test_function_with_all_types(): | CODE |
| LOW | tests/test_utils.py | 116 | def test_function_docstring_parsing(): | CODE |
| LOW | tests/test_utils.py | 140 | def test_skewed_docstring_parsing(): | CODE |
| LOW | tests/test_utils.py | 160 | def test_function_with_no_docstring(): | CODE |
| LOW | tests/test_utils.py | 174 | def test_function_with_only_description(): | CODE |
| LOW | tests/test_utils.py | 184 | def only_description_with_args(x: int, y: int): | CODE |
| LOW | tests/test_utils.py | 203 | def test_function_with_yields(): | CODE |
| LOW | tests/test_utils.py | 222 | def test_function_with_no_types(): | CODE |
| LOW | tests/test_utils.py | 233 | def test_function_with_parentheses(): | CODE |
| LOW | tests/test_utils.py | 244 | def func_with_parentheses_and_args(a: int, b: int): | CODE |
| LOW | tests/test_systemone.py | 17 | async def test_systemone_wire_and_answers(variant, monkeypatch): | CODE |
| LOW | tests/test_systemone.py | 78 | async def test_systemone_http_errors(client_type, status, message): | CODE |
| LOW | tests/test_type_serialization.py | 10 | def test_image_serialization_bytes(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 29 | def test_image_serialization_plain_string(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 34 | def test_image_serialization_path(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 42 | def test_image_serialization_string_path(): | CODE |
| LOW | tests/test_type_serialization.py | 59 | def test_image_serialization_string_path_uppercase_extension(extension): | CODE |
| LOW | tests/test_type_serialization.py | 71 | def test_create_request_serialization(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 86 | def test_create_request_serialization_exclude_none_true(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 95 | def test_create_request_serialization_exclude_none_false(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 104 | def test_create_request_serialization_license_list(): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 111 | def test_think_model_defined_levels_serialization(level): | CODE |
| LOW⚡ | tests/test_type_serialization.py | 121 | def test_think_boolean_serialization(): | CODE |
| LOW⚡ | tests/test_client.py | 1374 | async def test_arbitrary_roles_accepted_in_message_request_async(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1382 | def test_client_web_search_requires_bearer_auth_header(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1391 | def test_client_web_fetch_requires_bearer_auth_header(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1414 | def test_client_web_search_with_env_api_key(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1422 | def test_client_web_fetch_with_env_api_key(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1430 | def test_client_web_search_with_explicit_bearer_header(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1438 | def test_client_web_fetch_with_explicit_bearer_header(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1446 | def test_client_bearer_header_from_env(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1453 | def test_client_explicit_bearer_header_overrides_env(monkeypatch: pytest.MonkeyPatch): | CODE |
| LOW⚡ | tests/test_client.py | 1475 | def test_client_context_manager(): | CODE |
| LOW⚡ | tests/test_client.py | 1484 | async def test_async_client_context_manager(): | CODE |
| LOW⚡ | tests/test_client.py | 1492 | def test_generate_think_annotation_matches_chat(): | CODE |
| LOW | tests/test_client.py | 65 | def test_client_chat_with_logprobs(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 194 | def test_client_chat_format_json(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 222 | def test_client_chat_format_pydantic(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 254 | async def test_async_client_chat_format_json(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 282 | async def test_async_client_chat_format_pydantic(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 336 | def test_client_generate_with_logprobs(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 370 | def test_client_generate_with_image_type(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 393 | def test_client_generate_with_invalid_image(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 410 | def test_client_generate_stream(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 445 | def test_client_generate_images(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 472 | def test_client_generate_format_json(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 495 | def test_client_generate_format_pydantic(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 522 | async def test_async_client_generate_format_json(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 545 | async def test_async_client_generate_format_pydantic(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 572 | def test_client_generate_image(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 600 | def test_client_generate_image_stream(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 656 | async def test_async_client_generate_image(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 778 | def test_client_create_with_blob(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 796 | def test_client_create_with_parameters_roundtrip(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 832 | def test_client_create_from_library(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 859 | def test_client_create_blob_exists(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 910 | async def test_async_client_chat_stream(httpserver: HTTPServer): | CODE |
| LOW | tests/test_client.py | 949 | async def test_async_client_chat_images(httpserver: HTTPServer): | CODE |
| 17 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/web_search_gpt_oss_helper.py | 1 | CODE | |
| LOW | examples/web-search-mcp.py | 16 | CODE | |
| LOW | ollama/__init__.py | 1 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/__init__.py | 2 | CODE | |
| LOW | ollama/_utils.py | 1 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_client.py | 738 | response = client.push('dummy') | CODE |
| HIGH | tests/test_client.py | 762 | response = client.push('dummy', stream=True) | CODE |
| HIGH | tests/test_client.py | 1124 | response = await client.push('dummy') | CODE |
| HIGH | tests/test_client.py | 1148 | response = await client.push('dummy', stream=True) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | ollama/_client.py | 206 | CODE | |
| LOW | ollama/_client.py | 230 | CODE | |
| LOW | ollama/_client.py | 253 | CODE | |
| LOW | ollama/_client.py | 313 | CODE | |
| LOW | ollama/_client.py | 329 | CODE | |
| LOW | ollama/_client.py | 344 | CODE | |
| LOW | ollama/_client.py | 563 | CODE | |
| LOW | ollama/_client.py | 580 | CODE | |
| LOW | ollama/_client.py | 596 | CODE | |
| LOW | ollama/_client.py | 862 | CODE | |
| LOW | ollama/_client.py | 886 | CODE | |
| LOW | ollama/_client.py | 909 | CODE | |
| LOW | ollama/_client.py | 968 | CODE | |
| LOW | ollama/_client.py | 984 | CODE | |
| LOW | ollama/_client.py | 999 | CODE | |
| LOW | ollama/_client.py | 1219 | CODE | |
| LOW | ollama/_client.py | 1236 | CODE | |
| LOW | ollama/_client.py | 1252 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | ollama/_types.py | 173 | except Exception: | CODE |
| HIGH | ollama/_client.py | 1474 | except ValueError: | CODE |
| HIGH | ollama/_client.py | 1388 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | examples/structured-outputs-image.py | 9 | # Define the schema for image objects | COMMENT |
| MEDIUM | examples/async-structured-outputs.py | 8 | # Define the schema for the response | COMMENT |
| MEDIUM | examples/structured-outputs.py | 6 | # Define the schema for the response | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/web_search_gpt_oss_helper.py | 67 | except Exception: | CODE |
| LOW | examples/web-search-gpt-oss.py | 92 | except Exception as e: | CODE |
| LOW | examples/web-search-mcp.py | 28 | except Exception: | CODE |
| LOW | ollama/_types.py | 173 | except Exception: | CODE |
| LOW | ollama/_types.py | 185 | except Exception: | CODE |
| MEDIUM | ollama/_client.py | 141 | def _request_raw(self, *args, **kwargs): | CODE |
| LOW | ollama/_client.py | 1388 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | README.md | 101 | export OLLAMA_API_KEY=your_api_key | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | ollama/_client.py | 702 | Performs a web search Args: query: The query to search for max_results: The maximum number of resu | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/web_search_gpt_oss_helper.py | 81 | def set_data(self, data: BrowserStateData) -> None: | CODE |
| LOW | examples/web_search_gpt_oss_helper.py | 97 | def set_client(self, client: Client) -> None: | CODE |
| LOW | ollama/__init__.py | 34 | __all__ = [ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/web_search_gpt_oss_helper.py | 124 | CODE | |
| LOW | ollama/_client.py | 178 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/structured-outputs-image.py | 45 | options={'temperature': 0}, # Set temperature to 0 for more deterministic output | CODE |