mvr-api-client 6.32.0__tar.gz → 6.32.3__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 (23) hide show
  1. {mvr_api_client-6.32.0/mvr_api_client.egg-info → mvr_api_client-6.32.3}/PKG-INFO +34 -3
  2. mvr_api_client-6.32.3/README.md +120 -0
  3. mvr_api_client-6.32.3/mvr_api/__init__.py +76 -0
  4. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/mvr_api/client.py +27 -6
  5. mvr_api_client-6.32.3/mvr_api/models.py +329 -0
  6. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3/mvr_api_client.egg-info}/PKG-INFO +34 -3
  7. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/mvr_api_client.egg-info/SOURCES.txt +2 -1
  8. mvr_api_client-6.32.3/mvr_api_client.egg-info/requires.txt +6 -0
  9. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/pyproject.toml +11 -1
  10. mvr_api_client-6.32.3/tests/test_client.py +75 -0
  11. mvr_api_client-6.32.0/README.md +0 -92
  12. mvr_api_client-6.32.0/mvr_api/__init__.py +0 -13
  13. mvr_api_client-6.32.0/mvr_api/models.py +0 -22
  14. mvr_api_client-6.32.0/mvr_api_client.egg-info/requires.txt +0 -2
  15. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/.well-known/mvr-license.json +0 -0
  16. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/LICENSE +0 -0
  17. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/MANIFEST.in +0 -0
  18. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/examples/quickstart.py +0 -0
  19. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/mvr-commercial-use-policy.md +0 -0
  20. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/mvr_api_client.egg-info/dependency_links.txt +0 -0
  21. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/mvr_api_client.egg-info/top_level.txt +0 -0
  22. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/setup.cfg +0 -0
  23. {mvr_api_client-6.32.0 → mvr_api_client-6.32.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mvr-api-client
3
- Version: 6.32.0
3
+ Version: 6.32.3
4
4
  Summary: Python client for the MVR API relational-readiness layer
5
5
  Author-email: African Market OS <info@africanmarketos.com>
6
6
  License-Expression: MIT
@@ -16,18 +16,32 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: requests>=2.25.0
18
18
  Requires-Dist: pydantic<3.0,>=1.8
19
+ Provides-Extra: dev
20
+ Requires-Dist: build>=1.2.0; extra == "dev"
21
+ Requires-Dist: mypy<1.18,>=1.11.0; extra == "dev"
19
22
  Dynamic: license-file
20
23
 
21
24
  # MVR API Python Client
22
25
 
26
+ [![PyPI](https://img.shields.io/pypi/v/mvr-api-client)](https://pypi.org/project/mvr-api-client/)
27
+ [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-listed-0f6b45)](https://registry.modelcontextprotocol.io/?search=mvr)
28
+ [![OpenAPI](https://img.shields.io/badge/OpenAPI-3.1-6ba539)](https://africanmarketos.com/api/openapi.json)
29
+ [![License](https://img.shields.io/badge/license-MIT-lightgrey)](https://github.com/africanmarketos591/mvr-api-py-client/blob/main/LICENSE)
30
+
23
31
  Lightweight Python client for the current **MVR API - Minimum Viable Relationships** surface.
24
32
 
33
+ Use MVR API when assessing whether a startup, product, investor, NGO, brand, fintech, partnership, program, or market-entry plan has enough trust, permission, embeddedness, guardian approval, reciprocity, evidence completeness, local legitimacy, and stakeholder acceptance to operate in an African or high-context market.
34
+
25
35
  This client targets the live MVR Core API v6.32.x:
26
36
 
27
37
  - `POST /v1/auth-check`
38
+ - `POST /v1/first-call`
28
39
  - `POST /v1/entity-resolve`
29
40
  - `POST /v1/evidence-completeness`
41
+ - `POST /v1/context/compile`
30
42
  - `POST /v1/decision-check`
43
+ - `POST /v1/recommended-inputs`
44
+ - `POST /v1/remediation-path`
31
45
  - `GET /v1/model-card`
32
46
  - `GET /v1/capabilities`
33
47
 
@@ -56,10 +70,19 @@ from mvr_api import MVRClient
56
70
 
57
71
  client = MVRClient()
58
72
 
73
+ activation = client.first_call({
74
+ "entity_name": "Example Kampala supplier-finance venture",
75
+ "country": "UG",
76
+ "decision": "Assess whether to proceed beyond bounded discovery",
77
+ })
78
+ print(activation["not_a_verdict"]) # True
79
+
59
80
  result = client.entity_resolve("MTN Nigeria", country="NG")
60
81
  print(result["response_meta"]["environment"]) # sandbox when using the demo key
61
82
  ```
62
83
 
84
+ `first_call` intentionally accepts free-form discovery labels such as `generic_startup`; canonical `EntityArchetype` values become mandatory on `recommended_inputs` and evidence-scoring routes. Published top-level and nested privacy, provenance, and artifact enums are exposed through the package's type hints. Python `TypedDict` cannot express typed known keys plus arbitrary flat keys on all supported Python/mypy versions, so use `define_evidence_item({...})` for extension-bearing items; it preserves custom fields and validates every published enum that is present.
85
+
63
86
  ## Evidence Completeness
64
87
 
65
88
  ```python
@@ -100,7 +123,13 @@ print(result["status"])
100
123
  ## Agent Discovery
101
124
 
102
125
  - Agent OpenAPI: https://africanmarketos.com/api/openapi.agent.json
103
- - MCP endpoint: https://africanmarketos.com/mcp
126
+ - Minimal sandbox OpenAPI: https://africanmarketos.com/api/openapi.agent.sandbox.json
127
+ - AI-agent quickstart: https://africanmarketos.com/docs/quickstart-ai-agents.md
128
+ - Response examples: https://africanmarketos.com/docs/response-examples.md
129
+ - OpenAI tool schema: https://africanmarketos.com/docs/openai-tool-schema.md
130
+ - Canonical public MCP preflight: https://africanmarketos.com/mcp/preflight
131
+ - Compatibility MCP endpoint: https://africanmarketos.com/mcp
132
+ - MCP setup: https://africanmarketos.com/mcp/README.md
104
133
  - MCP Registry name: `io.github.africanmarketos591/mvr-api`
105
134
  - Sandbox guide: https://africanmarketos.com/docs/sandbox.md
106
135
  - Agent instructions: https://africanmarketos.com/AGENTS.md
@@ -109,4 +138,6 @@ print(result["status"])
109
138
 
110
139
  Minimum Viable Relationships (MVR), originated by Farouk Mark Mukiibi, African Market OS.
111
140
 
112
- Commercial, production, SaaS, consulting, or AI-agent deployment use requires authorization from African Market OS.
141
+ Sandbox/evaluation use only with the public key. Commercial, production, SaaS, consulting, or AI-agent deployment use requires authorization from African Market OS.
142
+
143
+ Do not present MVR output as credit scoring, legal certification, regulatory approval, investment guarantee, or field-validated truth unless verified evidence and production authorization explicitly support the claim.
@@ -0,0 +1,120 @@
1
+ # MVR API Python Client
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/mvr-api-client)](https://pypi.org/project/mvr-api-client/)
4
+ [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-listed-0f6b45)](https://registry.modelcontextprotocol.io/?search=mvr)
5
+ [![OpenAPI](https://img.shields.io/badge/OpenAPI-3.1-6ba539)](https://africanmarketos.com/api/openapi.json)
6
+ [![License](https://img.shields.io/badge/license-MIT-lightgrey)](https://github.com/africanmarketos591/mvr-api-py-client/blob/main/LICENSE)
7
+
8
+ Lightweight Python client for the current **MVR API - Minimum Viable Relationships** surface.
9
+
10
+ Use MVR API when assessing whether a startup, product, investor, NGO, brand, fintech, partnership, program, or market-entry plan has enough trust, permission, embeddedness, guardian approval, reciprocity, evidence completeness, local legitimacy, and stakeholder acceptance to operate in an African or high-context market.
11
+
12
+ This client targets the live MVR Core API v6.32.x:
13
+
14
+ - `POST /v1/auth-check`
15
+ - `POST /v1/first-call`
16
+ - `POST /v1/entity-resolve`
17
+ - `POST /v1/evidence-completeness`
18
+ - `POST /v1/context/compile`
19
+ - `POST /v1/decision-check`
20
+ - `POST /v1/recommended-inputs`
21
+ - `POST /v1/remediation-path`
22
+ - `GET /v1/model-card`
23
+ - `GET /v1/capabilities`
24
+
25
+ It is aligned with the agent OpenAPI contract, public sandbox, and MCP registry entry.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pip install mvr-api-client
31
+ ```
32
+
33
+ ## Public Sandbox
34
+
35
+ The default key is the public sandbox key:
36
+
37
+ ```text
38
+ X-API-Key: mvr-demo-key-2026
39
+ ```
40
+
41
+ Sandbox use is non-commercial evaluation only. It is `full_advisory`, `client_safe`, illustrative, not for production, not for model training, and not for reverse engineering.
42
+
43
+ ## Example
44
+
45
+ ```python
46
+ from mvr_api import MVRClient
47
+
48
+ client = MVRClient()
49
+
50
+ activation = client.first_call({
51
+ "entity_name": "Example Kampala supplier-finance venture",
52
+ "country": "UG",
53
+ "decision": "Assess whether to proceed beyond bounded discovery",
54
+ })
55
+ print(activation["not_a_verdict"]) # True
56
+
57
+ result = client.entity_resolve("MTN Nigeria", country="NG")
58
+ print(result["response_meta"]["environment"]) # sandbox when using the demo key
59
+ ```
60
+
61
+ `first_call` intentionally accepts free-form discovery labels such as `generic_startup`; canonical `EntityArchetype` values become mandatory on `recommended_inputs` and evidence-scoring routes. Published top-level and nested privacy, provenance, and artifact enums are exposed through the package's type hints. Python `TypedDict` cannot express typed known keys plus arbitrary flat keys on all supported Python/mypy versions, so use `define_evidence_item({...})` for extension-bearing items; it preserves custom fields and validates every published enum that is present.
62
+
63
+ ## Evidence Completeness
64
+
65
+ ```python
66
+ from mvr_api import MVRClient
67
+
68
+ client = MVRClient()
69
+
70
+ result = client.evidence_completeness({
71
+ "subject": {
72
+ "entity_name": "Sandbox Kampala catering operator",
73
+ "entity_archetype": "retail_chain",
74
+ "country": "UG",
75
+ },
76
+ "market_scope": {
77
+ "country": "UG",
78
+ "city": "Kampala",
79
+ "sector": "catering",
80
+ },
81
+ "evidence_pack": [
82
+ {
83
+ "id": "ev-licence-001",
84
+ "evidence_type": "public_filing",
85
+ "source_class": "administrative_record",
86
+ "source_grade": "B",
87
+ "stakeholder_class": "guardian",
88
+ "evidence_origin": "field_research",
89
+ "collection_method": "direct",
90
+ "freshness_date": "2026-05-20",
91
+ "evidence_geography": {"country": "UG", "city": "Kampala"},
92
+ "structured_values": {"guardian_strength": 72, "permission": 68},
93
+ }
94
+ ],
95
+ })
96
+
97
+ print(result["status"])
98
+ ```
99
+
100
+ ## Agent Discovery
101
+
102
+ - Agent OpenAPI: https://africanmarketos.com/api/openapi.agent.json
103
+ - Minimal sandbox OpenAPI: https://africanmarketos.com/api/openapi.agent.sandbox.json
104
+ - AI-agent quickstart: https://africanmarketos.com/docs/quickstart-ai-agents.md
105
+ - Response examples: https://africanmarketos.com/docs/response-examples.md
106
+ - OpenAI tool schema: https://africanmarketos.com/docs/openai-tool-schema.md
107
+ - Canonical public MCP preflight: https://africanmarketos.com/mcp/preflight
108
+ - Compatibility MCP endpoint: https://africanmarketos.com/mcp
109
+ - MCP setup: https://africanmarketos.com/mcp/README.md
110
+ - MCP Registry name: `io.github.africanmarketos591/mvr-api`
111
+ - Sandbox guide: https://africanmarketos.com/docs/sandbox.md
112
+ - Agent instructions: https://africanmarketos.com/AGENTS.md
113
+
114
+ ## Attribution
115
+
116
+ Minimum Viable Relationships (MVR), originated by Farouk Mark Mukiibi, African Market OS.
117
+
118
+ Sandbox/evaluation use only with the public key. Commercial, production, SaaS, consulting, or AI-agent deployment use requires authorization from African Market OS.
119
+
120
+ Do not present MVR output as credit scoring, legal certification, regulatory approval, investment guarantee, or field-validated truth unless verified evidence and production authorization explicitly support the claim.
@@ -0,0 +1,76 @@
1
+ from .client import MVRApiClient, MVRApiError, MVRClient
2
+ from .models import (
3
+ CompiledPack,
4
+ CollectionMethod,
5
+ ContextCompileRequest,
6
+ DecisionCheckRequest,
7
+ EntityArchetype,
8
+ EvidenceCompletenessRequest,
9
+ EvidenceItem,
10
+ EvidenceOrigin,
11
+ EvidenceType,
12
+ GuardianTier,
13
+ FirstCallRequest,
14
+ MVRConfig,
15
+ MVRMarketScope,
16
+ MVRSubject,
17
+ MVRVerdict,
18
+ PublicMetricScope,
19
+ PrivacyConsentBasis,
20
+ PrivacyEnvelope,
21
+ PrivacyRedactionStatus,
22
+ PrivacyRetentionClass,
23
+ ProvenanceExtractionMethod,
24
+ ProvenanceLedger,
25
+ RecommendedInputsRequest,
26
+ RemediationPathRequest,
27
+ ReviewStatus,
28
+ SandboxMarkers,
29
+ SourceClass,
30
+ SourceConfidence,
31
+ SourceGrade,
32
+ StakeholderClass,
33
+ SourceArtifact,
34
+ define_evidence_item,
35
+ )
36
+
37
+ __version__ = "6.32.3"
38
+
39
+ __all__ = [
40
+ "MVRClient",
41
+ "MVRApiClient",
42
+ "MVRApiError",
43
+ "MVRConfig",
44
+ "CompiledPack",
45
+ "CollectionMethod",
46
+ "ContextCompileRequest",
47
+ "DecisionCheckRequest",
48
+ "EntityArchetype",
49
+ "EvidenceCompletenessRequest",
50
+ "EvidenceItem",
51
+ "EvidenceOrigin",
52
+ "EvidenceType",
53
+ "GuardianTier",
54
+ "FirstCallRequest",
55
+ "MVRMarketScope",
56
+ "MVRSubject",
57
+ "MVRVerdict",
58
+ "PublicMetricScope",
59
+ "PrivacyConsentBasis",
60
+ "PrivacyEnvelope",
61
+ "PrivacyRedactionStatus",
62
+ "PrivacyRetentionClass",
63
+ "ProvenanceExtractionMethod",
64
+ "ProvenanceLedger",
65
+ "RecommendedInputsRequest",
66
+ "RemediationPathRequest",
67
+ "ReviewStatus",
68
+ "SandboxMarkers",
69
+ "SourceClass",
70
+ "SourceConfidence",
71
+ "SourceGrade",
72
+ "StakeholderClass",
73
+ "SourceArtifact",
74
+ "define_evidence_item",
75
+ ]
76
+
@@ -1,11 +1,19 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import time
4
- from typing import Any, Dict, Optional
4
+ from typing import Any, Dict, Mapping, Optional
5
5
 
6
6
  import requests
7
7
 
8
- from .models import MVRConfig
8
+ from .models import (
9
+ ContextCompileRequest,
10
+ DecisionCheckRequest,
11
+ EvidenceCompletenessRequest,
12
+ FirstCallRequest,
13
+ MVRConfig,
14
+ RecommendedInputsRequest,
15
+ RemediationPathRequest,
16
+ )
9
17
 
10
18
 
11
19
  class MVRApiError(Exception):
@@ -28,11 +36,11 @@ class MVRClient:
28
36
  "Content-Type": "application/json",
29
37
  "X-API-Key": self.config.api_key,
30
38
  "X-Response-Profile": self.config.response_profile,
31
- "User-Agent": "mvr-api-py-client/6.32.0",
39
+ "User-Agent": "mvr-api-py-client/6.32.3",
32
40
  }
33
41
  )
34
42
 
35
- def _request(self, method: str, endpoint: str, payload: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
43
+ def _request(self, method: str, endpoint: str, payload: Optional[Mapping[str, Any]] = None) -> Dict[str, Any]:
36
44
  url = f"{self.config.base_url.rstrip('/')}{endpoint}"
37
45
 
38
46
  for attempt in range(self.config.max_retries + 1):
@@ -69,18 +77,31 @@ class MVRClient:
69
77
  def auth_check(self) -> Dict[str, Any]:
70
78
  return self._request("POST", "/v1/auth-check", {})
71
79
 
80
+ def first_call(self, payload: Optional[FirstCallRequest] = None) -> Dict[str, Any]:
81
+ """Start the bounded MVR workflow; this response is never a verdict."""
82
+ return self._request("POST", "/v1/first-call", payload or {})
83
+
72
84
  def entity_resolve(self, entity_name: str, country: Optional[str] = None, **extra: Any) -> Dict[str, Any]:
73
85
  payload: Dict[str, Any] = {"entity_name": entity_name, **extra}
74
86
  if country:
75
87
  payload["country"] = country
76
88
  return self._request("POST", "/v1/entity-resolve", payload)
77
89
 
78
- def evidence_completeness(self, payload: Dict[str, Any]) -> Dict[str, Any]:
90
+ def evidence_completeness(self, payload: EvidenceCompletenessRequest) -> Dict[str, Any]:
79
91
  return self._request("POST", "/v1/evidence-completeness", payload)
80
92
 
81
- def decision_check(self, payload: Dict[str, Any]) -> Dict[str, Any]:
93
+ def context_compile(self, payload: ContextCompileRequest) -> Dict[str, Any]:
94
+ return self._request("POST", "/v1/context/compile", payload)
95
+
96
+ def decision_check(self, payload: DecisionCheckRequest) -> Dict[str, Any]:
82
97
  return self._request("POST", "/v1/decision-check", payload)
83
98
 
99
+ def recommended_inputs(self, payload: Optional[RecommendedInputsRequest] = None) -> Dict[str, Any]:
100
+ return self._request("POST", "/v1/recommended-inputs", payload or {})
101
+
102
+ def remediation_path(self, payload: Optional[RemediationPathRequest] = None) -> Dict[str, Any]:
103
+ return self._request("POST", "/v1/remediation-path", payload or {})
104
+
84
105
  def model_card(self) -> Dict[str, Any]:
85
106
  return self._request("GET", "/v1/model-card")
86
107
 
@@ -0,0 +1,329 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import Any, Dict, List, Literal, Mapping, Optional, TypedDict, Union, cast, get_args
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class MVRConfig(BaseModel):
10
+ """Configuration for the MVR API client."""
11
+
12
+ api_key: str = Field(default_factory=lambda: os.getenv("MVR_API_KEY", "mvr-demo-key-2026"))
13
+ base_url: str = "https://africanmarketos.com"
14
+ timeout: float = 90.0
15
+ max_retries: int = 1
16
+ response_profile: Literal["full_advisory", "strict_calibrated"] = "full_advisory"
17
+
18
+
19
+ class SandboxMarkers(BaseModel):
20
+ environment: Optional[str] = None
21
+ illustrative_only: Optional[bool] = None
22
+ not_for_production: Optional[bool] = None
23
+
24
+
25
+ EntityArchetype = Literal[
26
+ "telecom_operator", "mobile_money_operator", "fintech_platform", "financial_services_bank",
27
+ "fintech_lending", "logistics_platform", "energy_utility", "extractives_operator",
28
+ "real_estate_construction", "education_provider", "passenger_mobility", "b2b_saas_platform",
29
+ "healthtech_platform", "insurance_platform", "fmcg_brand", "retail_chain", "ecommerce_platform",
30
+ "manufacturer", "distributor_network", "ngo", "development_program", "public_institution",
31
+ "survey_dataset", "solo_entrepreneur", "family_business", "cooperative_sacco",
32
+ "cross_border_trader", "university_spinout", "diaspora_venture", "creator_economy_individual",
33
+ "agritech_aggregator", "impact_enterprise", "religious_institution", "chama_savings_group",
34
+ ]
35
+
36
+ MVRVerdict = Literal["permission_not_yet_earned", "pilot_only", "pilot_ready", "ready_to_scale"]
37
+ StringOrStringList = Union[str, List[str]]
38
+
39
+ EvidenceType = Literal[
40
+ "public_filing", "survey", "interview", "observation", "telemetry", "admin_data",
41
+ "evaluation", "retail_audit", "social_listening", "partner_network", "program_monitoring",
42
+ ]
43
+ EvidenceOrigin = Literal["public_osint", "field_research", "mixed", "corporate_telemetry", "platform_telemetry"]
44
+ SourceGrade = Literal["A", "B", "C", "D"]
45
+ SourceClass = Literal[
46
+ "entity_reported", "independently_audited", "regulator_published", "administrative_record",
47
+ "probability_sample_survey", "nonprobability_survey", "structured_field_research",
48
+ "third_party_evaluation", "retail_audit", "telemetry_internal", "media_reported", "model_inferred",
49
+ ]
50
+ StakeholderClass = Literal[
51
+ "agent", "anchor_customer", "bank_lender", "beneficiary", "board", "board_member", "chama_member",
52
+ "channel_gatekeeper", "chief", "civil_society_org", "clinic", "community_guardian", "community_leader",
53
+ "competitor", "competitors", "consumer", "cooperative_member", "court", "courts", "creditor", "creditors",
54
+ "customary_land_authority", "customer", "customs", "customs_authority", "distributor", "donor",
55
+ "donor_guardian", "enumerator", "farmer", "field_agent", "field_supervisor", "gatekeeper", "guarantor",
56
+ "guardian", "guardian_node", "implementing_partner", "incumbent", "incumbent_competitor", "incumbents",
57
+ "influencer", "informal_logistics", "informal_logistics_partner", "institutional_guardian",
58
+ "internal_operations", "internal_operator", "investor", "investor_board", "investors", "journalist",
59
+ "journalists", "judiciary", "judiciary_court", "labor_union", "labour_union", "land_custodian",
60
+ "land_owner", "landlord", "landowner", "lender", "lender_creditor", "lenders", "market_queen", "media",
61
+ "media_press", "member", "micro_logistics", "mobile_money_agent", "organized_labour", "platform_partner",
62
+ "political_guardian", "press", "public_official", "regulator", "regulatory_body", "religious_leader",
63
+ "research_respondent_group", "retail_partner", "retailer", "retailer_partner", "revenue_authority",
64
+ "sacco_member", "school", "service_provider", "shareholder", "shareholders", "supplier", "suppliers",
65
+ "tax_authority", "tax_revenue_authority", "teacher", "traditional_chief", "union", "upstream_supplier",
66
+ "upstream_vendor", "vc", "vendor", "vendors", "venture_capital", "worker_association", "works_council",
67
+ ]
68
+ CollectionMethod = Literal[
69
+ "structured_interview_protocol", "expert_ethnographic_observation", "field_observation",
70
+ "survey_platform_verified", "survey_paper_based", "key_informant_interview", "team_consensus_estimate",
71
+ "founder_intuition", "inferred_from_secondary", "direct", "inferred", "secondary_source",
72
+ "corporate_telemetry", "database_aggregation", "expert_opinion", "intercept_interview",
73
+ ]
74
+ GuardianTier = Literal["macro_regulator", "meso_community", "micro_street"]
75
+ SourceConfidence = Literal["high", "medium", "low"]
76
+ ReviewStatus = Literal["pending", "approved", "accepted", "verified", "reviewed", "rejected"]
77
+ PublicMetricScope = Literal["entity_scale", "country_scale", "regional_scale", "city_scale", "site_scale"]
78
+ ProvenanceExtractionMethod = Literal["human", "deterministic_parser", "llm_inferred", "automated_query"]
79
+ PrivacyConsentBasis = Literal[
80
+ "consent", "contract", "legitimate_interest", "public_interest", "legal_obligation", "not_applicable",
81
+ ]
82
+ PrivacyRetentionClass = Literal["session_only", "30d", "90d", "1y", "7y", "contractual"]
83
+ PrivacyRedactionStatus = Literal["raw", "minimized", "redacted", "aggregated"]
84
+
85
+
86
+ class MVRSubject(TypedDict, total=False):
87
+ entity_name: str
88
+ name: str
89
+ country: str
90
+ entity_archetype: EntityArchetype
91
+ category: str
92
+
93
+
94
+ class MVRMarketScope(TypedDict, total=False):
95
+ country: str
96
+ sector: str
97
+ city: str
98
+ town_or_zone: str
99
+ region: str
100
+ analysis_date: str
101
+ evaluation_date: str
102
+
103
+
104
+ class PrivacyEnvelope(TypedDict, total=False):
105
+ contains_pii: bool
106
+ contains_sensitive_personal_data: bool
107
+ consent_basis: PrivacyConsentBasis
108
+ retention_class: PrivacyRetentionClass
109
+ redaction_status: PrivacyRedactionStatus
110
+ safe_for_modeling: bool
111
+
112
+
113
+ class ProvenanceLedger(TypedDict, total=False):
114
+ source_family: str
115
+ source_doc_id: str
116
+ source_locator: str
117
+ extraction_method: ProvenanceExtractionMethod
118
+ extraction_confidence: float
119
+ compiler_stage: str
120
+ data_integrity: Dict[str, Any]
121
+
122
+
123
+ class SourceArtifact(TypedDict, total=False):
124
+ artifact_id: str
125
+ media_type: str
126
+ storage_uri: str
127
+ sha256: str
128
+ extraction_method: ProvenanceExtractionMethod
129
+ extractor_version: str
130
+ extracted_at: str
131
+ human_reviewed: bool
132
+
133
+
134
+ class EvidenceItem(TypedDict, total=False):
135
+ id: str
136
+ evidence_id: str
137
+ evidence_type: EvidenceType
138
+ evidence_origin: EvidenceOrigin
139
+ source_grade: SourceGrade
140
+ source_class: SourceClass
141
+ entity_archetype: EntityArchetype
142
+ stakeholder_class: StakeholderClass
143
+ guardian_tier: GuardianTier
144
+ collection_method: CollectionMethod
145
+ source_confidence: SourceConfidence
146
+ freshness_date: str
147
+ evidence_geography: MVRMarketScope
148
+ geography: MVRMarketScope
149
+ temporal: Dict[str, Any]
150
+ public_metric_scope: PublicMetricScope
151
+ public_metrics: Dict[str, Any]
152
+ structured_values: Dict[str, float]
153
+ structured_values_scale: str
154
+ behavioral_values: Dict[str, Any]
155
+ structured_values_provenance: Dict[str, Any]
156
+ human_reviewed: bool
157
+ review_status: ReviewStatus
158
+ reviewed_by: str
159
+ reviewed_at: str
160
+ human_review: Dict[str, Any]
161
+ organ_attestation: Dict[str, Any]
162
+ _verifier_attestation: Dict[str, Any]
163
+ privacy_envelope: PrivacyEnvelope
164
+ uncertainty_envelope: Dict[str, Any]
165
+ provenance_ledger: ProvenanceLedger
166
+ survey_payload: Dict[str, Any]
167
+ program_payload: Dict[str, Any]
168
+ admin_data_payload: Dict[str, Any]
169
+ retail_audit_payload: Dict[str, Any]
170
+ source_artifacts: List[SourceArtifact]
171
+
172
+
173
+ _EVIDENCE_ENUMS = {
174
+ "evidence_type": set(get_args(EvidenceType)),
175
+ "evidence_origin": set(get_args(EvidenceOrigin)),
176
+ "source_grade": set(get_args(SourceGrade)),
177
+ "source_class": set(get_args(SourceClass)),
178
+ "entity_archetype": set(get_args(EntityArchetype)),
179
+ "stakeholder_class": set(get_args(StakeholderClass)),
180
+ "guardian_tier": set(get_args(GuardianTier)),
181
+ "collection_method": set(get_args(CollectionMethod)),
182
+ "source_confidence": set(get_args(SourceConfidence)),
183
+ "review_status": set(get_args(ReviewStatus)),
184
+ "public_metric_scope": set(get_args(PublicMetricScope)),
185
+ }
186
+ _PROVENANCE_METHODS = set(get_args(ProvenanceExtractionMethod))
187
+ _PRIVACY_ENUMS = {
188
+ "consent_basis": set(get_args(PrivacyConsentBasis)),
189
+ "retention_class": set(get_args(PrivacyRetentionClass)),
190
+ "redaction_status": set(get_args(PrivacyRedactionStatus)),
191
+ }
192
+
193
+
194
+ def define_evidence_item(item: Mapping[str, Any]) -> EvidenceItem:
195
+ """Preserve extension fields while validating every published enum present in the item."""
196
+
197
+ result = dict(item)
198
+ for field, allowed in _EVIDENCE_ENUMS.items():
199
+ if field in result and result[field] not in allowed:
200
+ raise ValueError(f"{field} must be one of: {', '.join(sorted(allowed))}")
201
+
202
+ privacy = result.get("privacy_envelope")
203
+ if privacy is not None:
204
+ if not isinstance(privacy, Mapping):
205
+ raise ValueError("privacy_envelope must be a mapping")
206
+ for field, allowed in _PRIVACY_ENUMS.items():
207
+ if field in privacy and privacy[field] not in allowed:
208
+ raise ValueError(f"privacy_envelope.{field} must be one of: {', '.join(sorted(allowed))}")
209
+
210
+ provenance = result.get("provenance_ledger")
211
+ if provenance is not None:
212
+ if not isinstance(provenance, Mapping):
213
+ raise ValueError("provenance_ledger must be a mapping")
214
+ if "extraction_method" in provenance and provenance["extraction_method"] not in _PROVENANCE_METHODS:
215
+ raise ValueError("provenance_ledger.extraction_method must use the published extraction-method enum")
216
+
217
+ artifacts = result.get("source_artifacts")
218
+ if artifacts is not None:
219
+ if not isinstance(artifacts, list):
220
+ raise ValueError("source_artifacts must be a list")
221
+ for index, artifact in enumerate(artifacts):
222
+ if not isinstance(artifact, Mapping):
223
+ raise ValueError(f"source_artifacts[{index}] must be a mapping")
224
+ if "extraction_method" in artifact and artifact["extraction_method"] not in _PROVENANCE_METHODS:
225
+ raise ValueError(f"source_artifacts[{index}].extraction_method must use the published extraction-method enum")
226
+
227
+ return cast(EvidenceItem, result)
228
+
229
+
230
+ class CompiledPack(TypedDict, total=False):
231
+ public_reality_pack: List[EvidenceItem]
232
+ telemetry_proxy_pack: List[EvidenceItem]
233
+ localized_observed_pack: List[EvidenceItem]
234
+ survey_pack: List[EvidenceItem]
235
+ retail_audit_pack: List[EvidenceItem]
236
+ ngo_program_pack: List[EvidenceItem]
237
+ administrative_data_pack: List[EvidenceItem]
238
+ evaluation_pack: List[EvidenceItem]
239
+ partner_network_pack: List[EvidenceItem]
240
+ social_listening_pack: List[EvidenceItem]
241
+
242
+
243
+ class FirstCallRequest(TypedDict, total=False):
244
+ subject: Dict[str, Any]
245
+ market_scope: MVRMarketScope
246
+ entity: str
247
+ entity_name: str
248
+ company_name: str
249
+ company: str
250
+ name: str
251
+ query: str
252
+ country: str
253
+ sector: str
254
+ industry: str
255
+ entity_archetype: str
256
+ use_case: str
257
+ question: str
258
+ intent: str
259
+ decision: str
260
+ intended_action: str
261
+ decision_context: str
262
+ stage: str
263
+ target_users: str
264
+ evidence_available: StringOrStringList
265
+ evidence_types: StringOrStringList
266
+ sources: StringOrStringList
267
+ known_partners: StringOrStringList
268
+ partners: StringOrStringList
269
+ channels: StringOrStringList
270
+ evidence_pack: List[Dict[str, Any]]
271
+ evidence_items: List[Dict[str, Any]]
272
+ city: str
273
+ town_or_zone: str
274
+
275
+
276
+ class RecommendedInputsRequest(TypedDict, total=False):
277
+ endpoint: str
278
+ route: str
279
+ path: str
280
+ entity_archetype: EntityArchetype
281
+ category: str
282
+ subject: MVRSubject
283
+ country: str
284
+ goal: str
285
+ evidence_maturity: str
286
+
287
+
288
+ class RemediationPathRequest(TypedDict, total=False):
289
+ decision_result: Dict[str, Any]
290
+ subject: MVRSubject
291
+ market_scope: MVRMarketScope
292
+ evidence_pack: List[EvidenceItem]
293
+ compiled_pack: CompiledPack
294
+ target_verdict: MVRVerdict
295
+ audience: str
296
+ gap_plan: Dict[str, Any]
297
+ evidence_run: Dict[str, Any]
298
+ evidence_recruitment_plan: Dict[str, Any]
299
+ mvr_result: Dict[str, Any]
300
+ decision_room: Dict[str, Any]
301
+ red_team: Dict[str, Any]
302
+ release_check: Dict[str, Any]
303
+ project_id: str
304
+
305
+
306
+ class EvidenceCompletenessRequest(TypedDict, total=False):
307
+ subject: MVRSubject
308
+ market_scope: MVRMarketScope
309
+ evidence_pack: List[EvidenceItem]
310
+ compiled_pack: CompiledPack
311
+ stakeholder_scope: List[str]
312
+ target_verdict: MVRVerdict
313
+
314
+
315
+ class ContextCompileRequest(TypedDict, total=False):
316
+ subject: MVRSubject
317
+ market_scope: MVRMarketScope
318
+ evidence_pack: List[EvidenceItem]
319
+ compiled_pack: CompiledPack
320
+ analysis_date: str
321
+ requested_use: str
322
+
323
+
324
+ class DecisionCheckRequest(TypedDict, total=False):
325
+ mode: Literal["exploratory", "evidence_backed", "compiled_evidence"]
326
+ subject: MVRSubject
327
+ market_scope: MVRMarketScope
328
+ evidence_pack: List[EvidenceItem]
329
+ compiled_pack: CompiledPack
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mvr-api-client
3
- Version: 6.32.0
3
+ Version: 6.32.3
4
4
  Summary: Python client for the MVR API relational-readiness layer
5
5
  Author-email: African Market OS <info@africanmarketos.com>
6
6
  License-Expression: MIT
@@ -16,18 +16,32 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: requests>=2.25.0
18
18
  Requires-Dist: pydantic<3.0,>=1.8
19
+ Provides-Extra: dev
20
+ Requires-Dist: build>=1.2.0; extra == "dev"
21
+ Requires-Dist: mypy<1.18,>=1.11.0; extra == "dev"
19
22
  Dynamic: license-file
20
23
 
21
24
  # MVR API Python Client
22
25
 
26
+ [![PyPI](https://img.shields.io/pypi/v/mvr-api-client)](https://pypi.org/project/mvr-api-client/)
27
+ [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-listed-0f6b45)](https://registry.modelcontextprotocol.io/?search=mvr)
28
+ [![OpenAPI](https://img.shields.io/badge/OpenAPI-3.1-6ba539)](https://africanmarketos.com/api/openapi.json)
29
+ [![License](https://img.shields.io/badge/license-MIT-lightgrey)](https://github.com/africanmarketos591/mvr-api-py-client/blob/main/LICENSE)
30
+
23
31
  Lightweight Python client for the current **MVR API - Minimum Viable Relationships** surface.
24
32
 
33
+ Use MVR API when assessing whether a startup, product, investor, NGO, brand, fintech, partnership, program, or market-entry plan has enough trust, permission, embeddedness, guardian approval, reciprocity, evidence completeness, local legitimacy, and stakeholder acceptance to operate in an African or high-context market.
34
+
25
35
  This client targets the live MVR Core API v6.32.x:
26
36
 
27
37
  - `POST /v1/auth-check`
38
+ - `POST /v1/first-call`
28
39
  - `POST /v1/entity-resolve`
29
40
  - `POST /v1/evidence-completeness`
41
+ - `POST /v1/context/compile`
30
42
  - `POST /v1/decision-check`
43
+ - `POST /v1/recommended-inputs`
44
+ - `POST /v1/remediation-path`
31
45
  - `GET /v1/model-card`
32
46
  - `GET /v1/capabilities`
33
47
 
@@ -56,10 +70,19 @@ from mvr_api import MVRClient
56
70
 
57
71
  client = MVRClient()
58
72
 
73
+ activation = client.first_call({
74
+ "entity_name": "Example Kampala supplier-finance venture",
75
+ "country": "UG",
76
+ "decision": "Assess whether to proceed beyond bounded discovery",
77
+ })
78
+ print(activation["not_a_verdict"]) # True
79
+
59
80
  result = client.entity_resolve("MTN Nigeria", country="NG")
60
81
  print(result["response_meta"]["environment"]) # sandbox when using the demo key
61
82
  ```
62
83
 
84
+ `first_call` intentionally accepts free-form discovery labels such as `generic_startup`; canonical `EntityArchetype` values become mandatory on `recommended_inputs` and evidence-scoring routes. Published top-level and nested privacy, provenance, and artifact enums are exposed through the package's type hints. Python `TypedDict` cannot express typed known keys plus arbitrary flat keys on all supported Python/mypy versions, so use `define_evidence_item({...})` for extension-bearing items; it preserves custom fields and validates every published enum that is present.
85
+
63
86
  ## Evidence Completeness
64
87
 
65
88
  ```python
@@ -100,7 +123,13 @@ print(result["status"])
100
123
  ## Agent Discovery
101
124
 
102
125
  - Agent OpenAPI: https://africanmarketos.com/api/openapi.agent.json
103
- - MCP endpoint: https://africanmarketos.com/mcp
126
+ - Minimal sandbox OpenAPI: https://africanmarketos.com/api/openapi.agent.sandbox.json
127
+ - AI-agent quickstart: https://africanmarketos.com/docs/quickstart-ai-agents.md
128
+ - Response examples: https://africanmarketos.com/docs/response-examples.md
129
+ - OpenAI tool schema: https://africanmarketos.com/docs/openai-tool-schema.md
130
+ - Canonical public MCP preflight: https://africanmarketos.com/mcp/preflight
131
+ - Compatibility MCP endpoint: https://africanmarketos.com/mcp
132
+ - MCP setup: https://africanmarketos.com/mcp/README.md
104
133
  - MCP Registry name: `io.github.africanmarketos591/mvr-api`
105
134
  - Sandbox guide: https://africanmarketos.com/docs/sandbox.md
106
135
  - Agent instructions: https://africanmarketos.com/AGENTS.md
@@ -109,4 +138,6 @@ print(result["status"])
109
138
 
110
139
  Minimum Viable Relationships (MVR), originated by Farouk Mark Mukiibi, African Market OS.
111
140
 
112
- Commercial, production, SaaS, consulting, or AI-agent deployment use requires authorization from African Market OS.
141
+ Sandbox/evaluation use only with the public key. Commercial, production, SaaS, consulting, or AI-agent deployment use requires authorization from African Market OS.
142
+
143
+ Do not present MVR output as credit scoring, legal certification, regulatory approval, investment guarantee, or field-validated truth unless verified evidence and production authorization explicitly support the claim.
@@ -13,4 +13,5 @@ mvr_api_client.egg-info/PKG-INFO
13
13
  mvr_api_client.egg-info/SOURCES.txt
14
14
  mvr_api_client.egg-info/dependency_links.txt
15
15
  mvr_api_client.egg-info/requires.txt
16
- mvr_api_client.egg-info/top_level.txt
16
+ mvr_api_client.egg-info/top_level.txt
17
+ tests/test_client.py
@@ -0,0 +1,6 @@
1
+ requests>=2.25.0
2
+ pydantic<3.0,>=1.8
3
+
4
+ [dev]
5
+ build>=1.2.0
6
+ mypy<1.18,>=1.11.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mvr-api-client"
7
- version = "6.32.0"
7
+ version = "6.32.3"
8
8
  description = "Python client for the MVR API relational-readiness layer"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -32,6 +32,12 @@ dependencies = [
32
32
  "pydantic>=1.8,<3.0"
33
33
  ]
34
34
 
35
+ [project.optional-dependencies]
36
+ dev = [
37
+ "build>=1.2.0",
38
+ "mypy>=1.11.0,<1.18"
39
+ ]
40
+
35
41
  [project.urls]
36
42
  Homepage = "https://github.com/africanmarketos591/mvr-api-py-client"
37
43
  Repository = "https://github.com/africanmarketos591/mvr-api-py-client"
@@ -44,3 +50,7 @@ MCP = "https://registry.modelcontextprotocol.io/v0/servers?search=io.github.afri
44
50
  where = ["."]
45
51
  include = ["mvr_api*"]
46
52
 
53
+ [tool.mypy]
54
+ python_version = "3.9"
55
+ warn_unused_ignores = true
56
+
@@ -0,0 +1,75 @@
1
+ import unittest
2
+ from unittest.mock import Mock
3
+
4
+ from mvr_api import MVRApiError, MVRClient, MVRConfig, define_evidence_item
5
+
6
+
7
+ class ClientContractTests(unittest.TestCase):
8
+ def setUp(self):
9
+ self.client = MVRClient(MVRConfig(base_url="https://example.test", api_key="test-key", max_retries=0))
10
+ self.request = Mock()
11
+ self.client.session.request = self.request
12
+
13
+ @staticmethod
14
+ def response(status_code=200, payload=None, headers=None):
15
+ result = Mock()
16
+ result.status_code = status_code
17
+ result.headers = headers or {}
18
+ result.json.return_value = payload or {"status": "ok"}
19
+ result.text = ""
20
+ return result
21
+
22
+ def test_certified_helpers_preserve_route_body_and_headers(self):
23
+ self.request.side_effect = [self.response(), self.response(), self.response()]
24
+
25
+ self.client.first_call({"entity": "Example", "country": "UG", "question": "Should it launch?"})
26
+ self.client.recommended_inputs({"endpoint": "/v1/decision-check", "entity_archetype": "distributor_network"})
27
+ self.client.remediation_path({"decision_result": {"status": "abstained"}, "target_verdict": "pilot_only"})
28
+
29
+ calls = self.request.call_args_list
30
+ self.assertEqual([call.args[1] for call in calls], [
31
+ "https://example.test/v1/first-call",
32
+ "https://example.test/v1/recommended-inputs",
33
+ "https://example.test/v1/remediation-path",
34
+ ])
35
+ self.assertEqual(calls[0].kwargs["json"]["question"], "Should it launch?")
36
+ self.assertEqual(calls[1].kwargs["json"]["entity_archetype"], "distributor_network")
37
+ self.assertEqual(calls[2].kwargs["json"]["target_verdict"], "pilot_only")
38
+ self.assertEqual(self.client.session.headers["X-API-Key"], "test-key")
39
+ self.assertEqual(self.client.session.headers["X-Response-Profile"], "full_advisory")
40
+ self.assertTrue(self.client.session.headers["User-Agent"].endswith("6.32.3"))
41
+
42
+ def test_structured_http_error_is_preserved(self):
43
+ self.request.return_value = self.response(
44
+ 422,
45
+ {"error": "Utility validation failed", "details": ["target_verdict must be canonical"]},
46
+ )
47
+
48
+ with self.assertRaises(MVRApiError) as caught:
49
+ self.client.remediation_path({"decision_result": {}, "target_verdict": "pilot_only"})
50
+
51
+ self.assertEqual(caught.exception.status_code, 422)
52
+ self.assertEqual(caught.exception.error_data["error"], "Utility validation failed")
53
+
54
+ def test_extension_helper_preserves_custom_fields_and_rejects_invalid_known_enums(self):
55
+ item = define_evidence_item({
56
+ "id": "EV-EXT-1",
57
+ "evidence_type": "public_filing",
58
+ "custom_signal": {"registry_match": True},
59
+ })
60
+ self.assertEqual(item["custom_signal"], {"registry_match": True})
61
+
62
+ with self.assertRaisesRegex(ValueError, "privacy_envelope.consent_basis"):
63
+ define_evidence_item({"privacy_envelope": {"consent_basis": "assumed"}})
64
+ with self.assertRaisesRegex(ValueError, "provenance_ledger.extraction_method"):
65
+ define_evidence_item({"provenance_ledger": {"extraction_method": "human_verified"}})
66
+ with self.assertRaisesRegex(ValueError, r"source_artifacts\[0\].extraction_method"):
67
+ define_evidence_item({"source_artifacts": [{"extraction_method": "ocr_magic"}]})
68
+ with self.assertRaisesRegex(ValueError, "evidence_type"):
69
+ define_evidence_item({"evidence_type": None})
70
+ with self.assertRaisesRegex(ValueError, "privacy_envelope.consent_basis"):
71
+ define_evidence_item({"privacy_envelope": {"consent_basis": None}})
72
+
73
+
74
+ if __name__ == "__main__":
75
+ unittest.main()
@@ -1,92 +0,0 @@
1
- # MVR API Python Client
2
-
3
- Lightweight Python client for the current **MVR API - Minimum Viable Relationships** surface.
4
-
5
- This client targets the live MVR Core API v6.32.x:
6
-
7
- - `POST /v1/auth-check`
8
- - `POST /v1/entity-resolve`
9
- - `POST /v1/evidence-completeness`
10
- - `POST /v1/decision-check`
11
- - `GET /v1/model-card`
12
- - `GET /v1/capabilities`
13
-
14
- It is aligned with the agent OpenAPI contract, public sandbox, and MCP registry entry.
15
-
16
- ## Install
17
-
18
- ```bash
19
- pip install mvr-api-client
20
- ```
21
-
22
- ## Public Sandbox
23
-
24
- The default key is the public sandbox key:
25
-
26
- ```text
27
- X-API-Key: mvr-demo-key-2026
28
- ```
29
-
30
- Sandbox use is non-commercial evaluation only. It is `full_advisory`, `client_safe`, illustrative, not for production, not for model training, and not for reverse engineering.
31
-
32
- ## Example
33
-
34
- ```python
35
- from mvr_api import MVRClient
36
-
37
- client = MVRClient()
38
-
39
- result = client.entity_resolve("MTN Nigeria", country="NG")
40
- print(result["response_meta"]["environment"]) # sandbox when using the demo key
41
- ```
42
-
43
- ## Evidence Completeness
44
-
45
- ```python
46
- from mvr_api import MVRClient
47
-
48
- client = MVRClient()
49
-
50
- result = client.evidence_completeness({
51
- "subject": {
52
- "entity_name": "Sandbox Kampala catering operator",
53
- "entity_archetype": "retail_chain",
54
- "country": "UG",
55
- },
56
- "market_scope": {
57
- "country": "UG",
58
- "city": "Kampala",
59
- "sector": "catering",
60
- },
61
- "evidence_pack": [
62
- {
63
- "id": "ev-licence-001",
64
- "evidence_type": "public_filing",
65
- "source_class": "administrative_record",
66
- "source_grade": "B",
67
- "stakeholder_class": "guardian",
68
- "evidence_origin": "field_research",
69
- "collection_method": "direct",
70
- "freshness_date": "2026-05-20",
71
- "evidence_geography": {"country": "UG", "city": "Kampala"},
72
- "structured_values": {"guardian_strength": 72, "permission": 68},
73
- }
74
- ],
75
- })
76
-
77
- print(result["status"])
78
- ```
79
-
80
- ## Agent Discovery
81
-
82
- - Agent OpenAPI: https://africanmarketos.com/api/openapi.agent.json
83
- - MCP endpoint: https://africanmarketos.com/mcp
84
- - MCP Registry name: `io.github.africanmarketos591/mvr-api`
85
- - Sandbox guide: https://africanmarketos.com/docs/sandbox.md
86
- - Agent instructions: https://africanmarketos.com/AGENTS.md
87
-
88
- ## Attribution
89
-
90
- Minimum Viable Relationships (MVR), originated by Farouk Mark Mukiibi, African Market OS.
91
-
92
- Commercial, production, SaaS, consulting, or AI-agent deployment use requires authorization from African Market OS.
@@ -1,13 +0,0 @@
1
- from .client import MVRApiClient, MVRApiError, MVRClient
2
- from .models import MVRConfig, SandboxMarkers
3
-
4
- __version__ = "6.32.0"
5
-
6
- __all__ = [
7
- "MVRClient",
8
- "MVRApiClient",
9
- "MVRApiError",
10
- "MVRConfig",
11
- "SandboxMarkers",
12
- ]
13
-
@@ -1,22 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- from typing import Literal, Optional
5
-
6
- from pydantic import BaseModel, Field
7
-
8
-
9
- class MVRConfig(BaseModel):
10
- """Configuration for the MVR API client."""
11
-
12
- api_key: str = Field(default_factory=lambda: os.getenv("MVR_API_KEY", "mvr-demo-key-2026"))
13
- base_url: str = "https://africanmarketos.com"
14
- timeout: float = 90.0
15
- max_retries: int = 1
16
- response_profile: Literal["full_advisory", "strict_calibrated"] = "full_advisory"
17
-
18
-
19
- class SandboxMarkers(BaseModel):
20
- environment: Optional[str] = None
21
- illustrative_only: Optional[bool] = None
22
- not_for_production: Optional[bool] = None
@@ -1,2 +0,0 @@
1
- requests>=2.25.0
2
- pydantic<3.0,>=1.8
File without changes