{"id":28326884,"url":"https://github.com/canonical/acceptable","last_synced_at":"2025-07-06T16:05:10.475Z","repository":{"id":38335866,"uuid":"79877881","full_name":"canonical/acceptable","owner":"canonical","description":"API metadata and schema tool for generating tests and documentation","archived":false,"fork":false,"pushed_at":"2025-05-20T13:09:58.000Z","size":398,"stargazers_count":8,"open_issues_count":0,"forks_count":13,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-06-02T10:44:25.280Z","etag":null,"topics":["api","flask","store","testing"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/acceptable/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/canonical.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-01-24T04:20:33.000Z","updated_at":"2025-05-20T13:10:02.000Z","dependencies_parsed_at":"2025-05-26T15:15:58.687Z","dependency_job_id":null,"html_url":"https://github.com/canonical/acceptable","commit_stats":{"total_commits":202,"total_committers":23,"mean_commits":8.782608695652174,"dds":0.7821782178217822,"last_synced_commit":"94949f38d173857260a3e0893724b9cf89836c51"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/canonical/acceptable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Facceptable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Facceptable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Facceptable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Facceptable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canonical","download_url":"https://codeload.github.com/canonical/acceptable/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Facceptable/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261306685,"owners_count":23138726,"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":["api","flask","store","testing"],"created_at":"2025-05-26T01:15:20.493Z","updated_at":"2025-07-06T16:05:10.462Z","avatar_url":"https://github.com/canonical.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"acceptable\n==========\n\nAcceptable is python tool to annotate and capture the metadata around your\npython web API. This metadata can be used for validation, documentation,\ntesting and linting of your API code.\n\nIt works standalone, or can be hooked into Flask (beta support for Django) web\napps for richer integration.\n\n\nDesign Goals:\n-------------\n\n- Tightly couple code, metadata, and documentation to reduce drift and increase DRY.\n\n- Validation of JSON input and output\n\n- Provide tools for developers to make safe changes to APIs\n\n- Make it easy to generate API documentation.\n\n\nUsage\n-----\n\nAnd example, for flask::\n\n    from acceptable import AcceptableService\n\n    service = AcceptableService('example')\n\n    foo_api = service.api('foo', '/foo', introduced_at=1, methods=['POST'])\n    foo_api.request_schema = \u003cJSON Schema...\u003e\n    foo_api.response_schema = \u003cJSON Schema...\u003e\n    foo_api.changelog(3, 'Changed other thing')\n    foo_api.changelog(2, 'Changed something')\n\n    @foo_api\n    def view():\n        ...\n\nYou can use this metadata to bind the URL to a flask app::\n\n    from acceptable import get_metadata()\n    app = Flask(__name__)\n    get_metadata().bind_all(app)\n\nYou can now generate API metadata like so::\n\n    acceptable metadata your.import.path \u003e api.json\n\nThis metadata can now be used to generate documentation, and provide API linting.\n\n\nDjango\n------\n\nNote: Django support is very limited at the minute, and is mainly for documentation.\n\nMarking up the APIs themselves is a little different::\n\n    from acceptable import AcceptableService\n\n    service = AcceptableService('example')\n\n    # url is looked up from name, like reverse()\n    foo_api = service.django_api('app:foo', introduced_at=1)\n    foo_api.django_form = SomeForm\n    foo_api.changelog(3, 'Changed other thing)\n    foo_api.changelog(2, 'Changed something')\n\n    @foo_api.handler\n    class MyHandler(BaseHandler):\n        allowed_methods=['POST']\n        ...\n\nAcceptable will generate a JSON schema representation of the form for documentation.\n\nTo generate API metadata, you should add 'acceptable' to INSTALLED_APPS. This\nwill provide an 'acceptable' management command::\n\n    ./manage.py acceptable metadata \u003e api.json   # generate metadata\n\nAnd also::\n\n    ./manage.py acceptable api-version api.json  # inspect the current version\n\n\nDocumentation (beta)\n--------------------\n\nOne of the goals of acceptable is to use the metadata about your API to build documentation.\n\nOnce you have your metadata in JSON format, as above, you can transform that into markdown documentation::\n\n    acceptable render api.json --name 'My Service'\n\nYou can do this in a single step::\n\n    acceptable metadata path/to/files*.py | acceptable render --name 'My Service'\n\nThis markdown is designed to rendered to html by\n`documentation-builder \u003chttps://docs.ubuntu.com/documentation-builder/en/\u003e`::\n\n    documentation-builder --base-directory docs\n\n\nIncludable Makefile\n-------------------\n\n*If you are using make files to automate your build you might find this useful.*\n\nThe acceptable package contains a make file fragment that can be included to\ngive you the following targets:\n\n- ``api-lint`` - Checks backward compatibility and version numbers;\n- ``api-update-metadata`` - Check like ``api-lint`` then update the saved metadata;\n- ``api-version`` - Print the saved metadata and current API version;\n- ``api-docs-markdown`` - Generates markdown documentation.\n\nThe make file has variables for the following which you can override if\nneeded:\n\n- ``ACCEPTABLE_ENV`` - The virtual environment with acceptable installed, it defaults to ``$(ENV)``.\n- ``ACCEPTABLE_METADATA`` - The saved metadata filename, it defaults to ``api.json``;\n- ``ACCEPTABLE_DOCS`` - The directory ``api-docs-markdown`` will generate documentation under, it defaults to ``docs``.\n\nYou will need to create a saved metadata manually the first time using\n``acceptable metadata`` command and saving it to the value of ``ACCEPTABLE_METADATA``.\n\nThe make file assumes the following variables:\n\n- ``ACCEPTABLE_MODULES`` is a space separated list of modules containing acceptable annotated services;\n- ``ACCEPTABLE_SERVICE_TITLE`` is the title of the service used by ``api-docs-markdown``.\n\n``ACCEPTABLE_SERVICE_TITLE`` should not be quoted e.g.::\n\n    ACCEPTABLE_SERVICE_TITLE := Title of the Service\n\nTo include the file you'll need to get its path, if the above variables and\nconditions exist you can put this in your make file::\n\n    include $(shell $(ENV)/bin/python -c 'import pkg_resources; print(pkg_resources.resource_filename(\"acceptable\", \"make/Makefile.acceptable\"))' 2\u003e /dev/null)\n\nDevelopment\n-----------\n\n``make test`` and ``make tox`` should run without errors.\n\nTo run a single test module invoke::\n\n    env/bin/pytest acceptable/tests/test_module.py\n\nor::\n\n    tox -epy38 -- --test-suite acceptable.tests.test_module\n\n...the latter runs \"test_module\" against Python 3.8 only.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanonical%2Facceptable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanonical%2Facceptable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanonical%2Facceptable/lists"}