From ed2ba940f131f4451729a364e2ecb32fc50b1c36 Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Tue, 15 Sep 2026 08:52:08 -0300 Subject: [PATCH 1/6] chore(beads): restore server mode projection --- .beads/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.beads/metadata.json b/.beads/metadata.json index de133752..00798a84 100644 --- a/.beads/metadata.json +++ b/.beads/metadata.json @@ -1,5 +1,6 @@ { "backend": "dolt", "database": "dolt", + "dolt_mode": "server", "dolt_database": "flext" } From 513d184e6be754375b371006d933823f095640de Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Tue, 15 Sep 2026 09:19:07 -0300 Subject: [PATCH 2/6] fix(api): publish class-object HTTP contracts and typed async client --- README.md | 6 +-- docs/api-reference/README.md | 6 +-- docs/api-reference/generated/overview.md | 14 +++--- src/flext_api/__init__.py | 3 ++ src/flext_api/_protocols/transports.py | 27 ++++------- src/flext_api/_utilities/serializers.py | 2 +- src/flext_api/protocols.py | 23 +++++----- src/flext_api/services/__init__.py | 3 ++ .../services/_services/base_request.py | 27 +++++++---- src/flext_api/services/async_client.py | 19 +++----- src/flext_api/services/base_client.py | 18 ++++---- src/flext_api/services/client.py | 17 ++----- tests/unit/__init__.py | 7 ++- .../{_model_contract.py => model_contract.py} | 0 tests/unit/test_async_client.py | 4 +- tests/unit/test_serializers.py | 16 +++---- tests/unit/test_smoke.py | 4 +- tests/unit/test_transports_facade_httpx.py | 46 ++++++++++++------- 18 files changed, 124 insertions(+), 118 deletions(-) rename tests/unit/{_model_contract.py => model_contract.py} (100%) diff --git a/README.md b/README.md index 9c46930d..c40b9f0f 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,9 @@ slot registry verification). - Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array filtered by `flext-*`. The FLEXT cascade is encoded in the inheritance lists of the facade classes listed under Module Map above. -- Public extensions exposed by this project: `FlextApi`, `FlextApiCli`, - `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants` - (+6 more). +- Public extensions exposed by this project: `FlextApi`, `FlextApiAsyncClient`, + `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 + more). - Library abstraction boundaries: see AGENTS.md §2.7. ## Quality Gates diff --git a/docs/api-reference/README.md b/docs/api-reference/README.md index 93fc11d2..19ef92fe 100644 --- a/docs/api-reference/README.md +++ b/docs/api-reference/README.md @@ -25,8 +25,8 @@ This section is generated from public exports and real docstrings. ## Surface Summary -- Primary facades: `FlextApi`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants` (+6 more) -- Generated module pages: `11` +- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more) +- Generated module pages: `12` Back to [project docs](../index.md). diff --git a/docs/api-reference/generated/overview.md b/docs/api-reference/generated/overview.md index d8c80c60..73e6a2ab 100644 --- a/docs/api-reference/generated/overview.md +++ b/docs/api-reference/generated/overview.md @@ -16,15 +16,15 @@ :: 3.13` (+3 more) - Project class: `domain` - Keywords: `enterprise`, `fastapi`, `flext`, `http`, `rest`, `typed` -- Main facades: `FlextApi`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, `FlextApiModels`, - `FlextApiProtocols` (+4 more) +- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, + `FlextApiModels` (+5 more) - Alias exports: `c`, `d`, `e`, `h`, `m`, `p`, `r`, `s`, `t`, `u`, `x` -- Public symbol exports: `FlextApi`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, `FlextApiModels`, - `FlextApiProtocols`, `FlextApiServiceBase`, `FlextApiSettings` (+11 more) +- Public symbol exports: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, + `FlextApiModels`, `FlextApiProtocols`, `FlextApiServiceBase` (+12 more) - Exported module shortcuts: `api`, `services` -- Generated module pages: `11` +- Generated module pages: `12` ## Next Pages diff --git a/src/flext_api/__init__.py b/src/flext_api/__init__.py index 3b1ef27c..f190bad6 100644 --- a/src/flext_api/__init__.py +++ b/src/flext_api/__init__.py @@ -41,12 +41,14 @@ HttpxResponse, HttpxTimeoutException, ) + from .services.async_client import FlextApiAsyncClient from .services.base_client import FlextApiClientBase from .services.client import FlextApiClient from .typings import FlextApiTypes, FlextApiTypes as t from .utilities import FlextApiUtilities, FlextApiUtilities as u __all__: tuple[str, ...] = ( "FlextApi", + "FlextApiAsyncClient", "FlextApiCli", "FlextApiClient", "FlextApiClientBase", @@ -112,6 +114,7 @@ "p", ), ".services": ("services",), + ".services.async_client": ("FlextApiAsyncClient",), ".services.base_client": ("FlextApiClientBase",), ".services.client": ("FlextApiClient",), ".typings": ("FlextApiTypes", "t"), diff --git a/src/flext_api/_protocols/transports.py b/src/flext_api/_protocols/transports.py index 252331ff..26d5bc33 100644 --- a/src/flext_api/_protocols/transports.py +++ b/src/flext_api/_protocols/transports.py @@ -11,7 +11,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Final, override +from typing import TYPE_CHECKING, ClassVar, Protocol, override, runtime_checkable import httpx @@ -29,26 +29,17 @@ class FlextApiProtocolsTransports: """FLEXT API transport implementations.""" - class Httpx: - """Owner facade for the httpx transport primitives. + @runtime_checkable + class Httpx(Protocol): + """Protocol namespace for owner-derived HTTP status contracts. - Consumers route every httpx dependency through this namespace so no - consumer module imports httpx directly (transport ownership stays - with flext-api, ENFORCE-070). The status constant is derived from the - httpx owner at import time, never restated as a literal here. Members - stay real class objects so consumer isinstance/narrowing keeps its - runtime and static meaning (PEP 695 alias objects would neither be - valid isinstance second arguments nor narrow in mypy). + Runtime classes and exceptions are published as module-level + ``Httpx*`` class-object re-exports. Keeping class identity out of this + protocol namespace preserves both construction/isinstance semantics and + the Protocol/namespace census contract. """ - Client = httpx.Client - AsyncClient = httpx.AsyncClient - Response = httpx.Response - HTTPError = httpx.HTTPError - HTTPStatusError = httpx.HTTPStatusError - RequestError = httpx.RequestError - TimeoutException = httpx.TimeoutException - CONFLICT: Final[int] = int(httpx.codes.CONFLICT) + CONFLICT: ClassVar[int] = int(httpx.codes.CONFLICT) # Why: no member here carries @abstractmethod (TransportPlugin's Protocol # bodies are structural, not abstract), so an explicit ABC base added diff --git a/src/flext_api/_utilities/serializers.py b/src/flext_api/_utilities/serializers.py index 80ecc341..7d6b8562 100644 --- a/src/flext_api/_utilities/serializers.py +++ b/src/flext_api/_utilities/serializers.py @@ -45,7 +45,7 @@ def unpackb(data: bytes) -> p.Result[t.JsonValue]: result = msgpack.unpackb(data) if result is None: return r[t.JsonValue].fail( - "msgpack nil is forbidden because None cannot be a success payload" + "msgpack nil is forbidden because Result cannot carry None as success" ) normalized = t.Api.API_JSON_VALUE_ADAPTER.validate_python(result) return r[t.JsonValue].ok(normalized) diff --git a/src/flext_api/protocols.py b/src/flext_api/protocols.py index ac4561c0..3681e9dd 100644 --- a/src/flext_api/protocols.py +++ b/src/flext_api/protocols.py @@ -10,10 +10,16 @@ from __future__ import annotations -from typing import TypeAlias - -import httpx from flext_web import p +from httpx import ( + AsyncClient as HttpxAsyncClient, + Client as HttpxClient, + HTTPError as HttpxHTTPError, + HTTPStatusError as HttpxHTTPStatusError, + RequestError as HttpxRequestError, + Response as HttpxResponse, + TimeoutException as HttpxTimeoutException, +) from ._protocols import ( FlextApiProtocolPlugins, @@ -42,15 +48,8 @@ class Api( p = FlextApiProtocols -# Module-level explicit aliases: valid per PEP 613, real classes at runtime, -# so consumer isinstance narrowing keeps both its static and runtime meaning. -HttpxClient: TypeAlias = httpx.Client -HttpxAsyncClient: TypeAlias = httpx.AsyncClient -HttpxResponse: TypeAlias = httpx.Response -HttpxHTTPError: TypeAlias = httpx.HTTPError -HttpxHTTPStatusError: TypeAlias = httpx.HTTPStatusError -HttpxRequestError: TypeAlias = httpx.RequestError -HttpxTimeoutException: TypeAlias = httpx.TimeoutException +# Module-level explicit class-object re-exports: consumers can construct and +# isinstance-narrow these names with both static and runtime class semantics. __all__: list[str] = [ "FlextApiProtocols", diff --git a/src/flext_api/services/__init__.py b/src/flext_api/services/__init__.py index 18ef6c19..c7ad50bc 100644 --- a/src/flext_api/services/__init__.py +++ b/src/flext_api/services/__init__.py @@ -14,9 +14,11 @@ from ._services.base_request import FlextApiClientBaseRequestMixin from ._services.codec import FlextApiClientCodecMixin from ._services.request import FlextApiClientRequestMixin + from .async_client import FlextApiAsyncClient from .base_client import FlextApiClientBase from .client import FlextApiClient __all__: tuple[str, ...] = ( + "FlextApiAsyncClient", "FlextApiClient", "FlextApiClientAsyncRequestMixin", "FlextApiClientBase", @@ -34,6 +36,7 @@ "._services.base_request": ("FlextApiClientBaseRequestMixin",), "._services.codec": ("FlextApiClientCodecMixin",), "._services.request": ("FlextApiClientRequestMixin",), + ".async_client": ("FlextApiAsyncClient",), ".base_client": ("FlextApiClientBase",), ".client": ("FlextApiClient",), }), diff --git a/src/flext_api/services/_services/base_request.py b/src/flext_api/services/_services/base_request.py index 88c7b36d..7d7033cc 100644 --- a/src/flext_api/services/_services/base_request.py +++ b/src/flext_api/services/_services/base_request.py @@ -16,13 +16,17 @@ class FlextApiClientBaseRequestMixin(FlextApiClientCodecMixin): """Shared request execution helpers for sync and async clients.""" - settings: FlextApiSettings + if TYPE_CHECKING: + + @property + def client_settings(self) -> FlextApiSettings: + """Typed settings supplied by the concrete client base.""" def _build_url(self, path: str) -> p.Result[str]: """Build full URL from base_url and path.""" # NOTE (multi-agent): mro-t9s9 — request defaults belong to this # client's injected runtime settings, never the global singleton. - api_settings = self.settings.Api + api_settings = self.client_settings.Api if not path: return r[str].fail("URL path cannot be empty") path_stripped = path.strip() @@ -37,12 +41,12 @@ def _build_url(self, path: str) -> p.Result[str]: def _prepare_request( self, request: m.Api.HttpRequest - ) -> p.Result[tuple[str, t.StrMapping, bytes, t.MappingKV[str, t.StrMapping]]]: + ) -> p.Result[tuple[str, t.StrMapping, bytes, t.MappingKV[str, str]]]: """Prepare URL, headers, body, and extensions for HTTP request.""" url_result = self._build_url(request.url) if url_result.failure: return r[ - tuple[str, t.StrMapping, bytes, t.MappingKV[str, t.StrMapping]] + tuple[str, t.StrMapping, bytes, t.MappingKV[str, str]] ].from_failure(url_result) request_body: t.Api.RequestBody = ( request.body if request.body is not None else b"" @@ -50,13 +54,16 @@ def _prepare_request( body_result = self._serialize_body(request_body) if body_result.failure: return r[ - tuple[str, t.StrMapping, bytes, t.MappingKV[str, t.StrMapping]] + tuple[str, t.StrMapping, bytes, t.MappingKV[str, str]] ].from_failure(body_result) - headers: t.StrMapping = {**self.settings.Api.default_headers, **request.headers} - extensions = ( - {"sni_hostname": request.sni_hostname} if request.sni_hostname else {} - ) - return r[tuple[str, t.StrMapping, bytes, t.MappingKV[str, t.StrMapping]]].ok(( + headers: t.StrMapping = { + **self.client_settings.Api.default_headers, + **request.headers, + } + extensions: t.MutableStrMapping = {} + if request.sni_hostname: + extensions["sni_hostname"] = request.sni_hostname + return r[tuple[str, t.StrMapping, bytes, t.MappingKV[str, str]]].ok(( url_result.value, headers, body_result.value, diff --git a/src/flext_api/services/async_client.py b/src/flext_api/services/async_client.py index 3bf168ee..d57a2c23 100644 --- a/src/flext_api/services/async_client.py +++ b/src/flext_api/services/async_client.py @@ -2,24 +2,17 @@ from __future__ import annotations -from typing import override - -from .. import p, r, t, u +from .. import FlextApiSettings, t from ._services import FlextApiClientAsyncRequestMixin from .base_client import FlextApiClientBase -class FlextApiAsyncClient(FlextApiClientAsyncRequestMixin, FlextApiClientBase): +class FlextApiAsyncClient(FlextApiClientBase, FlextApiClientAsyncRequestMixin): """Generic async HTTP client using FLEXT patterns.""" - @override - def execute(self, **kwargs: t.Scalar) -> p.Result[bool]: - """Execute service lifecycle parity.""" - if kwargs: - u.fetch_logger(__name__).info( - "Execute called with kwargs keys: %s", list(kwargs.keys()) - ) - return r[bool].ok(True) + def __init__(self, *, settings: FlextApiSettings | None = None) -> None: + """Bind one async client to explicit settings or the global singleton.""" + super().__init__(settings=settings) -__all: t.MutableSequenceOf[str] = ["FlextApiAsyncClient"] +__all__: t.MutableSequenceOf[str] = ["FlextApiAsyncClient"] diff --git a/src/flext_api/services/base_client.py b/src/flext_api/services/base_client.py index 3bdc3b5f..f2b54b7d 100644 --- a/src/flext_api/services/base_client.py +++ b/src/flext_api/services/base_client.py @@ -4,32 +4,34 @@ from typing import override -from flext_core import m - from .. import FlextApiSettings, p, r, s, t, u class FlextApiClientBase(s[bool]): """Base HTTP client using FLEXT patterns.""" - settings: FlextApiSettings = m.Field( - description="Client runtime settings bound at construction" - ) - def __init__(self, settings: FlextApiSettings | None = None) -> None: """Bind the client to explicit settings or the global singleton.""" resolved = settings if settings is not None else FlextApiSettings.fetch_global() s.__init__(self, runtime_settings=resolved) + @property + def client_settings(self) -> FlextApiSettings: + """The typed API settings bound to this client.""" + current = super().settings + if isinstance(current, FlextApiSettings): + return current + return FlextApiSettings.fetch_global() + @property def base_url(self) -> str: """The configured API base URL.""" - return self.settings.Api.base_url + return self.client_settings.Api.base_url @property def timeout(self) -> float: """The configured request timeout in seconds.""" - return self.settings.Api.timeout + return self.client_settings.Api.timeout @override def execute(self, **kwargs: t.Scalar) -> p.Result[bool]: diff --git a/src/flext_api/services/client.py b/src/flext_api/services/client.py index 8f188c18..a4c28d7f 100644 --- a/src/flext_api/services/client.py +++ b/src/flext_api/services/client.py @@ -2,24 +2,17 @@ from __future__ import annotations -from typing import override - -from .. import p, r, t, u +from .. import FlextApiSettings, t from ._services import FlextApiClientRequestMixin from .base_client import FlextApiClientBase -class FlextApiClient(FlextApiClientRequestMixin, FlextApiClientBase): +class FlextApiClient(FlextApiClientBase, FlextApiClientRequestMixin): """Generic HTTP client using FLEXT patterns.""" - @override - def execute(self, **kwargs: t.Scalar) -> p.Result[bool]: - """Execute service lifecycle parity.""" - if kwargs: - u.fetch_logger(__name__).info( - "Execute called with kwargs keys: %s", list(kwargs.keys()) - ) - return r[bool].ok(True) + def __init__(self, *, settings: FlextApiSettings | None = None) -> None: + """Bind one client to explicit settings or the global singleton.""" + super().__init__(settings=settings) __all__: t.MutableSequenceOf[str] = ["FlextApiClient"] diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py index d8264fc4..4928230f 100644 --- a/tests/unit/__init__.py +++ b/tests/unit/__init__.py @@ -11,12 +11,14 @@ if TYPE_CHECKING: from flext_tests import c, d, e, h, m, p, r, s, t, td, tf, tk, tm, tv, u, x - from ._model_contract import TestsFlextApiModelContract + from .model_contract import TestsFlextApiModelContract from .test_async_client import TestsFlextApiAsyncClientSmoke from .test_serializers import TestsFlextApiSerializers from .test_smoke import TestsFlextApiSmoke + from .test_transports_facade_httpx import TestsFlextApiHttpxContracts __all__: tuple[str, ...] = ( "TestsFlextApiAsyncClientSmoke", + "TestsFlextApiHttpxContracts", "TestsFlextApiModelContract", "TestsFlextApiSerializers", "TestsFlextApiSmoke", @@ -41,10 +43,11 @@ _LAZY_IMPORTS = MappingProxyType( build_lazy_import_map( MappingProxyType({ - "._model_contract": ("TestsFlextApiModelContract",), + ".model_contract": ("TestsFlextApiModelContract",), ".test_async_client": ("TestsFlextApiAsyncClientSmoke",), ".test_serializers": ("TestsFlextApiSerializers",), ".test_smoke": ("TestsFlextApiSmoke",), + ".test_transports_facade_httpx": ("TestsFlextApiHttpxContracts",), "flext_tests": ( "c", "d", diff --git a/tests/unit/_model_contract.py b/tests/unit/model_contract.py similarity index 100% rename from tests/unit/_model_contract.py rename to tests/unit/model_contract.py diff --git a/tests/unit/test_async_client.py b/tests/unit/test_async_client.py index b942ad8c..779bef20 100644 --- a/tests/unit/test_async_client.py +++ b/tests/unit/test_async_client.py @@ -16,10 +16,10 @@ from flext_api import FlextApiAsyncClient, FlextApiSettings -from ._model_contract import FlextApiModelContractTests +from .model_contract import TestsFlextApiModelContract -class TestsFlextApiAsyncClientSmoke(FlextApiModelContractTests): +class TestsFlextApiAsyncClientSmoke(TestsFlextApiModelContract): """Behavioral contract of the flext-api async client public surface.""" # ---- Client / facade contract --------------------------------------- diff --git a/tests/unit/test_serializers.py b/tests/unit/test_serializers.py index 6534d6fc..1f6f295d 100644 --- a/tests/unit/test_serializers.py +++ b/tests/unit/test_serializers.py @@ -63,11 +63,11 @@ def test_unpackb_success_supports_flat_map_combinator(self) -> None: def test_unpackb_invalid_input_fails(self) -> None: """Invalid msgpack yields a failure with an error message.""" - result = u.Api.unpackb(b"\xff") + result = u.Api.unpackb(b"\xd4") tm.that(result.success, eq=False) tm.that(result.failure, eq=True) - tm.that(result.error, is_str=True) + tm.that(result.error, is_=str) def test_packb_unpackb_roundtrip(self) -> None: """packb() followed by unpackb() yields the original value.""" @@ -111,14 +111,14 @@ def test_packb_unpackb_roundtrip_bool(self) -> None: tm.that(result.success, eq=True) tm.that(result.value, eq=original) - def test_packb_unpackb_roundtrip_none(self) -> None: - """Round-trip for null.""" - original: t.JsonValue = None - packed = u.Api.packb(original) + def test_unpackb_rejects_nil_payload(self) -> None: + """An encoded msgpack nil fails because Result cannot succeed with None.""" + packed = u.Api.packb(None) result = u.Api.unpackb(packed) - tm.that(result.success, eq=True) - tm.that(result.value, eq=original) + tm.that(result.success, eq=False) + tm.that(result.failure, eq=True) + tm.that(str(result.error), has="Result cannot carry None") __all__: list[str] = ["TestsFlextApiSerializers"] diff --git a/tests/unit/test_smoke.py b/tests/unit/test_smoke.py index 230f524e..57a81244 100644 --- a/tests/unit/test_smoke.py +++ b/tests/unit/test_smoke.py @@ -14,10 +14,10 @@ from flext_api import FlextApi, FlextApiClient, FlextApiSettings, c -from ._model_contract import FlextApiModelContractTests +from .model_contract import TestsFlextApiModelContract -class TestsFlextApiSmoke(FlextApiModelContractTests): +class TestsFlextApiSmoke(TestsFlextApiModelContract): """Behavioral contract of the flext-api public surface.""" # ---- Constants contract --------------------------------------------- diff --git a/tests/unit/test_transports_facade_httpx.py b/tests/unit/test_transports_facade_httpx.py index abcb6a79..d0e216df 100644 --- a/tests/unit/test_transports_facade_httpx.py +++ b/tests/unit/test_transports_facade_httpx.py @@ -1,39 +1,51 @@ -"""The transport facade owns the httpx primitives consumers route through.""" +"""The public HTTP class contracts own httpx construction and exception identity.""" from __future__ import annotations import httpx -from flext_api import p +from flext_api import ( + HttpxAsyncClient, + HttpxClient, + HttpxHTTPError, + HttpxHTTPStatusError, + HttpxRequestError, + HttpxResponse, + HttpxTimeoutException, + p, +) -class TestsTransportsFacadeHttpx: - """Httpx primitives surface identity and behavior through the owner.""" +class TestsFlextApiHttpxContracts: + """Observable construction and exception contracts of the HTTP owner.""" def test_client_primitives_are_the_owner_types(self) -> None: """Client factories and response type are the httpx owner types.""" - assert p.Api.Transports.Httpx.Client is httpx.Client - assert p.Api.Transports.Httpx.AsyncClient is httpx.AsyncClient - assert p.Api.Transports.Httpx.Response is httpx.Response + assert HttpxClient is httpx.Client + assert HttpxAsyncClient is httpx.AsyncClient + assert HttpxResponse is httpx.Response def test_exception_primitives_are_the_owner_types(self) -> None: """Exception types match the httpx owner for consumer except clauses.""" - assert p.Api.Transports.Httpx.HTTPError is httpx.HTTPError - assert p.Api.Transports.Httpx.HTTPStatusError is httpx.HTTPStatusError - assert p.Api.Transports.Httpx.RequestError is httpx.RequestError - assert p.Api.Transports.Httpx.TimeoutException is httpx.TimeoutException + assert HttpxHTTPError is httpx.HTTPError + assert HttpxHTTPStatusError is httpx.HTTPStatusError + assert HttpxRequestError is httpx.RequestError + assert HttpxTimeoutException is httpx.TimeoutException def test_conflict_status_is_derived_from_the_owner(self) -> None: """The conflict constant stays int-typed and equals the httpx owner.""" - conflict = p.Api.Transports.Httpx.CONFLICT + conflict = p.Api.Httpx.CONFLICT assert isinstance(conflict, int) assert conflict == int(httpx.codes.CONFLICT) - def test_client_constructs_through_the_facade(self) -> None: - """A real client constructs and closes through the facade alias.""" - client = p.Api.Transports.Httpx.Client(timeout=2.0) + def test_client_constructs_through_the_public_contract(self) -> None: + """A real client constructs and closes through the owner type.""" + client = HttpxClient(timeout=2.0) try: - assert client.is_closed is False + assert not client.is_closed finally: client.close() - assert client.is_closed is True + assert client.is_closed + + +__all__: tuple[str, ...] = ("TestsFlextApiHttpxContracts",) From 8f1c34315f3dd7e76b6b1d496feac3234ae05131 Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Fri, 18 Sep 2026 20:24:06 -0300 Subject: [PATCH 3/6] chore(gen): converge projections with integration tip (standalone CI=Y fixed point) --- .github/workflows/ci.yml | 2 +- .gitignore | 7 +++ .mise.toml | 2 +- Makefile | 12 ++--- README.md | 42 +++++++++-------- docs/README.md | 46 ++++++++++--------- docs/api-reference/README.md | 6 +-- docs/api-reference/generated/modules/index.md | 2 - docs/api-reference/generated/overview.md | 14 +++--- docs/api-reference/generated/public-api.md | 9 ++-- docs/api/core.md | 25 ++++++---- docs/api/middleware.md | 16 ++++--- docs/api/schemas.md | 16 ++++--- docs/api/storage.md | 16 ++++--- .../decisions/002-railway-pattern.md | 15 ++++-- .../decisions/003-protocol-abstraction.md | 12 +++-- docs/architecture/overview.md | 18 ++++++-- docs/guides/README.md | 6 +-- docs/guides/implementation_status.md | 4 +- docs/index.md | 27 ++++++----- mkdocs.yml | 1 + src/flext_api/__init__.py | 31 ++++++++++++- 22 files changed, 202 insertions(+), 127 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a9bd221..840d7e5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,7 +164,7 @@ jobs: run: CI=Y make check # Why (aihub-v01jg): CI=Y runs ONE HALF of the gate set - # (lint pyright silent-failure deferred-self-reference security markdown markdown-format markdown-code loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication); the complement + # (lint pyright silent-failure deferred-self-reference security markdown markdown-format loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication); the complement # (pyrefly mypy) is owned by # CI=N and, without this step, ran on developer # machines only. That split let real defects reach main twice: five diff --git a/.gitignore b/.gitignore index 9ad5b68e..0ff5810b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,8 +29,15 @@ uv.lock # Agent hooks and operator config (runtime state, never source) .github/hooks/ */.hooks.json.agents-governance.json +.claude/settings.json +.claude/*.agents-governance.json +.gemini/settings.json +.gemini/*.agents-governance.json .claude/settings.local.json +# Operator-private local config overrides +/config/codegen-overrides.local.yaml + # Gas City skill projections (runtime state, never source) .agents/skills/.gc-skill-ownership.json .agents/skills/core.gc-* diff --git a/.mise.toml b/.mise.toml index 69e47d3d..2aedd958 100644 --- a/.mise.toml +++ b/.mise.toml @@ -47,7 +47,7 @@ node = "latest" go = "latest" make = "latest" [tools."github:qltysh/qlty"] -version = "latest" +version = "0.642.0" github_attestations = false [tools."github:marlon-costa-dc/beads"] diff --git a/Makefile b/Makefile index e6687170..ec2ade9a 100644 --- a/Makefile +++ b/Makefile @@ -1037,10 +1037,10 @@ _builtin-self-test: _builtin_require_environment _builtin-self-check: _builtin_require_environment @set -eu; \ - gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,markdown-code,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ if [ "$(strip $(CI))" = "Y" ]; then \ - gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,markdown-code,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ - printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown markdown-format markdown-code loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ + gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown markdown-format loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ fi; \ if [ -z "$$gates" ]; then \ printf 'ERROR: no check gates remain after CI=Y filtering\n' >&2; \ @@ -1075,10 +1075,10 @@ _builtin_build_artifacts: # make.ci.local_check_gates. _builtin_check_all: _builtin_require_environment @set -eu; \ - gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,markdown-code,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ if [ "$(strip $(CI))" = "Y" ]; then \ - gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,markdown-code,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ - printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown markdown-format markdown-code loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ + gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown markdown-format loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ fi; \ if [ -z "$$gates" ]; then \ printf 'ERROR: no check gates remain after CI=Y filtering\n' >&2; \ diff --git a/README.md b/README.md index 1e96351d..79d1bb80 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # flext-api - - [Purpose](#purpose) - [Module Map](#module-map) - [Collection Rules](#collection-rules) @@ -9,16 +8,15 @@ - [Integration Points](#integration-points) - [Quality Gates](#quality-gates) - [Governance Pointer](#governance-pointer) - **Version**: `0.12.0` | **Python**: 3.13+ | **Project class**: `domain` -> **Alpha (0.12.0).** This package is alpha quality. Every package in the workspace must -> be re-checked and re-validated at 0.12.0 before any promotion beyond alpha; treat -> interfaces as unstable. +> **Alpha (0.12.0).** This package is alpha quality. Every package in the +> workspace must be re-checked and re-validated at 0.12.0 before any promotion +> beyond alpha; treat interfaces as unstable. ## Purpose @@ -26,15 +24,20 @@ FLEXT API - High-Performance REST API with FastAPI ## Module Map -::: flext_api options: members: false show_root_heading: false show_root_toc_entry: -false show_source: false +::: flext_api + options: + members: false + show_root_heading: false + show_root_toc_entry: false + show_source: false ## Collection Rules -Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent -FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry -verification). +Read +[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist +(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, +slot registry verification). ## Operation Flow @@ -42,22 +45,23 @@ verification). [`docs/api-reference/README.md`](docs/api-reference/README.md). - Generated module overview: [`docs/api-reference/generated/overview.md`](docs/api-reference/generated/overview.md). -- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and `FlextSettings` - ConfigDict. +- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and + `FlextSettings` ConfigDict. ## Integration Points -- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array filtered - by `flext-*`. The FLEXT cascade is encoded in the inheritance lists of the facade - classes listed under Module Map above. +- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array + filtered by `flext-*`. The FLEXT cascade is encoded in the inheritance lists + of the facade classes listed under Module Map above. - Public extensions exposed by this project: `FlextApi`, `FlextApiAsyncClient`, - `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more). + `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 + more). - Library abstraction boundaries: see AGENTS.md §2.7. ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared -operations directly — see +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their +declared operations directly — see [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) `Build & Test` and `Required Python quality gates`. diff --git a/docs/README.md b/docs/README.md index 5da01b74..0449a871 100644 --- a/docs/README.md +++ b/docs/README.md @@ -39,7 +39,7 @@ Pydantic v2 request/response models, and railway-oriented error handling through > implemented. Additional protocols, middleware, and schema generation are not yet part > of the public API. -______________________________________________________________________ +--- ## Overview @@ -62,7 +62,7 @@ enterprise-grade patterns: typed settings, validated request/response models, an - **FLEXT Data Platform** → HTTP operations for data pipeline orchestration - **FLEXT Projects** → Shared HTTP facade preventing duplicate implementations -______________________________________________________________________ +--- ## Current Source Structure @@ -98,7 +98,7 @@ src/flext_api/ - **Configuration SSOT** — `config/*.yaml` and `FlextApiSettings` as the single source of truth -______________________________________________________________________ +--- ## Documentation Structure @@ -116,7 +116,7 @@ ______________________________________________________________________ - **[Testing Guide](guides/testing.md)** — Testing strategies and examples - **[Troubleshooting](guides/troubleshooting.md)** — Common issues and solutions -______________________________________________________________________ +--- ## Quick Start @@ -132,7 +132,7 @@ uv sync --package flext-api ### Basic HTTP Client Usage -``` python notest +````python notest from __future__ import annotations from flext_api import FlextApi, FlextApiSettings @@ -164,14 +164,15 @@ settings = FlextApiSettings( print(settings.Api.base_url) print(settings.Api.timeout) -``` +```` + ### FastAPI Application Setup A FastAPI application factory is **not** currently part of the public API. Use -`FlextApi` and `FlextApiClient` directly in your own FastAPI/Starlette -application if needed. +`FlextApi` and `FlextApiClient` directly in your own FastAPI/Starlette application if +needed. -______________________________________________________________________ +--- ## Testing @@ -188,17 +189,17 @@ uv run pytest tests/integration/ # Integration tests uv run pytest tests/e2e/ # End-to-end tests ``` -______________________________________________________________________ +--- ## Current Status -| Metric | Status | Details | -| ---------------------- | ----------- | -------------------------------------------- | -| **Core Functionality** | Complete | HTTP client facade and settings implemented | -| **Test Coverage** | In progress | Examples validated; package tests growing | -| **Type Safety** | Strict | FLEXT patterns and Pydantic v2 models | -| **Code Quality** | In progress | Ruff / Pyrefly gates via `make check` | -| **FLEXT Integration** | Active | Full flext-core facade integration | +| Metric | Status | Details | +| ---------------------- | ----------- | ------------------------------------------- | +| **Core Functionality** | Complete | HTTP client facade and settings implemented | +| **Test Coverage** | In progress | Examples validated; package tests growing | +| **Type Safety** | Strict | FLEXT patterns and Pydantic v2 models | +| **Code Quality** | In progress | Ruff / Pyrefly gates via `make check` | +| **FLEXT Integration** | Active | Full flext-core facade integration | ### Production Readiness @@ -208,7 +209,7 @@ ______________________________________________________________________ - **Documentation**: User-facing guides and API reference updated to the real API - **Testing**: Markdown examples run under `uv run pytest --markdown-docs` -______________________________________________________________________ +--- ## Contributing @@ -217,7 +218,7 @@ ______________________________________________________________________ 3. **Documentation**: Update relevant guides when changing public APIs 4. **Quality Gates**: Run `make check` before opening a PR -______________________________________________________________________ +--- ## Roadmap @@ -239,7 +240,10 @@ ______________________________________________________________________ - **Middleware API**: First-class request/response interception (if added) - **Schema Generation**: OpenAPI/JSON Schema helpers from public models (if added) -______________________________________________________________________ +--- **FLEXT-API** — Enterprise HTTP Foundation | Built for reliability and scale -```` + +``` + +``` diff --git a/docs/api-reference/README.md b/docs/api-reference/README.md index 81f947ec..19ef92fe 100644 --- a/docs/api-reference/README.md +++ b/docs/api-reference/README.md @@ -1,11 +1,9 @@ # flext-api API Reference - - [Source of Truth](#source-of-truth) - [Generated Pages](#generated-pages) - [Surface Summary](#surface-summary) - @@ -27,8 +25,8 @@ This section is generated from public exports and real docstrings. ## Surface Summary -- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig` (+7 more) +- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more) - Generated module pages: `12` Back to [project docs](../index.md). diff --git a/docs/api-reference/generated/modules/index.md b/docs/api-reference/generated/modules/index.md index 9277a473..d8f682b9 100644 --- a/docs/api-reference/generated/modules/index.md +++ b/docs/api-reference/generated/modules/index.md @@ -1,9 +1,7 @@ # flext-api Module Index - - No sections found - diff --git a/docs/api-reference/generated/overview.md b/docs/api-reference/generated/overview.md index fe5b6125..9bef9eb6 100644 --- a/docs/api-reference/generated/overview.md +++ b/docs/api-reference/generated/overview.md @@ -1,9 +1,7 @@ # flext-api API Overview - - [Next Pages](#next-pages) - @@ -14,17 +12,17 @@ - Doc summary: Flext Api package. - Classifiers: `Development Status :: 3 - Alpha`, `Framework :: FastAPI`, `Intended Audience :: Developers`, `Operating System :: OS Independent`, - `Programming Language :: Python :: 3 :: Only`, - `Programming Language :: Python :: 3.13` (+3 more) + `Programming Language :: Python :: 3 :: Only`, `Programming Language :: Python + :: 3.13` (+3 more) - Project class: `domain` - Keywords: `enterprise`, `fastapi`, `flext`, `http`, `rest`, `typed` -- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, `FlextApiModels` (+5 - more) +- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, + `FlextApiModels` (+5 more) - Alias exports: `c`, `d`, `e`, `h`, `m`, `p`, `r`, `s`, `t`, `u`, `x` - Public symbol exports: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, - `FlextApiModels`, `FlextApiProtocols`, `FlextApiServiceBase` (+5 more) + `FlextApiModels`, `FlextApiProtocols`, `FlextApiServiceBase` (+12 more) - Exported module shortcuts: `api`, `services` - Generated module pages: `12` diff --git a/docs/api-reference/generated/public-api.md b/docs/api-reference/generated/public-api.md index cdbff39a..11a74b2f 100644 --- a/docs/api-reference/generated/public-api.md +++ b/docs/api-reference/generated/public-api.md @@ -1,12 +1,13 @@ # flext-api Public API - - No sections found - -::: flext_api options: show_root_heading: true show_root_full_path: false show_source: -false +::: flext_api + options: + show_root_heading: true + show_root_full_path: false + show_source: false diff --git a/docs/api/core.md b/docs/api/core.md index cca31bb3..5521060a 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -28,7 +28,7 @@ executes validated `m.Api.HttpRequest` instances through `request(...)`. It does expose `get/post/put/delete/patch` directly; those methods live on the `FlextApi` facade. -``` python notest +````python notest from __future__ import annotations from flext_api import FlextApiClient, FlextApiSettings, c, m, p @@ -121,7 +121,8 @@ result: p.Result[m.Api.HttpResponse] = api.get("/users") result = api.get("/users", request_kwargs={"params": {"limit": 10, "offset": 0}}) result = api.get("/users", headers={"Accept": "application/json"}) -``` +```` + **POST/PUT/PATCH/DELETE Requests:** ```python @@ -141,13 +142,14 @@ patch_result = api.patch("/users/123", data={"email": "new@example.com"}) delete_result = api.delete("/users/123") ``` + ## Configuration ### FlextApiSettings - Configuration Model -`FlextApiSettings` is a Pydantic settings model. Project-specific fields are -nested under the `Api` namespace, but flat constructor arguments are automatically -lifted into that namespace for convenience. +`FlextApiSettings` is a Pydantic settings model. Project-specific fields are nested +under the `Api` namespace, but flat constructor arguments are automatically lifted into +that namespace for convenience. ```python from __future__ import annotations @@ -172,6 +174,7 @@ settings_nested = FlextApiSettings( print(settings.Api.base_url) print(settings.Api.timeout) ``` + To extend settings with custom fields, subclass `FlextApiSettings` and add fields outside the `Api` namespace or declare an additional nested group. @@ -192,12 +195,12 @@ config = MyApiConfig(base_url="https://api.example.com", custom_setting="custom" assert config.custom_setting == "custom" assert config.Api.base_url == "https://api.example.com" ``` + ## HTTP Models ### Request/Response Models -HTTP payloads are represented by immutable Pydantic value models under -`m.Api`. +HTTP payloads are represented by immutable Pydantic value models under `m.Api`. ```python from __future__ import annotations @@ -223,12 +226,13 @@ response = m.Api.create_response( assert response.success assert response.status_code == 201 ``` + ## HTTP Utilities ### RequestUtils - Helper Functions -`u.Api.RequestUtils` provides small, pure helpers for normalizing request -components before they are validated into `m.Api.HttpRequest`. +`u.Api.RequestUtils` provides small, pure helpers for normalizing request components +before they are validated into `m.Api.HttpRequest`. ```python from __future__ import annotations @@ -259,11 +263,12 @@ timeout_result = u.Api.RequestUtils.coerce_positive_timeout(5.0) assert timeout_result.success print(timeout_result.unwrap()) ``` + ## Usage Examples ### Complete HTTP Client Example -```python notest +````python notest from __future__ import annotations from flext_api import FlextApi, FlextApiSettings, m, p, r diff --git a/docs/api/middleware.md b/docs/api/middleware.md index 021c3dd6..9e21cfd9 100644 --- a/docs/api/middleware.md +++ b/docs/api/middleware.md @@ -20,7 +20,7 @@ The idiomatic way to add behavior around HTTP calls is to subclass `FlextApi` an override the verbs you care about. The example below adds request/response logging without relying on any non-existent middleware API. -``` python +```python from __future__ import annotations from flext_api import FlextApi, FlextApiSettings, m, p, r @@ -61,10 +61,11 @@ result = api.get("/users") assert result.success assert result.unwrap().status_code == 200 ``` + ## What Is Not Implemented -The following middleware concepts are **not** part of the current public API -and are therefore not documented as executable examples: +The following middleware concepts are **not** part of the current public API and are +therefore not documented as executable examples: - `FlextApiMiddleware` base class - `MiddlewarePipeline` chain @@ -73,6 +74,9 @@ and are therefore not documented as executable examples: - Decorators such as `require_roles` or `require_permissions` - FastAPI `app.add_middleware(...)` integration -If a future release adds a first-class middleware API, this page will be -updated with real, runnable examples. -```` +If a future release adds a first-class middleware API, this page will be updated with +real, runnable examples. + +``` + +``` diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 5912bf40..d2fad776 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -16,7 +16,7 @@ This page documents the schema/model story for `flext-api`. ## Public HTTP Models -``` python +```python from __future__ import annotations from flext_api import c, m @@ -40,16 +40,20 @@ response = m.Api.create_response( assert response.success assert response.status_code == 201 ``` + ## What Is Not Implemented -The following schema concepts are **not** part of the current public API and -are therefore not documented as executable examples: +The following schema concepts are **not** part of the current public API and are +therefore not documented as executable examples: - `OpenApiSchema`, `OpenApiConfig`, `create_fastapi_app` - `AsyncApiSchema`, `JsonSchema`, `JsonSchemaValidator` - `SchemaValidationError`, `JsonSchemaExtension` - FastAPI-specific `response_model` integration -If a future release adds schema generation helpers, this page will be updated -with real, runnable examples. -```` +If a future release adds schema generation helpers, this page will be updated with real, +runnable examples. + +``` + +``` diff --git a/docs/api/storage.md b/docs/api/storage.md index 1665a48c..70e494cc 100644 --- a/docs/api/storage.md +++ b/docs/api/storage.md @@ -15,7 +15,7 @@ This page documents the storage/cache story for `flext-api`. ## Modeling File Payloads with HTTP Models -``` python +```python from __future__ import annotations from flext_api import FlextApi, FlextApiSettings, m, p, r @@ -55,16 +55,20 @@ body = result.unwrap().body assert body["filename"] == "report.txt" assert body["id"] == 1 ``` + ## What Is Not Implemented -The following storage concepts are **not** part of the current public API and -are therefore not documented as executable examples: +The following storage concepts are **not** part of the current public API and are +therefore not documented as executable examples: - `FlextApiStorage`, `FlextApiCache`, `MultiBackendStorage` - `FlextFileProcessor`, `FileUploadMiddleware` - `UploadFile`, `ImageResizer`, `ImageOptimizer`, `VirusScanner` - File lifecycle helpers such as TTL, clear, or size operations -If a future release adds a storage abstraction, this page will be updated with -real, runnable examples. -```` +If a future release adds a storage abstraction, this page will be updated with real, +runnable examples. + +``` + +``` diff --git a/docs/architecture/decisions/002-railway-pattern.md b/docs/architecture/decisions/002-railway-pattern.md index 3989ac2b..dde705b2 100644 --- a/docs/architecture/decisions/002-railway-pattern.md +++ b/docs/architecture/decisions/002-railway-pattern.md @@ -64,7 +64,7 @@ Every public method returns `p.Result[T]`. Operations are composed using `flat_m ### Option 1: Traditional Exceptions -``` python notest +````python notest from __future__ import annotations import httpx @@ -145,10 +145,11 @@ api = FakeUserApi(runtime_settings=FlextApiSettings(base_url="https://example.co result = api.fetch_user(123) assert result.success assert result.unwrap().body["name"] == "Alice" -``` +```` + ### Usage in Application Code -```python notest +````python notest from __future__ import annotations from flext_api import FlextApi, FlextApiSettings, m, p, r @@ -215,7 +216,8 @@ def test_get_user_not_found(): test_get_user_success() test_get_user_not_found() -``` +```` + ## Migration Strategy - [x] Implement `r` integration in all HTTP operations @@ -242,9 +244,12 @@ r[str].fail("Invalid user ID: must be a positive integer") r[str].fail("HTTP request timeout after 30 seconds") r[str].fail("JSON parsing failed: invalid response format") ``` + ## References - [Railway-Oriented Programming](https://fsharpforfunandprofit.com/rop/) - GitHub Issue: #156 - Railway Pattern Implementation -```` +``` + +``` diff --git a/docs/architecture/decisions/003-protocol-abstraction.md b/docs/architecture/decisions/003-protocol-abstraction.md index 7395b005..8f79cd2b 100644 --- a/docs/architecture/decisions/003-protocol-abstraction.md +++ b/docs/architecture/decisions/003-protocol-abstraction.md @@ -52,7 +52,7 @@ a railway result-oriented lifecycle contract. ### Protocol Plugin Manager -``` python +```python from __future__ import annotations from flext_api import FlextApiProtocolPluginManager, FlextApiProtocolPluginTypes, p, r @@ -86,6 +86,7 @@ assert resolve_result.unwrap().version == "1.0.0" assert manager.unload_plugin("json-schema").success ``` + ### HTTP Protocol Facade ```python @@ -119,6 +120,7 @@ result = api.health_check() assert result.success assert result.unwrap().body["status"] == "healthy" ``` + ## What Is Not Implemented The following protocols are **not** currently exposed by `flext-api`: @@ -129,11 +131,13 @@ The following protocols are **not** currently exposed by `flext-api`: - gRPC / Protocol Buffers - MQTT -If a future release adds support for additional protocols, this page will be -updated with real, runnable examples. +If a future release adds support for additional protocols, this page will be updated +with real, runnable examples. ## References - GitHub Issue: #159 - Protocol Plugin Architecture -```` +``` + +``` diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index 33cc2532..b53dc798 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -98,9 +98,10 @@ concerns across multiple layers, designed for extensibility and maintainability. **Domain Patterns:** -``` python +```python from __future__ import annotations ``` + **Key Components:** - **FlextApiClient**: Main HTTP client implementation @@ -117,31 +118,37 @@ FLEXT-API uses a plugin system for protocol extensibility. ```python from __future__ import annotations ``` + ### Request Processing Pipeline ```python from __future__ import annotations ``` + ### Storage Interface ```python from __future__ import annotations ``` + ### Cache Configuration ```python from __future__ import annotations ``` + ### Security Middleware ```python from __future__ import annotations ``` + ### Performance Monitoring ```python from __future__ import annotations ``` + ### Deployment Configuration ```text @@ -162,9 +169,10 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ # Start application CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] ``` + ### Kubernetes Deployment -```yaml +````yaml apiVersion: apps/v1 kind: Deployment metadata: @@ -249,7 +257,8 @@ class CustomProtocol: # Register new protocol registry = ProtocolRegistry() registry.register("custom", CustomProtocol()) -``` +```` + ### Custom Middleware ```python notest @@ -273,6 +282,7 @@ class CustomBusinessMiddleware: # Register middleware app.add_middleware(CustomBusinessMiddleware()) ``` + ## Performance Considerations ### Bottlenecks and Optimization @@ -300,7 +310,7 @@ app.add_middleware(CustomBusinessMiddleware()) ### Monitoring and Optimization -```python notest +````python notest from __future__ import annotations diff --git a/docs/guides/README.md b/docs/guides/README.md index 50d1e89d..710dbc76 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -1,15 +1,13 @@ # flext-api Guides - - No sections found - -Curated operational guides live here. Keep API behavior in generated reference pages -sourced from code and docstrings. +Curated operational guides live here. Keep API behavior in generated reference +pages sourced from code and docstrings. - [Configuration](configuration.md) - [Development](development.md) diff --git a/docs/guides/implementation_status.md b/docs/guides/implementation_status.md index c012a058..5cbd94e0 100644 --- a/docs/guides/implementation_status.md +++ b/docs/guides/implementation_status.md @@ -34,8 +34,8 @@ platform. **Current Status**: Production foundation implemented · 23 tests passing, 76 failing -(28% pass rate) · 2,927 lines across 14 modules **Quality Gates**: Linting ✅ · -checking ❌ (295 errors) · Security ✅ +(28% pass rate) · 2,927 lines across 14 modules **Quality Gates**: Linting ✅ · checking +❌ (295 errors) · Security ✅ ## Implementation Progress Summary diff --git a/docs/index.md b/docs/index.md index 7797bc22..7bd4776e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,13 +1,11 @@ # flext-api Documentation - - [Start Here](#start-here) - [Public Surface Summary](#public-surface-summary) - [Collection Rules](#collection-rules) - [Quality Gates](#quality-gates) - [Governance Pointer](#governance-pointer) - @@ -17,8 +15,8 @@ - Package: `flext_api` - Description: FLEXT API - High-Performance REST API with FastAPI -This project portal is generated from `pyproject.toml`, package exports, and real -docstrings. +This project portal is generated from `pyproject.toml`, package exports, and +real docstrings. ## Start Here @@ -29,20 +27,25 @@ docstrings. ## Public Surface Summary -::: flext_api options: members: false show_root_heading: false show_root_toc_entry: -false show_source: false +::: flext_api + options: + members: false + show_root_heading: false + show_root_toc_entry: false + show_source: false ## Collection Rules -Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent -FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry -verification). +Read +[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist +(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, +slot registry verification). ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared -operations directly — see +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their +declared operations directly — see [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) `Build & Test` and `Required Python quality gates`. diff --git a/mkdocs.yml b/mkdocs.yml index d918818c..afd2be6d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -38,6 +38,7 @@ theme: icon: material/weather-sunny name: Switch to light mode + plugins: - search - autorefs diff --git a/src/flext_api/__init__.py b/src/flext_api/__init__.py index cd15aaf5..f190bad6 100644 --- a/src/flext_api/__init__.py +++ b/src/flext_api/__init__.py @@ -30,7 +30,17 @@ from .cli import FlextApiCli from .constants import FlextApiConstants, FlextApiConstants as c from .models import FlextApiModels, FlextApiModels as m - from .protocols import FlextApiProtocols, FlextApiProtocols as p + from .protocols import ( + FlextApiProtocols, + FlextApiProtocols as p, + HttpxAsyncClient, + HttpxClient, + HttpxHTTPError, + HttpxHTTPStatusError, + HttpxRequestError, + HttpxResponse, + HttpxTimeoutException, + ) from .services.async_client import FlextApiAsyncClient from .services.base_client import FlextApiClientBase from .services.client import FlextApiClient @@ -50,6 +60,13 @@ "FlextApiSettings", "FlextApiTypes", "FlextApiUtilities", + "HttpxAsyncClient", + "HttpxClient", + "HttpxHTTPError", + "HttpxHTTPStatusError", + "HttpxRequestError", + "HttpxResponse", + "HttpxTimeoutException", "__author__", "__author_email__", "__description__", @@ -85,7 +102,17 @@ ".cli": ("FlextApiCli",), ".constants": ("FlextApiConstants", "c"), ".models": ("FlextApiModels", "m"), - ".protocols": ("FlextApiProtocols", "p"), + ".protocols": ( + "FlextApiProtocols", + "HttpxAsyncClient", + "HttpxClient", + "HttpxHTTPError", + "HttpxHTTPStatusError", + "HttpxRequestError", + "HttpxResponse", + "HttpxTimeoutException", + "p", + ), ".services": ("services",), ".services.async_client": ("FlextApiAsyncClient",), ".services.base_client": ("FlextApiClientBase",), From 1d19d8b988d159b40a592648cae10da0c5c8d8ae Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Fri, 18 Sep 2026 21:04:08 -0300 Subject: [PATCH 4/6] fix(docs): repair markdown code-fence structure; converge projections with 1f0add99 - Normalized corrupted fences (4-backtick openers, indented closers, orphan pairs) in docs/architecture/decisions/002-railway-pattern.md and docs/api/core.md so embedded python blocks extract cleanly (markdown-code gate: 41 -> 0 findings) - prettier reflow via canonical make fmt (markdown-format: 9 -> 0) - gen fixed point against integration tip 1f0add99 --- README.md | 41 ++++++++----------- docs/api-reference/README.md | 5 ++- docs/api-reference/generated/modules/index.md | 1 + docs/api-reference/generated/overview.md | 11 ++--- docs/api-reference/generated/public-api.md | 8 ++-- docs/api/core.md | 20 +++++---- .../decisions/002-railway-pattern.md | 21 +++++----- docs/guides/README.md | 5 ++- docs/index.md | 26 +++++------- 9 files changed, 66 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 79d1bb80..6114f852 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # flext-api + - [Purpose](#purpose) - [Module Map](#module-map) - [Collection Rules](#collection-rules) @@ -14,9 +15,9 @@ **Version**: `0.12.0` | **Python**: 3.13+ | **Project class**: `domain` -> **Alpha (0.12.0).** This package is alpha quality. Every package in the -> workspace must be re-checked and re-validated at 0.12.0 before any promotion -> beyond alpha; treat interfaces as unstable. +> **Alpha (0.12.0).** This package is alpha quality. Every package in the workspace must +> be re-checked and re-validated at 0.12.0 before any promotion beyond alpha; treat +> interfaces as unstable. ## Purpose @@ -24,20 +25,15 @@ FLEXT API - High-Performance REST API with FastAPI ## Module Map -::: flext_api - options: - members: false - show_root_heading: false - show_root_toc_entry: false - show_source: false +::: flext_api options: members: false show_root_heading: false show_root_toc_entry: +false show_source: false ## Collection Rules -Read -[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist -(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, -slot registry verification). +Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent +FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry +verification). ## Operation Flow @@ -45,23 +41,22 @@ slot registry verification). [`docs/api-reference/README.md`](docs/api-reference/README.md). - Generated module overview: [`docs/api-reference/generated/overview.md`](docs/api-reference/generated/overview.md). -- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and - `FlextSettings` ConfigDict. +- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and `FlextSettings` + ConfigDict. ## Integration Points -- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array - filtered by `flext-*`. The FLEXT cascade is encoded in the inheritance lists - of the facade classes listed under Module Map above. +- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array filtered + by `flext-*`. The FLEXT cascade is encoded in the inheritance lists of the facade + classes listed under Module Map above. - Public extensions exposed by this project: `FlextApi`, `FlextApiAsyncClient`, - `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 - more). + `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more). - Library abstraction boundaries: see AGENTS.md §2.7. ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their -declared operations directly — see +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared +operations directly — see [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) `Build & Test` and `Required Python quality gates`. diff --git a/docs/api-reference/README.md b/docs/api-reference/README.md index 19ef92fe..166c7ebd 100644 --- a/docs/api-reference/README.md +++ b/docs/api-reference/README.md @@ -1,6 +1,7 @@ # flext-api API Reference + - [Source of Truth](#source-of-truth) - [Generated Pages](#generated-pages) - [Surface Summary](#surface-summary) @@ -25,8 +26,8 @@ This section is generated from public exports and real docstrings. ## Surface Summary -- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, - `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more) +- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, + `FlextApiClientBase`, `FlextApiConfig` (+7 more) - Generated module pages: `12` Back to [project docs](../index.md). diff --git a/docs/api-reference/generated/modules/index.md b/docs/api-reference/generated/modules/index.md index d8f682b9..70ea5bd0 100644 --- a/docs/api-reference/generated/modules/index.md +++ b/docs/api-reference/generated/modules/index.md @@ -1,6 +1,7 @@ # flext-api Module Index + - No sections found diff --git a/docs/api-reference/generated/overview.md b/docs/api-reference/generated/overview.md index 9bef9eb6..3ad880a2 100644 --- a/docs/api-reference/generated/overview.md +++ b/docs/api-reference/generated/overview.md @@ -1,6 +1,7 @@ # flext-api API Overview + - [Next Pages](#next-pages) @@ -12,13 +13,13 @@ - Doc summary: Flext Api package. - Classifiers: `Development Status :: 3 - Alpha`, `Framework :: FastAPI`, `Intended Audience :: Developers`, `Operating System :: OS Independent`, - `Programming Language :: Python :: 3 :: Only`, `Programming Language :: Python - :: 3.13` (+3 more) + `Programming Language :: Python :: 3 :: Only`, + `Programming Language :: Python :: 3.13` (+3 more) - Project class: `domain` - Keywords: `enterprise`, `fastapi`, `flext`, `http`, `rest`, `typed` -- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, - `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, - `FlextApiModels` (+5 more) +- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, + `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, `FlextApiModels` (+5 + more) - Alias exports: `c`, `d`, `e`, `h`, `m`, `p`, `r`, `s`, `t`, `u`, `x` - Public symbol exports: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, diff --git a/docs/api-reference/generated/public-api.md b/docs/api-reference/generated/public-api.md index 11a74b2f..2aa72e5e 100644 --- a/docs/api-reference/generated/public-api.md +++ b/docs/api-reference/generated/public-api.md @@ -1,13 +1,11 @@ # flext-api Public API + - No sections found -::: flext_api - options: - show_root_heading: true - show_root_full_path: false - show_source: false +::: flext_api options: show_root_heading: true show_root_full_path: false show_source: +false diff --git a/docs/api/core.md b/docs/api/core.md index 5521060a..2c3ba91e 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -28,7 +28,7 @@ executes validated `m.Api.HttpRequest` instances through `request(...)`. It does expose `get/post/put/delete/patch` directly; those methods live on the `FlextApi` facade. -````python notest +```python notest from __future__ import annotations from flext_api import FlextApiClient, FlextApiSettings, c, m, p @@ -62,7 +62,8 @@ if result.success: print(response.body) else: print(f"Transport error: {result.error}") - ``` +``` + **Key Features:** - Type-safe HTTP operations via Pydantic models @@ -80,8 +81,8 @@ else: ### FlextApi - Unified Facade -`FlextApi` is the public entry point. It creates and owns a `FlextApiClient` -lazily and exposes convenience methods for each HTTP verb. +`FlextApi` is the public entry point. It creates and owns a `FlextApiClient` lazily and +exposes convenience methods for each HTTP verb. ```python from __future__ import annotations @@ -102,7 +103,8 @@ if result.success: print(f"Body: {response.body}") else: print(f"Error: {result.error}") - ``` +``` + ### HTTP Methods All methods return `p.Result[m.Api.HttpResponse]`. @@ -121,7 +123,7 @@ result: p.Result[m.Api.HttpResponse] = api.get("/users") result = api.get("/users", request_kwargs={"params": {"limit": 10, "offset": 0}}) result = api.get("/users", headers={"Accept": "application/json"}) -```` +``` **POST/PUT/PATCH/DELETE Requests:** @@ -268,7 +270,7 @@ print(timeout_result.unwrap()) ### Complete HTTP Client Example -````python notest +```python notest from __future__ import annotations from flext_api import FlextApi, FlextApiSettings, m, p, r @@ -367,8 +369,8 @@ if update_result.success: delete_result = client.delete_user(1) if delete_result.success: print(f"Deleted user, status: {delete_result.unwrap().status_code}") - ``` +``` + This core API provides the public HTTP surface for `flext-api`: typed settings, a validated request model, a monadic response model, and the `FlextApi` facade for convenient HTTP verbs. -```` diff --git a/docs/architecture/decisions/002-railway-pattern.md b/docs/architecture/decisions/002-railway-pattern.md index dde705b2..5e02d64d 100644 --- a/docs/architecture/decisions/002-railway-pattern.md +++ b/docs/architecture/decisions/002-railway-pattern.md @@ -64,7 +64,7 @@ Every public method returns `p.Result[T]`. Operations are composed using `flat_m ### Option 1: Traditional Exceptions -````python notest +```python notest from __future__ import annotations import httpx @@ -75,7 +75,8 @@ def get_user(user_id: int) -> dict: response = httpx.get(f"https://api.example.com/users/{user_id}") response.raise_for_status() return response.json() - ``` +``` + ### Option 2: Result Pattern (Custom Implementation) ```python @@ -89,7 +90,8 @@ class Result: self.success = success self.value = value self.error = error - ``` +``` + ### Option 3: Hybrid Approach - **Description**: Use railway pattern internally but expose traditional APIs @@ -145,11 +147,11 @@ api = FakeUserApi(runtime_settings=FlextApiSettings(base_url="https://example.co result = api.fetch_user(123) assert result.success assert result.unwrap().body["name"] == "Alice" -```` +``` ### Usage in Application Code -````python notest +```python notest from __future__ import annotations from flext_api import FlextApi, FlextApiSettings, m, p, r @@ -176,7 +178,8 @@ if result.success: print(f"Found profile: {profile['bio']}") else: print(f"Error: {result.error}") - ``` +``` + ### Testing Railway Code ```python @@ -216,7 +219,7 @@ def test_get_user_not_found(): test_get_user_success() test_get_user_not_found() -```` +``` ## Migration Strategy @@ -249,7 +252,3 @@ r[str].fail("JSON parsing failed: invalid response format") - [Railway-Oriented Programming](https://fsharpforfunandprofit.com/rop/) - GitHub Issue: #156 - Railway Pattern Implementation - -``` - -``` diff --git a/docs/guides/README.md b/docs/guides/README.md index 710dbc76..898accc3 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -1,13 +1,14 @@ # flext-api Guides + - No sections found -Curated operational guides live here. Keep API behavior in generated reference -pages sourced from code and docstrings. +Curated operational guides live here. Keep API behavior in generated reference pages +sourced from code and docstrings. - [Configuration](configuration.md) - [Development](development.md) diff --git a/docs/index.md b/docs/index.md index 7bd4776e..2b7c4082 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,7 @@ # flext-api Documentation + - [Start Here](#start-here) - [Public Surface Summary](#public-surface-summary) - [Collection Rules](#collection-rules) @@ -15,8 +16,8 @@ - Package: `flext_api` - Description: FLEXT API - High-Performance REST API with FastAPI -This project portal is generated from `pyproject.toml`, package exports, and -real docstrings. +This project portal is generated from `pyproject.toml`, package exports, and real +docstrings. ## Start Here @@ -27,25 +28,20 @@ real docstrings. ## Public Surface Summary -::: flext_api - options: - members: false - show_root_heading: false - show_root_toc_entry: false - show_source: false +::: flext_api options: members: false show_root_heading: false show_root_toc_entry: +false show_source: false ## Collection Rules -Read -[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist -(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, -slot registry verification). +Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent +FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry +verification). ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their -declared operations directly — see +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared +operations directly — see [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) `Build & Test` and `Required Python quality gates`. From 9bd15596b26885bb301905b7bc7e6c4696ae0ede Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Fri, 18 Sep 2026 21:11:37 -0300 Subject: [PATCH 5/6] chore(gen): fixed-point render resolved against infra tip a0df83a5 --- README.md | 41 +++++++++++-------- docs/api-reference/README.md | 5 +-- docs/api-reference/generated/modules/index.md | 1 - docs/api-reference/generated/overview.md | 11 +++-- docs/api-reference/generated/public-api.md | 8 ++-- docs/guides/README.md | 5 +-- docs/index.md | 26 +++++++----- 7 files changed, 52 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 6114f852..79d1bb80 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # flext-api - - [Purpose](#purpose) - [Module Map](#module-map) - [Collection Rules](#collection-rules) @@ -15,9 +14,9 @@ **Version**: `0.12.0` | **Python**: 3.13+ | **Project class**: `domain` -> **Alpha (0.12.0).** This package is alpha quality. Every package in the workspace must -> be re-checked and re-validated at 0.12.0 before any promotion beyond alpha; treat -> interfaces as unstable. +> **Alpha (0.12.0).** This package is alpha quality. Every package in the +> workspace must be re-checked and re-validated at 0.12.0 before any promotion +> beyond alpha; treat interfaces as unstable. ## Purpose @@ -25,15 +24,20 @@ FLEXT API - High-Performance REST API with FastAPI ## Module Map -::: flext_api options: members: false show_root_heading: false show_root_toc_entry: -false show_source: false +::: flext_api + options: + members: false + show_root_heading: false + show_root_toc_entry: false + show_source: false ## Collection Rules -Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent -FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry -verification). +Read +[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist +(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, +slot registry verification). ## Operation Flow @@ -41,22 +45,23 @@ verification). [`docs/api-reference/README.md`](docs/api-reference/README.md). - Generated module overview: [`docs/api-reference/generated/overview.md`](docs/api-reference/generated/overview.md). -- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and `FlextSettings` - ConfigDict. +- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and + `FlextSettings` ConfigDict. ## Integration Points -- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array filtered - by `flext-*`. The FLEXT cascade is encoded in the inheritance lists of the facade - classes listed under Module Map above. +- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array + filtered by `flext-*`. The FLEXT cascade is encoded in the inheritance lists + of the facade classes listed under Module Map above. - Public extensions exposed by this project: `FlextApi`, `FlextApiAsyncClient`, - `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more). + `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 + more). - Library abstraction boundaries: see AGENTS.md §2.7. ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared -operations directly — see +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their +declared operations directly — see [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) `Build & Test` and `Required Python quality gates`. diff --git a/docs/api-reference/README.md b/docs/api-reference/README.md index 166c7ebd..19ef92fe 100644 --- a/docs/api-reference/README.md +++ b/docs/api-reference/README.md @@ -1,7 +1,6 @@ # flext-api API Reference - - [Source of Truth](#source-of-truth) - [Generated Pages](#generated-pages) - [Surface Summary](#surface-summary) @@ -26,8 +25,8 @@ This section is generated from public exports and real docstrings. ## Surface Summary -- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig` (+7 more) +- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more) - Generated module pages: `12` Back to [project docs](../index.md). diff --git a/docs/api-reference/generated/modules/index.md b/docs/api-reference/generated/modules/index.md index 70ea5bd0..d8f682b9 100644 --- a/docs/api-reference/generated/modules/index.md +++ b/docs/api-reference/generated/modules/index.md @@ -1,7 +1,6 @@ # flext-api Module Index - - No sections found diff --git a/docs/api-reference/generated/overview.md b/docs/api-reference/generated/overview.md index 3ad880a2..9bef9eb6 100644 --- a/docs/api-reference/generated/overview.md +++ b/docs/api-reference/generated/overview.md @@ -1,7 +1,6 @@ # flext-api API Overview - - [Next Pages](#next-pages) @@ -13,13 +12,13 @@ - Doc summary: Flext Api package. - Classifiers: `Development Status :: 3 - Alpha`, `Framework :: FastAPI`, `Intended Audience :: Developers`, `Operating System :: OS Independent`, - `Programming Language :: Python :: 3 :: Only`, - `Programming Language :: Python :: 3.13` (+3 more) + `Programming Language :: Python :: 3 :: Only`, `Programming Language :: Python + :: 3.13` (+3 more) - Project class: `domain` - Keywords: `enterprise`, `fastapi`, `flext`, `http`, `rest`, `typed` -- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, - `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, `FlextApiModels` (+5 - more) +- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, + `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, + `FlextApiModels` (+5 more) - Alias exports: `c`, `d`, `e`, `h`, `m`, `p`, `r`, `s`, `t`, `u`, `x` - Public symbol exports: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, diff --git a/docs/api-reference/generated/public-api.md b/docs/api-reference/generated/public-api.md index 2aa72e5e..11a74b2f 100644 --- a/docs/api-reference/generated/public-api.md +++ b/docs/api-reference/generated/public-api.md @@ -1,11 +1,13 @@ # flext-api Public API - - No sections found -::: flext_api options: show_root_heading: true show_root_full_path: false show_source: -false +::: flext_api + options: + show_root_heading: true + show_root_full_path: false + show_source: false diff --git a/docs/guides/README.md b/docs/guides/README.md index 898accc3..710dbc76 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -1,14 +1,13 @@ # flext-api Guides - - No sections found -Curated operational guides live here. Keep API behavior in generated reference pages -sourced from code and docstrings. +Curated operational guides live here. Keep API behavior in generated reference +pages sourced from code and docstrings. - [Configuration](configuration.md) - [Development](development.md) diff --git a/docs/index.md b/docs/index.md index 2b7c4082..7bd4776e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,6 @@ # flext-api Documentation - - [Start Here](#start-here) - [Public Surface Summary](#public-surface-summary) - [Collection Rules](#collection-rules) @@ -16,8 +15,8 @@ - Package: `flext_api` - Description: FLEXT API - High-Performance REST API with FastAPI -This project portal is generated from `pyproject.toml`, package exports, and real -docstrings. +This project portal is generated from `pyproject.toml`, package exports, and +real docstrings. ## Start Here @@ -28,20 +27,25 @@ docstrings. ## Public Surface Summary -::: flext_api options: members: false show_root_heading: false show_root_toc_entry: -false show_source: false +::: flext_api + options: + members: false + show_root_heading: false + show_root_toc_entry: false + show_source: false ## Collection Rules -Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent -FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry -verification). +Read +[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist +(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, +slot registry verification). ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared -operations directly — see +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their +declared operations directly — see [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) `Build & Test` and `Required Python quality gates`. From 7bccc2b19263273c46eb41d88d967ab7b11cd6b8 Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Sat, 19 Sep 2026 01:23:17 -0300 Subject: [PATCH 6/6] fix(tests): test facades declare one nested Tests MRO (NS-STRUCT-001) The new namespace structure rule requires each test facade to declare exactly one nested class composing the production letter. The five test facades carried empty helper nesteds plus a second Tests class; collapsed to the canonical single Tests MRO shape. Full check (19 gates) and test suite green locally. --- .envrc | 5 ++- .github/workflows/ci.yml | 2 +- .github/workflows/docs.yml | 2 +- .gitignore | 3 -- Makefile | 12 +++--- README.md | 40 ++++++++++--------- docs/api-reference/README.md | 6 ++- docs/api-reference/generated/modules/index.md | 2 + docs/api-reference/generated/overview.md | 16 ++++---- docs/api-reference/generated/public-api.md | 3 ++ docs/guides/README.md | 6 ++- docs/index.md | 25 +++++++----- tests/constants.py | 8 +--- tests/models.py | 8 +--- tests/protocols.py | 8 +--- tests/typings.py | 8 +--- tests/utilities.py | 8 +--- 17 files changed, 73 insertions(+), 89 deletions(-) diff --git a/.envrc b/.envrc index 9495d001..882679b7 100644 --- a/.envrc +++ b/.envrc @@ -32,7 +32,8 @@ PROJECT_SCRATCH_IDENTITY="${PROJECT_SCRATCH_IDENTITY%/}" PROJECT_SCRATCH="${HOME}/tmp/.flext-runtime${PROJECT_SCRATCH_IDENTITY}/scratch" mkdir -p "${PROJECT_SCRATCH}" if command -v chattr >/dev/null 2>&1; then - if [[ "$(stat -f -c %T "${PROJECT_SCRATCH}")" == "btrfs" ]]; then + project_scratch_fs="$(stat -f -c %T "${PROJECT_SCRATCH}" 2>/dev/null || true)" + if [[ "${project_scratch_fs}" == "btrfs" ]]; then chattr +C "${PROJECT_SCRATCH}" fi fi @@ -92,7 +93,7 @@ if [[ -v AGENTS_GAS_CITY_ROOT ]]; then # Source: typed BeadsWorkspaceEnvironmentSpec shared by both direnv profiles. # Environment sources are host-provided and optional: isolated CI must still # activate while a city-connected host keeps their exports. -source_env_if_exists "$HOME/.config/environment.d/projects/agent-tools.envrc" +source_env_if_exists "${HOME}/.config/environment.d/projects/agent-tools.envrc" # End SECTION: beads watched inputs # === SECTION: canonical roots (managed) === diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5fbd5a35..e23f1b0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,7 +164,7 @@ jobs: run: CI=Y make check # Why (aihub-v01jg): CI=Y runs ONE HALF of the gate set - # (lint pyright silent-failure deferred-self-reference security markdown markdown-format loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication); the complement + # (lint pyright silent-failure deferred-self-reference security markdown loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication); the complement # (pyrefly mypy) is owned by # CI=N and, without this step, ran on developer # machines only. That split let real defects reach main twice: five diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 846038d5..9629e040 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -135,7 +135,7 @@ jobs: pages: write id-token: write environment: - name: ${{ 'github-pages' }} + name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - name: Deploy to GitHub Pages diff --git a/.gitignore b/.gitignore index 0ff5810b..fd23f07b 100644 --- a/.gitignore +++ b/.gitignore @@ -372,9 +372,6 @@ CLAUDE.local.md !.github/workflows/ci.yml !.github/workflows/docs.yml !.github/workflows/release.yml -!.github/workflows/_fragments/ -!.github/workflows/_fragments/cross_repo_dependency_credential -!.github/workflows/_fragments/testmon_cache !.qlty/ !.qlty/qlty.toml !.vscode/settings.json diff --git a/Makefile b/Makefile index ec2ade9a..c24dd73f 100644 --- a/Makefile +++ b/Makefile @@ -1037,10 +1037,10 @@ _builtin-self-test: _builtin_require_environment _builtin-self-check: _builtin_require_environment @set -eu; \ - gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ if [ "$(strip $(CI))" = "Y" ]; then \ - gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ - printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown markdown-format loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ + gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ fi; \ if [ -z "$$gates" ]; then \ printf 'ERROR: no check gates remain after CI=Y filtering\n' >&2; \ @@ -1075,10 +1075,10 @@ _builtin_build_artifacts: # make.ci.local_check_gates. _builtin_check_all: _builtin_require_environment @set -eu; \ - gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + gates="lint,pyrefly,mypy,pyright,silent-failure,deferred-self-reference,security,markdown,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ if [ "$(strip $(CI))" = "Y" ]; then \ - gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,markdown-format,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ - printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown markdown-format loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ + gates="lint,pyright,silent-failure,deferred-self-reference,security,markdown,loc-cap,boundary,runtime-census,namespace,tier-whitelist,index-declarations,smells,codemod,layout,canonical-alias,direnv,duplication"; \ + printf 'INFO: CI=Y runs check gates: lint pyright silent-failure deferred-self-reference security markdown loc-cap boundary runtime-census namespace tier-whitelist index-declarations smells codemod layout canonical-alias direnv duplication\n'; \ fi; \ if [ -z "$$gates" ]; then \ printf 'ERROR: no check gates remain after CI=Y filtering\n' >&2; \ diff --git a/README.md b/README.md index 79d1bb80..9e12c331 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # flext-api + - [Purpose](#purpose) - [Module Map](#module-map) - [Collection Rules](#collection-rules) @@ -8,15 +9,16 @@ - [Integration Points](#integration-points) - [Quality Gates](#quality-gates) - [Governance Pointer](#governance-pointer) + **Version**: `0.12.0` | **Python**: 3.13+ | **Project class**: `domain` -> **Alpha (0.12.0).** This package is alpha quality. Every package in the -> workspace must be re-checked and re-validated at 0.12.0 before any promotion -> beyond alpha; treat interfaces as unstable. +> **Alpha (0.12.0).** This package is alpha quality. Every package in the workspace must +> be re-checked and re-validated at 0.12.0 before any promotion beyond alpha; treat +> interfaces as unstable. ## Purpose @@ -25,6 +27,7 @@ FLEXT API - High-Performance REST API with FastAPI ## Module Map ::: flext_api + options: members: false show_root_heading: false @@ -33,11 +36,10 @@ FLEXT API - High-Performance REST API with FastAPI ## Collection Rules -Read -[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist -(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, -slot registry verification). +Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent +FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry +verification). ## Operation Flow @@ -45,25 +47,25 @@ slot registry verification). [`docs/api-reference/README.md`](docs/api-reference/README.md). - Generated module overview: [`docs/api-reference/generated/overview.md`](docs/api-reference/generated/overview.md). -- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and - `FlextSettings` ConfigDict. +- Settings env prefix: see project `pyproject.toml` `[tool.flext]` and `FlextSettings` + ConfigDict. ## Integration Points -- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array - filtered by `flext-*`. The FLEXT cascade is encoded in the inheritance lists - of the facade classes listed under Module Map above. +- Parent FLEXT chain: read this project's `pyproject.toml` `dependencies` array filtered + by `flext-*`. The FLEXT cascade is encoded in the inheritance lists of the facade + classes listed under Module Map above. - Public extensions exposed by this project: `FlextApi`, `FlextApiAsyncClient`, - `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 - more). + `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more). - Library abstraction boundaries: see AGENTS.md §2.7. ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their -declared operations directly — see -[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -`Build & Test` and `Required Python quality gates`. +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared +operations directly. + +See [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +for the build, test, and Python quality gates. ## Governance Pointer diff --git a/docs/api-reference/README.md b/docs/api-reference/README.md index 19ef92fe..81f947ec 100644 --- a/docs/api-reference/README.md +++ b/docs/api-reference/README.md @@ -1,9 +1,11 @@ # flext-api API Reference + - [Source of Truth](#source-of-truth) - [Generated Pages](#generated-pages) - [Surface Summary](#surface-summary) + @@ -25,8 +27,8 @@ This section is generated from public exports and real docstrings. ## Surface Summary -- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, - `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig` (+7 more) +- Primary facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, + `FlextApiClientBase`, `FlextApiConfig` (+7 more) - Generated module pages: `12` Back to [project docs](../index.md). diff --git a/docs/api-reference/generated/modules/index.md b/docs/api-reference/generated/modules/index.md index d8f682b9..9277a473 100644 --- a/docs/api-reference/generated/modules/index.md +++ b/docs/api-reference/generated/modules/index.md @@ -1,7 +1,9 @@ # flext-api Module Index + - No sections found + diff --git a/docs/api-reference/generated/overview.md b/docs/api-reference/generated/overview.md index 9bef9eb6..83e9895d 100644 --- a/docs/api-reference/generated/overview.md +++ b/docs/api-reference/generated/overview.md @@ -1,7 +1,9 @@ # flext-api API Overview + - [Next Pages](#next-pages) + @@ -10,15 +12,15 @@ - Version: `0.12.0` - Description: FLEXT API - High-Performance REST API with FastAPI - Doc summary: Flext Api package. -- Classifiers: `Development Status :: 3 - Alpha`, `Framework :: FastAPI`, - `Intended Audience :: Developers`, `Operating System :: OS Independent`, - `Programming Language :: Python :: 3 :: Only`, `Programming Language :: Python - :: 3.13` (+3 more) +- Classifiers: Development Status :: 3 - Alpha, Framework :: FastAPI, Intended Audience + :: Developers, Operating System :: OS Independent, Programming Language :: Python :: 3 + :: Only, Programming Language :: Python :: 3.13, Topic :: Internet :: WWW/HTTP :: HTTP + Servers, Topic :: Software Development :: Libraries :: Python Modules, Typing :: Typed - Project class: `domain` - Keywords: `enterprise`, `fastapi`, `flext`, `http`, `rest`, `typed` -- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, - `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, - `FlextApiModels` (+5 more) +- Main facades: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, + `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, `FlextApiModels` (+5 + more) - Alias exports: `c`, `d`, `e`, `h`, `m`, `p`, `r`, `s`, `t`, `u`, `x` - Public symbol exports: `FlextApi`, `FlextApiAsyncClient`, `FlextApiCli`, `FlextApiClient`, `FlextApiClientBase`, `FlextApiConfig`, `FlextApiConstants`, diff --git a/docs/api-reference/generated/public-api.md b/docs/api-reference/generated/public-api.md index 11a74b2f..3025a431 100644 --- a/docs/api-reference/generated/public-api.md +++ b/docs/api-reference/generated/public-api.md @@ -1,12 +1,15 @@ # flext-api Public API + - No sections found + ::: flext_api + options: show_root_heading: true show_root_full_path: false diff --git a/docs/guides/README.md b/docs/guides/README.md index 710dbc76..50d1e89d 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -1,13 +1,15 @@ # flext-api Guides + - No sections found + -Curated operational guides live here. Keep API behavior in generated reference -pages sourced from code and docstrings. +Curated operational guides live here. Keep API behavior in generated reference pages +sourced from code and docstrings. - [Configuration](configuration.md) - [Development](development.md) diff --git a/docs/index.md b/docs/index.md index 7bd4776e..2876bede 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,13 @@ # flext-api Documentation + - [Start Here](#start-here) - [Public Surface Summary](#public-surface-summary) - [Collection Rules](#collection-rules) - [Quality Gates](#quality-gates) - [Governance Pointer](#governance-pointer) + @@ -15,8 +17,8 @@ - Package: `flext_api` - Description: FLEXT API - High-Performance REST API with FastAPI -This project portal is generated from `pyproject.toml`, package exports, and -real docstrings. +This project portal is generated from `pyproject.toml`, package exports, and real +docstrings. ## Start Here @@ -28,6 +30,7 @@ real docstrings. ## Public Surface Summary ::: flext_api + options: members: false show_root_heading: false @@ -36,18 +39,18 @@ real docstrings. ## Collection Rules -Read -[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist -(parent FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, -slot registry verification). +Read [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +§9 — Agent Execution Pre-requisites — for the canonical pre-change checklist (parent +FLEXT chain, Scope bootstrap, skill loading, zero-debt baseline, slot registry +verification). ## Quality Gates -Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their -declared operations directly — see -[`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) -`Build & Test` and `Required Python quality gates`. +Canonical `make` verbs (`gen`, `check`, `test`, `fmt`, `docs`) execute their declared +operations directly. + +See [`/flext/AGENTS.md`](https://github.com/flext-sh/flext/blob/0.12.0-dev/AGENTS.md) +for the build, test, and Python quality gates. ## Governance Pointer diff --git a/tests/constants.py b/tests/constants.py index 22fb86aa..e3d4a908 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -12,13 +12,7 @@ class TestsFlextApiConstants(c): """Test constants for flext-api — extends flext_api.c.""" - class _ApiConstants: - """API-specific test constants.""" - - class _WebConstants: - """Web-specific test constants.""" - - class TestsFlextApi(_ApiConstants, _WebConstants): + class Tests(c): """Test-specific constants.""" diff --git a/tests/models.py b/tests/models.py index bf753146..e25d2bec 100644 --- a/tests/models.py +++ b/tests/models.py @@ -12,13 +12,7 @@ class TestsFlextApiModels(m): """Test models for flext-api — extends flext_api.m.""" - class _RequestModels: - """Request-specific test models.""" - - class _ResponseModels: - """Response-specific test models.""" - - class TestsFlextApi(_RequestModels, _ResponseModels): + class Tests(m): """Test-specific models.""" diff --git a/tests/protocols.py b/tests/protocols.py index c95607a1..f44ad17e 100644 --- a/tests/protocols.py +++ b/tests/protocols.py @@ -12,13 +12,7 @@ class TestsFlextApiProtocols(p): """Test protocols for flext-api — extends flext_api.p.""" - class _ClientProtocols: - """Client-specific test protocols.""" - - class _TransportProtocols: - """Transport-specific test protocols.""" - - class TestsFlextApi(_ClientProtocols, _TransportProtocols): + class Tests(p): """Test-specific protocols.""" diff --git a/tests/typings.py b/tests/typings.py index 31cd7ed9..b2fac909 100644 --- a/tests/typings.py +++ b/tests/typings.py @@ -12,13 +12,7 @@ class TestsFlextApiTypes(t): """Test type aliases for flext-api — extends flext_api.t.""" - class _RequestTypes: - """Request-specific test type aliases.""" - - class _ResponseTypes: - """Response-specific test type aliases.""" - - class TestsFlextApi(_RequestTypes, _ResponseTypes): + class Tests(t): """Test-specific type aliases.""" diff --git a/tests/utilities.py b/tests/utilities.py index b344e5d9..a598b4b0 100644 --- a/tests/utilities.py +++ b/tests/utilities.py @@ -12,13 +12,7 @@ class TestsFlextApiUtilities(u): """Test utilities for flext-api — extends flext_api.u.""" - class _RequestUtilities: - """Request-specific test utilities.""" - - class _ResponseUtilities: - """Response-specific test utilities.""" - - class TestsFlextApi(_RequestUtilities, _ResponseUtilities): + class Tests(u): """Test-specific utilities."""