{"id":14986681,"url":"https://github.com/cliftbar/automd","last_synced_at":"2026-01-05T11:05:19.975Z","repository":{"id":55626300,"uuid":"244724040","full_name":"cliftbar/automd","owner":"cliftbar","description":"Flask API Documentation Generation","archived":false,"fork":false,"pushed_at":"2020-12-17T06:21:36.000Z","size":110,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2025-03-01T22:04:48.509Z","etag":null,"topics":["documentation","documentation-generator","flask","flaskrestful","openapi-spec","webargs"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/AutoMD/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cliftbar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-03T19:31:24.000Z","updated_at":"2020-12-17T03:53:51.000Z","dependencies_parsed_at":"2022-08-15T04:50:26.763Z","dependency_job_id":null,"html_url":"https://github.com/cliftbar/automd","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cliftbar%2Fautomd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cliftbar%2Fautomd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cliftbar%2Fautomd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cliftbar%2Fautomd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cliftbar","download_url":"https://codeload.github.com/cliftbar/automd/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244836045,"owners_count":20518368,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["documentation","documentation-generator","flask","flaskrestful","openapi-spec","webargs"],"created_at":"2024-09-24T14:13:20.003Z","updated_at":"2026-01-05T11:05:17.881Z","avatar_url":"https://github.com/cliftbar.png","language":"Python","readme":"# AutoMD\nAutoMD is a documentation library for Flask APIs build with FlaskRESTful and Webargs.\nEndpoint parameters and basic responses are automatically parsed into the OpenAPI specification,\nusing Type Hints and introspection, and a endpoints registered to serve the specification.\n\n## Motivation\nDocumentation libraries tend to rely heavily on elaborate docstrings and static generation from source code.\nThis library requires minimal changes to existing code, and most information (especially parameter specs)\ndoesn't rely on keeping docstrings up to date.\n\n## Installation\nAutoMD is available through [PyPi](https://pypi.org/project/AutoMD/).  AutoMD requires Python \u003e= 3.6\n\nInstall using pip:\n```\npip install automd\n```\n\nAutoMD also installs the following dependencies:\n- flask\n- flask-restful\n- webargs\n- apispec\n- pyyaml\n- marshmallow\n- werkzeug\n\n## Usage\n### AutoMD registration/initialization\nThe first step is to initialize the AutoMD app from a FlaskRESTful Api.\n\n```python\nfrom flask import Flask\nfrom flask_restful import Api\nfrom automd.registration import AutoMDApp\n\n\napp: Flask = Flask(__name__)\napi: Api = Api(app)\n\nspec: AutoMDApp = AutoMDApp(api, title=\"AutoMD Test App\", app_version=\"1.0.0\", openapi_version=\"3.0.0\")\n``` \n\nAfter that, all that is *required* is adding the `@automd` decorator to an existing Resource endpoint.\n\n```python\nfrom flask_restful import Resource\nfrom marshmallow import fields\nfrom webargs.flaskparser import use_kwargs\nfrom automd.decorators import automd\n\n\nclass MinimalStatus(Resource):\n    get_query_arguments = {\n        \"text\": fields.String(required=False)\n    }\n\n    @automd()\n    @use_kwargs(get_query_arguments)\n    def get(self, text):\n        return text\n```\nwhich will mark the endpoint for inclusion in the OpenAPI spec.  In this example, the spec information\nwill be pretty limited, but will still have the API url, argument, and a default value.\n\nWith more complete python annotations, more information can be gleaned:\n```python\nfrom flask_restful import Resource\nfrom marshmallow import fields\nfrom webargs.flaskparser import use_kwargs\nfrom automd.decorators import automd\n\n\nclass IntrospectionStatus(Resource):\n    post_query_arguments = {\n        \"text\": fields.String(required=False)\n    }\n\n    @automd()\n    @use_kwargs(post_query_arguments, location=\"json\")\n    def post(self, text: str = \"Hello AutoMD\") -\u003e str:\n        ret_text: str = \"status check OK\"\n\n        if text is not None:\n            ret_text = f\"{ret_text}: {text}\"\n\n        return ret_text\n```\nFrom this the APISpec also get the parameter type, default value, and API response type.  It does not get the parameter\nlocation yet though, that takes more aguements to automd.\n\nFilling in more information in the webargs fields, automd decorator, use_kwargs decorator, and using one of the\nAutoMD response classes for type annotation and  gives even better information:\n```python\nfrom flask_restful import Resource\nfrom marshmallow import fields\nfrom webargs.flaskparser import use_kwargs\nfrom automd.decorators import automd\nfrom automd.responses import ValueResponse\n\nclass Status(Resource):\n    get_query_arguments = {\n        \"text\": fields.String(required=False, description='Text to return', doc_default=\"Hello AutoMD\")\n    }\n\n    @automd(parameter_schema=get_query_arguments,\n             summary=\"Status Endpoint\",\n             description=\"Status Endpoint, responds with a message made from the input string\")\n    @use_kwargs(get_query_arguments, location=\"query\")\n    def get(self, text: str = None) -\u003e ValueResponse:\n        log_text: str = \"status check OK\"\n\n        log_text = f\"{log_text}: {text or 'Hello AutoMD'}\"\n\n        return ValueResponse(log_text)\n```\n\nWith this information argument types, return types, summaries, descriptions, detailed default\ninformation, and parameter location info (body, query, etc) is included.  Summary and description\nare the only \"magic strings\" needed, and those will generally not change much or be onerous to\nkeep up to date compared to the automatically grabbed information.\n\nThere is also no need to use FlaskRestful to register routes, flask routes can be registered directly\n\n```python\n@automd(summary=\"flask route\", description=\"example of a route defined using Flasks '@app.route' decorator\")\n@app.route(\"/flask/status\", methods=[\"GET\", \"POST\"])\ndef flask_status() -\u003e str:\n    return \"OK\"\n```\n\nAlso, setting the `always_document` flag of the AutoMDApp class to `true` will cause AutoMD to inspect all\nroutes in the flask app, as if they were decorated with `@automd()` (without arugments).\n\nAn example Flask API app is provided to showcase some functionality.  Start it using `run.py`.\nA sample of the OpenAPI spec generated is [here](https://cliftbar.github.io/automd/documentation/sample_spec.html).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcliftbar%2Fautomd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcliftbar%2Fautomd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcliftbar%2Fautomd/lists"}