Repository: striglia/pyramid_swagger
Pull request #198 (2017-03-24 13:55:41)

Api docs base path
Added new setting for api docs base path for #187 


Patch:
diff --git a/docs/configuration.rst b/docs/configuration.rst
index b8a9bab..bc1a2bd 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -73,6 +73,12 @@ A few relevant settings for your `Pyramid .ini file <http://docs.pylonsproject.o
         # schemas (true by default)
         pyramid_swagger.enable_api_doc_views = true
 
+        # Base path for api docs (empty by default)
+        # Examples:
+        #   - leave empty and get api doc with GET /swagger.yaml
+        #   - set to '/help' and get api doc with GET /help/swagger.yaml
+        pyramid_swagger.base_path_api_docs = ''
+
         # Enable/disable generating the /api-doc endpoint from a resource
         # listing template (false by default). See `generate_resource_listing`
         # below for more details
diff --git a/pyramid_swagger/__init__.py b/pyramid_swagger/__init__.py
index 1e1c4a9..23bb55e 100644
--- a/pyramid_swagger/__init__.py
+++ b/pyramid_swagger/__init__.py
@@ -43,8 +43,6 @@ def includeme(config):
     )
 
     if settings.get('pyramid_swagger.enable_api_doc_views', True):
-        # TODO: add a new setting to pyramid_swagger that allows setting a
-        #       different base_path for api_docs, and pass it in here
         if SWAGGER_12 in swagger_versions:
             register_api_doc_endpoints(
                 config,
@@ -54,4 +52,4 @@ def includeme(config):
             register_api_doc_endpoints(
                 config,
                 build_swagger_20_swagger_schema_views(config),
-                base_path='')
+                base_path=settings.get('pyramid_swagger.base_path_api_docs', ''))
diff --git a/pyramid_swagger/api.py b/pyramid_swagger/api.py
index 6774977..f30dcb6 100644
--- a/pyramid_swagger/api.py
+++ b/pyramid_swagger/api.py
@@ -536,9 +536,16 @@ def _build_swagger_20_schema_views(config):
     file_map = {}
 
     def view_for_swagger_schema(request):
-        path, ext = os.path.splitext(request.path_info)
+        _, ext = os.path.splitext(request.path)
         ext = ext.lstrip('.')
-        actual_fname = file_map[request.path_info]
+
+        base_path = config.registry.settings\
+            .get('pyramid_swagger.base_path_api_docs', '').rstrip('/')
+
+        key_path = request.path_info[len(base_path):]
+
+        actual_fname = file_map[key_path]
+
         with spec.resolver.resolving(actual_fname) as spec_dict:
             clean_response = strip_xscope(spec_dict)
             ref_walker = NodeWalkerForCleaningRefs()


Test patch:
diff --git a/tests/acceptance/api_test.py b/tests/acceptance/api_test.py
index c2a1599..7266b43 100644
--- a/tests/acceptance/api_test.py
+++ b/tests/acceptance/api_test.py
@@ -98,6 +98,52 @@ def test_recursive_swagger_api_external_refs():
     recursive_test_app.get('/external.json', status=200)
 
 
+def test_base_path_api_docs_on_good_app_schema():
+    base_path = '/web/base/path'
+
+    recursive_test_app = App(main({}, **{
+        'pyramid_swagger.schema_directory':
+            'tests/sample_schemas/good_app/',
+        'pyramid_swagger.base_path_api_docs':
+            base_path
+    }))
+
+    recursive_test_app.get(base_path + '/swagger.json', status=200)
+    recursive_test_app.get('/swagger.json', status=404)
+
+
+def test_base_path_api_docs_on_recursive_app_schema():
+    base_path = '/some/path'
+    recursive_test_app = App(main({}, **{
+        'pyramid_swagger.schema_directory':
+            'tests/sample_schemas/recursive_app/external/',
+        'pyramid_swagger.base_path_api_docs':
+            base_path
+    }))
+
+    recursive_test_app.get(base_path + '/swagger.json', status=200)
+    recursive_test_app.get('/swagger.json', status=404)
+    recursive_test_app.get(base_path + '/external.json', status=200)
+    recursive_test_app.get('/external.json', status=404)
+
+
+def test_base_path_api_docs_with_script_name_on_recursive_app_schema():
+    base_path = '/some/path'
+    script_name = '/scriptname'
+    test_app = App(main({}, **{
+        'pyramid_swagger.schema_directory':
+            'tests/sample_schemas/recursive_app/external/',
+        'pyramid_swagger.base_path_api_docs':
+            base_path}),
+        {'SCRIPT_NAME': script_name})
+
+    test_app.get(script_name + base_path + '/swagger.json', status=200)
+    test_app.get('/swagger.json', status=404)
+
+    test_app.get(script_name + base_path + '/external.json', status=200)
+    test_app.get('/external.json', status=404)
+
+
 def test_virtual_subpath(settings):
     test_app = App(main({}, **settings), {'SCRIPT_NAME': '/subpath'})
     test_app.get('/subpath/swagger.json', status=200)