Skip to content

Commit 2d64942

Browse files
committed
Merge branch 'release/4.3.0'
2 parents d9f3ab3 + b7a0c54 commit 2d64942

22 files changed

+357
-48
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ build
1313
_build
1414
.tox
1515
.eggs
16+
.nox
1617

1718
# IDE cruft
1819
.idea

HISTORY

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
4.3.0
2+
=====
3+
4+
Features
5+
--------
6+
7+
- Async commands, ``app.command`` can not be applied to async functions and
8+
handle the event loop.
9+
10+
- ``app.default`` now returns a Command Proxy supporting async and additional
11+
command line arguments.
12+
13+
114
4.2.0
215
=====
316

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ So what do we handle?
6262
specific default settings.
6363

6464
- Application - Provides a extensible and simple CLI interface for running
65-
commands, comes with built-in commands to execute check, setting and extension
66-
reports.
65+
commands (including async), comes with built-in commands to execute check, setting
66+
and extension reports.
6767

6868
- Logging - Initialise and apply sane logging defaults.
6969

docs/developers.rst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ met:
99
- Install the `pre-commit <https://github.com/pre-commit/pre-commit>`_ hooks to
1010
ensure you code is formatted by `black <https://github.com/ambv/black>`_.
1111

12-
- Ensure your code has unit test coverage (we use pytest). Unit tests should be
12+
- Ensure your code has unit test coverage (using pyTest). Unittests should be
1313
designed to be as fast as possible.
1414

15+
- Ensure your code passes the pyLint checks (this is part of the travis build).
16+
1517
- Update the docs with the details if required.
1618

1719
- The API matters, ensure any features provide a nice API for end users.
1820

1921

20-
The core pyApp package is intended to be fairly light and mainly made up of
21-
plumbing code. If you want to add support for a particular service or server
22-
an extension is the best way to do that.
22+
The core pyApp package is intended to be light and mainly made up of plumbing
23+
code. If you want to add support for a particular service or server an extension
24+
is the way to do this.
25+
26+
See the *Developing an Extension* section of the extensions doc for guidance on
27+
building your own extension.

docs/extensions.rst

Lines changed: 139 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ Extensions
66
Available Extensions
77
====================
88

9-
pyApp.org Supplied
10-
------------------
9+
pyApp Developed
10+
---------------
1111

12-
These are extensions supplied by `pyApp`.
12+
Extensions available for use:
1313

1414
- `pyapp.aiobotocore <https://github.com/pyapp-org/pyapp.aiobotocore>`_ -
1515
Factory for `Async AWS client library <https://github.com/aio-libs/aiobotocore>`_
@@ -21,12 +21,147 @@ These are extensions supplied by `pyApp`.
2121
Factory for `SQLALchemy <https://www.sqlalchemy.org>`_
2222

2323

24-
These extensions are in development.
24+
Extensions in beta:
2525

2626
- `pyapp-messaging <https://github.com/pyapp-org/pyapp-messaging>`_ -
2727
Abstract messaging framework for interacting with Pub/Sub and Message Queues.
2828

