Skip to content

Commit

Permalink
Merge pull request #8 from cisco-ie/python2
Browse files Browse the repository at this point in the history
Python 2 Support
  • Loading branch information
remingtonc authored Sep 9, 2019
2 parents 851961f + cdbaef2 commit 6e0d16e
Show file tree
Hide file tree
Showing 10 changed files with 38 additions and 440 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Custom
.vscode/
Pipfile.lock

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ name = "pypi"
grpcio-tools = "*"
googleapis-common-protos = "*"
pylint = "*"
black = "==19.3b0"
twine = "*"
setuptools = "*"
wheel = "*"

[packages]
grpcio = "*"
protobuf = "*"
enum34 = "*"
six = "*"

[requires]
python_version = "3.6"
424 changes: 0 additions & 424 deletions Pipfile.lock

This file was deleted.

9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ gRPC Network Management Interface (gNMI) is a service defining an interface for
gNMI is a specification developed by [OpenConfig](https://openconfig.net), an operator-driven working-group. It is important to note that gNMI only defines a protocol of behavior - not data models. This is akin to SNMP/MIBs and NETCONF/YANG. SNMP and NETCONF are respectively decoupled from the data itself in MIBs and YANG modules. gNMI is a control protocol, not a standardization of data. OpenConfig does develop standard data models as well, and does have some specialized behavior with OpenConfig originating models, but the data models themselves are out of the scope of gNMI.

## Development
Requires Python and utilizes `pipenv` for environment management. Manual usage of `pip`/`virtualenv` is not covered. Uses `black` for code formatting and `pylint` for code linting.
Requires Python and utilizes `pipenv` for environment management. Manual usage of `pip`/`virtualenv` is not covered. Uses `black` for code formatting and `pylint` for code linting. `black` is not explicitly installed as it requires Python 3.6+.

### Get Source
```bash
Expand All @@ -39,17 +39,20 @@ cd cisco-gnmi-python
# If pipenv not installed, install!
pip install --user pipenv
# Now use pipenv
pipenv --three install
pipenv --three install --dev
# Enter virtual environment
pipenv shell
# Do your thing.
exit
```

### Code Hygiene
We use [`black`](https://github.com/ambv/black) for code formatting and [`pylint`](https://www.pylint.org/) for code linting. `hygiene.sh` will run `black` against all of the code under `gnmi/` except for `protoc` compiled protobufs, and run `pylint` against Python files directly under `gnmi/`. They don't totally agree, so we're not looking for perfection here.
We use [`black`](https://github.com/ambv/black) for code formatting and [`pylint`](https://www.pylint.org/) for code linting. `hygiene.sh` will run `black` against all of the code under `gnmi/` except for `protoc` compiled protobufs, and run `pylint` against Python files directly under `gnmi/`. They don't totally agree, so we're not looking for perfection here. `black` is not automatically installed due to requiring Python 3.6+. `hygiene.sh` will check for regular path availability and via `pipenv`, and otherwise falls directly to `pylint`. If `black` usage is desired, please install it into `pipenv` if using Python 3.6+ or separate methods e.g. `brew install black`.

```bash
# If using Python 3.6+
pipenv install --dev black
# Otherwise...
./hygiene.sh
```

Expand Down
14 changes: 11 additions & 3 deletions hygiene.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#!/usr/bin/env bash
# Script which autoformats (black) and lints (pylint) code
pipenv run black --safe --verbose --exclude proto src/cisco_gnmi
# Many disabled to accomodate black disagreements...
echo "Running black ..."
FORMAT_COMMAND="black --safe --verbose --exclude proto src/cisco_gnmi"
if black &> /dev/null; then
eval $FORMAT_COMMAND
elif pipenv run black &> /dev/null; then
eval "pipenv run $FORMAT_COMMAND"
else
echo "black formatter not found on system, proceeding to pylint..."
fi
echo "Running pylint ..."
# Many failures due to protos being runtime-functional and difficult to lint.
pipenv run pylint --disable line-too-long --disable pointless-string-statement --disable no-member --disable wrong-import-position --disable bad-continuation src/cisco_gnmi/*.py
pipenv run pylint --disable no-member --disable wrong-import-position --disable bad-continuation src/cisco_gnmi/*.py
6 changes: 6 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-i https://pypi.org/simple
enum34
futures ; python_version < '3.2'
grpcio
protobuf
six
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@
install_requires=[
"grpcio",
"protobuf",
"enum34",
"six",
],
extras_require={
"dev": [
"grpcio-tools",
"googleapis-common-protos",
"pylint",
"black==19.3b0",
"twine",
"setuptools",
"wheel",
Expand Down
2 changes: 1 addition & 1 deletion src/cisco_gnmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
from .client import Client
from .xr import XRClient

__version__ = "0.0.1"
__version__ = "0.0.2"
5 changes: 3 additions & 2 deletions src/cisco_gnmi/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
# Python 2
from urlparse import urlparse

from six import string_types
import grpc
from . import proto

Expand Down Expand Up @@ -98,11 +99,11 @@ def gen_options(tls_server_override):

def parse_xpath_to_gnmi_path(xpath, origin=None):
"""Parses an XPath to proto.gnmi_pb2.Path."""
if not isinstance(xpath, str):
if not isinstance(xpath, string_types):
raise Exception("xpath must be a string!")
path = proto.gnmi_pb2.Path()
if origin:
if not isinstance(origin, str):
if not isinstance(origin, string_types):
raise Exception("origin must be a string!")
path.origin = origin
for element in xpath.split("/"):
Expand Down
11 changes: 6 additions & 5 deletions src/cisco_gnmi/xr.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import json
import logging

from six import string_types
from .client import Client, proto, util


Expand Down Expand Up @@ -88,7 +89,7 @@ def delete_xpaths(self, xpaths, prefix=None):
-------
set()
"""
if isinstance(xpaths, str):
if isinstance(xpaths, string_types):
xpaths = [xpaths]
paths = []
for xpath in xpaths:
Expand Down Expand Up @@ -128,7 +129,7 @@ def set_json(self, update_json_configs=None, replace_json_configs=None, ietf=Tru
raise Exception("Must supply at least one set of configurations to method!")

def check_configs(name, configs):
if isinstance(name, str):
if isinstance(name, string_types):
logging.debug("Handling %s as JSON string.", name)
try:
configs = json.loads(configs)
Expand Down Expand Up @@ -204,7 +205,7 @@ def get_xpaths(self, xpaths, data_type="ALL", encoding="JSON_IETF"):
gnmi_path = None
if isinstance(xpaths, (list, set)):
gnmi_path = map(util.parse_xpath_to_gnmi_path, set(xpaths))
elif isinstance(xpaths, str):
elif isinstance(xpaths, string_types):
gnmi_path = [util.parse_xpath_to_gnmi_path(xpaths)]
else:
raise Exception(
Expand Down Expand Up @@ -279,11 +280,11 @@ def subscribe_xpaths(
subscription_list.encoding = util.validate_proto_enum(
"encoding", encoding, "Encoding", proto.gnmi_pb2.Encoding
)
if isinstance(xpath_subscriptions, str):
if isinstance(xpath_subscriptions, string_types):
xpath_subscriptions = [xpath_subscriptions]
for xpath_subscription in xpath_subscriptions:
subscription = None
if isinstance(xpath_subscription, str):
if isinstance(xpath_subscription, string_types):
subscription = proto.gnmi_pb2.Subscription()
subscription.path.CopyFrom(
util.parse_xpath_to_gnmi_path(xpath_subscription)
Expand Down

0 comments on commit 6e0d16e

Please sign in to comment.