We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Make the location of version.json configurable
Currently @phrawzty had to put the `version.json` at the root location of the container.

If the location would be a setting we could specify via env variable in the dockerfile for example

Make the location of version.json configurable
Currently @phrawzty had to put the `version.json` at the root location of the container.

If the location would be a setting we could specify via env variable in the dockerfile for example


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kinto/core/__init__.py`
Content:
```
1 """Main entry point
2 """
3 import pkg_resources
4 
5 from cornice import Service as CorniceService
6 from pyramid.settings import aslist
7 
8 from kinto.core import authentication
9 from kinto.core import errors
10 from kinto.core import events
11 from kinto.core.initialization import (  # NOQA
12     initialize, install_middlewares,
13     load_default_settings)
14 from kinto.core.utils import (
15     follow_subrequest, current_service, current_resource_name)
16 from kinto.core.logs import logger
17 
18 
19 # Module version, as defined in PEP-0396.
20 __version__ = pkg_resources.get_distribution('kinto').version  # FIXME?
21 
22 
23 DEFAULT_SETTINGS = {
24     'backoff': None,
25     'batch_max_requests': 25,
26     'cache_backend': '',
27     'cache_url': '',
28     'cache_pool_size': 25,
29     'cache_prefix': '',
30     'cors_origins': '*',
31     'cors_max_age_seconds': 3600,
32     'eos': None,
33     'eos_message': None,
34     'eos_url': None,
35     'error_info_link': 'https://github.com/Kinto/kinto/issues/',
36     'http_host': None,
37     'http_scheme': None,
38     'id_generator': 'kinto.core.storage.generators.UUID4',
39     'includes': '',
40     'initialization_sequence': (
41         'kinto.core.initialization.setup_request_bound_data',
42         'kinto.core.initialization.setup_json_serializer',
43         'kinto.core.initialization.setup_logging',
44         'kinto.core.initialization.setup_storage',
45         'kinto.core.initialization.setup_permission',
46         'kinto.core.initialization.setup_cache',
47         'kinto.core.initialization.setup_requests_scheme',
48         'kinto.core.initialization.setup_version_redirection',
49         'kinto.core.initialization.setup_deprecation',
50         'kinto.core.initialization.setup_authentication',
51         'kinto.core.initialization.setup_backoff',
52         'kinto.core.initialization.setup_statsd',
53         'kinto.core.initialization.setup_listeners',
54         'kinto.core.events.setup_transaction_hook',
55     ),
56     'event_listeners': '',
57     'heartbeat_timeout_seconds': 10,
58     'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',
59     'newrelic_config': None,
60     'newrelic_env': 'dev',
61     'paginate_by': None,
62     'permission_backend': '',
63     'permission_url': '',
64     'permission_pool_size': 25,
65     'profiler_dir': '/tmp',
66     'profiler_enabled': False,
67     'project_docs': '',
68     'project_name': '',
69     'project_version': '',
70     'readonly': False,
71     'retry_after_seconds': 30,
72     'statsd_backend': 'kinto.core.statsd',
73     'statsd_prefix': 'kinto.core',
74     'statsd_url': None,
75     'storage_backend': '',
76     'storage_url': '',
77     'storage_max_fetch_size': 10000,
78     'storage_pool_size': 25,
79     'tm.annotate_user': False,  # Do annotate transactions with the user-id.
80     'transaction_per_request': True,
81     'userid_hmac_secret': '',
82     'version_prefix_redirect_enabled': True,
83     'trailing_slash_redirect_enabled': True,
84     'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',
85     'multiauth.policies': 'basicauth',
86     'multiauth.policy.basicauth.use': ('kinto.core.authentication.'
87                                        'BasicAuthAuthenticationPolicy'),
88     'multiauth.authorization_policy': ('kinto.core.authorization.'
89                                        'AuthorizationPolicy')
90 }
91 
92 
93 class Service(CorniceService):
94     """Subclass of the default cornice service.
95 
96     This is useful in order to attach specific behaviours without monkey
97     patching the default cornice service (which would impact other uses of it)
98     """
99     default_cors_headers = ('Backoff', 'Retry-After', 'Alert',
100                             'Content-Length')
101 
102     def error_handler(self, error):
103         return errors.json_error_handler(error)
104 
105     @classmethod
106     def init_from_settings(cls, settings):
107         cls.cors_origins = tuple(aslist(settings['cors_origins']))
108         cors_max_age = settings['cors_max_age_seconds']
109         cls.cors_max_age = int(cors_max_age) if cors_max_age else None
110 
111 
112 def includeme(config):
113     settings = config.get_settings()
114 
115     # Heartbeat registry.
116     config.registry.heartbeats = {}
117 
118     # Public settings registry.
119     config.registry.public_settings = {'batch_max_requests', 'readonly'}
120 
121     # Directive to declare arbitrary API capabilities.
122     def add_api_capability(config, identifier, description="", url="", **kw):
123         existing = config.registry.api_capabilities.get(identifier)
124         if existing:
125             error_msg = "The '%s' API capability was already registered (%s)."
126             raise ValueError(error_msg % (identifier, existing))
127 
128         capability = dict(description=description, url=url, **kw)
129         config.registry.api_capabilities[identifier] = capability
130 
131     config.add_directive('add_api_capability', add_api_capability)
132     config.registry.api_capabilities = {}
133 
134     # Resource events helpers.
135     config.add_request_method(events.get_resource_events,
136                               name='get_resource_events')
137     config.add_request_method(events.notify_resource_event,
138                               name='notify_resource_event')
139 
140     # Setup cornice.
141     config.include("cornice")
142 
143     # Per-request transaction.
144     config.include("pyramid_tm")
145 
146     # Add CORS settings to the base kinto.core Service class.
147     Service.init_from_settings(settings)
148 
149     # Setup components.
150     for step in aslist(settings['initialization_sequence']):
151         step_func = config.maybe_dotted(step)
152         step_func(config)
153 
154     # Custom helpers.
155     config.add_request_method(follow_subrequest)
156     config.add_request_method(authentication.prefixed_userid, property=True)
157     config.add_request_method(lambda r: {'id': r.prefixed_userid},
158                               name='get_user_info')
159     config.add_request_method(current_resource_name, reify=True)
160     config.add_request_method(current_service, reify=True)
161     config.commit()
162 
163     # Include plugins after init, unlike pyramid includes.
164     includes = aslist(settings['includes'])
165     for app in includes:
166         config.include(app)
167 
168     # # Show settings to output.
169     # for key, value in settings.items():
170     #     logger.info('Using %s = %s' % (key, value))
171 
172     # Scan views.
173     config.scan("kinto.core.views")
174 
175     # Give sign of life.
176     msg = "Running %(project_name)s %(project_version)s."
177     logger.info(msg % settings)
178
```

Path: `kinto/core/views/version.py`
Content:
```
1 import json
2 import os
3 
4 from pyramid import httpexceptions
5 from pyramid.security import NO_PERMISSION_REQUIRED
6 from kinto.core import Service
7 
8 HERE = os.path.dirname(os.path.abspath(__file__))
9 ORIGIN = os.path.dirname(os.path.dirname(HERE))
10 
11 VERSION_PATH = 'version.json'
12 VERSION_JSON = None
13 
14 version = Service(name="version", path='/__version__', description="Version")
15 
16 VERSIONS_FILES = [
17     VERSION_PATH,  # Relative to the CURRENT_WORKING_DIR.
18     os.path.join(ORIGIN, VERSION_PATH),  # Relative to the package.
19     os.path.join(HERE, VERSION_PATH)]  # Relative to this file.
20 
21 for version_file in VERSIONS_FILES:
22     file_path = os.path.abspath(version_file)
23     if os.path.exists(file_path):
24         with open(file_path) as f:
25             VERSION_JSON = json.load(f)
26             break  # The first one wins
27 
28 
29 @version.get(permission=NO_PERMISSION_REQUIRED)
30 def version_view(request):
31     if VERSION_JSON is not None:
32         return VERSION_JSON
33 
34     raise httpexceptions.HTTPNotFound()
35
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kinto/core/__init__.py b/kinto/core/__init__.py
--- a/kinto/core/__init__.py
+++ b/kinto/core/__init__.py
@@ -79,6 +79,7 @@
     'tm.annotate_user': False,  # Do annotate transactions with the user-id.
     'transaction_per_request': True,
     'userid_hmac_secret': '',
