refactor into several python packages
This commit is contained in:
Родитель
b4ae0f0601
Коммит
9c1ef82b6a
|
@ -1,2 +1,3 @@
|
|||
releng_api.egg-info/
|
||||
*.pyc
|
||||
*.egg-info
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
RelengAPI
|
||||
=========
|
||||
|
||||
Your Interface to Release Engineering Automation.
|
||||
|
||||
Users
|
||||
-----
|
||||
|
||||
Haha, not yet.
|
||||
|
||||
Developers
|
||||
----------
|
||||
|
||||
Structure
|
||||
.........
|
||||
|
||||
RelengAPI is a Flask application. It is composed of several Python packages.
|
||||
|
||||
The base is `relengapi`.
|
||||
It implements the root app, and lots of other common features.
|
||||
It also searches its python environment for other packages that can provide blueprints for the Releng API.
|
||||
These act as plugins, adding extra endpoints to the API.
|
||||
|
||||
The `relengapi-docs` package implements the documentation tree for the Releng API, and is a prototypical blueprint package.
|
||||
|
||||
Running
|
||||
.......
|
||||
|
||||
To run the tool for development, pip install the base:
|
||||
|
||||
pip install -e base
|
||||
|
||||
and any Blueprints you want:
|
||||
|
||||
pip install -e docs
|
||||
|
||||
then run `relengapi` to run the server in the foreground.
|
||||
This tool has some command-line options that may be useful; see its `--help`.
|
||||
|
||||
Writing a Blueprint
|
||||
...................
|
||||
|
||||
If your blueprint will be meaty enough to deserve its own project, repo, and so forth, then start that now.
|
||||
Otherwise, add it to the relengapi project in a top-level directory.
|
||||
|
||||
Add a `setup.py` similar to that in `docs/`.
|
||||
Name the package with a `relengapi-` prefix, so it's easy to find.
|
||||
The `install_requires` parameter should name both `Flask` and `relengapi`, as well as any other dependencies.
|
||||
The `namespace_packages` line allows multiple packages to share the same Python path:
|
||||
|
||||
namespace_packages=['relengapi.blueprints'],
|
||||
|
||||
Finally, include an entry point so that the base can find the blueprint:
|
||||
|
||||
entry_points={
|
||||
"relengapi_blueprints": [
|
||||
'mypackage = relengapi.blueprints.mypackage:bp',
|
||||
],
|
||||
},
|
||||
|
||||
The `relengapi.blueprints.mypackage:bp` in the above is an import path leading to the Blueprint object.
|
||||
|
||||
Finally, create the directory structure:
|
||||
|
||||
relengapi/__init__.py
|
||||
relengapi/blueprints/__init__.py
|
||||
relengapi/blueprints/mypackage/__init__.py
|
||||
|
||||
The first two of the `__init__.py` files must have *only* the following contents:
|
||||
|
||||
__import__('pkg_resources').declare_namespace(__name__)
|
||||
|
||||
In the third, create your Blueprint:
|
||||
|
||||
from flask import Blueprint, jsonify
|
||||
bp = Blueprint('docs', __name__)
|
||||
@bp.route('/some/path')
|
||||
def root():
|
||||
return jsonify("HELLO")
|
||||
|
||||
This function would be available at `/mypackage/some/path`.
|
|
@ -0,0 +1 @@
|
|||
__import__('pkg_resources').declare_namespace(__name__)
|
|
@ -4,11 +4,12 @@ from flask import url_for
|
|||
import pkg_resources
|
||||
|
||||
def create_app():
|
||||
app = Flask('releng_api')
|
||||
app = Flask('relengapi')
|
||||
app.config.from_envvar('RELENG_API_SETTINGS', silent=True)
|
||||
|
||||
# get blueprints from pkg_resources
|
||||
for ep in pkg_resources.iter_entry_points('releng_api_blueprints'):
|
||||
for ep in pkg_resources.iter_entry_points('relengapi_blueprints'):
|
||||
print " * registering blueprint", ep.name
|
||||
app.register_blueprint(ep.load(), url_prefix='/%s' % ep.name)
|
||||
|
||||
@app.route('/')
|
|
@ -0,0 +1 @@
|
|||
__import__('pkg_resources').declare_namespace(__name__)
|
|
@ -1,8 +1,8 @@
|
|||
import argparse
|
||||
from releng_api import create_app
|
||||
from relengapi.app import create_app
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="run a dev instance of releng_api")
|
||||
parser = argparse.ArgumentParser(description="Run a dev instance of relengapi")
|
||||
parser.add_argument("-a", "--all-interfaces", action='store_true',
|
||||
help='Run on all interfaces, not just localhost')
|
||||
parser.add_argument("--no-debug", action='store_true',
|
|
@ -1,12 +1,12 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name='releng-api',
|
||||
name='relengapi',
|
||||
version='0.0',
|
||||
description='The One True API',
|
||||
description='The code behind https://api.pub.build.mozilla.org',
|
||||
author='Dustin J. Mitchell',
|
||||
author_email='dustin@mozilla.com',
|
||||
url='',
|
||||
url='https://api.pub.build.mozilla.org',
|
||||
install_requires=[
|
||||
"Flask",
|
||||
],
|
||||
|
@ -14,12 +14,10 @@ setup(
|
|||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
test_suite='nose.collector',
|
||||
namespace_packages=['relengapi.blueprints'],
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
'releng_api = releng_api.scripts.server:main',
|
||||
],
|
||||
"releng_api_blueprints": [
|
||||
'docs = releng_api.blueprints.docs:bp',
|
||||
'relengapi = relengapi.scripts.server:main',
|
||||
],
|
||||
},
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
__import__('pkg_resources').declare_namespace(__name__)
|
|
@ -0,0 +1 @@
|
|||
__import__('pkg_resources').declare_namespace(__name__)
|
|
@ -0,0 +1,24 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name='relengapi-docs',
|
||||
version='0.0',
|
||||
description='Documentation blueprint for relengapi',
|
||||
author='Dustin J. Mitchell',
|
||||
author_email='dustin@mozilla.com',
|
||||
url='',
|
||||
install_requires=[
|
||||
"Flask",
|
||||
"relengapi",
|
||||
],
|
||||
tests_require=["nose", "mock"],
|
||||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
test_suite='nose.collector',
|
||||
namespace_packages=['relengapi.blueprints'],
|
||||
entry_points={
|
||||
"relengapi_blueprints": [
|
||||
'docs = relengapi.blueprints.docs:bp',
|
||||
],
|
||||
},
|
||||
)
|
Загрузка…
Ссылка в новой задаче