Skip to content

Commit 2f51d3b

Browse files
committed
Merge remote-tracking branch 'origin/feature/pep517' into feature/pep517
# Conflicts: # README.md # mrmat_python_api_flask/__init__.py # requirements.txt
2 parents 29266e0 + da9f317 commit 2f51d3b

File tree

19 files changed

+361
-311
lines changed

19 files changed

+361
-311
lines changed

.flake8

Lines changed: 0 additions & 3 deletions
This file was deleted.

.github/workflows/build.yml

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
- name: Calculate Build Context
4545
run: |
4646
MRMAT_VERSION="${MAJOR}.${MINOR}.${GITHUB_RUN_NUMBER}"
47-
if [ "$GITHUB_EVENT_NAME" == 'pull_request_target' ]; then
47+
if [ "$GITHUB_EVENT_NAME" == 'pull_request_target' && GITHUB_BASE_REF == 'main']; then
4848
MRMAT_IS_RELEASE=true
4949
echo "::warning ::Building release ${MRMAT_VERSION}"
5050
echo "MRMAT_IS_RELEASE=true" >> $GITHUB_ENV
@@ -65,19 +65,12 @@ jobs:
6565
path: ~/.local
6666
key: ${{ runner.os }}
6767

68-
- name: Install dependencies
68+
- name: Build
6969
run: |
70-
python -m pip install --upgrade pip
71-
pip install --user wheel
7270
pip install --user -r requirements.txt
73-
pip install --user -r test-requirements.txt
74-
75-
- name: Test
76-
run: |
77-
flake8 --statistics
78-
pylint mrmat_python_api_flask
79-
python ./setup.py install
80-
python -m pytest
71+
pylint ${GITHUB_WORKSPACE}/mrmat_python_api_flask
72+
PYTHONPATH=${GITHUB_WORKSPACE} python -m pytest --cov=mrmat_python_api_flask
73+
PYTHONPATH=${GITHUB_WORKSPACE} python -m build --wheel -n
8174
8275
- name: Upload test results
8376
uses: actions/upload-artifact@v2
@@ -90,7 +83,7 @@ jobs:
9083
9184
- name: Conditional Release
9285
uses: marvinpinto/action-automatic-releases@latest
93-
if: github.event.pull_request.merged == true
86+
if: (github.event.pull_request.merged == true && github.base_ref == 'main')
9487
with:
9588
repo_token: "${{ secrets.GITHUB_TOKEN }}"
9689
automatic_release_tag: "${{ env.MRMAT_VERSION }}"

.idea/dataSources.xml

Lines changed: 4 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/markdown.xml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/runConfigurations/tests.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ This variant of a Python Flask API is code-first and using native Flask
1818

1919
## How to build this
2020

21-
In bash:
21+
Building a wheel boils down to this (in bash or Powershell):
2222

