Skip to content

Commit e06ff73

Browse files
ricardogsilvaRicardo Garcia Silvatomkralidis
authored
custom cli commands (geopython#1234)
* Implemented discovery of third-party cli commands * Updated authors * Added python3-importlib-metadata to debian control file * Replaced ellipsis with a pass statement --------- Co-authored-by: Ricardo Garcia Silva <ricardo@kartoza.com> Co-authored-by: Tom Kralidis <tomkralidis@gmail.com>
1 parent fddefc4 commit e06ff73

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

debian/control

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Depends: ${python3:Depends},
1818
python3-click,
1919
python3-dateutil,
2020
python3-flask,
21+
python3-importlib-metadata,
2122
python3-jsonschema,
2223
python3-tz,
2324
python3-unicodecsv,

docs/source/plugins.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,56 @@ The following methods are options to connect a plugin to pygeoapi:
6666
id_field: stn_id
6767
6868
69+
Specifying custom pygeoapi CLI commands
70+
+++++++++++++++++++++++++++++++++++++++
71+
72+
Third-party plugins may also provide custom CLI commands. This can be done by means of two additional steps:
73+
74+
1. Create your CLI commands using click
75+
2. In your plugin's ``setup.py`` or ``pyproject.toml`` file, specify an entrypoint for the ``pygeoapi`` group
76+
pointing to your click CLI command or group.
77+
78+
As a simple example, lets imagine you develop a plugin named ``myplugin``, which has a ``cli.py`` module with
79+
the following contents:
80+
81+
.. code-block:: python
82+
83+
# module: myplugin.cli
84+
import click
85+
86+
@click.command(name="super-command")
87+
def my_cli_command():
88+
print("Hello, this is my custom pygeoapi CLI command!")
89+
90+
91+
Then, in your plugin's ``setup.py`` file, specify the entrypoints section:
92+
93+
.. code-block:: python
94+
95+
# file: setup.py
96+
entry_points={
97+
'pygeoapi': ['my-plugin = myplugin.cli:my_cli_command']
98+
}
99+
100+
Alternatively, if using a ``pyproject.toml`` file instead:
101+
102+
.. code-block:: python
103+
104+
# file: pyproject.toml
105+
# Noter that this example uses poetry, other Python projects may differ in
106+
# how they expect entry_points to be specified
107+
[tool.poetry.plugins."pygeoapi"]
108+
my-plugin = 'myplugin.cli:my_cli_command'
109+
110+
111+
After having installed this plugin, you should now be able to call the CLI command by running:
112+
113+
.. code-block:: sh
114+
115+
$ pygeoapi plugins super-command
116+
Hello, this is my custom pygeoapi CLI command!
117+
118+
69119
.. note:: The United States Geological Survey has created a Cookiecutter project for creating pygeoapi plugins. See the `pygeoapi-plugin-cookiecutter`_ project to get started.
70120

71121
**Option 2**: Update in core pygeoapi:

pygeoapi/__init__.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# =================================================================
22
#
33
# Authors: Tom Kralidis <tomkralidis@gmail.com>
4+
# Ricardo Garcia Silva <ricardo.garcia.silva@geobeyond.it>
45
#
56
# Copyright (c) 2021 Tom Kralidis
7+
# Copyright (c) 2023 Ricardo Garcia Silva
68
#
79
# Permission is hereby granted, free of charge, to any person
810
# obtaining a copy of this software and associated documentation
@@ -30,16 +32,47 @@
3032
__version__ = '0.15.dev0'
3133

3234
import click
35+
try:
36+
# importlib.metadata is part of Python's standard library from 3.8
37+
from importlib.metadata import entry_points
38+
except ImportError:
39+
from importlib_metadata import entry_points
3340
from pygeoapi.config import config
3441
from pygeoapi.openapi import openapi
3542

3643

44+
def _find_plugins():
45+
"""
46+
A decorator to find pygeoapi CLI plugins provided by third-party packages.
47+
48+
pygeoapi plugins can hook into the pygeoapi CLI by providing their CLI
49+
functions and then using an entry_point named 'pygeoapi'.
50+
"""
51+
52+
def decorator(click_group):
53+
for entry_point in entry_points(group="pygeoapi"):
54+
try:
55+
click_group.add_command(entry_point.load())
56+
except Exception as err:
57+
print(err)
58+
return click_group
59+
60+
return decorator
61+
62+
3763
@click.group()
3864
@click.version_option(version=__version__)
3965
def cli():
4066
pass
4167

4268

69+
@_find_plugins()
70+
@cli.group()
71+
def plugins():
72+
"""Additional commands provided by third-party pygeoapi plugins"""
73+
pass
74+
75+
4376
@cli.command()
4477
@click.option('--flask', 'server', flag_value="flask", default=True)
4578
@click.option('--starlette', 'server', flag_value="starlette")

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Babel
22
click
33
Flask
4+
importlib_metadata
45
jinja2
56
jsonschema
67
pydantic

0 commit comments

Comments
 (0)