Skip to main content
Glama
test_uniprot_client.py8.29 kB
from __future__ import annotations from typing import Any import httpx import pytest from uniprot_mcp.adapters import uniprot_client from uniprot_mcp.adapters.uniprot_client import FIELDS_SEQUENCE_MIN, UniProtClientError @pytest.mark.asyncio async def test_new_client_enables_redirects_and_trust_env(): async with uniprot_client.new_client() as client: assert client.follow_redirects is True assert client.trust_env is True timeout = client.timeout assert isinstance(timeout, httpx.Timeout) assert timeout.read == 20.0 @pytest.mark.asyncio async def test_fetch_entry_json_returns_empty_on_404(): def handler(request: httpx.Request) -> httpx.Response: return httpx.Response(404) async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL, ) as client: payload = await uniprot_client.fetch_entry_json(client, "NOPE") assert payload == {} @pytest.mark.asyncio async def test_fetch_entry_json_retries_then_succeeds(monkeypatch): attempts = {"count": 0} def handler(request: httpx.Request) -> httpx.Response: if "retry" in request.url.path and attempts["count"] == 0: attempts["count"] += 1 return httpx.Response(500) return httpx.Response(200, json={"primaryAccession": "retry"}) monkeypatch.setenv("UNIPROT_ENABLE_FIELDS", "1") async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL, ) as client: payload = await uniprot_client.fetch_entry_json(client, "retry") assert payload["primaryAccession"] == "retry" assert attempts["count"] == 1 @pytest.mark.asyncio async def test_fetch_entry_json_raises_on_unexpected_error(): def handler(request: httpx.Request) -> httpx.Response: return httpx.Response(400) async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: with pytest.raises(UniProtClientError): await uniprot_client.fetch_entry_json(client, "bad") @pytest.mark.asyncio async def test_start_id_mapping_extracts_job_id(): responses: dict[str, Any] = {"/idmapping/run": httpx.Response(200, json={"jobId": "abc123"})} def handler(request: httpx.Request) -> httpx.Response: return responses[request.url.path] async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: job_id = await uniprot_client.start_id_mapping( client, from_db="UniProtKB_AC-ID", to_db="Ensembl", ids=["P12345"] ) assert job_id == "abc123" @pytest.mark.asyncio async def test_get_mapping_results_returns_dict(): def handler(request: httpx.Request) -> httpx.Response: if request.url.path.startswith("/idmapping/results"): return httpx.Response(200, json={"results": []}) return httpx.Response(200, json={}) async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: status = await uniprot_client.get_mapping_status(client, "job") results = await uniprot_client.get_mapping_results(client, "job") assert status == {} assert results == {"results": []} @pytest.mark.asyncio async def test_fetch_entry_json_accepts_fields_and_version(monkeypatch): observed: dict[str, Any] = {} def handler(request: httpx.Request) -> httpx.Response: observed.update(request.url.params) return httpx.Response(200, json={"primaryAccession": "P12345"}) monkeypatch.delenv("UNIPROT_ENABLE_FIELDS", raising=False) async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: await uniprot_client.fetch_entry_json( client, "P12345", fields=["accession", "sequence"], version="last", ) assert observed["fields"] == "accession,sequence" assert observed["version"] == "last" @pytest.mark.asyncio async def test_search_json_supports_optional_parameters(monkeypatch): observed: dict[str, Any] = {} def handler(request: httpx.Request) -> httpx.Response: observed.update(request.url.params) return httpx.Response(200, json={"results": []}) monkeypatch.delenv("UNIPROT_ENABLE_FIELDS", raising=False) async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: await uniprot_client.search_json( client, query="kinase", size=25, reviewed_only=True, fields=["accession"], sort="accession desc", include_isoform=True, ) assert observed["fields"] == "accession" assert observed["sort"] == "accession desc" assert observed["includeIsoform"] == "true" assert "reviewed:true" in observed["query"] assert int(observed["size"]) == 25 @pytest.mark.asyncio async def test_search_json_clamps_size(monkeypatch): observed: dict[str, Any] = {} def handler(request: httpx.Request) -> httpx.Response: observed.update(request.url.params) return httpx.Response(200, json={"results": []}) async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: await uniprot_client.search_json(client, query="kinase", size=999) assert int(observed["size"]) == 500 @pytest.mark.asyncio async def test_fetch_sequence_json_uses_minimal_fields(monkeypatch): observed: dict[str, Any] = {} def handler(request: httpx.Request) -> httpx.Response: observed.update(request.url.params) return httpx.Response(200, json={"sequence": {"value": "AA", "length": 2}}) monkeypatch.setenv("UNIPROT_ENABLE_FIELDS", "1") async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: payload = await uniprot_client.fetch_sequence_json(client, "P12345") assert payload["sequence"]["value"] == "AA" assert observed["fields"] == FIELDS_SEQUENCE_MIN @pytest.mark.asyncio async def test_fetch_sequence_json_retries(monkeypatch): attempts = {"count": 0} def handler(request: httpx.Request) -> httpx.Response: if attempts["count"] == 0: attempts["count"] += 1 return httpx.Response(503) return httpx.Response(200, json={"sequence": {"value": "AA", "length": 2}}) monkeypatch.setenv("UNIPROT_ENABLE_FIELDS", "1") async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: payload = await uniprot_client.fetch_sequence_json(client, "P12345") assert payload["sequence"]["length"] == 2 assert attempts["count"] == 1 @pytest.mark.asyncio async def test_fetch_entry_flatfile_sets_headers_and_params(monkeypatch): observed: dict[str, Any] = {} def handler(request: httpx.Request) -> httpx.Response: observed["accept"] = request.headers.get("accept") observed["params"] = dict(request.url.params) return httpx.Response(200, text="ENTRY DATA") async with httpx.AsyncClient( transport=httpx.MockTransport(handler), base_url=uniprot_client.DEFAULT_BASE_URL ) as client: text = await uniprot_client.fetch_entry_flatfile(client, "P12345", "6") assert text == "ENTRY DATA" assert observed["accept"] == "text/plain;format=txt" assert observed["params"]["version"] == "6" assert observed["params"]["format"] == "txt" @pytest.mark.asyncio async def test_fetch_entry_flatfile_rejects_unknown_format(monkeypatch): async with httpx.AsyncClient( transport=httpx.MockTransport(lambda request: httpx.Response(200, text="ok")), base_url=uniprot_client.DEFAULT_BASE_URL, ) as client: with pytest.raises(ValueError): await uniprot_client.fetch_entry_flatfile(client, "P12345", "6", format="xml")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/josefdc/Uniprot-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server