├── .github └── workflows │ └── python.yml ├── .gitignore ├── MANIFEST.in ├── Makefile ├── README.rst ├── docs ├── Makefile └── source │ ├── _static │ └── .keep │ ├── _templates │ └── .keep │ ├── api.rst │ ├── conf.py │ └── index.rst ├── myservice ├── __init__.py ├── app.py ├── settings.ini ├── tests │ ├── __init__.py │ └── test_home.py └── views │ ├── __init__.py │ └── home.py ├── requirements.txt ├── setup.py └── tox.ini /.github/workflows/python.yml: -------------------------------------------------------------------------------- 1 | name: Python Testing 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | strategy: 10 | matrix: 11 | python-version: [3.7, 3.8, 3.9] 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up Python ${{ matrix.python-version }} 16 | uses: actions/setup-python@v2 17 | with: 18 | python-version: ${{ matrix.python-version }} 19 | - name: Install dependencies 20 | run: | 21 | python -m pip install --upgrade pip 22 | pip install tox tox-gh-actions 23 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 24 | - name: Run tox 25 | run: tox 26 | - name: Coveralls GitHub Action 27 | uses: coverallsapp/github-action@v1.1.2 28 | with: 29 | github-token: ${{ secrets.GITHUB_TOKEN }} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.un~ 2 | __pycache__ 3 | .tox 4 | .coverage 5 | .Python 6 | myservice.egg-info 7 | docs/build/ 8 | src 9 | bin 10 | lib 11 | include 12 | .cache 13 | .vscode 14 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | include README.rst 3 | recursive-include myservice *.ini 4 | recursive-include docs *.rst *.png *.svg *.css *.html conf.py 5 | prune docs/build/* 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | HERE = $(shell pwd) 2 | VENV = . 3 | VIRTUALENV = virtualenv 4 | BIN = $(VENV)/bin 5 | PYTHON = $(BIN)/python 6 | 7 | INSTALL = $(BIN)/pip install --no-deps 8 | 9 | .PHONY: all test docs build_extras 10 | 11 | all: build 12 | 13 | $(PYTHON): 14 | $(VIRTUALENV) $(VTENV_OPTS) $(VENV) 15 | 16 | build: $(PYTHON) 17 | $(PYTHON) setup.py develop 18 | 19 | clean: 20 | rm -rf $(VENV) 21 | 22 | test_dependencies: 23 | $(BIN)/pip install flake8 tox 24 | 25 | test: build test_dependencies 26 | $(BIN)/flake8 myservice 27 | $(BIN)/tox 28 | 29 | run: 30 | QUART_APP=myservice bin/quart run 31 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | microservice-skeleton 2 | ===================== 3 | 4 | **DISCLAIMER** This repository is part of an application made for 5 | the Python Microservices Development. It was made for educational 6 | purpose and not suitable for production. It's still being updated. 7 | If you find any issue or want to talk with the author, feel free to 8 | open an issue in the issue tracker. 9 | 10 | 11 | This project is a template for building microservices with Quart. 12 | 13 | .. image:: https://coveralls.io/repos/github/PythonMicroservices/microservice-skeleton/badge.svg?branch=main 14 | :target: https://coveralls.io/github/PythonMicroservices/microservice-skeleton?branch=main 15 | 16 | .. image:: https://github.com/PythonMicroservices/microservice-skeleton/workflows/Python%20Testing/badge.svg 17 | :target: https://github.com/PythonMicroservices/microservice-skeleton/actions 18 | 19 | .. image:: https://readthedocs.org/projects/microservice/badge/?version=latest 20 | :target: https://microservice.readthedocs.io 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = myservice 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/source/_static/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMicroservices/microservice-skeleton/658431a2ea474296c5cdc6fba6bc4d9d34c4380d/docs/source/_static/.keep -------------------------------------------------------------------------------- /docs/source/_templates/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMicroservices/microservice-skeleton/658431a2ea474296c5cdc6fba6bc4d9d34c4380d/docs/source/_templates/.keep -------------------------------------------------------------------------------- /docs/source/api.rst: -------------------------------------------------------------------------------- 1 | APIS 2 | ==== 3 | 4 | 5 | **myservice** includes one view that's linked to the root path: 6 | 7 | .. autofunction:: myservice.views.home.index 8 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'microservice-skeleton' 21 | copyright = '2021, Simon Fraser' 22 | author = 'Simon Fraser' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '1.0' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = ["sphinx.ext.autodoc"] 34 | 35 | # Add any paths that contain templates here, relative to this directory. 36 | templates_path = ['_templates'] 37 | 38 | # List of patterns, relative to source directory, that match files and 39 | # directories to ignore when looking for source files. 40 | # This pattern also affects html_static_path and html_extra_path. 41 | exclude_patterns = [] 42 | 43 | 44 | # -- Options for HTML output ------------------------------------------------- 45 | 46 | 47 | # The name of the Pygments (syntax highlighting) style to use. 48 | pygments_style = "sphinx" 49 | 50 | # The theme to use for HTML and HTML Help pages. See the documentation for 51 | # a list of builtin themes. 52 | # 53 | html_theme = 'alabaster' 54 | 55 | # Add any paths that contain custom static files (such as style sheets) here, 56 | # relative to this directory. They are copied after the builtin static files, 57 | # so a file named "default.css" will overwrite the builtin "default.css". 58 | html_static_path = ['_static'] 59 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Myservice 2 | ========= 3 | 4 | 5 | **myservice** is a simple JSON Quart application. 6 | 7 | The application is created with :func:`create_app`: 8 | 9 | .. literalinclude:: ../../myservice/app.py 10 | 11 | 12 | The :file:`settings.ini` file which is passed to :func:`create_app` 13 | contains options for running the Quart app, like the DEBUG flag: 14 | 15 | .. literalinclude:: ../../myservice/settings.ini 16 | :language: ini 17 | 18 | 19 | Blueprint are imported from :mod:`myservice.views` and one 20 | Blueprint and view example was provided in :file:`myservice/views/home.py`: 21 | 22 | .. literalinclude:: ../../myservice/views/home.py 23 | :name: home.py 24 | :emphasize-lines: 13 25 | 26 | 27 | Views can return simple mappings (as highlighted in the example above), 28 | in that case they will be converted into a JSON response. 29 | 30 | .. toctree:: 31 | :maxdepth: 2 32 | 33 | api 34 | -------------------------------------------------------------------------------- /myservice/__init__.py: -------------------------------------------------------------------------------- 1 | from myservice.app import app # NOQA 2 | -------------------------------------------------------------------------------- /myservice/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | from myservice.views import blueprints 3 | from quart import Quart 4 | 5 | _HERE = os.path.dirname(__file__) 6 | _SETTINGS = os.path.join(_HERE, "settings.ini") 7 | 8 | 9 | def create_app(name=__name__, blueprints=None, settings=None): 10 | app = Quart(name) 11 | 12 | # load configuration 13 | settings = os.environ.get("QUART_SETTINGS", settings) 14 | if settings is not None: 15 | app.config.from_pyfile(settings) 16 | 17 | # register blueprints 18 | if blueprints is not None: 19 | for bp in blueprints: 20 | app.register_blueprint(bp) 21 | 22 | return app 23 | 24 | 25 | app = create_app(blueprints=blueprints, settings=_SETTINGS) 26 | -------------------------------------------------------------------------------- /myservice/settings.ini: -------------------------------------------------------------------------------- 1 | [quart] 2 | DEBUG = true 3 | -------------------------------------------------------------------------------- /myservice/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMicroservices/microservice-skeleton/658431a2ea474296c5cdc6fba6bc4d9d34c4380d/myservice/tests/__init__.py -------------------------------------------------------------------------------- /myservice/tests/test_home.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class TestSomething(unittest.TestCase): 5 | def test_my_view(self): 6 | pass 7 | -------------------------------------------------------------------------------- /myservice/views/__init__.py: -------------------------------------------------------------------------------- 1 | from myservice.views.home import home 2 | 3 | 4 | blueprints = [home] 5 | -------------------------------------------------------------------------------- /myservice/views/home.py: -------------------------------------------------------------------------------- 1 | from quart import Blueprint 2 | 3 | 4 | home = Blueprint("home", __name__) 5 | 6 | 7 | @home.route("/") 8 | def index(): 9 | """Home view. 10 | 11 | This view will return an empty JSON mapping. 12 | """ 13 | return {} 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | quart 2 | swagger_parser 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from setuptools import setup, find_packages 3 | 4 | 5 | with open("requirements.txt") as f: 6 | deps = [ 7 | dep 8 | for dep in f.read().split("\n") 9 | if dep.strip() != "" and not dep.startswith("-e") 10 | ] 11 | install_requires = deps 12 | 13 | 14 | setup( 15 | name="myservice", 16 | version="0.1", 17 | packages=find_packages(), 18 | zip_safe=False, 19 | include_package_data=True, 20 | install_requires=install_requires, 21 | ) 22 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py37,py38,py39,formatting,docs 3 | 4 | 5 | [gh-actions] 6 | python = 7 | 3.7: py37 8 | 3.8: py38 9 | 3.9: py39,formatting,docs 10 | 11 | [testenv] 12 | deps = pytest 13 | pytest-cov 14 | coveralls 15 | -rrequirements.txt 16 | 17 | commands = 18 | pytest --cov-config .coveragerc --cov myservice myservice/tests 19 | - coveralls 20 | 21 | 22 | [testenv:formatting] 23 | commands = 24 | black --check --diff myservice setup.py 25 | isort --check --diff myservice 26 | deps = 27 | black 28 | isort 29 | 30 | [testenv:docs] 31 | basepython=python 32 | deps = 33 | -rrequirements.txt 34 | sphinx 35 | commands= 36 | sphinx-build -W -b html docs/source docs/build 37 | --------------------------------------------------------------------------------