23-
```shell
23+
```bash
2424
$ pip install -r requirements.txt # Manually install dependencies (see note in requirements.txt!)
2525
$ export PYTHONPATH=`pwd` # In order to find the build-time ci module
2626
$ export MRMAT_VERSION=1.0.27 # Optional: To influence the version. Normally calculated and set by CI
@@ -29,15 +29,28 @@ $ ls dist/
2929
mrmat_python_api_flask-1.0.27.dev0-py3-none-any.whl
3030
```
3131

32-
In PowerShell:
33-
3432
```powershell
3533
PS> pip install -r build-requirements.txt # Manually install dependencies (see note in requirements.txt!)
3634
PS> $Env:PYTHONPATH=(pwd) # In order to find the build-time ci module
3735
PS> $Env:MRMAT_VERSION = "1.0.27" # Optional: To influence the version. Normally calculated and set by CI
3836
PS> python -m build
3937
```
4038

39+
This project uses the [PEP517 build mechanism](https://www.python.org/dev/peps/pep-0517/), but with a twist so CI is in
40+
control over the generation of the micro version number. In our case, CI is GitHub Actions, which has the top-level
41+
environment variables `MAJOR` and `MINOR`. These two are intended to be infrequently updated manually if and when
42+
it is needed. The micro version is automatically set by the `GITHUB_RUN_NUMBER` which increases for every build
43+
we do. The `MRMAT_VERSION` environment variable is a concatenation of these three. If the build is via a PR onto
44+
main then this is the release version. Otherwise `.dev0` is appended to the version.
45+
46+
If you are building locally, then your version will **always** be `0.0.0.dev0` (unless you explicitly set the
47+
`MRMAT_VERSION` environment variable to something different).
48+
49+
It is necessary for setup.cfg to figure out whether and what `MRMAT_VERSION` is set to. Since this is no longer
50+
an executable in PEP517, we tell it to use the `ci` module for doing so. The `ci` module simply picks up `MRMAT_VERSION`
51+
from the environment, no more and the module is explicitly ignored from packaging. However, you must ensure that
52+
the top-level `ci` module is on the Python path as you build (hence the setup above).
53+
4154
## How to run this
4255

4356
You have the choice of running this

mrmat_python_api_flask/__init__.py

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,48 +25,31 @@
2525

2626
import sys
2727
import os
28+
import logging
2829
import importlib.metadata
29-
from logging.config import dictConfig
30+
31+
from rich.console import Console
32+
from rich.logging import RichHandler
3033

3134
from flask import Flask
3235
from flask_sqlalchemy import SQLAlchemy
3336
from flask_migrate import Migrate
3437
from flask_marshmallow import Marshmallow
3538
from flask_oidc import OpenIDConnect
3639

37-
try:
38-
__version__ = importlib.metadata.version('mrmat-python-api-flask')
39-
except importlib.metadata.PackageNotFoundError:
40-
# You have not explicitly installed the package just yet
41-
__version__ = 'UNKNOWN'
40+
logging.basicConfig(level='INFO',
41+
handlers=[RichHandler(rich_tracebacks=True,
42+
show_path=False,
43+
omit_repeated_times=False)])
44+
log = logging.getLogger(__name__)
45+
console = Console()
4246

47+
__version__ = importlib.metadata.version('mrmat-python-api-flask')
4348
db = SQLAlchemy()
4449
ma = Marshmallow()
4550
migrate = Migrate()
4651
oidc = OpenIDConnect()
4752

48-
dictConfig({
49-
'version': 1,
50-
'formatters': {'default': {
51-
'format': '[%(asctime)s] %(levelname)s: %(message)s',
52-
}},
53-
'handlers': {
54-
'wsgi': {
55-
'class': 'logging.StreamHandler',
56-
'stream': 'ext://flask.logging.wsgi_errors_stream',
57-
'formatter': 'default'
58-
}
59-
},
60-
'root': {
61-
'level': 'INFO',
62-
'handlers': ['wsgi']
63-
},
64-
'mrmat_python_api_flask': {
65-
'level': 'INFO',
66-
'handlers': ['wsgi']
67-
}
68-
})
69-
7053

7154
def create_app(config_override=None, instance_path=None):
7255
"""Factory method to create a Flask app.
@@ -87,7 +70,8 @@ def create_app(config_override=None, instance_path=None):
8770
#
8871
# Set configuration defaults. If a config file is present then load it. If we have overrides, apply them
8972

90-
app.config.setdefault('SECRET_KEY', os.urandom(16))
73+
# TODO
74+
#app.config.setdefault('SECRET_KEY', 'JFg4K1l5vVmusHmI0cNAFg')
9175
app.config.setdefault('SQLALCHEMY_DATABASE_URI',
9276
'sqlite+pysqlite:///' + os.path.join(app.instance_path, 'mrmat-python-api-flask.sqlite'))
9377
app.config.setdefault('SQLALCHEMY_TRACK_MODIFICATIONS', False)

mrmat_python_api_flask/apis/resource/v1/api.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838

3939
def _extract_identity() -> Tuple:
4040
return g.oidc_token_info['client_id'], \
41-
g.oidc_token_info['preferred_username']
41+
g.oidc_token_info['username']
4242

4343

4444
@bp.route('/', methods=['GET'])
45-
@oidc.accept_token(require_token=True, scopes_required=['mrmat-python-api-flask-resource-read'])
45+
@oidc.accept_token(require_token=True, scopes_required=['mpaf-read'])
4646
def get_all():
4747
identity = _extract_identity()
4848
logger.info(f'Called by {identity[1]} ({identity[0]}')
@@ -51,7 +51,7 @@ def get_all():
5151

5252

5353
@bp.route('/<i>', methods=['GET'])
54-
@oidc.accept_token(require_token=True, scopes_required=['mrmat-python-api-flask-resource-read'])
54+
@oidc.accept_token(require_token=True, scopes_required=['mpaf-read'])
5555
def get_one(i: int):
5656
identity = _extract_identity()
5757
logger.info(f'Called by {identity[1]} ({identity[0]}')
@@ -62,7 +62,7 @@ def get_one(i: int):
6262

6363

6464
@bp.route('/', methods=['POST'])
65-
@oidc.accept_token(require_token=True, scopes_required=['mrmat-python-api-flask-resource-write'])
65+
@oidc.accept_token(require_token=True, scopes_required=['mpaf-write'])
6666
def create():
6767
(client_id, name) = _extract_identity()
6868
logger.info(f'Called by {name} ({client_id}')
@@ -99,7 +99,7 @@ def create():
9999

100100

101101
@bp.route('/<i>', methods=['PUT'])
102-
@oidc.accept_token(require_token=True, scopes_required=['mrmat-python-api-flask-resource-write'])
102+
@oidc.accept_token(require_token=True, scopes_required=['mpaf-write'])
103103
def modify(i: int):
104104
(client_id, name) = _extract_identity()
105105
logger.info(f'Called by {name} ({client_id}')
@@ -118,7 +118,7 @@ def modify(i: int):
118118

119119

120120
@bp.route('/<i>', methods=['DELETE'])
121-
@oidc.accept_token(require_token=True, scopes_required=['mrmat-python-api-flask-resource-write'])
121+
@oidc.accept_token(require_token=True, scopes_required=['mpaf-write'])
122122
def remove(i: int):
123123
(client_id, name) = _extract_identity()
124124
logger.info(f'Called by {name} ({client_id}')

mrmat_python_api_flask/client.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@
2929
from time import sleep
3030
from argparse import ArgumentParser, Namespace
3131
from typing import List, Optional, Dict
32-
import cli_ui
33-
from halo import Halo
3432
import requests
3533

36-
from mrmat_python_api_flask import __version__
34+
from mrmat_python_api_flask import __version__, log
3735

3836

3937
class ClientException(Exception):
@@ -76,7 +74,6 @@ def oidc_device_auth(config: Dict, discovery: Dict) -> Dict:
7674
return data
7775

7876

79-
@Halo(text='Checking authentication')
8077
def oidc_check_auth(config: Dict, discovery: Dict, device_auth: Dict):
8178
wait = 5
8279
stop = False
@@ -159,7 +156,6 @@ def main(argv=None) -> int:
159156
args = parse_args(argv if argv is not None else sys.argv[1:])
160157
if args is None:
161158
return 0
162-
cli_ui.setup(verbose=args.debug, quiet=args.quiet, timestamp=False)
163159

164160
#
165161
# Read from the config file by default, but allow overrides via the CLI
@@ -191,23 +187,23 @@ def main(argv=None) -> int:
191187
raise ClientException(msg='No expires_in in device_auth')
192188

193189
# Adding the user code to the URL is convenient, but not as secure as it could be
194-
cli_ui.info(f'Please visit {device_auth["verification_uri"]} within {device_auth["expires_in"]} seconds and '
190+
log.info(f'Please visit {device_auth["verification_uri"]} within {device_auth["expires_in"]} seconds and '
195191
f'enter code {device_auth["user_code"]}. Or just visit {device_auth["verification_uri_complete"]}')
196192

197193
auth = oidc_check_auth(config, discovery, device_auth)
198-
cli_ui.info('Authenticated')
194+
log.info('Authenticated')
199195

200196
#
201197
# We're using requests directly here because requests_oauthlib doesn't support device code flow directly
202198

203199
resp = requests.get('http://127.0.0.1:5000/api/greeting/v3/',
204200
headers={'Authorization': f'Bearer {auth["id_token"]}'})
205-
cli_ui.info(f'Status Code: {resp.status_code}')
206-
cli_ui.info(resp.content)
201+
log.info(f'Status Code: {resp.status_code}')
202+
log.info(resp.content)
207203

208204
return 0
209205
except ClientException as ce:
210-
cli_ui.error(ce.msg)
206+
log.error(ce.msg)
211207
return ce.exit_code
212208

213209

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
[pytest]
66
testpaths = tests
7-
addopts = --cov=mrmat_python_api_flask --cov-report=term --cov-report=xml:build/coverage.xml --junit-xml=build/junit.xml
7+
#addopts = --cov=mrmat_python_api_flask --cov-report=term --cov-report=xml:build/coverage.xml --junit-xml=build/junit.xml
88
junit_family = xunit2
99
log_cli = 1
1010
log_cli_level = INFO

0 commit comments

Comments
 (0)