Skip to content

Commit

Permalink
Use linters and formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
theirix committed Dec 9, 2024
1 parent 237f7e6 commit 3290039
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 166 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,15 @@ jobs:

- name: Run tests
run: uv run pytest tests

- name: Run pylint
run: uv run pylint apispec_flask_restful tests

- name: Install tools
run: uv tool install black isort

- name: Run black
run: uv tool run black --check .

- name: Run isort
run: uv tool run isort --check-only .
11 changes: 6 additions & 5 deletions apispec_flask_restful/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from importlib.metadata import version

from .flask_restful import RestfulPlugin

try:
__version__ = version('apispec-flask-restful')
except:
__version__ = 'unknown'
from importlib.metadata import version

from .flask_restful import RestfulPlugin
__version__ = version("apispec-flask-restful")
except ImportError:
__version__ = "unknown"
45 changes: 26 additions & 19 deletions apispec_flask_restful/flask_restful.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,46 @@
import logging
import re

import yaml
import apispec
import yaml
from apispec import yaml_utils
from apispec.exceptions import APISpecError


def deduce_path(resource, **kwargs):
"""Find resource path using provided API or path itself"""
api = kwargs.get('api', None)
api = kwargs.get("api", None)
if not api:
# flask-restful resource url passed
return kwargs.get('path')
return kwargs.get("path")

# flask-restful API passed
# Require MethodView
if not getattr(resource, 'endpoint', None):
raise APISpecError('Flask-RESTful resource needed')
if not getattr(resource, "endpoint", None):
raise APISpecError("Flask-RESTful resource needed")

if api.blueprint:
# it is required to have Flask app to be able enumerate routes
app = kwargs.get('app')
app = kwargs.get("app")
if app:
for rule in app.url_map.iter_rules():
if rule.endpoint.endswith('.' + resource.endpoint):
if rule.endpoint.endswith("." + resource.endpoint):
break
else:
raise APISpecError('Cannot find blueprint resource {}'.format(resource.endpoint))
raise APISpecError(
"Cannot find blueprint resource {}".format(resource.endpoint)
)
else:
# Application not initialized yet, fallback to path
return kwargs.get('path')
return kwargs.get("path")

else:
for rule in api.app.url_map.iter_rules():
if rule.endpoint == resource.endpoint:
rule.endpoint.endswith('.' + resource.endpoint)
rule.endpoint.endswith("." + resource.endpoint)
break
else:
raise APISpecError('Cannot find resource {}'.format(resource.endpoint))
raise APISpecError("Cannot find resource {}".format(resource.endpoint))

return rule.rule

Expand All @@ -57,30 +59,35 @@ def parse_operations(resource, operations):
operation = None
if not operation:
logging.getLogger(__name__).warning(
'Cannot load docstring for {}/{}'.format(resource, method))
operations[method.lower()] = operation or dict()
"Cannot load docstring for {}/{}".format(resource, method)
)
operations[method.lower()] = operation or {}


class RestfulPlugin(apispec.BasePlugin):
"""Extracts swagger spec from `flask-restful` methods."""

def path_helper(self, path=None, operations=None, parameters=None, **kwargs):
kwargs["path"] = path
try:
resource = kwargs.pop('resource')
resource = kwargs.pop("resource")
path = deduce_path(resource, **kwargs)
path = re.sub(r'<(?:[^:<>]+:)?([^<>]+)>', r'{\1}', path)
path = re.sub(r"<(?:[^:<>]+:)?([^<>]+)>", r"{\1}", path)
return path
except Exception as exc:
logging.getLogger(__name__).exception('Exception parsing APISpec', exc_info=exc)
logging.getLogger(__name__).exception(
"Exception parsing APISpec", exc_info=exc
)
raise

def operation_helper(self, path=None, operations=None, **kwargs):
if operations is None:
return
try:
resource = kwargs.pop('resource')
resource = kwargs.pop("resource")
parse_operations(resource, operations)
except Exception as exc:
logging.getLogger(__name__).exception('Exception parsing APISpec', exc_info=exc)
logging.getLogger(__name__).exception(
"Exception parsing APISpec", exc_info=exc
)
raise

10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@ dev = [
"pytest>=8.3.4",
"pylint>=2.6.0",
"pytest-cov>=4",
"black~=23.0"
]

[tool.pytest.ini_options]
pythonpath = ["."]
addopts = [
"--import-mode=importlib",
]

[tool.isort]
profile = "black"

[tool.pylint.messages_control]
disable = [
"missing-module-docstring", "missing-function-docstring", "missing-class-docstring",
"too-few-public-methods", "protected-access", "consider-using-f-string", "logging-format-interpolation"
]
28 changes: 20 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Dummy conftest.py for apispec_flask_restful.
import pytest
from flask import Flask
from flask_restful import Api

If you don't know what this is for, just leave it empty.
Read more about conftest.py under:
https://pytest.org/latest/plugins.html
"""
from __future__ import print_function, absolute_import, division

import pytest
@pytest.fixture()
def app():
_app = Flask(__name__)
ctx = _app.test_request_context()
ctx.push()
yield _app
ctx.pop()


@pytest.fixture()
def api():
_app = Flask(__name__)
_api = Api(_app)
ctx = _app.test_request_context()
ctx.push()
yield _api
ctx.pop()
Loading

0 comments on commit 3290039

Please sign in to comment.