Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Black and Pytest in GH Actions #254

Merged
merged 1 commit into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/py2pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: PR Test

on: [pull_request]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python: [2.7]

steps:
- uses: actions/checkout@v2

- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}

- name: Install pynetbox and testing packages.
run: pip install . mock

- name: Run Tests
run: python -m unittest discover

10 changes: 4 additions & 6 deletions .github/workflows/pr.yml → .github/workflows/py3pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: [2.7, 3.6]
python: [3.6, 3.8]

steps:
- uses: actions/checkout@v2
Expand All @@ -19,13 +19,11 @@ jobs:
python-version: ${{ matrix.python }}

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

- name: Run Linter
run: |
pycodestyle pynetbox
pycodestyle --ignore=E501 tests
run: black --check .

- name: Run Tests
run: python -m unittest discover
run: pytest

58 changes: 27 additions & 31 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import os
import sys
from pkg_resources import get_distribution
sys.path.insert(0, os.path.abspath('../'))

sys.path.insert(0, os.path.abspath("../"))


# -- General configuration ------------------------------------------------
Expand All @@ -31,33 +32,33 @@
# 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']
extensions = ["sphinx.ext.autodoc"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
source_suffix = ".rst"

# The master toctree document.
master_doc = 'index'
master_doc = "index"

# General information about the project.
project = u'pynetbox'
copyright = u'2017, DigitalOcean'
author = u'Zach Moody'
project = u"pynetbox"
copyright = u"2017, DigitalOcean"
author = u"Zach Moody"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
# The full version, including alpha/beta/rc tags.
release = get_distribution('pynetbox').version
release = get_distribution("pynetbox").version
#
# The short X.Y version.
version = '.'.join(release.split('.')[:2])
version = ".".join(release.split(".")[:2])

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

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
pygments_style = "sphinx"

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

html_sidebars = {'**': [
'globaltoc.html',
'relations.html',
'sourcelink.html',
'searchbox.html'
]
html_sidebars = {
"**": ["globaltoc.html", "relations.html", "sourcelink.html", "searchbox.html"]
}

# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'pynetboxdoc'
htmlhelp_basename = "pynetboxdoc"


# -- Options for LaTeX output ---------------------------------------------
Expand All @@ -116,15 +113,12 @@
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',

# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
Expand All @@ -134,19 +128,15 @@
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'pynetbox.tex', u'pynetbox Documentation',
u'Zach Moody', 'manual'),
(master_doc, "pynetbox.tex", u"pynetbox Documentation", u"Zach Moody", "manual"),
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'pynetbox', u'pynetbox Documentation',
[author], 1)
]
man_pages = [(master_doc, "pynetbox", u"pynetbox Documentation", [author], 1)]


# -- Options for Texinfo output -------------------------------------------
Expand All @@ -155,7 +145,13 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'pynetbox', u'pynetbox Documentation',
author, 'pynetbox', 'A python library for NetBox.',
'Miscellaneous'),
(
master_doc,
"pynetbox",
u"pynetbox Documentation",
author,
"pynetbox",
"A python library for NetBox.",
"Miscellaneous",
),
]
19 changes: 7 additions & 12 deletions pynetbox/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,7 @@ class Api(object):
"""

def __init__(
self,
url,
token=None,
private_key=None,
private_key_file=None,
threading=False,
self, url, token=None, private_key=None, private_key_file=None, threading=False,
):
if private_key and private_key_file:
raise ValueError(
Expand All @@ -81,8 +76,10 @@ def __init__(
self.session_key = None
self.http_session = requests.Session()
if threading and sys.version_info.major == 2:
raise NotImplementedError("Threaded pynetbox calls not supported \
in Python 2")
raise NotImplementedError(
"Threaded pynetbox calls not supported \
in Python 2"
)
self.threading = threading

if self.private_key_file:
Expand Down Expand Up @@ -119,8 +116,7 @@ def version(self):
>>>
"""
version = Request(
base=self.base_url,
http_session=self.http_session,
base=self.base_url, http_session=self.http_session,
).get_version()
return version

Expand All @@ -143,6 +139,5 @@ def openapi(self):
>>>
"""
return Request(
base=self.base_url,
http_session=self.http_session,
base=self.base_url, http_session=self.http_session,
).get_openapi()
16 changes: 5 additions & 11 deletions pynetbox/core/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class App(object):
:raises: :py:class:`.RequestError`
if requested endpoint doesn't exist.
"""

def __init__(self, api, name):
self.api = api
self.name = name
Expand All @@ -38,18 +39,14 @@ def __init__(self, api, name):
"ipam": ipam,
"circuits": circuits,
"virtualization": virtualization,
"extras": extras
"extras": extras,
}

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

def __getstate__(self):
return {
'api': self.api,
'name': self.name,
'_choices': self._choices
}
return {"api": self.api, "name": self.name, "_choices": self._choices}

def __setstate__(self, d):
self.__dict__.update(d)
Expand All @@ -68,7 +65,7 @@ def _set_session_key(self):
base=self.api.base_url,
token=self.api.token,
private_key=self.api.private_key,
http_session=self.api.http_session
http_session=self.api.http_session,
).get_session_key()

def choices(self):
Expand Down Expand Up @@ -106,10 +103,7 @@ def custom_choices(self):
'Testfield2': {'Othervalue2': 4, 'Othervalue1': 3}}
"""
custom_field_choices = Request(
base="{}/{}/_custom_field_choices/".format(
self.api.base_url,
self.name,
),
base="{}/{}/_custom_field_choices/".format(self.api.base_url, self.name,),
token=self.api.token,
private_key=self.api.private_key,
http_session=self.api.http_session,
Expand Down
39 changes: 11 additions & 28 deletions pynetbox/core/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@

def response_loader(req, return_obj, endpoint):
if isinstance(req, list):
return [
return_obj(i, endpoint.api, endpoint)
for i in req
]
return [return_obj(i, endpoint.api, endpoint) for i in req]
return return_obj(req, endpoint.api, endpoint)


Expand Down Expand Up @@ -57,9 +54,7 @@ def __init__(self, api, app, name, model=None):
self.token = api.token
self.session_key = api.session_key
self.url = "{base_url}/{app}/{endpoint}".format(
base_url=self.base_url,
app=app.name,
endpoint=self.name,
base_url=self.base_url, app=app.name, endpoint=self.name,
)
self._choices = None

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

if not kwargs:
raise ValueError(
"filter must be passed kwargs. Perhaps use all() instead."
)
raise ValueError("filter must be passed kwargs. Perhaps use all() instead.")
if any(i in RESERVED_KWARGS for i in kwargs):
raise ValueError(
"A reserved {} kwarg was passed. Please remove it "
Expand Down Expand Up @@ -330,17 +323,15 @@ def choices(self):
http_session=self.api.http_session,
).options()
try:
post_data = req['actions']['POST']
post_data = req["actions"]["POST"]
except KeyError:
raise ValueError(
"Unexpected format in the OPTIONS response at {}".format(
self.url
)
"Unexpected format in the OPTIONS response at {}".format(self.url)
)
self._choices = {}
for prop in post_data:
if 'choices' in post_data[prop]:
self._choices[prop] = post_data[prop]['choices']
if "choices" in post_data[prop]:
self._choices[prop] = post_data[prop]["choices"]

return self._choices

Expand Down Expand Up @@ -405,9 +396,7 @@ class DetailEndpoint(object):
def __init__(self, parent_obj, name, custom_return=None):
self.parent_obj = parent_obj
self.custom_return = custom_return
self.url = "{}/{}/{}/".format(
parent_obj.endpoint.url, parent_obj.id, name
)
self.url = "{}/{}/{}/".format(parent_obj.endpoint.url, parent_obj.id, name)
self.request_kwargs = dict(
base=self.url,
token=parent_obj.api.token,
Expand All @@ -431,9 +420,7 @@ def list(self, **kwargs):
req = Request(**self.request_kwargs).get(add_params=kwargs)

if self.custom_return:
return response_loader(
req, self.custom_return, self.parent_obj.endpoint
)
return response_loader(req, self.custom_return, self.parent_obj.endpoint)
return req

def create(self, data=None):
Expand All @@ -452,14 +439,10 @@ def create(self, data=None):
data = data or {}
req = Request(**self.request_kwargs).post(data)
if self.custom_return:
return response_loader(
req, self.custom_return, self.parent_obj.endpoint
)
return response_loader(req, self.custom_return, self.parent_obj.endpoint)
return req


class RODetailEndpoint(DetailEndpoint):
def create(self, data):
raise NotImplementedError(
"Writes are not supported for this endpoint."
)
raise NotImplementedError("Writes are not supported for this endpoint.")
Loading