Commit 8613e5fe authored by Romain Damian's avatar Romain Damian
Browse files

📚 Set up docs, README and badges

📚 Build sphinx docs
📝 Add LICENSE and MANIFEST
📝 Improve README
🎨 Add badges
📚 Add all source files for docs
parent 4fd32832
......@@ -4,3 +4,4 @@ dist
venv
__pycache__
**/__pycache__
docs/build
image: python:3.7
stages:
- test
- build
- sphinx
- deploy
before_script:
- python -V # Print out python version for debugging
unit_tests:
stage: test
script:
- pip install -r requirements.txt
- pip install pytest
- pip install pytest-cov
- pip install codecov
- pytest --cov-report=xml --cov=pyux
- codecov --token=$CODECOV_TOKEN
except:
- master
build:
stage: build
script:
- python setup.py sdist
- pip install dist/*
artifacts:
paths:
- dist/*.tar.gz
only:
- /^release.*$/
- master
documentation:
stage: sphinx
script:
- pip install sphinx
- pip install sphinx_rtd_theme
- cd docs
- make html
only:
- /^release.*$/
- develop
- master
deploy-pypi:
stage: deploy
variables:
TWINE_USERNAME: $PYPI_USER
TWINE_PASSWORD: $PYPI_PWD
script:
- pip install twine
- python setup.py sdist
- twine upload dist/*
only:
- tags
MIT License
Copyright (c) [2019] Romain DAMIAN
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
include requirements.txt
prune tests
Python helpers for eXplain Perfectur and Dobby
==============================================
[![codecov](https://codecov.io/bb/romain_dam/slackbot-tools/branch/master/graph/badge.svg?token=jbhm9OtZi2)](https://codecov.io/bb/romain_dam/slackbot-tools)
# Installation
```bash
pip3 install git+ssh://git@bitbucket.org/Romain_dam/gspreads.git@master#egg=easyspread
```
# Environment variables
The `Gspread` class needs an environment variable containing a path to the json-file
containings credentials for google API. The name is your choice, so that you can
instantiate various classes for different credentials.
Same for slack bots, which need the name of the environment variable containing slack
token to connect to the API.
Python wrappers for google spread and slack
+++++++++++++++++++++++++++++++++++++++++++
Presentation
============
Available modules
-----------------
WIP
Installation
------------
.. code:: bash
pip3 install --upgrade slackspread
Prerequisites for a smooth authentication
=========================================
Authentication to slack API
---------------------------
If using python sdk for slack API is new to you, head over `here <https://github.com/slackapi/python-slackclient>`__
to get a nice introduction. When everyting is in place and you got your slack bot
token from Slack, just store it as an environment variable (``MYBOT_TOKEN`` in
the below exemple) and initiate the slack web client on python by giving the
variable's name as argument.
.. code:: python
from slackbot import SlackBot
mybot = SlackBot(token = "MYBOT_TOKEN")
Authentication to google spreads API
------------------------------------
``Gspread`` revolves on a json credentials file to authenticate on google
spreads API. The ``init`` method of ``Gspread`` needs both the json file and a
set of environment variables.
Details on have to obtain that file can be found `here <https://gspread.readthedocs.io/en/latest/>`__.
This file would generally have the following form ::
{
"type": "service_account",
"project_id": "project id",
"private_key_id": "private key id",
"private_key": "private key",
"client_email": "client email",
"client_id": "client id",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": ""
}
Some of the fields in the ``credentials.json`` must be kept private, so we strongly
advise to replace those fields with empty or non-explicit values, especially if
you push the json credentials file to a git repo.
In any case, when initiating a ``Gspread`` object, several environment variables
will be looked for to replace the sensitive fields from the json with the right
values (stored as environment variables). Here is the list of fields that will
be replaced within the json before trying to authenticate on the spread API ::
PROJECT_ID
PRIVATE_KEY_ID
PRIVATE_KEY
CLIENT_ID
CLIENT_EMAIL
Precisely, ``Gspread()`` takes three arguments :
:name: name of spreadsheet to connect to
:environ_prefix: prefix for above listed environment variables
:credentials: path to json file containing credentials with *false* sensitive
fields
The prefix allows to store environment variables for several spreadsheet API
projects. Say your project's name is something like ``my daily budget``. You
would first store the following environment variables ::
BUDGET_PROJECT_ID
BUDGET_PRIVATE_KEY_ID
BUDGET_PRIVATE_KEY
BUDGET_CLIENT_ID
BUDGET_CLIENT_EMAIL
And store somewhere a ``credentials.json``, let's say at
``~/.gscredits/budget-credentials.json`` (on which you would have
replaced the sensitive fields with non-explicit or wrong values).
All you need to do is call ``Gspread`` with the following syntax :
.. code:: python
from easyspread import Gspread
budget_spread = Gspread(
name = 'my daily budget',
environ_prefix = 'BUDGET',
credentials = "~/.gscredits/budget-credentials.json"
)
Using environment variables makes it possible to have your code working while
being safe on a network server, since the json file is stored without any sensitive
data in it and the sensitive values are protected as environment variables.
image: python:3.6.7
definitions:
steps:
- step: &run-test
name: unit tests
caches:
- pip
script: # running tests
- mkdir -p ~/.ssh
- echo $SSH_KEY > ~/.ssh/id_rsa
- pip install pytest
- pip install pytest-cov
- pip install codecov
- pip install -r requirements.txt
- pytest --cov-report=xml --cov=. tests
- codecov --token=$CODECOV_TOKEN
- step: &build
name: build package
caches:
- pip
script:
- mkdir -p ~/.ssh
- echo $SSH_KEY > ~/.ssh/id_rsa
- pip install -r requirements.txt
- python setup.py sdist bdist_wheel
pipelines:
default:
- step: *run-test
branches:
master:
- step: *run-test
- step: *build
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- Project information -----------------------------------------------------
project = 'slackspread'
copyright = '2019, Romain Damian'
author = 'Romain Damian'
# The full version, including alpha/beta/rc tags
release = '0.1.3'
# -- General configuration ---------------------------------------------------
master_doc = "index"
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
"sphinx_rtd_theme"
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
Contributing
************
All contributions to the package are welcome ! It is likely that the
repository settings on Gitlab are not perfectly tuned for anyone to
contribute, so feel free to contact the package's maintainer if you
encounter any problem.
Since ``slackspread`` is a simple and little package, there are no real rules
when contributing, rather some simple guidelines to keep it clean and
sound.
Coding convention
=================
Code
----
For python's code, we generally follow `PEP8 <https://www.python.org/dev/peps/pep-0008/>`__
convention, for many of our contributors use PyCharm as IDE, which automatically checks
for that convention. As can be seen below, we'd be happy that you add type indications
to a function's signature.
Docstrings
----------
We mostly follow the rules given by ``sphinx`` documentation for docstrings,
about which you can read `here <https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html>`__.
- present tense and imperative mode is preferred for the first sentence, which
should end with a period
- always use triple quotes for docstrings (``"""Your line."""``) it makes it
easier for next contributors to add new lines to the docstring.
- for multi-line docstrings, please do not leave a starting blank line
- specify argument types and return with ``:param x:``, ``:type x:``,
``:return: something`` and ``:rtype: str`` (for instance)
- try as much as possible to provide at least one usable example
- do not start an argument specification with a cap
- if you write more than one description paragraph, please put all but the first
*after* the function's arguments specification, but *before examples*
A typical docstring would thus be :
.. code:: python
def a_wonderful_function(first_arg: int, second_arg: str) -> None:
"""Print first the second, secondly the first."""
print("A string %s with a number %d" % (second_arg, first_arg))
return None
def another_function(one_arg: str, prefix: str = 'a prefix : ') -> str:
"""Add a prefix to a string.
This function is not really useful.
:param one_arg: the string to be prefixed
:type one_arg: str
:param prefix: default ``'a prefix'`` : the prefix to use
:type prefix: str
:return: the input string prefixed with the given prefix
:rtype: str
Here goes the rest of the description, details, etc.
:Example:
>>> another_function('rosso', 'pesto')
"""
return None
Pull requests
=============
A default template is provided for merge requests. It is not compulsory to use it,
it is only meant to ease reviewing your changes and keeping things simple and
straightforward.
Commit conventions
==================
The more your commits will follow these conventions, the easier it will
be to understand what you did and navigate through the repo's history.
- use present tense and imperative mode for the first line of your commit :
instead of "Added new function" or "Adds new function", write "Add new function"
- keep the first line less than 80 characters and without period at the end
- feel free to explain with as many lines as needed after the first line, but
always leave the second one empty
- using emojis to prefix commits is highly appreciated, not only for fun
but also because it adds another layer of easily understood contextualisation
About emojis, feel free to use whichever you want to, here are the ones that
are the most often used in the package :
- |zap| or |racehorse| When your changes improve performance
- |pencil2| When you modify comments, docstrings or non-python files
- |books| When you modify the documentation files (in ``docs/source``)
- |nut_and_bolt| When you change or fix some object mechanism
- |cyclone| When you refactor something (more than a little change)
- |bug| When you resolve a bug starting from ``develop``
- |fire| When you resolve a bug starting from ``master``
- |dash| When you delete or remove something (in the code or a whole file)
- |art| When you improve format and code's appearence (indentation, etc.)
- |arrow_up| or |arrow_down| When you move files upward or downward in the folder's tree
- |arrow_left| and |arrow_right| When you move files from a folder to another in the same level of the folder's tree
- |clock1| (or any clock) When the changes are temporary or need to be refined
- |construction| When the changes are a work in progress and call for subsequent changes
- |white_check_mark| When you add tests or make broken tests work
- |bus| or |aerial_tramway| When some work or improvement has been done (in short, when none of the above apply)
- |sparkles| When a new functionality has been completed
- |package| and |tada| Reserved for releases of merge commits
- |green_heart| when you did something you're very proud of
.. |zap| replace:: ⚡
.. |racehorse| replace:: 🐎
.. |pencil2| replace:: 📝
.. |books| replace:: 📚
.. |nut_and_bolt| replace:: 🔩
.. |cyclone| replace:: 🌀
.. |bug| replace:: 🐛
.. |fire| replace:: 🔥
.. |dash| replace:: 💨
.. |art| replace:: 🎨
.. |arrow_up| replace:: ⬆️
.. |arrow_right| replace:: ➡️
.. |arrow_down| replace:: ⬇️
.. |arrow_left| replace:: ⬅️
.. |clock1| replace:: 🕐
.. |construction| replace:: 🚧
.. |white_check_mark| replace:: ✅
.. |bus| replace:: 🚌
.. |aerial_tramway| replace:: 🚡
.. |sparkles| replace:: ✨
.. |package| replace:: 📦
.. |tada| replace:: 🎉
.. |green_heart| replace:: 💚
Easyspread
==========
.. automodule:: easyspread
:members:
:undoc-members:
:show-inheritance:
.. image:: https://gitlab.com/roamdam/slackspread-tools/badges/master/pipeline.svg
:target: https://gitlab.com/roamdam/slackspread-tools/commits/master
:alt: Pipeline Status
.. image:: https://codecov.io/bb/romain_dam/slackbot-tools/branch/master/graph/badge.svg?token=jbhm9OtZi2
:target: https://codecov.io/bb/romain_dam/slackbot-tools
.. image:: https://readthedocs.org/projects/slack-and-gspread-tools/badge/?version=latest
:target: https://slack-and-gspread-tools.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://badge.fury.io/py/slackspread.svg
:target: https://badge.fury.io/py/slackspread
:alt: PyPi status
----------
.. include:: ../../README.rst
.. toctree::
:maxdepth: 1
:caption: Modules
slackbot
easyspread
.. toctree::
:maxdepth: 1
:caption: Other content
release_notes
contributing
* :ref:`genindex`
Release notes
=============
Version 0.1.3
-------------
WIP
Slackbot
========
.. automodule:: slackbot
:members:
:undoc-members:
:show-inheritance:
{
"type": "service_account",
"project_id": "officemanager-1540564862362",
"private_key_id": "f638b42d9cabeef8853275db2516dd0618a12e3b",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClLNRmozezYcvP\nGCDxcZzoc3YhMVK5tD+6z6AmSzhlw6+leY117LCp01dTRd3agSDLNSwfnsuF0FPe\nq0r18wCBlmQeul5siM40hlT6Jgm0X5bfo8Hwj1CsXGcar0JtWmEy9TroAyQmtV3x\nWAZd6W+y6qRoZHkFlWcBtK1wk+XgN2Oxn+aBoWWTVNtiAx8kmfh0QdhrvaaiMEkS\nSoOxrjLwSnbdN4ey/Y2FZbxbD37d6lP9Kiss4tOwAA1KONrEyk8zTtdoxS3/GLsH\n3BbIg7cma8+7StJLmNItg3ruSFBptqcXWn561icPa1j928+wh17nt6Gqx0clar8R\nS4HO5Fl3AgMBAAECggEAOaR+b18wdhp//MLH5FqoznpU1FqZKxObVf9VPWfsw57Z\n8l6MHoY+VNXbWMU+Gh4MKr5gqpxJHGbKjh+rJk/qck7gm9SgVTIc/DmQ+EdEBb2C\nMoO8j84D8lLA7JATF4R9/UGVkBhgil2q7imw9x8bCw5V19SQY4FzFCZQjMQgafF7\nAMhCDb8nx8AQ7dm6E6AVKFM4bvYGbVLZNgUDKAQpq2f0eppLZK5U1DIfWS6YtmMT\nksyW1ayN/EZcsrG2HWq9/1GYN48n5fpMGZCbU7TjFNjhzaqJWo6G4CM0j0hismz8\nAtLjkU5+taWaRx0dvWA70nALCZKTs3rRZkWqBkbsWQKBgQDQQ/8ily5oGtaTlbQG\nMkT0eKVEyXmUlfP9IWCGHpbMyJR0CIfIoOoAgmfFy3CUGJN7ZFqGmHY4kjx1Kj6y\nZhxWFxmaOSTG22lNK1GfHm+UwnOgRgI3hfPSfC0h3jx2I4K42XPCYq7T5XX7cqy/\nGs5I+UGlPCSbvaiZE36gqGLcKwKBgQDLCH6PiBHWm+By02MORolvkUWY0HSFhjdS\nJMIsnoy3+J04KQTK3lgrtANlnd7PIo8Gd9WF/zm8kEFq3r/ux4FxHKkG3RhG712y\nB5q+W3GlEwJlwvA2J7tkPsBfmBP6qIcRpejm32RiN5l4T1Fw10sK/9hvroqzqk6z\n9DT+1eG15QKBgAjcG6p5C/xZx+8XW0U4Nj7AMyet+oIbrvmBxf1up7OmhMo64qvi\nTJIg+hEsCmoCcaO6LS+0pLLbZb8GQQyN037GFMy+yZW8F8q0oRBH1y9Y5lpXIBkE\nlc7KgZEDR0cvU4xRk98dG5rgFBjSVA79MPFhyS0iVdxaQSXh8m0bPLlpAoGBALJ3\nUgBKhBuXwvBL/YtD13T5RirwOSxRcPlElGXyLBFeeJwv+iV00h4ASugcoAiFASGX\nXlo9oXutdcNB74YtWguaPL1qxPc9Wqet5YikCr4menoGo22G+UJBoomkvRMc5jVO\nF+4wuSVYaA+H8Td2F2GgyJhK3WLWNf4akCbczF09AoGBAK0vNYUEmzUKCAqqRT7e\nMNIM4UBw12dph0OIRiNE75OE1eX0waxA063Qp4h6ng0ruDoOGXWpJNtATRfH1CpY\nnx5hukX+jyIWes+qgqvNnYo4s8dcEZyPDUFUltmtB4pRAsHeThxxdFCL83xBOKzP\nq9gtwNmo+/NUn2pjQPaeZibc\n-----END PRIVATE KEY-----\n",
"client_email": "officemanager@officemanager-1540564862362.iam.gserviceaccount.com",
"client_id": "114552555422680928358",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/officemanager%40officemanager-1540564862362.iam.gserviceaccount.com"
}
......@@ -7,14 +7,14 @@ with open('README.md', 'r') as file:
README = file.read()
setuptools.setup(
name='slackbot-tools',
name='slackspread',
version='0.1.3',
description="Set of tools to build eXplain slack bots",
description="Wrappers around gspread and slack API",
long_description=README,
long_description_content_type="text/markdown",
long_description_content_type="text/x-rst",
packages=setuptools.find_packages(),
install_requires=requirements,
include_package_data=True,
author='Romain Damian',
author_email='rdamian@explain.fr'
author_email='damian.romain@gmail.com'
)
......@@ -8,6 +8,7 @@ import ssl
class SlackBot:
"""Slack web client to build a python slack bot."""
mention_regex = '<@(|[WU].+?)>(.*)'
def __init__(self, token):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment