plaster_yaml 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ## Version 0.2.0 - 2021-05-02
2
+
3
+ * Implementation get_wsgi_app_settings for the Loader
4
+
5
+ ## Version 0.1.1 - 2021-04-26
6
+
7
+ * Fix default logging
8
+
9
+ ## Version 0.1.0 - 2021-04-26
10
+
11
+ * Initial Release
@@ -0,0 +1,6 @@
1
+ from importlib import metadata
2
+
3
+ from .loader import Loader
4
+
5
+ __all__ = ["Loader"]
6
+ __version__ = metadata.version("plaster-yaml")
plaster_yaml/loader.py ADDED
@@ -0,0 +1,96 @@
1
+ """Implement a loader for plaster using yaml format."""
2
+ import pathlib
3
+ from logging.config import dictConfig
4
+ from typing import Callable
5
+
6
+ from importlib import metadata
7
+
8
+ import plaster
9
+ import yaml
10
+
11
+ DEFAULT_LOGGING_CONFIG = {
12
+ "version": 1,
13
+ "disable_existing_loggers": False,
14
+ "formatters": {
15
+ "console": {
16
+ "format": "%(asctime)s [%(levelname)s]: %(name)s - %(message)s",
17
+ },
18
+ },
19
+ "handlers": {
20
+ "console": {
21
+ "class": "logging.StreamHandler",
22
+ "level": "INFO",
23
+ "stream": "ext://sys.stderr",
24
+ "formatter": "console",
25
+ },
26
+ },
27
+ "root": {"level": "ERROR", "handlers": ["console"]},
28
+ }
29
+
30
+
31
+ def resolve_use(use: str, entrypoint: str) -> Callable:
32
+ try:
33
+ pkg, name = use.split("#")
34
+ except ValueError:
35
+ pkg, name = use, "main"
36
+ try:
37
+ scheme, pkg = pkg.split(":")
38
+ except ValueError:
39
+ scheme = "egg"
40
+ if scheme != "egg":
41
+ raise ValueError(f"{use}: unsupported scheme {scheme}")
42
+
43
+ eps = metadata.entry_points(group=entrypoint, name=name)
44
+ (runner,) = [ep for ep in eps if ep.module.split(".")[0] == pkg]
45
+ return runner.load()
46
+
47
+
48
+ class Loader(plaster.ILoader):
49
+ def __init__(self, uri):
50
+ self.uri = uri
51
+
52
+ path = pathlib.Path(self.uri.path)
53
+ self.defaults = {
54
+ "__file__": str(path.absolute()),
55
+ "here": str(path.parent),
56
+ }
57
+ with open(self.uri.path, "r") as stream:
58
+ self._conf = yaml.safe_load(stream)
59
+
60
+ def get_sections(self):
61
+ return ["app"]
62
+
63
+ def get_settings(self, section=None, defaults=None):
64
+ # fallback to the fragment from config_uri if no section is given
65
+ if not section:
66
+ section = self.uri.fragment or "app"
67
+ # if section is still none we could fallback to some
68
+ # loader-specific default
69
+
70
+ result = self.defaults.copy()
71
+ if defaults is not None:
72
+ result.update(defaults)
73
+
74
+ settings = self._conf[section].copy()
75
+
76
+ for key, val in settings.items():
77
+ if isinstance(val, str):
78
+ if "%(here)s" in val:
79
+ settings[key] = val % self.defaults
80
+ return settings
81
+
82
+ def get_wsgi_app_settings(self, name=None, defaults=None):
83
+ return self.get_settings(name, defaults)
84
+
85
+ def setup_logging(self, config_vars):
86
+ dictConfig(self._conf.get("logging", DEFAULT_LOGGING_CONFIG))
87
+
88
+ def get_wsgi_server(self, name=None, defaults=None):
89
+ settings = self.get_settings("server", defaults)
90
+ server = resolve_use(settings.pop("use"), "paste.server_runner")
91
+ return lambda app: server(app, self.defaults, **settings)
92
+
93
+ def get_wsgi_app(self, name=None, defaults=None):
94
+ settings = self.get_settings(name, defaults)
95
+ use = resolve_use(settings.pop("use"), "paste.app_factory")
96
+ return use(defaults, **settings)
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2021, Guillaume Gauvrit and Contributors
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the <organization> nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.1
2
+ Name: plaster_yaml
3
+ Version: 1.0.0
4
+ Summary: A plaster plugin to configure pyramid app with Yaml
5
+ Home-page: https://github.com/mardiros/plaster-yaml
6
+ License: BSD-derived
7
+ Author: Guillaume Gauvrit
8
+ Author-email: guillaume@gauvr.it
9
+ Requires-Python: >=3.8,<4.0
10
+ Classifier: License :: Other/Proprietary License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Dist: PyYAML (>=6.0.1,<7.0.0)
18
+ Requires-Dist: plaster (>=1.0,<2.0)
19
+ Project-URL: Repository, https://github.com/mardiros/plaster-yaml
20
+ Description-Content-Type: text/markdown
21
+
22
+ # plaster-yaml
23
+
24
+ ## Introduction
25
+
26
+ By default, Pyramid uses a PasteDeploy (.ini) file format for its
27
+ configuration.
28
+
29
+ When the `plaster-yaml` plugin is used, Pyramid applications are
30
+ instead configured with a YAML configuration file.
31
+
32
+ For example:
33
+
34
+ ```
35
+ pserve development.yaml
36
+ ```
37
+
38
+ ## Installation
39
+
40
+ ## With poetry
41
+
42
+ ```
43
+ poetry add plaster-yaml
44
+ ```
45
+
46
+ ## With pip
47
+
48
+ ```
49
+ pip install plaster-yaml
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ The `plaster-yaml` plugin must be "registered". This is done by
55
+ configuring a Python package "entry point" using the packaging tool of
56
+ your choice. How this is done depends on the packaging tool.
57
+ Examples are given below.
58
+
59
+ When developing, using an "editable" install that executes your
60
+ unpackaged code, after changing your package's configuration your
61
+ packaging tool must be run in order to finalize the registration.
62
+ Examples are given below.
63
+
64
+ No special steps must be taken after configuring a entry point and
65
+ (correctly) packaging your project. The `plaster-yaml` plugin is
66
+ registered when your project's package is installed.
67
+
68
+ ## With poetry
69
+
70
+ Plugin registration is configured in your `pyproject.toml`, as
71
+ follows:
72
+
73
+ ```
74
+ [tool.poetry.plugins."paste.app_factory"]
75
+ main = "<PATH_TO_MODULE_CONTAINING_MAIN>:main"
76
+
77
+ [tool.poetry.plugins."plaster.loader_factory"]
78
+ "file+yaml" = "plaster_yaml:Loader"
79
+ ```
80
+
81
+ When developing, run `poetry install` to register your plugin after
82
+ adding the above to your `pyproject.toml`.
83
+
84
+ ## With setuptools
85
+
86
+ When developing, run `pip install -e .` to register your plugin after
87
+ using either of approaches below.
88
+
89
+ ### With `pyproject.toml` and a `setuptools` `build` back-end
90
+
91
+ This is the preferred method.
92
+
93
+ Plugin registration may be configured in your `pyproject.toml`, as
94
+ follows:
95
+
96
+ ```
97
+ [project.entry-points.'paste.app_factory']
98
+ main = '<my_app>:main']
99
+ [project.entry-points.'plaster.loader_factory']
100
+ yaml = 'plaster_yaml:Loader'
101
+ ```
102
+
103
+ ### With `setup.py`
104
+
105
+ This method is generally obsolete, but it can be used when the
106
+ `[project.entry-points]` table is declared "dynamic". However, this
107
+ method must be used when the deprecated `python setup.py ...`
108
+ command is the package building method.
109
+
110
+ Plugin registration may be configured in your `setup.py`, as
111
+ follows:
112
+
113
+ ```
114
+ setup(
115
+ ...,
116
+ entry_points={
117
+ 'paste.app_factory': ['main = <my_app>:main'],
118
+ 'plaster.loader_factory': ['yaml = plaster_yaml:Loader'],
119
+ ...
120
+ },
121
+ )
122
+ ```
123
+
124
+ ## Troubleshooting
125
+
126
+ The following exception means that you did not successfully register
127
+ the `plaster-yaml` plugin:
128
+
129
+ ```
130
+ plaster.exceptions.LoaderNotFound: Could not find a matching loader for the scheme "file+yaml", protocol "wsgi".
131
+ ```
132
+
133
+ Read the relevant "Usage" sub-section, above, to find out how to
134
+ register it properly.
135
+
@@ -0,0 +1,7 @@
1
+ CHANGELOG.md,sha256=C3iG3bFYhv40jPS7H5BBKEjtl0l-iLfIPes2VdO6xTo,189
2
+ plaster_yaml/__init__.py,sha256=jdU3GEtYUJb2P9oW-BmbRxbmcRrzEUV4tzRMeCit_tg,128
3
+ plaster_yaml/loader.py,sha256=7EfZxjuwg5Ib-IzVUg61j4Htogp0uNIYmZPiIuROFsc,2928
4
+ plaster_yaml-1.0.0.dist-info/LICENSE,sha256=V32F3pzX0PY1vHGqIq3DV-as9q6cglrNA60gA70oN4U,1521
5
+ plaster_yaml-1.0.0.dist-info/METADATA,sha256=WSdBxwUHQdHo62quubRz8wa8TVxebt8R7lrVSlSnjjQ,3509
6
+ plaster_yaml-1.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
7
+ plaster_yaml-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any