Repository: opsdroid/opsdroid

Issue:
Add Google Style Docstrings
We should implement Google Style Docstrings to every function, method, class in opsdroid. This style will support existing documentation and will help in the future by generating documentation automatically.

This consists in a bit of effort so this issue can be worked by more than one contributor, just make sure that everyone knows what you are working on in order to avoid other contributors spending time on something that you are working on.

If you are unfamiliar with the Google Style Docstrings I'd recommend that you check these resources:

 - [Sphix 1.8.0+ - Google Style Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html)



Docstrings that need to be updated:

- main.py
  - [x] configure_lang
  - [ ] configure_log
  - [ ] get_logging_level
  - [ ] check_dependencies
  - [ ] print_version
  - [ ] print_example_config
  - [ ] edit_files
  - [x] welcome_message
- ~~helper.py~~
  - [x] get_opsdroid
  - [x] del_rw
  - [x] move_config_to_appdir
- memory.py
  - [x] Memory
  - [x] get
  - [x] put
  - [x] _get_from_database
  - [x] _put_to_database
- message.py
  - [x] Message
  - [x]  __init__
  - [x]  _thinking_delay
  - [x]  _typing delay
  - [x]  respond
  - [x]  react
- web.py
  - [ ] Web
  - [x] get_port
  - [x] get_host
  - [x]  get_ssl_context
  - [ ]  start
  - [ ]  build_response
  - [ ]  web_index_handler
  - [ ]  web_stats_handler
- matchers.py
  - [ ] match_regex
  - [ ] match_apiai_action
  - [ ] match_apiai_intent
  - [ ]  match_dialogflow_action
  - [ ]  match_dialogflow_intent
  - [ ] match_luisai_intent
  - [ ] match_rasanlu
  - [ ] match_recastai
  - [ ] match_witai
  - [ ] match_crontab
  - [ ] match_webhook
  - [ ] match_always
- core.py
  - [ ] OpsDroid
  - [ ] default_connector
  - [ ] exit
  - [ ] critical
  - [ ]  call_stop
  - [ ] disconnect
  - [ ] stop
  - [ ] load
  - [ ] start_loop
  - [x] setup_skills
  - [ ] train_parsers
  - [ ] start_connector_tasks
  - [ ] start_database
  - [ ] run_skill
  - [ ] get_ranked_skills
  - [ ] parse
- loader.py
  - [ ] Loader
  - [x] import_module_from_spec
  - [x] import_module
  - [x] check_cache
  - [x] build_module_import_path
  - [x] build_module_install_path
  - [x] git_clone
  - [x] git_pull
  - [x] pip_install_deps
  - [x] create_default_config
  - [x] load_config_file
  - [ ] envvar_constructor
  - [ ] include_constructor
  - [x] setup_modules_directory
  - [x] load_modules_from_config
  - [x] _load_modules
  - [x] _install_module
  - [x] _update_module
  - [ ] _install_git_module
  - [x] _install_local_module









---- ORIGINAL POST ---- 
I've been wondering about this for a while now and I would like to know if we should replace/update all the docstrings in opsdroid with the Google Style doc strings. 

I think this could help new and old contributors to contribute and commit to opsdroid since the Google Style docstrings give more information about every method/function and specifies clearly what sort of input the function/method expects, what will it return and what will be raised (if applicable).

The downsize of this style is that the length of every .py file will increase due to the doc strings, but since most IDE's allow you to hide those fields it shouldn't be too bad.