+    'version_json_path': 'version.json',
     'version_prefix_redirect_enabled': True,
     'trailing_slash_redirect_enabled': True,
     'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',
diff --git a/kinto/core/views/version.py b/kinto/core/views/version.py
--- a/kinto/core/views/version.py
+++ b/kinto/core/views/version.py
@@ -8,27 +8,27 @@
 HERE = os.path.dirname(os.path.abspath(__file__))
 ORIGIN = os.path.dirname(os.path.dirname(HERE))
 
-VERSION_PATH = 'version.json'
-VERSION_JSON = None
-
 version = Service(name="version", path='/__version__', description="Version")
 
-VERSIONS_FILES = [
-    VERSION_PATH,  # Relative to the CURRENT_WORKING_DIR.
-    os.path.join(ORIGIN, VERSION_PATH),  # Relative to the package.
-    os.path.join(HERE, VERSION_PATH)]  # Relative to this file.
-
-for version_file in VERSIONS_FILES:
-    file_path = os.path.abspath(version_file)
-    if os.path.exists(file_path):
-        with open(file_path) as f:
-            VERSION_JSON = json.load(f)
-            break  # The first one wins
-
 
 @version.get(permission=NO_PERMISSION_REQUIRED)
 def version_view(request):
-    if VERSION_JSON is not None:
-        return VERSION_JSON
+    try:
+        return version_view.__json__
+    except AttributeError:
+        pass
+
+    location = request.registry.settings['version_json_path']
+    files = [
+        location,  # Default is current working dir.
+        os.path.join(ORIGIN, 'version.json'),  # Relative to the package root.
+        os.path.join(HERE, 'version.json')  # Relative to this file.
+    ]
+    for version_file in files:
+        file_path = os.path.abspath(version_file)
+        if os.path.exists(file_path):
+            with open(file_path) as f:
+                version_view.__json__ = json.load(f)
+                return version_view.__json__  # First one wins.
 
     raise httpexceptions.HTTPNotFound()

