Skip to content

Commit 0f6cb07

Browse files
authored
Add a setuptools support for building proto files (#1)
2 parents 34a26f7 + f0501dd commit 0f6cb07

File tree

12 files changed

+489
-68
lines changed

12 files changed

+489
-68
lines changed

.darglint

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[darglint]
2+
docstring_style=google

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Frequenz Energy-as-a-Service GmbH
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Frequenz repository common configuration for Python
2+
3+
This is very opinionated set of tools and configurations to setup a Python
4+
repository for Frequenz projects.
5+
6+
If offers:
7+
8+
* Trivial build of `noxfile.py` with some predefined sessions with all common
9+
checks.
10+
* Tools to build protobuf/grpc files as Python, including type information.

pyproject.toml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,21 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "frequenz-repo-config"
7-
description = "Frequenz project setup tools and common configuration"
7+
description = "Frequenz repository setup tools and common configuration"
88
readme = "README.md"
99
license = { text = "MIT" }
10-
keywords = ["frequenz", "package", "project", "config", "tool"]
10+
keywords = [
11+
"frequenz",
12+
"package",
13+
"project",
14+
"config",
15+
"tool",
16+
"repository",
17+
"setuptools",
18+
"nox",
19+
"grpc",
20+
"protobuf",
21+
]
1122
classifiers = [
1223
"Development Status :: 3 - Alpha",
1324
"Intended Audience :: Developers",
@@ -26,6 +37,11 @@ name = "Frequenz Energy-as-a-Service GmbH"
2637
2738

2839
[project.optional-dependencies]
40+
api = [
41+
"grpcio-tools >= 1.47.0, < 2",
42+
"mypy-protobuf >= 3.0.0, < 4",
43+
"setuptools >= 67.6.0, < 68",
44+
]
2945
docs-gen = [
3046
"mike == 1.1.2",
3147
"mkdocs-gen-files == 0.4.0",
@@ -38,6 +54,7 @@ docs-lint = ["pydocstyle == 6.3.0", "darglint == 1.8.1"]
3854
format = ["black == 23.3.0", "isort == 5.12.0"]
3955
mypy = [
4056
"mypy == 1.1.1",
57+
"types-setuptools >= 67.6.0, < 68", # Should match the global dependency
4158
# For checking the docs/ script, and tests
4259
"frequenz-repo-config[docs-gen,pytest]",
4360
]
Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,150 @@
11
# License: MIT
22
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
33

4-
"""Frequenz project setup tools and common configuration."""
4+
"""Frequenz project setup tools and common configuration.
55
6-
from . import nox
6+
The tools are provided to configure 4 main types of repositories:
7+
8+
- APIs (api)
9+
- Actors (actor)
10+
- Applications (app)
11+
- Libraries (lib)
12+
13+
# Common
14+
15+
## `nox`
16+
17+
Projects wanting to use `nox` to run lint checkers and other utilities can use
18+
the [`frequenz.repo.config.nox`][] package.
19+
20+
Make sure to add this package as `dev` dependency to your project's
21+
`pyproject.tom` file, for example:
22+
23+
```toml
24+
[project.optional-dependencies]
25+
nox = [
26+
"nox == 2022.11.21",
27+
"frequenz-repo-config[lib] == 0.1.0",
28+
]
29+
```
30+
31+
Please note the `lib` optional dependency. Make sure you specify the correct
32+
one based on the type of your project (`api`, `actor`, `app`, `lib`). Also make
33+
sure to adjust the versions.
34+
35+
When writing the `noxfile.py` you should import the `nox` module from this
36+
package and use the [`frequenz.repo.config.nox.configure`][] function,
37+
which will configure all nox sessions.
38+
39+
You should call `configure()` using one of the default configurations provided
40+
in the [`frequenz.repo.config.nox.default`][] module. For example:
41+
42+
```python
43+
from frequenz.repo import config
44+
45+
config.nox.configure(config.nox.default.lib_config)
46+
```
47+
48+
Again, make sure to pick the correct default configuration based on the type of
49+
your project (`api_config`, `actor_config`, `app_config`, `lib_config`).
50+
51+
If you need to modify the configuration, you can copy one of the default
52+
configurations by using the
53+
[`copy()`][frequenz.repo.config.nox.config.Config.copy] method:
54+
55+
```python
56+
from frequenz.repo import config
57+
58+
conf = config.nox.default.lib_config.copy()
59+
conf.opts.black.append("--diff")
60+
config.nox.configure(conf)
61+
```
62+
63+
If you need further customization or to define new sessions, you can use the
64+
following modules:
65+
66+
- [`frequenz.repo.config.nox.config`][]: Low-level utilities to configure nox
67+
sessions. It defines the `Config` and CommandsOptions` classes and the actual
68+
implementation of the `configure()` function. It also defines the `get()`
69+
function, which can be used to get the currently used configuration object.
70+
71+
- [`frequenz.repo.config.nox.session`][]: Predefined nox sessions. These are
72+
the sessions that are used by default.
73+
74+
- [`frequenz.repo.config.nox.util`][]: General purpose utility functions.
75+
76+
77+
# APIs
78+
79+
## `setuptools` gRPC support
80+
81+
When configuring APIs it is assumed that they have a gRPC interface.
82+
83+
Normally Frequenz APIs use basic types from
84+
[`google/api-common-protos`](https://github.com/googleapis/api-common-protos),
85+
so you need to make sure the proper submodule is added to your project:
86+
87+
```sh
88+
mkdir submodules
89+
git submodule add https://github.com:googleapis/api-common-protos.git submodules/api-common-protos
90+
git commit -m "Add Google api-common-protos submodule" submodules/api-common-protos
91+
```
92+
93+
Then you need to create a `setup.py` file with the following content:
94+
95+
```py
96+
import setuptools
97+
98+
from frequenz.repo.config.setuptools import grpc_tools
99+
100+
if __name__ == "__main__":
101+
setuptools.setup(cmdclass=grpc_tools.build_proto_cmdclass())
102+
```
103+
104+
Then you need to add this package as a build dependency and a few extra
105+
dependencies to your project, for example:
106+
107+
```toml
108+
requires = [
109+
"setuptools >= 67.3.2, < 68",
110+
"setuptools_scm[toml] >= 7.1.0, < 8",
111+
"frequenz-repo-config[api] >= 0.1.0, < 0.2.0",
112+
]
113+
build-backend = "setuptools.build_meta"
114+
115+
[project]
116+
dependencies = [
117+
"googleapis-common-protos == 1.56.2",
118+
"grpcio == 1.51.0",
119+
]
120+
```
121+
122+
Note the `api` extra in `frequenz-repo-config[api]`, this will ensure all
123+
dependencies to build the protocol files will be installed when building the
124+
package. Of course you need to replace the version numbers with the correct
125+
ones too.
126+
127+
Finally you need to make sure to include the generated `*.pyi` files in the
128+
source distribution, as well as the Google api-common-protos files, as it
129+
is not handled automatically yet
130+
([#13](https://github.com/frequenz-floss/frequenz-repo-config-python/issues/13)):
131+
132+
```
133+
recursive-include py *.pyi
134+
recursive-include submodules/api-common-protos/google *.proto
135+
```
136+
137+
If you need to customize how the protobuf files are compiled, you can pass
138+
a path to look for the protobuf files, a glob pattern to find the protobuf
139+
files, and a list of paths to include when compiling the protobuf files. By
140+
default `submodules/api-common-protos` is used as an include path, so if
141+
yout configured the submodules in a different path, you need to pass the
142+
correct path to the `include_paths` argument.
143+
"""
144+
145+
from . import nox, setuptools
7146

8147
__all__ = [
9148
"nox",
149+
"setuptools",
10150
]

src/frequenz/repo/config/nox/__init__.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,45 @@
1-
"""TODO."""
1+
# License: MIT
2+
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
23

3-
from __future__ import annotations
4+
"""Utilities to build noxfiles.
5+
6+
The main entry point is the [`configure()`][configure] function, which will
7+
configure all nox sessions according to some configuration.
8+
9+
You should call `configure()` using one of the default configurations provided
10+
in the [`default`][] module. For example:
11+
12+
```python
13+
from frequenz.repo import config
14+
15+
config.nox.configure(config.nox.default.lib_config)
16+
```
17+
18+
If you need to modify the configuration, you can copy one of the default
19+
configurations by using the
20+
[`copy()`][frequenz.repo.config.nox.config.Config.copy] method:
21+
22+
```python
23+
from frequenz.repo import config
24+
25+
conf = config.nox.default.lib_config.copy()
26+
conf.opts.black.append("--diff")
27+
config.nox.configure(conf)
28+
```
29+
30+
If you need further customization or to define new sessions, you can use the
31+
following modules:
32+
33+
- [`config`][]: Low-level utilities to configure nox sessions. It defines the
34+
`Config` and CommandsOptions` classes and the actual implementation of the
35+
`configure()` function. It also defines the `get()` function, which can be
36+
used to get the currently used configuration object.
37+
38+
- [`session`][]: Predefined nox sessions. These are the sessions that are used
39+
by default.
40+
41+
- [`util`][]: General purpose utility functions.
42+
"""
443

544
from . import config, default, session, util
645
from .config import configure

0 commit comments

Comments
 (0)