Skip to content

Commit 21b40ff

Browse files
author
Zach Moody
authored
Merge pull request #254 from digitalocean/black
Use Black and Pytest in GH Actions
2 parents 1d53796 + dcd988d commit 21b40ff

23 files changed

+503
-672
lines changed

.github/workflows/py2pr.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: PR Test
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: ubuntu-latest
9+
strategy:
10+
matrix:
11+
python: [2.7]
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
16+
- name: Setup Python
17+
uses: actions/setup-python@v2
18+
with:
19+
python-version: ${{ matrix.python }}
20+
21+
- name: Install pynetbox and testing packages.
22+
run: pip install . mock
23+
24+
- name: Run Tests
25+
run: python -m unittest discover
26+

.github/workflows/pr.yml renamed to .github/workflows/py3pr.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ubuntu-latest
99
strategy:
1010
matrix:
11-
python: [2.7, 3.6]
11+
python: [3.6, 3.8]
1212

1313
steps:
1414
- uses: actions/checkout@v2
@@ -19,13 +19,11 @@ jobs:
1919
python-version: ${{ matrix.python }}
2020

2121
- name: Install pynetbox and testing packages.
22-
run: pip install . pycodestyle mock
22+
run: pip install . black pytest
2323

2424
- name: Run Linter
25-
run: |
26-
pycodestyle pynetbox
27-
pycodestyle --ignore=E501 tests
25+
run: black --check .
2826

2927
- name: Run Tests
30-
run: python -m unittest discover
28+
run: pytest
3129

docs/conf.py

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
import os
2020
import sys
2121
from pkg_resources import get_distribution
22-
sys.path.insert(0, os.path.abspath('../'))
22+
23+
sys.path.insert(0, os.path.abspath("../"))
2324

2425

2526
# -- General configuration ------------------------------------------------
@@ -31,33 +32,33 @@
3132
# Add any Sphinx extension module names here, as strings. They can be
3233
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
3334
# ones.
34-
extensions = ['sphinx.ext.autodoc']
35+
extensions = ["sphinx.ext.autodoc"]
3536

3637
# Add any paths that contain templates here, relative to this directory.
37-
templates_path = ['_templates']
38+
templates_path = ["_templates"]
3839

3940
# The suffix(es) of source filenames.
4041
# You can specify multiple suffix as a list of string:
4142
#
4243
# source_suffix = ['.rst', '.md']
43-
source_suffix = '.rst'
44+
source_suffix = ".rst"
4445

4546
# The master toctree document.
46-
master_doc = 'index'
47+
master_doc = "index"
4748

4849
# General information about the project.
49-
project = u'pynetbox'
50-
copyright = u'2017, DigitalOcean'
51-
author = u'Zach Moody'
50+
project = u"pynetbox"
51+
copyright = u"2017, DigitalOcean"
52+
author = u"Zach Moody"
5253

5354
# The version info for the project you're documenting, acts as replacement for
5455
# |version| and |release|, also used in various other places throughout the
5556
# built documents.
5657
# The full version, including alpha/beta/rc tags.
57-
release = get_distribution('pynetbox').version
58+
release = get_distribution("pynetbox").version
5859
#
5960
# The short X.Y version.
60-
version = '.'.join(release.split('.')[:2])
61+
version = ".".join(release.split(".")[:2])
6162

6263
# The language for content autogenerated by Sphinx. Refer to documentation
6364
# for a list of supported languages.
@@ -69,10 +70,10 @@
6970
# List of patterns, relative to source directory, that match files and
7071
# directories to ignore when looking for source files.
7172
# This patterns also effect to html_static_path and html_extra_path
72-
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
73+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
7374

7475
# The name of the Pygments (syntax highlighting) style to use.
75-
pygments_style = 'sphinx'
76+
pygments_style = "sphinx"
7677

7778
# If true, `todo` and `todoList` produce output, else they produce nothing.
7879
todo_include_todos = False
@@ -96,18 +97,14 @@
9697
# so a file named "default.css" will overwrite the builtin "default.css".
9798
# html_static_path = ['_static']
9899