Here is a good example of Google Style Doc strings:  [Sphix 1.8.0+ - Google Style Docstrings](http://www.sphinx-doc.org/en/master/ext/example_google.html)

I would like to know what you all think about this idea and if its worth spending time on it.


Discussion:
Yes we should definitely do this!

It can also be really useful for automatically generating reference documentation. 
Awesome I'll wait a few days to see if anyone is opposed to this idea or if they would like to give some advice/comment on the issue. 

If in a few days no one says anything I'll edit this issue just to explain more in depth what we expect of the comments and how to do it - I'd recommend dividing opsdroid per each .py file so different people can contribute to the issue 😄 
I like the idea. Is it possible to add a test that inspects the doc strings,  and fails if they don't match the format? If so, would Jacob be happy with test coverage "reducing" in the short term as this test was added,  but before all the doc strings complied?



On 29 April 2018 2:42:05 am AEST, "Fábio Rosado" <notifications@github.com> wrote:
>Awesome I'll wait a few days to see if anyone is opposed to this idea
>or if they would like to give some advice/comment on the issue. 
>
>If in a few days no one says anything I'll edit this issue just to
>explain more in depth what we expect of the comments and how to do it -
>I'd recommend dividing opsdroid per each .py file so different people
>can contribute to the issue 😄 
>
>-- 
>You are receiving this because you are subscribed to this thread.
>Reply to this email directly or view it on GitHub:
>https://github.com/opsdroid/opsdroid/issues/532#issuecomment-385189370

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Yes I'm happy with that approach. 

I've been thinking about it and I think there are two reasons why anyone would want to do this. The first is for autogenerating documentation, the second is making it easier for people to contribute. 

As you said you are intending this to help people contribute, and I definitely agree. I just want to be clear on why we are doing this beyond it just being a thing that some projects do. 

We currently run `pydocstyle` as part of the lint suite. I wonder if there is a way of telling it to enforce this docstring style?
I'm not sure if it's possible to enforce google doc style in the lint, but I know that you can run tests on the docstrings like @go8ose  suggested, Sphinx has a command for this (it uses the doctest module), but this tests might provide some issues and headaches.

The doctests will use the string representation present in the docstring to run the tests, if the result is not consistent like... a function that deals with dates for example and uses date.now() this test will always fail.
Another example would be running doctests with dictionaries, these tests will mostly fail due to the unsorted nature of dicts, the only way to make them pass would be to sort the dict all the time.  

One way to work around it would be to just test some docstrings and not others. In Sphinx you can just add the command: 

```
..doctest::
  >>> foo()
  bar
```

Finally, I believe that all the tests that we have at the moment do a very good job at testing every single piece of code in opsdroid so perhaps adding the doctests would be extra effort for no real gain - these will test what it's being tested already.

--EDIT--

I've updated my first post with all the functions,classes and methods that need to be updated, let me know if you need some added in or removed 👍 
Hi Fabio,

I'm not suggesting we add more tests in the form of doctests. That would indeed be a waste of effort. I'm suggesting we check conformance with the google style doc strings.

Jacob suggested seeing if this can be checked in the linting run. That is a good idea,  linting is what I should have suggested initially.

Cheers, 
Geoff

On 30 April 2018 5:51:38 pm AEST, "Fábio Rosado" <notifications@github.com> wrote:
>I'm not sure if it's possible to enforce google doc style in the lint,
>but I know that you can run tests on the docstrings like @go8ose 
>suggested, Sphinx has a command for this (it uses the doctest module),
>but this tests might provide some issues and headaches.
>
>The doctests will use the string representation present in the
>docstring to run the tests, if the result is not consistent like... a
>function that deals with dates for example and uses date.now() this
>test will always fail.
>Another example would be running doctests with dictionaries, these
>tests will mostly fail due to the unsorted nature of dicts, the only
>way to make them pass would be to sort the dict all the time.  
>
>One way to work around it would be to just test some docstrings and not
>others. In Sphinx you can just add the command: 
>
>``` ..doctest::
>>>> foo()
>bar
>```
>
>Finally, I believe that all the tests that we have at the moment do a
>very good job at testing every single piece of code in opsdroid so
>perhaps adding the doctests would be extra effort for no real gain -
>these will test what it's being tested already.
>
>-- 
>You are receiving this because you were mentioned.
>Reply to this email directly or view it on GitHub:
>https://github.com/opsdroid/opsdroid/issues/532#issuecomment-385332374

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
This tool looks like it tests the docstrings against the google convention. We should explore it more.

https://github.com/terrencepreilly/darglint
Hi Fabio,
I like your idea, i new here on this project i can try to do something and make a pull request.
For my part i'm going to begin with **helper.py** it's Thk ok for you ?
Thk best regards
Heya @sims34 yeah that would be much appreciated, let me know in gitter if you need any help with this 👍 
Hi Fabio, 
I am new here on this project. I was hoping I could help out with main.py
Regards
Hey @purvaudai, please go ahead!
Hello @purvaudai did you manage to work on `main.py`? If you are stuck with something let us know, we would be happy to help you getting started 👍 
Hi Guys is anyone working on this issue
@mraza007 not currently. Please go ahead.
Sure I will start working on this issue. Is there a way that you can assign this issue to me and on what files do I have to add google style doc string functions

Sorry for the lack of replies from my side. I tried solving this issue but
got confused, so I decided to look through the docs again, and I got
carried away learning. I am sorry for the lack of professionalism from my
side.

On Mon, 25 Jun 2018 at 19:33, Muhammad <notifications@github.com> wrote:

> Sure I will start working on this issue. Is there a way that you can
> assign this issue to me and on what files do I have to add google style doc
> string functions
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/opsdroid/opsdroid/issues/532#issuecomment-399963131>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AeXNt1F1hUU9JhsW2bl75KQG7SRQEceRks5uAO2_gaJpZM4TqkMs>
> .
>


-- 
Purva Udai Singh

@purvaudai Hey are working on this issue do you want to continue
Hi guys I'd love to contribute too.  
@mraza007 @purvaudai  I know you guys are working on this, but if you need my help with any of the file, I'll be more than happy to contribute.
@mraza007 @purvaudai @NikhilRaverkar Thanks for all wanting to contribute! There is a lot to be done on this issue so I strongly recommend picking a file and starting work on it. 

Don't worry too much about duplicates, it's unlikely to happen given the number of methods that need updating. I would also be happy for you to submit lots of small PRs. Just pick a few methods, update the docstrings and raise a PR.
Yup I think that would be a great idea
@purvaudai  Don't worry my friend sometimes these things happen, if you want to contribute to opsdroid in the future we will be glad to help you 👍 

@mraza007  @NikhilRaverkar  If you guys need any help, let us know. You can work on different files if you want and if something is not clear feel free to hit us up either in here or our [gitter channel](https://gitter.im/opsdroid/developers)
Sure I just joined the channel I will start working on this over the weekend
I’ll start working on this over the weekend.

Thanks a lot,
Nikhil 

> On Jun 28, 2018, at 10:44 AM, Muhammad <notifications@github.com> wrote:
> 
> Sure I just joined the channel I will start working on this over the week
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or mute the thread.

I would like to contribute to this. For starters I was thinking about taking the web.py file. :smile:
Hello, please go ahead and let us know if you need any help 
@FabioRosado Can I grab message.py? This would be my first issue!
@archime please go ahead! Let me know if you need any help with this issue. Also, welcome to the project 👍
Hey, I'd like to add couple of docstrings, however I've got a question first.
The Google style guide in the description seems to be deprecated.
Should I reference this one https://github.com/google/styleguide/blob/gh-pages/pyguide.md instead?
Hello @kritokrator Thanks for showing interest in this matter. 
The sphinx documentation has an up to date style. We are not using typehints in our codebase yet so we will be specifying the type as:


```
Args:
   arg1 (String): This arg does things
   arg2 (Boolean, optional): This arg can be true, its optional
```

This is a very brief explanation but should get you started, I also recommend you check the [Facebook Connector](https://github.com/opsdroid/opsdroid/blob/master/opsdroid/connector/facebook/__init__.py) as an example of how we would like the doc strings 👍 
Hey @FabioRosado, I would like to add docstrings to web.py.  The link above no longer works so is this the format you are looking for?

https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html

Looking forward to this as this is my first issue!
Hello @GrugLife you are right that is the style we intent to implement in opsdroid. We would be glad to have you contribute to the project let me know if you need any help 😀👍
Hi @FabioRosado,  I  would like to help on this and would like to start on main.py - this is my first time using github so I'm not entirely sure how to proceed - but I'm sure I'll figure it out. Looking forward to working with you. 
Hello @empathic-geek thank you so much for reaching out and working on this issue 😄 Please do let me know if you encounter any issue setting up your development environment or if you have any questions at all! 

You can reach me on the [opsdroid chat](https://gitter.im/opsdroid/developers) or any other social networks 😄 👍 
I've create pull request for some docstring update :)
Hi @FabioRosado, I would like to start on loader.py.
Hello @WillHensel that would be awesome, feel free to start a PR and let us know if you need any help 👍 
Hi @FabioRosado, I would like to take a crack at matchers.py.  This will be my first time contributing to a project so I'll ask for your patience :smiley: 
Hello Xavier welcome! It would be great if you could work on that and it will help us a lot moving forward to a more consistent code base! 

If you do need any help please let us know 😄
Hey @FabioRosado, taking up core.py. Raising multiple small PRs as suggested by @jacobtomlinson.  


> Don't worry too much about duplicates, it's unlikely to happen given the number of methods that need updating. I would also be happy for you to submit lots of small PRs. Just pick a few methods, update the docstrings and raise a PR.


Hello @killerontherun1 that would be awesome, please let me know if you need any help with anything 👍 
Hey Fabio, do you have a doctest written? So that one can check whether the
docstrings are fine or not?

On Sun, 30 Jun, 2019, 3:51 PM Fábio Rosado, <notifications@github.com>
wrote:

> Hello @killerontherun1 <https://github.com/killerontherun1> that would be
> awesome, please let me know if you need any help with anything 👍
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/opsdroid/opsdroid/issues/532?email_source=notifications&email_token=AF2JNPBQZIS5V5VSUCD3VQTP5CCIXA5CNFSM4E5KIMWKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY4JK2A#issuecomment-507024744>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AF2JNPABO7T6TRR6PFHRN7LP5CCIXANCNFSM4E5KIMWA>
> .
>

Yeah you can have a look at this link: [Example of Google style docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html), you can also have a look at the following methods that have been updated with the docstrings:
- Core: 
  - setup_skills
  - send
- Memory.py

And there are a few other places, these should provide you some help. Let me know if you need further help

Sorry, I'm a bit of a noob. But do you want me to rewrite the docstrings itself? Or just adjust the follow the syntax in the given link?
Hi I'd like to help out with this as well! I can try to check out the `matchers.py `file if no one else is working on that.
Hello @profwacko that would be great let me know if you need any help 👍 
Hi!
I am a beginner of this project, but I will participate because I can contribute easily.

It may be a really small PR...

Sounds great @pluse09! We look forward to reviewing it. 
The URL to Sphinx example in the first comment is broken, it has an extra "l" in ".html"
I'd commented on other issues that I'd tackle on them but people already started to do some part of it, so I'll let for them. So, I'll try to document some of the missing files in the list above, respecting what @pluse09 already started doing at #1087.
I'd like to try my hand at adding docstrings to the `core.py` file and its pending methods, if it's not assigned to anyone else already! 
Please go ahead
Hi, may I look into `loaders.py`, there are couple of methods that need Google style docstrings
Hello @suparnasnair thank you for the message, that would be great. Please let me know if you need any help with anything 😄👍
I have updated for 2 methods for a start. Sorry I'm a newbie. Please let me know if this is fine, I can go ahead with the remaining ones and clean them up. Thanks !
@FabioRosado there are couple of methods left in loader.py(envvar_constructor, include_constructor), can I take them up if no one else is working on them?
@suparnasnair your PR was great. Welcome to open source! Please feel free to do more.

@p0larstern please go ahead.

@FabioRosado did you mean to close this?
Ooops I didn't notice that the PR that I've merged would close the issue. I've reopened it haha
Hi, I'm new to open source. Can I help out with adding docstrings in `main.py` if noone else is working on it?
@lkcbharath please go ahead
Hi @FabioRosado would there be a quick way for me to understand the functionality of each of the functions I'm writing docstrings for (in `matchers.py`)? Or maybe sort of bump me into the best direction for that.
I'd say reading the matchers documentation might give you a better understanding of what each of them do. But basically matchers are decorators that you use to match a skill(python function) to an intent obtained from a parser.

For example on the dialogflow  - the parser will call the API and send over the message from the user, then the API does its thing and returns a response which might contain an intent and other entities.

In dialogflow there is an intent called - `smalltalk.greetings` so you use the `@match_dialogflow_intent('smalltalk.greetings')` to trigger a skill. The matchers basically make that bridge between parsing a message and getting a result and then match a skill with said intent.

You can check the example on the [dialogflow documentation](https://docs.opsdroid.dev/en/stable/matchers/dialogflow/) for more information.

I hope this made sense?
Hi @FabioRosado!
I'm looking to help out on this as well. Looks like the checklist may be out of date now? - I see there was a merge for the CORE section but still some outstanding checkboxes. Can you confirm if the checklist is up to date? I'd love to try and tackle any stragglers. 
Hello paqman unfortunately the checklist has been out of date for a while and I haven't have the time to fix it yet. It would be great if you could tackle some of them, Im off in 5 days so I'll try to update the list, you can wait until then or check each file and see if any is left without the google style docstrings - I know there is still a lot of them that don't have it
Hi @FabioRosado, thanks for the tips. It's definitely more clear now. The checklist for `matchers.py` seems to be lacking a few more functions, namely:

- [ ] match_event
- [ ] match_parse
- [ ] match_sapcai
- [ ] match_watson

Also the following functions don't seem to be there anymore, i'm guessing they are now the dialogflow api ones?
- [ ] ~match_apiai_action~
- [ ] ~match_apiai_intent~

I'll fix up the docstrings for these as a starting point:
- [ ] match_event
- [ ] match_regex
- [ ] match_parse
Yeah you were right the api ai matcher has now become dialogflow - i think I added the google style on them when i updated the version not sure though.

Those new ones aren't there because they were added after I created this issue, which reminds me that I forgot to update the list 👍 
@FabioRosado I hope my pull request is okay for the first few changes I did, please let me know if there's anything I can do to make the pull request better! I am also doing this for hacktoberfest 😄 
I'll claim a few more docstrings for matchers.py, i'll be doing the `diaglogflow`, `crontab`, `webhook` and `always` docstrings.

Here's the updated checklist for that:
- [x]  match_regex
- [ ] ~match_apiai_action~
- [ ] ~match_apiai_intent~
- [ ]  match_dialogflow_action
- [ ]  match_dialogflow_intent
- [ ]  match_luisai_intent
- [ ]  match_rasanlu
- [ ]  match_recastai
- [ ]  match_witai
- [ ]  match_crontab
- [ ]  match_webhook
- [ ]  match_always
- [x]  match_event
- [x]  match_parse
- [ ]  match_sapcai
- [ ]  match_watson

Resolving patch:
diff --git a/opsdroid/matchers.py b/opsdroid/matchers.py
--- a/opsdroid/matchers.py
+++ b/opsdroid/matchers.py
@@ -151,7 +151,17 @@ def matcher(func):
 
 
 def match_luisai_intent(intent):
-    """Return luisai intent match decorator."""
+    """Return luis.ai intent match decorator.
+
+    Decorator that calls a function on specific luis.ai intents.
+
+    Args:
+        intent (str): luis.ai intent name
+
+    Returns:
+        Decorated Function
+
+    """
 
     def matcher(func):
         """Add decorated function to skills list for luisai matching."""
@@ -163,7 +173,17 @@ def matcher(func):
 
 
 def match_rasanlu(intent):
-    """Return Rasa NLU intent match decorator."""
+    """Return Rasa NLU intent match decorator.
+
+    Decorator that calls a function on specific Rasa NLU intents.
+
+    Args:
+        intent (str): Rasa NLU intent name
+
+    Returns:
+        Decorated Function
+
+    """
 
     def matcher(func):
         """Add decorated function to skills list for Rasa NLU matching."""
@@ -175,7 +195,17 @@ def matcher(func):
 
 
 def match_recastai(intent):
-    """Return recastai intent match decorator."""
+    """Return Recast.ai intent match decorator.
+
+    Decorator that calls a function on specific Recast.ai intents.
+
+    Args:
+        intent (str): Recast.ai intent name
+
+    Returns:
+        Decorated Function
+
+    """
 
     def matcher(func):
         """Add decorated function to skills list for recastai matching."""
@@ -194,7 +224,17 @@ def matcher(func):
 
 
 def match_sapcai(intent):
-    """Return SAP Conversational AI intent match decorator."""
+    """Return SAP Conversational AI intent match decorator.
+
+    Decorator that calls a function on specific SAP Conversational AI intents.
+
+    Args:
+        intent (str): SAP Conversational AI intent name
+
+    Returns:
+        Decorated Function
+
+    """
 
     def matcher(func):
         """Add decorated function to skills list for SAPCAI matching."""
@@ -206,7 +246,17 @@ def matcher(func):
 
 
 def match_watson(intent):
-    """Return watson intent match decorator."""
+    """Return IBM Watson intent match decorator.
+
+    Decorator that calls a function on specific IBM Watson intents.
+
+    Args:
+        intent (str): IBM Watson intent name
+
+    Returns:
+        Decorated Function
+
+    """
 
     def matcher(func):
         """Add decorated function to skills list for watson matching."""
@@ -218,7 +268,17 @@ def matcher(func):
 
 
 def match_witai(intent):
-    """Return witai intent match decorator."""
+    """Return wit.ai intent match decorator.
+
+    Decorator that calls a function on specific wit.ai intents.
+
+    Args:
+        intent (str): wit.ai intent name
+
+    Returns:
+        Decorated Function
+
+    """
 
     def matcher(func):
         """Add decorated function to skills list for witai matching."""


Test patch: