api_runner.py ============= .. module:: api_runner Parses markdown API documentation to generate JSON configs and runs them. Classes ------- .. py:class:: ApiEndpoint Data class representing a single API endpoint parsed from markdown. .. py:attribute:: path :type: str .. py:attribute:: description :type: str .. py:attribute:: method :type: str .. py:attribute:: url :type: str .. py:attribute:: content_type :type: str .. py:attribute:: headers :type: list[dict] .. py:attribute:: parameters :type: list[dict] .. py:attribute:: body_params :type: list[dict] .. py:attribute:: response_example :type: str .. py:attribute:: file_name :type: str .. py:method:: to_dict() -> dict Serialize the endpoint to a dictionary. .. py:method:: __str__() -> str Return a human-readable summary: ``METHOD path - description``. .. py:class:: ApiRunner(api_dir="./", config_dir="config") Orchestrates config generation and execution. .. py:method:: _load_auth_properties() -> dict Load ``auth.properties`` from ``api_dir`` if it exists. .. py:method:: load_endpoints() -> None Read all ``*.md`` files in ``api_dir`` and parse them into ``ApiEndpoint`` instances. .. py:method:: parse_markdown_file(file_path) -> ApiEndpoint | None Parse a single markdown spec file. **Extraction rules:** * Line 0 → ``path`` * Line 1 → ``description`` * Regex ``(GET|POST|PUT|DELETE|PATCH) (https?://\S+)`` → ``method``, ``url`` * Regex ``Content type\n\s*\|\s*([^\n]+)`` → ``content_type`` * ``Headers`` table → list of dicts with ``name``, ``type``, ``description`` * ``Parameters`` table → list of dicts with ``name``, ``type``, ``required``, ``description`` * ``Body payload`` table → list of dicts with ``name``, ``type`` * ``Response`` section → ``response_example`` string .. py:method:: generate_config_files() -> None Create JSON configs in ``config_dir`` for every loaded endpoint. Default config structure: .. code-block:: json { "endpoint": { ... }, "config": { "headers": {}, "path_params": {}, "query_params": {}, "body": {} } } Body defaults are typed based on the parameter type declared in markdown: ``object``/``array`` → ``{}``, ``number`` → ``0``, ``boolean`` → ``False``, everything else → ``""``. .. py:method:: list_apis() -> None Print all generated configs with method, path, and description. .. py:method:: run_api(api_name) -> bool Execute a single API using its JSON config. Special handling for ``auth-signin``: creates a temporary ``ApiClient`` with an empty token to avoid auth prompts. For non-auth APIs, injects ``access_token`` and ``id_token`` from ``auth.properties`` into the ``access-token`` and ``Authorization`` headers if they are empty in the config. .. py:method:: _handle_auth_signin_response(response) -> None Extract tokens from a successful sign-in response and write them to ``auth.properties``. Also calls ``_update_config_files_with_tokens()``. .. py:method:: _update_config_files_with_tokens(access_token, id_token) -> None Iterate all JSON config files (except ``auth-signin.json``) and set their ``Authorization`` and ``access-token`` header values. .. py:method:: run_all_apis() -> None Run every config file in alphabetical order. Functions --------- .. py:function:: print_usage() Print the module docstring (usage information). .. py:function:: main() CLI entry point for commands: ``generate``, ``list``, ``run ``, ``run-all``.