99-
html_sidebars = {'**': [
100-
'globaltoc.html',
101-
'relations.html',
102-
'sourcelink.html',
103-
'searchbox.html'
104-
]
100+
html_sidebars = {
101+
"**": ["globaltoc.html", "relations.html", "sourcelink.html", "searchbox.html"]
105102
}
106103

107104
# -- Options for HTMLHelp output ------------------------------------------
108105

109106
# Output file base name for HTML help builder.
110-
htmlhelp_basename = 'pynetboxdoc'
107+
htmlhelp_basename = "pynetboxdoc"
111108

112109

113110
# -- Options for LaTeX output ---------------------------------------------
@@ -116,15 +113,12 @@
116113
# The paper size ('letterpaper' or 'a4paper').
117114
#
118115
# 'papersize': 'letterpaper',
119-
120116
# The font size ('10pt', '11pt' or '12pt').
121117
#
122118
# 'pointsize': '10pt',
123-
124119
# Additional stuff for the LaTeX preamble.
125120
#
126121
# 'preamble': '',
127-
128122
# Latex figure (float) alignment
129123
#
130124
# 'figure_align': 'htbp',
@@ -134,19 +128,15 @@
134128
# (source start file, target name, title,
135129
# author, documentclass [howto, manual, or own class]).
136130
latex_documents = [
137-
(master_doc, 'pynetbox.tex', u'pynetbox Documentation',
138-
u'Zach Moody', 'manual'),
131+
(master_doc, "pynetbox.tex", u"pynetbox Documentation", u"Zach Moody", "manual"),
139132
]
140133

141134

142135
# -- Options for manual page output ---------------------------------------
143136

144137
# One entry per manual page. List of tuples
145138
# (source start file, name, description, authors, manual section).
146-
man_pages = [
147-
(master_doc, 'pynetbox', u'pynetbox Documentation',
148-
[author], 1)
149-
]
139+
man_pages = [(master_doc, "pynetbox", u"pynetbox Documentation", [author], 1)]
150140

151141

152142
# -- Options for Texinfo output -------------------------------------------
@@ -155,7 +145,13 @@
155145
# (source start file, target name, title, author,
156146
# dir menu entry, description, category)
157147
texinfo_documents = [
158-
(master_doc, 'pynetbox', u'pynetbox Documentation',
159-
author, 'pynetbox', 'A python library for NetBox.',
160-
'Miscellaneous'),
148+
(
149+
master_doc,
150+
"pynetbox",
151+
u"pynetbox Documentation",
152+
author,
153+
"pynetbox",
154+
"A python library for NetBox.",
155+
"Miscellaneous",
156+
),
161157
]

pynetbox/api.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,7 @@ class Api(object):
6262
"""
6363

6464
def __init__(
65-
self,
66-
url,
67-
token=None,
68-
private_key=None,
69-
private_key_file=None,
70-
threading=False,
65+
self, url, token=None, private_key=None, private_key_file=None, threading=False,
7166
):
7267
if private_key and private_key_file:
7368
raise ValueError(
@@ -81,8 +76,10 @@ def __init__(
8176
self.session_key = None
8277
self.http_session = requests.Session()
8378
if threading and sys.version_info.major == 2:
84-
raise NotImplementedError("Threaded pynetbox calls not supported \
85-
in Python 2")
79+
raise NotImplementedError(
80+
"Threaded pynetbox calls not supported \
81+
in Python 2"
82+
)
8683
self.threading = threading
8784

8885
if self.private_key_file:
@@ -119,8 +116,7 @@ def version(self):
119116
>>>
120117
"""
121118
version = Request(
122-
base=self.base_url,
123-
http_session=self.http_session,
119+
base=self.base_url, http_session=self.http_session,
124120
).get_version()
125121
return version
126122

@@ -143,6 +139,5 @@ def openapi(self):
143139
>>>
144140
"""
145141
return Request(
146-
base=self.base_url,
147-
http_session=self.http_session,
142+
base=self.base_url, http_session=self.http_session,
148143
).get_openapi()

pynetbox/core/app.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class App(object):
2727
:raises: :py:class:`.RequestError`
2828
if requested endpoint doesn't exist.
2929
"""
30+
3031
def __init__(self, api, name):
3132
self.api = api
3233
self.name = name
@@ -38,18 +39,14 @@ def __init__(self, api, name):
3839
"ipam": ipam,
3940
"circuits": circuits,
4041
"virtualization": virtualization,
41-
"extras": extras
42+
"extras": extras,
4243
}
4344

4445
def _setmodel(self):
4546
self.model = App.models[self.name] if self.name in App.models else None
4647

4748
def __getstate__(self):
48-
return {
49-
'api': self.api,
50-
'name': self.name,
51-
'_choices': self._choices
52-
}
49+
return {"api": self.api, "name": self.name, "_choices": self._choices}
5350

