Skip to content

Commit e817f32

Browse files
SkelmisShineyDevlgaan
authored
Implement Docs - Sphinx (nextcord#12)
* Add Sphinx * Remove the license from the documentation pages * Update license word check * Add basic docs * Add examples.rst * Add .readthedocs.yaml to automate documentation generation * Add a guide for how to setup read the docs * Update the guide * Update the guide further * add deploy workflow * update setup.py whoops * Clean .gitignore * Remove built docs * Clean conf.py * Remove requested files * Update requested files * Resolve sphinx build errors * Blacked code * Update .readthedocs.yaml * Update relevant directives * Add errors.rst * Add documentation to server.py * Appease linter * Fix spelling * Push fixed references They break locally but I think thats my machine. * Change to local ref * update server.py * Update conf.py * Resolve server.rst backticks * Add examples to examples.rst * Update discord/ext/ipc/client.py Co-authored-by: Riley Shaw <[email protected]> * Add `version` to conf.py * Blacked code Co-authored-by: Riley Shaw <[email protected]> Co-authored-by: Logan <[email protected]>
1 parent d0c8e88 commit e817f32

File tree

12 files changed

+429
-26
lines changed

12 files changed

+429
-26
lines changed

.github/workflows/deploy.yml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Deploy
2+
3+
on: [pull_request, push]
4+
5+
jobs:
6+
job:
7+
name: Deploy
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v2
13+
14+
- name: Set up Python 3.7
15+
uses: actions/setup-python@v2
16+
with:
17+
python-version: 3.7
18+
19+
- name: Install dependencies
20+
run: |-
21+
python -m pip install --upgrade pip
22+
python -m pip install --upgrade .[docs]
23+
24+
- name: Build documentation
25+
run: sphinx-build -n -W -b html ./docs ./docs/build

.readthedocs.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: 2
2+
3+
sphinx:
4+
configuration: docs/conf.py
5+
6+
python:
7+
version: 3.7
8+
install:
9+
- method: pip
10+
path: .
11+
extra_requirements:
12+
- docs

discord/ext/ipc/client.py

+22-14
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@
2020

2121

2222
class Client:
23-
"""Handles webserver side requests to the bot process.
24-
25-
:param host: The IP or host of the IPC server, defaults to localhost
26-
:type host: ``str``, optional
27-
:param port: The port of the IPC server. If not supplied the port will be found automatically, defaults to None
28-
:type port: ``int``, optional
29-
:param secret_key: The secret key for your IPC server. Must match the server secret_key or requests will not go ahead, defaults to None
30-
:type secret_key: ``Union[str, bytes]``, optional
23+
"""
24+
Handles webserver side requests to the bot process.
25+
26+
Parameters
27+
----------
28+
host: str
29+
The IP or host of the IPC server, defaults to localhost
30+
port: int
31+
The port of the IPC server. If not supplied the port will be found automatically, defaults to None
32+
secret_key: Union[str, bytes]
33+
The secret key for your IPC server. Must match the server secret_key or requests will not go ahead, defaults to None
3134
"""
3235

3336
def __init__(
@@ -56,8 +59,10 @@ def __init__(
5659
async def init_sock(self):
5760
"""Attempts to connect to the server
5861
59-
:return: The websocket connection to the server
60-
:rtype: ``Websocket``
62+
Returns
63+
-------
64+
:class:`~aiohttp.ClientWebSocketResponse`
65+
The websocket connection to the server
6166
"""
6267
self.session = aiohttp.ClientSession()
6368

@@ -86,10 +91,13 @@ async def init_sock(self):
8691
async def request(self, endpoint: str, **kwargs):
8792
"""Make a request to the IPC server process.
8893
89-
:param endpoint: The endpoint to request on the server
90-
:type endpoint: str
91-
:param **kwargs: The data to send to the endpoint
92-
:type **kwargs: ``Any``, optional"""
94+
Parameters
95+
----------
96+
endpoint: str
97+
The endpoint to request on the server
98+
**kwargs
99+
The data to send to the endpoint
100+
"""
93101
if not self.session:
94102
await self.init_sock()
95103

discord/ext/ipc/server.py

+59-12
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,17 @@
1717
from discord.ext.ipc.errors import *
1818

1919

20-
def route(name=None):
21-
"""Used to register a coroutine as an endpoint"""
20+
def route(name: str = None):
21+
"""
22+
Used to register a coroutine as an endpoint when you don't have
23+
access to an instance of :class:`.Server`
24+
25+
Parameters
26+
----------
27+
name: str
28+
The endpoint name. If not provided the method name will be
29+
used.
30+
"""
2231

2332
def decorator(func):
2433
if not name:
@@ -32,9 +41,7 @@ def decorator(func):
3241

3342

3443
class IpcServerResponse:
35-
"""Format the json data parsed into a nice object"""
36-
37-
def __init__(self, data):
44+
def __init__(self, data: dict):
3845
self._json = data
3946
self.length = len(data)
4047

@@ -44,7 +51,6 @@ def __init__(self, data):
4451
setattr(self, key, value)
4552

4653
def to_json(self):
47-
"""Convert object to json"""
4854
return self._json
4955

5056
def __repr__(self):
@@ -55,6 +61,26 @@ def __str__(self):
5561

5662

5763
class Server:
64+
"""The IPC server. Usually used on the bot process for receiving
65+
requests from the client.
66+
67+
Attributes
68+
----------
69+
bot: :class:`~discord.ext.commands.Bot`
70+
Your bot instance
71+
host: str
72+
The host to run the IPC Server on. Defaults to localhost.
73+
port: int
74+
The port to run the IPC Server on. Defaults to 8765.
75+
secret_key: str
76+
A secret key. Used for authentication and should be the same as
77+
your client's secret key.
78+
do_multicast: bool
79+
Turn multicasting on/off. Defaults to True
80+
multicast_port: int
81+
The port to run the multicasting server on. Defaults to 20000
82+
"""
83+
5884
ROUTES = {}
5985

6086
def __init__(
@@ -82,8 +108,15 @@ def __init__(
82108

83109
self.endpoints = {}
84110

85-
def route(self, name=None):
86-
"""Used to register a coroutine as an endpoint"""
111+
def route(self, name: str = None):
112+
"""Used to register a coroutine as an endpoint when you have
113+
access to an instance of :class:`.Server`.
114+
115+
Parameters
116+
----------
117+
name: str
118+
The endpoint name. If not provided the method name will be used.
119+
"""
87120

88121
def decorator(func):
89122
if not name:
@@ -96,11 +129,19 @@ def decorator(func):
96129
return decorator
97130

98131
def update_endpoints(self):
132+
"""Called internally to update the server's endpoints for cog routes."""
99133
self.endpoints = {**self.endpoints, **self.ROUTES}
100134

101135
self.ROUTES = {}
102136

103-
async def handle_accept(self, request):
137+
async def handle_accept(self, request: aiohttp.web.Request):
138+
"""Handles websocket requests from the client process.
139+
140+
Parameters
141+
----------
142+
request: :class:`~aiohttp.web.Request`
143+
The request made by the client, parsed by aiohttp.
144+
"""
104145
self.update_endpoints()
105146

106147
websocket = aiohttp.web.WebSocketResponse()
@@ -159,8 +200,14 @@ async def handle_accept(self, request):
159200

160201
raise JSONEncodeError(error_response)
161202

162-
async def handle_multicast(self, request):
163-
"""Handle multicast requests"""
203+
async def handle_multicast(self, request: aiohttp.web.Request):
204+
"""Handles multicasting websocket requests from the client.
205+
206+
Parameters
207+
----------
208+
request: :class:`~aiohttp.web.Request`
209+
The request made by the client, parsed by aiohttp.
210+
"""
164211
websocket = aiohttp.web.WebSocketResponse()
165212
await websocket.prepare(request)
166213

@@ -189,7 +236,7 @@ async def __start(self, application, port):
189236
await site.start()
190237

191238
def start(self):
192-
"""Start the IPC server"""
239+
"""Starts the IPC server."""
193240
self.bot.dispatch("ipc_ready")
194241

195242
self._server = aiohttp.web.Application(loop=self.loop)

docs/Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = .
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/conf.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import re
2+
3+
project = "discord-ext-ipc"
4+
copyright = "2021, Ext-Creators"
5+
author = "Ext-Creators"
6+
7+
with open("../discord/ext/ipc/__init__.py") as stream:
8+
release = version = re.search(
9+
r"^__version__\s*=\s*[\'\"]([^\'\"]*)[\'\"]", stream.read(), re.MULTILINE
10+
).group(1)
11+
12+
13+
extensions = [
14+
"sphinx.ext.autodoc",
15+
"sphinx.ext.napoleon",
16+
"sphinx.ext.intersphinx",
17+
"sphinx_rtd_theme",
18+
"sphinxcontrib_trio",
19+
]
20+
21+
22+
html_theme = "sphinx_rtd_theme"
23+
24+
autodoc_typehints = "none"
25+
intersphinx_mapping = {
26+
"aiohttp": ("https://docs.aiohttp.org/en/stable/", None),
27+
"python": ("https://docs.python.org/3", None),
28+
"discord": ("https://discordpy.readthedocs.io/en/latest", None),
29+
}
30+
31+
highlight_language = "python3"
32+
master_doc = "index"
33+
pygments_style = "friendly"
34+
source_suffix = ".rst"

docs/index.rst

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Welcome to discord-ext-ipc's documentation!
2+
===========================================
3+
4+
.. toctree::
5+
:numbered:
6+
:maxdepth: 2
7+
:caption: Contents:
8+
9+
modules/server.rst
10+
modules/client.rst
11+
modules/errors.rst
12+
modules/examples.rst
13+
14+
15+
16+
Indices and tables
17+
==================
18+
19+
* :ref:`genindex`
20+
* :ref:`modindex`
21+
* :ref:`search`

docs/modules/client.rst

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Client Connection
2+
=================
3+
4+
The IPC client is very simple.
5+
It will simply connect to your server process and send JSON data.
6+
If you do not supply a port on initialisation, the client will connect to the multicast server
7+
(see the server section) and return the port from said server.
8+
If you do supply a port, it will connect to the server instantly.
9+
10+
Requests are made by calling ``ipc.client.request(endpoint, **kwargs)``
11+
and will be sent to the server in the json format specified above.
12+
It will then wait for a response and return the data.
13+
14+
.. currentmodule:: discord.ext.ipc.client
15+
16+
.. autoclass:: Client
17+
:members:

docs/modules/errors.rst

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
IPC Errors
2+
==========
3+
4+
.. currentmodule:: discord.ext.ipc.errors
5+
6+
.. autoclass:: IPCError
7+
8+
.. autoclass:: NoEndpointFoundError
9+
10+
.. autoclass:: ServerConnectionRefusedError
11+
12+
.. autoclass:: JSONEncodeError
13+
14+
.. autoclass:: NotConnected

0 commit comments

Comments
 (0)