29+
Extensions in development:
30+
2931
- `pyapp.boto3 <https://github.com/pyapp-org/pyapp.boto3>`_ -
3032
Factory for `AWS client library <https://boto3.amazonaws.com/v1/documentation/api/latest/index.html>`_
3133
- `pyapp.smtp <https://github.com/pyapp-org/pyapp.SMTP>`_ -
3234
Interface to `smtplib <https://docs.python.org/3/library/smtplib.html>`_
35+
36+
.. note::
37+
The development status of these projects may have changed from when this
38+
documentation was generated, see the repository (or PyPi) of the extension
39+
package for up to date status.
40+
41+
Developing an Extension
42+
=======================
43+
44+
An extension is a standard Python package that exports a known entry point that
45+
pyApp uses to identify extensions. This entry point will reference a class with
46+
known attributes that pyApp recognises.
47+
48+
A Basic Project
49+
---------------
50+
51+
An extensions consists of a standard Python project structure eg::
52+
53+
├┬ my_extension
54+
│├ __init__.py
55+
│└ __version__.py
56+
├ README.rst
57+
├ setup.cfg
58+
└ setup.py
59+
60+
61+
The contents of which are:
62+
63+
``my_extension/__init__.py``
64+
The package init file, this file contains the extension entry point. While a
65+
package must container an Extension class every attribute on the class is optional.
66+
67+
.. code-block:: python
68+
69+
# Pull in the version
70+
from .__version__ import __version__
71+
72+
73+
class Extension:
74+
"""
75+
My pyApp Extension
76+
"""
77+
78+
default_settings = ".default_settings"
79+
checks = ".checks"
80+
81+
@staticmethod
82+
def register_commands(root):
83+
"""
84+
Register custom commands with pyApp.
85+
"""
86+
87+
@staticmethod
88+
def ready():
89+
"""
90+
Method called once pyApp has configured environment
91+
"""
92+
93+
94+
``my_extension/__version__.py``
95+
The package version; defining the version in a separate file simplifies the
96+
process of obtaining the version during the package build process.
97+
98+
.. code-block:: python
99+
100+
__version__ = "1.0"
101+
102+
103+
``README.rst``
104+
While not strictly necessary a README document is *highly recommended* and is
105+
included in the package as the long description.
106+
107+
.. code-block:: rst
108+
109+
##################
110+
My pyApp Extension
111+
##################
112+
113+
Information about my extension
114+
115+
116+
``setup.cfg``
117+
Defines the metadata and configuration used to build a package, this is also
118+
where the entry point used identify you extension is defined.
119+
120+
.. code-block:: ini
121+
122+
[metadata]
123+
name = my-extension
124+
author = Author
125+
author-email = [email protected]
126+
description = Blurb about my extension
127+
long-description = file: README.rst
128+
url = https://github.com/author/my-extension
129+
platforms = any
130+
license = BSD-3-Clause
131+
132+
[options]
133+
python_requires = >=3.6
134+
packages = find:
135+
setup_requires =
136+
setuptools >=38.3
137+
install_requires =
138+
pyapp >=4.3.0
139+
140+
[options.entry_points]
141+
# Used by pyApp to recognise my_extension
142+
pyapp.extensions =
143+
my-extension = my_extension:Extension
144+
145+
146+
``setup.py``
147+
Script that trigger ``setuptools`` to build a package. This example takes
148+
advantage of the version in a separate file to extract the version number.
149+
150+
.. code-block:: python
151+
152+
from pathlib import Path
153+
from setuptools import setup
154+
155+
HERE = Path(__file__).parent
156+
157+
about = {}
158+
with (HERE / "my_extension/__version__.py").open() as f:
159+
exec(f.read(), about)
160+
161+
setup(version=about["__version__"])
162+
163+
164+
.. tip::
165+
A gotcha when building extensions is attempting to access settings to early
166+
this is the reason for the ``ready`` event on the Extension class. Once ready
167+
has been called settings are setup and ready for use.

docs/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ So what do we handle?
6767
specific default settings.
6868

6969
- Application - Provides a extensible and simple CLI interface for running
70-
commands, comes with built-in commands to execute check, setting and extension
71-
reports.
70+
commands (including Async), comes with built-in commands to execute check, setting
71+
and extension reports.
7272

7373
- Logging - Initialise and apply sane logging defaults.
7474

docs/recipes/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Recipes
55
:maxdepth: 1
66

77
integration_with_django
8+
using_async_commands
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Using Async Commands
2+
====================
3+
4+
As of pyApp 4.3 command handlers can be defined as Async functions and pyApp will
5+
take care of setting up an event loop call the handler.
6+
7+
.. code-block:: python
8+
9+
app = CliApplication()
10+
11+
@app.command
12+
async def my_command(args):
13+
pass
14+
15+
16+
This feature is also available to the default handler.

noxfile.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import nox
2+
from nox.sessions import Session
3+
4+
5+
@nox.session(python=("3.6", "3.7", "3.8"))
6+
def tests(session: Session):
7+
session.run("python", "setup.py", "test")

pyapp/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# pylint: disable=missing-module-docstring
2-
__version__ = "4.2.0"
2+
__version__ = "4.3.0"

0 commit comments

Comments
 (0)