5451
def __setstate__(self, d):
5552
self.__dict__.update(d)
@@ -68,7 +65,7 @@ def _set_session_key(self):
6865
base=self.api.base_url,
6966
token=self.api.token,
7067
private_key=self.api.private_key,
71-
http_session=self.api.http_session
68+
http_session=self.api.http_session,
7269
).get_session_key()
7370

7471
def choices(self):
@@ -106,10 +103,7 @@ def custom_choices(self):
106103
'Testfield2': {'Othervalue2': 4, 'Othervalue1': 3}}
107104
"""
108105
custom_field_choices = Request(
109-
base="{}/{}/_custom_field_choices/".format(
110-
self.api.base_url,
111-
self.name,
112-
),
106+
base="{}/{}/_custom_field_choices/".format(self.api.base_url, self.name,),
113107
token=self.api.token,
114108
private_key=self.api.private_key,
115109
http_session=self.api.http_session,

pynetbox/core/endpoint.py

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121

2222
def response_loader(req, return_obj, endpoint):
2323
if isinstance(req, list):
24-
return [
25-
return_obj(i, endpoint.api, endpoint)
26-
for i in req
27-
]
24+
return [return_obj(i, endpoint.api, endpoint) for i in req]
2825
return return_obj(req, endpoint.api, endpoint)
2926

3027

@@ -57,9 +54,7 @@ def __init__(self, api, app, name, model=None):
5754
self.token = api.token
5855
self.session_key = api.session_key
5956
self.url = "{base_url}/{app}/{endpoint}".format(
60-
base_url=self.base_url,
61-
app=app.name,
62-
endpoint=self.name,
57+
base_url=self.base_url, app=app.name, endpoint=self.name,
6358
)
6459
self._choices = None
6560

@@ -211,9 +206,7 @@ def filter(self, *args, **kwargs):
211206
kwargs.update({"q": args[0]})
212207

213208
if not kwargs:
214-
raise ValueError(
215-
"filter must be passed kwargs. Perhaps use all() instead."
216-
)
209+
raise ValueError("filter must be passed kwargs. Perhaps use all() instead.")
217210
if any(i in RESERVED_KWARGS for i in kwargs):
218211
raise ValueError(
219212
"A reserved {} kwarg was passed. Please remove it "
@@ -330,17 +323,15 @@ def choices(self):
330323
http_session=self.api.http_session,
331324
).options()
332325
try:
333-
post_data = req['actions']['POST']
326+
post_data = req["actions"]["POST"]
334327
except KeyError:
335328
raise ValueError(
336-
"Unexpected format in the OPTIONS response at {}".format(
337-
self.url
338-
)
329+
"Unexpected format in the OPTIONS response at {}".format(self.url)
339330
)
340331
self._choices = {}
341332
for prop in post_data:
342-
if 'choices' in post_data[prop]:
343-
self._choices[prop] = post_data[prop]['choices']
333+
if "choices" in post_data[prop]:
334+
self._choices[prop] = post_data[prop]["choices"]
344335

345336
return self._choices
346337

@@ -405,9 +396,7 @@ class DetailEndpoint(object):
405396
def __init__(self, parent_obj, name, custom_return=None):
406397
self.parent_obj = parent_obj
407398
self.custom_return = custom_return
408-
self.url = "{}/{}/{}/".format(
409-
parent_obj.endpoint.url, parent_obj.id, name
410-
)
399+
self.url = "{}/{}/{}/".format(parent_obj.endpoint.url, parent_obj.id, name)
411400
self.request_kwargs = dict(
412401
base=self.url,
413402
token=parent_obj.api.token,
@@ -431,9 +420,7 @@ def list(self, **kwargs):
431420
req = Request(**self.request_kwargs).get(add_params=kwargs)
432421

433422
if self.custom_return:
434-
return response_loader(
435-
req, self.custom_return, self.parent_obj.endpoint
436-
)
423+
return response_loader(req, self.custom_return, self.parent_obj.endpoint)
437424
return req
438425

439426
def create(self, data=None):
@@ -452,14 +439,10 @@ def create(self, data=None):
452439
data = data or {}
453440
req = Request(**self.request_kwargs).post(data)
454441
if self.custom_return:
455-
return response_loader(
456-
req, self.custom_return, self.parent_obj.endpoint
457-
)
442+
return response_loader(req, self.custom_return, self.parent_obj.endpoint)
458443
return req
459444

460445

461446
class RODetailEndpoint(DetailEndpoint):
462447
def create(self, data):
463-
raise NotImplementedError(
464-
"Writes are not supported for this endpoint."
465-
)
448+
raise NotImplementedError("Writes are not supported for this endpoint.")

0 commit comments

Comments
 (0)