{"golden_diff": "diff --git a/kinto/core/__init__.py b/kinto/core/__init__.py\n--- a/kinto/core/__init__.py\n+++ b/kinto/core/__init__.py\n@@ -79,6 +79,7 @@\n     'tm.annotate_user': False,  # Do annotate transactions with the user-id.\n     'transaction_per_request': True,\n     'userid_hmac_secret': '',\n+    'version_json_path': 'version.json',\n     'version_prefix_redirect_enabled': True,\n     'trailing_slash_redirect_enabled': True,\n     'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',\ndiff --git a/kinto/core/views/version.py b/kinto/core/views/version.py\n--- a/kinto/core/views/version.py\n+++ b/kinto/core/views/version.py\n@@ -8,27 +8,27 @@\n HERE = os.path.dirname(os.path.abspath(__file__))\n ORIGIN = os.path.dirname(os.path.dirname(HERE))\n \n-VERSION_PATH = 'version.json'\n-VERSION_JSON = None\n-\n version = Service(name=\"version\", path='/__version__', description=\"Version\")\n \n-VERSIONS_FILES = [\n-    VERSION_PATH,  # Relative to the CURRENT_WORKING_DIR.\n-    os.path.join(ORIGIN, VERSION_PATH),  # Relative to the package.\n-    os.path.join(HERE, VERSION_PATH)]  # Relative to this file.\n-\n-for version_file in VERSIONS_FILES:\n-    file_path = os.path.abspath(version_file)\n-    if os.path.exists(file_path):\n-        with open(file_path) as f:\n-            VERSION_JSON = json.load(f)\n-            break  # The first one wins\n-\n \n @version.get(permission=NO_PERMISSION_REQUIRED)\n def version_view(request):\n-    if VERSION_JSON is not None:\n-        return VERSION_JSON\n+    try:\n+        return version_view.__json__\n+    except AttributeError:\n+        pass\n+\n+    location = request.registry.settings['version_json_path']\n+    files = [\n+        location,  # Default is current working dir.\n+        os.path.join(ORIGIN, 'version.json'),  # Relative to the package root.\n+        os.path.join(HERE, 'version.json')  # Relative to this file.\n+    ]\n+    for version_file in files:\n+        file_path = os.path.abspath(version_file)\n+        if os.path.exists(file_path):\n+            with open(file_path) as f:\n+                version_view.__json__ = json.load(f)\n+                return version_view.__json__  # First one wins.\n \n     raise httpexceptions.HTTPNotFound()\n", "issue": "Make the location of version.json configurable\nCurrently @phrawzty had to put the `version.json` at the root location of the container.\n\nIf the location would be a setting we could specify via env variable in the dockerfile for example\n\nMake the location of version.json configurable\nCurrently @phrawzty had to put the `version.json` at the root location of the container.\n\nIf the location would be a setting we could specify via env variable in the dockerfile for example\n\n", "before_files": [{"content": "\"\"\"Main entry point\n\"\"\"\nimport pkg_resources\n\nfrom cornice import Service as CorniceService\nfrom pyramid.settings import aslist\n\nfrom kinto.core import authentication\nfrom kinto.core import errors\nfrom kinto.core import events\nfrom kinto.core.initialization import (  # NOQA\n    initialize, install_middlewares,\n    load_default_settings)\nfrom kinto.core.utils import (\n    follow_subrequest, current_service, current_resource_name)\nfrom kinto.core.logs import logger\n\n\n# Module version, as defined in PEP-0396.\n__version__ = pkg_resources.get_distribution('kinto').version  # FIXME?\n\n\nDEFAULT_SETTINGS = {\n    'backoff': None,\n    'batch_max_requests': 25,\n    'cache_backend': '',\n    'cache_url': '',\n    'cache_pool_size': 25,\n    'cache_prefix': '',\n    'cors_origins': '*',\n    'cors_max_age_seconds': 3600,\n    'eos': None,\n    'eos_message': None,\n    'eos_url': None,\n    'error_info_link': 'https://github.com/Kinto/kinto/issues/',\n    'http_host': None,\n    'http_scheme': None,\n    'id_generator': 'kinto.core.storage.generators.UUID4',\n    'includes': '',\n    'initialization_sequence': (\n        'kinto.core.initialization.setup_request_bound_data',\n        'kinto.core.initialization.setup_json_serializer',\n        'kinto.core.initialization.setup_logging',\n        'kinto.core.initialization.setup_storage',\n        'kinto.core.initialization.setup_permission',\n        'kinto.core.initialization.setup_cache',\n        'kinto.core.initialization.setup_requests_scheme',\n        'kinto.core.initialization.setup_version_redirection',\n        'kinto.core.initialization.setup_deprecation',\n        'kinto.core.initialization.setup_authentication',\n        'kinto.core.initialization.setup_backoff',\n        'kinto.core.initialization.setup_statsd',\n        'kinto.core.initialization.setup_listeners',\n        'kinto.core.events.setup_transaction_hook',\n    ),\n    'event_listeners': '',\n    'heartbeat_timeout_seconds': 10,\n    'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',\n    'newrelic_config': None,\n    'newrelic_env': 'dev',\n    'paginate_by': None,\n    'permission_backend': '',\n    'permission_url': '',\n    'permission_pool_size': 25,\n    'profiler_dir': '/tmp',\n    'profiler_enabled': False,\n    'project_docs': '',\n    'project_name': '',\n    'project_version': '',\n    'readonly': False,\n    'retry_after_seconds': 30,\n    'statsd_backend': 'kinto.core.statsd',\n    'statsd_prefix': 'kinto.core',\n    'statsd_url': None,\n    'storage_backend': '',\n    'storage_url': '',\n    'storage_max_fetch_size': 10000,\n    'storage_pool_size': 25,\n    'tm.annotate_user': False,  # Do annotate transactions with the user-id.\n    'transaction_per_request': True,\n    'userid_hmac_secret': '',\n    'version_prefix_redirect_enabled': True,\n    'trailing_slash_redirect_enabled': True,\n    'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',\n    'multiauth.policies': 'basicauth',\n    'multiauth.policy.basicauth.use': ('kinto.core.authentication.'\n                                       'BasicAuthAuthenticationPolicy'),\n    'multiauth.authorization_policy': ('kinto.core.authorization.'\n                                       'AuthorizationPolicy')\n}\n\n\nclass Service(CorniceService):\n    \"\"\"Subclass of the default cornice service.\n\n    This is useful in order to attach specific behaviours without monkey\n    patching the default cornice service (which would impact other uses of it)\n    \"\"\"\n    default_cors_headers = ('Backoff', 'Retry-After', 'Alert',\n                            'Content-Length')\n\n    def error_handler(self, error):\n        return errors.json_error_handler(error)\n\n    @classmethod\n    def init_from_settings(cls, settings):\n        cls.cors_origins = tuple(aslist(settings['cors_origins']))\n        cors_max_age = settings['cors_max_age_seconds']\n        cls.cors_max_age = int(cors_max_age) if cors_max_age else None\n\n\ndef includeme(config):\n    settings = config.get_settings()\n\n    # Heartbeat registry.\n    config.registry.heartbeats = {}\n\n    # Public settings registry.\n    config.registry.public_settings = {'batch_max_requests', 'readonly'}\n\n    # Directive to declare arbitrary API capabilities.\n    def add_api_capability(config, identifier, description=\"\", url=\"\", **kw):\n        existing = config.registry.api_capabilities.get(identifier)\n        if existing:\n            error_msg = \"The '%s' API capability was already registered (%s).\"\n            raise ValueError(error_msg % (identifier, existing))\n\n        capability = dict(description=description, url=url, **kw)\n        config.registry.api_capabilities[identifier] = capability\n\n    config.add_directive('add_api_capability', add_api_capability)\n    config.registry.api_capabilities = {}\n\n    # Resource events helpers.\n    config.add_request_method(events.get_resource_events,\n                              name='get_resource_events')\n    config.add_request_method(events.notify_resource_event,\n                              name='notify_resource_event')\n\n    # Setup cornice.\n    config.include(\"cornice\")\n\n    # Per-request transaction.\n    config.include(\"pyramid_tm\")\n\n    # Add CORS settings to the base kinto.core Service class.\n    Service.init_from_settings(settings)\n\n    # Setup components.\n    for step in aslist(settings['initialization_sequence']):\n        step_func = config.maybe_dotted(step)\n        step_func(config)\n\n    # Custom helpers.\n    config.add_request_method(follow_subrequest)\n    config.add_request_method(authentication.prefixed_userid, property=True)\n    config.add_request_method(lambda r: {'id': r.prefixed_userid},\n                              name='get_user_info')\n    config.add_request_method(current_resource_name, reify=True)\n    config.add_request_method(current_service, reify=True)\n    config.commit()\n\n    # Include plugins after init, unlike pyramid includes.\n    includes = aslist(settings['includes'])\n    for app in includes:\n        config.include(app)\n\n    # # Show settings to output.\n    # for key, value in settings.items():\n    #     logger.info('Using %s = %s' % (key, value))\n\n    # Scan views.\n    config.scan(\"kinto.core.views\")\n\n    # Give sign of life.\n    msg = \"Running %(project_name)s %(project_version)s.\"\n    logger.info(msg % settings)\n", "path": "kinto/core/__init__.py"}, {"content": "import json\nimport os\n\nfrom pyramid import httpexceptions\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom kinto.core import Service\n\nHERE = os.path.dirname(os.path.abspath(__file__))\nORIGIN = os.path.dirname(os.path.dirname(HERE))\n\nVERSION_PATH = 'version.json'\nVERSION_JSON = None\n\nversion = Service(name=\"version\", path='/__version__', description=\"Version\")\n\nVERSIONS_FILES = [\n    VERSION_PATH,  # Relative to the CURRENT_WORKING_DIR.\n    os.path.join(ORIGIN, VERSION_PATH),  # Relative to the package.\n    os.path.join(HERE, VERSION_PATH)]  # Relative to this file.\n\nfor version_file in VERSIONS_FILES:\n    file_path = os.path.abspath(version_file)\n    if os.path.exists(file_path):\n        with open(file_path) as f:\n            VERSION_JSON = json.load(f)\n            break  # The first one wins\n\n\n@version.get(permission=NO_PERMISSION_REQUIRED)\ndef version_view(request):\n    if VERSION_JSON is not None:\n        return VERSION_JSON\n\n    raise httpexceptions.HTTPNotFound()\n", "path": "kinto/core/views/version.py"}], "after_files": [{"content": "\"\"\"Main entry point\n\"\"\"\nimport pkg_resources\n\nfrom cornice import Service as CorniceService\nfrom pyramid.settings import aslist\n\nfrom kinto.core import authentication\nfrom kinto.core import errors\nfrom kinto.core import events\nfrom kinto.core.initialization import (  # NOQA\n    initialize, install_middlewares,\n    load_default_settings)\nfrom kinto.core.utils import (\n    follow_subrequest, current_service, current_resource_name)\nfrom kinto.core.logs import logger\n\n\n# Module version, as defined in PEP-0396.\n__version__ = pkg_resources.get_distribution('kinto').version  # FIXME?\n\n\nDEFAULT_SETTINGS = {\n    'backoff': None,\n    'batch_max_requests': 25,\n    'cache_backend': '',\n    'cache_url': '',\n    'cache_pool_size': 25,\n    'cache_prefix': '',\n    'cors_origins': '*',\n    'cors_max_age_seconds': 3600,\n    'eos': None,\n    'eos_message': None,\n    'eos_url': None,\n    'error_info_link': 'https://github.com/Kinto/kinto/issues/',\n    'http_host': None,\n    'http_scheme': None,\n    'id_generator': 'kinto.core.storage.generators.UUID4',\n    'includes': '',\n    'initialization_sequence': (\n        'kinto.core.initialization.setup_request_bound_data',\n        'kinto.core.initialization.setup_json_serializer',\n        'kinto.core.initialization.setup_logging',\n        'kinto.core.initialization.setup_storage',\n        'kinto.core.initialization.setup_permission',\n        'kinto.core.initialization.setup_cache',\n        'kinto.core.initialization.setup_requests_scheme',\n        'kinto.core.initialization.setup_version_redirection',\n        'kinto.core.initialization.setup_deprecation',\n        'kinto.core.initialization.setup_authentication',\n        'kinto.core.initialization.setup_backoff',\n        'kinto.core.initialization.setup_statsd',\n        'kinto.core.initialization.setup_listeners',\n        'kinto.core.events.setup_transaction_hook',\n    ),\n    'event_listeners': '',\n    'heartbeat_timeout_seconds': 10,\n    'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',\n    'newrelic_config': None,\n    'newrelic_env': 'dev',\n    'paginate_by': None,\n    'permission_backend': '',\n    'permission_url': '',\n    'permission_pool_size': 25,\n    'profiler_dir': '/tmp',\n    'profiler_enabled': False,\n    'project_docs': '',\n    'project_name': '',\n    'project_version': '',\n    'readonly': False,\n    'retry_after_seconds': 30,\n    'statsd_backend': 'kinto.core.statsd',\n    'statsd_prefix': 'kinto.core',\n    'statsd_url': None,\n    'storage_backend': '',\n    'storage_url': '',\n    'storage_max_fetch_size': 10000,\n    'storage_pool_size': 25,\n    'tm.annotate_user': False,  # Do annotate transactions with the user-id.\n    'transaction_per_request': True,\n    'userid_hmac_secret': '',\n    'version_json_path': 'version.json',\n    'version_prefix_redirect_enabled': True,\n    'trailing_slash_redirect_enabled': True,\n    'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',\n    'multiauth.policies': 'basicauth',\n    'multiauth.policy.basicauth.use': ('kinto.core.authentication.'\n                                       'BasicAuthAuthenticationPolicy'),\n    'multiauth.authorization_policy': ('kinto.core.authorization.'\n                                       'AuthorizationPolicy')\n}\n\n\nclass Service(CorniceService):\n    \"\"\"Subclass of the default cornice service.\n\n    This is useful in order to attach specific behaviours without monkey\n    patching the default cornice service (which would impact other uses of it)\n    \"\"\"\n    default_cors_headers = ('Backoff', 'Retry-After', 'Alert',\n                            'Content-Length')\n\n    def error_handler(self, error):\n        return errors.json_error_handler(error)\n\n    @classmethod\n    def init_from_settings(cls, settings):\n        cls.cors_origins = tuple(aslist(settings['cors_origins']))\n        cors_max_age = settings['cors_max_age_seconds']\n        cls.cors_max_age = int(cors_max_age) if cors_max_age else None\n\n\ndef includeme(config):\n    settings = config.get_settings()\n\n    # Heartbeat registry.\n    config.registry.heartbeats = {}\n\n    # Public settings registry.\n    config.registry.public_settings = {'batch_max_requests', 'readonly'}\n\n    # Directive to declare arbitrary API capabilities.\n    def add_api_capability(config, identifier, description=\"\", url=\"\", **kw):\n        existing = config.registry.api_capabilities.get(identifier)\n        if existing:\n            error_msg = \"The '%s' API capability was already registered (%s).\"\n            raise ValueError(error_msg % (identifier, existing))\n\n        capability = dict(description=description, url=url, **kw)\n        config.registry.api_capabilities[identifier] = capability\n\n    config.add_directive('add_api_capability', add_api_capability)\n    config.registry.api_capabilities = {}\n\n    # Resource events helpers.\n    config.add_request_method(events.get_resource_events,\n                              name='get_resource_events')\n    config.add_request_method(events.notify_resource_event,\n                              name='notify_resource_event')\n\n    # Setup cornice.\n    config.include(\"cornice\")\n\n    # Per-request transaction.\n    config.include(\"pyramid_tm\")\n\n    # Add CORS settings to the base kinto.core Service class.\n    Service.init_from_settings(settings)\n\n    # Setup components.\n    for step in aslist(settings['initialization_sequence']):\n        step_func = config.maybe_dotted(step)\n        step_func(config)\n\n    # Custom helpers.\n    config.add_request_method(follow_subrequest)\n    config.add_request_method(authentication.prefixed_userid, property=True)\n    config.add_request_method(lambda r: {'id': r.prefixed_userid},\n                              name='get_user_info')\n    config.add_request_method(current_resource_name, reify=True)\n    config.add_request_method(current_service, reify=True)\n    config.commit()\n\n    # Include plugins after init, unlike pyramid includes.\n    includes = aslist(settings['includes'])\n    for app in includes:\n        config.include(app)\n\n    # # Show settings to output.\n    # for key, value in settings.items():\n    #     logger.info('Using %s = %s' % (key, value))\n\n    # Scan views.\n    config.scan(\"kinto.core.views\")\n\n    # Give sign of life.\n    msg = \"Running %(project_name)s %(project_version)s.\"\n    logger.info(msg % settings)\n", "path": "kinto/core/__init__.py"}, {"content": "import json\nimport os\n\nfrom pyramid import httpexceptions\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom kinto.core import Service\n\nHERE = os.path.dirname(os.path.abspath(__file__))\nORIGIN = os.path.dirname(os.path.dirname(HERE))\n\nversion = Service(name=\"version\", path='/__version__', description=\"Version\")\n\n\n@version.get(permission=NO_PERMISSION_REQUIRED)\ndef version_view(request):\n    try:\n        return version_view.__json__\n    except AttributeError:\n        pass\n\n    location = request.registry.settings['version_json_path']\n    files = [\n        location,  # Default is current working dir.\n        os.path.join(ORIGIN, 'version.json'),  # Relative to the package root.\n        os.path.join(HERE, 'version.json')  # Relative to this file.\n    ]\n    for version_file in files:\n        file_path = os.path.abspath(version_file)\n        if os.path.exists(file_path):\n            with open(file_path) as f:\n                version_view.__json__ = json.load(f)\n                return version_view.__json__  # First one wins.\n\n    raise httpexceptions.HTTPNotFound()\n", "path": "kinto/core/views/version.py"}]}