Skip to content

Commit 7431321

Browse files
authored
Feature/move to uv (#7)
* move to uv * forgot to move build to uv in make * added support for 3.13
1 parent ca9aea6 commit 7431321

16 files changed

+7557
-255
lines changed

.github/workflows/publish-to-pypi.yml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# This workflow will upload a Python Package using Twine when a release is created
1+
# This workflow will upload a Python Package using UV when a release is created
22
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
33

44
name: Upload Python Package to PyPi
@@ -18,16 +18,15 @@ jobs:
1818
- name: Set up Python
1919
uses: actions/setup-python@v5
2020
with:
21-
python-version: '3.12'
21+
python-version: "3.12"
2222

23-
- name: Install dependencies
23+
- name: Install UV
2424
run: |
25-
python -m pip install --upgrade pip setuptools wheel
26-
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi
25+
pip install uv
2726
- name: Build and publish
2827
env:
29-
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
30-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
28+
UV_PUBLISH_USERNAME: ${{ secrets.PYPI_USERNAME }}
29+
UV_PUBLISH_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
3130
run: |
3231
make build
33-
twine upload dist/*
32+
uv publish

.github/workflows/test-coverage-lint.yml

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ on:
77
push:
88
branches:
99
- master
10+
- main
1011
- develop
1112
- feature/*
1213
- bug/*
1314
pull_request:
1415
branches:
1516
- master
17+
- main
1618
- develop
1719
- feature/*
1820
- bug/*
@@ -24,10 +26,11 @@ jobs:
2426
fail-fast: false
2527
matrix:
2628
python-version:
27-
- 3.9
28-
- '3.10'
29-
- '3.11'
30-
- '3.12'
29+
- "3.9"
30+
- "3.10"
31+
- "3.11"
32+
- "3.12"
33+
- "3.13"
3134
os:
3235
- ubuntu-latest
3336

@@ -37,12 +40,9 @@ jobs:
3740
uses: actions/setup-python@v5
3841
with:
3942
python-version: ${{ matrix.python-version }}
40-
- name: Upgrade pip setuptools wheel
43+
- name: Install UV
4144
run: |
42-
python -m pip install --upgrade pip setuptools wheel
43-
- name: Install requirements from requirements-dev.txt
44-
run: |
45-
pip install -r requirements-dev.txt
45+
pip install uv
4646
- name: Run Linting
4747
run: |
4848
make pylint
@@ -54,10 +54,11 @@ jobs:
5454
fail-fast: false
5555
matrix:
5656
python-version:
57-
- 3.9
58-
- '3.10'
59-
- '3.11'
60-
- '3.12'
57+
- "3.9"
58+
- "3.10"
59+
- "3.11"
60+
- "3.12"
61+
- "3.13"
6162
os:
6263
- ubuntu-latest
6364

@@ -67,12 +68,9 @@ jobs:
6768
uses: actions/setup-python@v5
6869
with:
6970
python-version: ${{ matrix.python-version }}
70-
- name: Upgrade pip setuptools wheel
71-
run: |
72-
python -m pip install --upgrade pip setuptools wheel
73-
- name: Install requirements from requirements-dev.txt
71+
- name: Install UV
7472
run: |
75-
pip install -r requirements-dev.txt
73+
pip install uv
7674
- name: Run Unit-Testing and Coverage
7775
run: |
7876
make coverage
@@ -84,10 +82,11 @@ jobs:
8482
fail-fast: false
8583
matrix:
8684
python-version:
87-
- 3.9
88-
- '3.10'
89-
- '3.11'
90-
- '3.12'
85+
- "3.9"
86+
- "3.10"
87+
- "3.11"
88+
- "3.12"
89+
- "3.13"
9190
os:
9291
- ubuntu-latest
9392

@@ -97,12 +96,9 @@ jobs:
9796
uses: actions/setup-python@v5
9897
with:
9998
python-version: ${{ matrix.python-version }}
100-
- name: Upgrade pip setuptools wheel
101-
run: |
102-
python -m pip install --upgrade pip setuptools wheel
103-
- name: Install requirements from requirements-dev.txt
99+
- name: Install UV
104100
run: |
105-
pip install -r requirements-dev.txt
101+
pip install uv
106102
- name: Run Build
107103
run: |
108104
make build

.readthedocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: 2
33
build:
44
os: "ubuntu-22.04"
55
tools:
6-
python: "3.8"
6+
python: "3.12"
77

88
sphinx:
99
configuration: docs/conf.py

Makefile

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,45 @@
33
# Version: 1.0.3
44
#
55

6-
.PHONY: info app-run coverage pylint pytest gh-pages pdf build
6+
.PHONY: info all build coverage format pylint pytest check-security pip-export pdf
77

88
info:
99
@echo "make options"
10-
@echo " build To build"
11-
@echo " coverage To run coverage and display ASCII and output to htmlcov"
12-
@echo " pylint To run pylint"
13-
@echo " pytest To run pytest with verbose option"
14-
@echo " pdf To create PDF Docs"
10+
@echo " info To display this message"
11+
@echo " all To run all tasks"
12+
@echo " build To build"
13+
@echo " coverage To run coverage and display ASCII and output to htmlcov"
14+
@echo " format To run black on pyats_genie_command_parse and tests"
15+
@echo " pylint To run pylint"
16+
@echo " pytest To run pytest with verbose option"
17+
@echo " check-security To run bandit"
18+
@echo " pip-export To export requirements.txt and requirements-dev.txt"
19+
@echo " pdf To create PDF Docs"
20+
21+
all: format pylint coverage check-security pip-export
1522

1623
build:
17-
@python -m build
24+
@uv build --wheel --sdist
1825

1926
coverage:
20-
@pytest --cov --cov-report=html -vvv
27+
@uv run pytest --cov --cov-report=html -vvv
28+
29+
format:
30+
@uv run black pyats_genie_command_parse/
31+
@uv run black tests/
2132

2233
pylint:
23-
@pylint pyats_genie_command_parse/
34+
@uv run pylint pyats_genie_command_parse/
2435

2536
pytest:
26-
@pytest --cov -vvv
37+
@uv run pytest --cov -vvv
38+
39+
check-security:
40+
@uv run bandit -c pyproject.toml -r .
41+
42+
pip-export:
43+
@uv export --no-dev --no-emit-project --no-editable > requirements.txt
44+
@uv export --no-emit-project --no-editable > requirements-dev.txt
2745

2846
pdf:
29-
@sphinx-build -b rinoh ./docs ./docs/_build/pdf
47+
@uv run sphinx-build -b rinoh ./docs ./docs/_build/pdf
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""
22
init for pyats_genie_command_parse
33
"""
4+
45
from pyats_genie_command_parse.pyats_genie_command_parse import GenieCommandParse

pyats_genie_command_parse/pyats_genie_command_parse.py

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
the full command is, and the output string data from the command.
99
1010
"""
11+
1112
from genie.libs.parser.utils.common import get_parser
1213
from pyats.topology import Device
1314

@@ -32,6 +33,7 @@ class MockDevice: # pylint: disable=too-few-public-methods
3233
:type show_output_data: String
3334
:param show_output_data: The output data from the show command
3435
"""
36+
3537
def __init__(self, show_output_data: str) -> None:
3638
self.show_output_data = show_output_data
3739

@@ -49,30 +51,32 @@ def execute(self, *args, **kwargs) -> str: # pylint: disable=unused-argument
4951
return self.show_output_data
5052

5153
# Set to hold supported nos
52-
supported_nos = {'aireos',
53-
'apic',
54-
'asa',
55-
'bigip',
56-
'cheetah',
57-
'comware',
58-
'dnac',
59-
'gaia',
60-
'ios',
61-
'iosxe',
62-
'iosxr',
63-
'ironware',
64-
'junos',
65-
'linux',
66-
'nxos',
67-
'sros',
68-
'viptela'}
54+
supported_nos = {
55+
"aireos",
56+
"apic",
57+
"asa",
58+
"bigip",
59+
"cheetah",
60+
"comware",
61+
"dnac",
62+
"gaia",
63+
"ios",
64+
"iosxe",
65+
"iosxr",
66+
"ironware",
67+
"junos",
68+
"linux",
69+
"nxos",
70+
"sros",
71+
"viptela",
72+
}
6973

7074
def __init__(self, nos) -> None:
71-
self.mock_pyats_device = Device('Mock')
72-
self.mock_pyats_device.custom = {'abstraction': {'order': ['os']}}
75+
self.mock_pyats_device = Device("Mock")
76+
self.mock_pyats_device.custom = {"abstraction": {"order": ["os"]}}
7377

7478
if nos not in self.supported_nos:
75-
raise LookupError(f'nos needs to be one of theses options {self.supported_nos}')
79+
raise LookupError(f"nos needs to be one of theses options {self.supported_nos}")
7680

7781
self.nos = nos
7882
self.mock_pyats_device.os = nos
@@ -95,12 +99,12 @@ def parse_string(self, show_command: str, show_output_data: str) -> dict:
9599
:raises TypeError: if the show_output_data is not a string
96100
"""
97101
if not isinstance(show_output_data, str):
98-
raise TypeError(f'show_output_data must be a string received a {type(show_output_data)}')
102+
raise TypeError(f"show_output_data must be a string received a {type(show_output_data)}")
99103

100104
self.show_output_data = show_output_data
101105

102106
if not isinstance(show_command, str):
103-
raise TypeError(f'show_command must be a string received a {type(show_command)}')
107+
raise TypeError(f"show_command must be a string received a {type(show_command)}")
104108

105109
return self.__parse(show_command)
106110

@@ -119,9 +123,9 @@ def parse_file(self, show_command: str, file_name_and_path: str) -> dict:
119123
:raises FileNotFoundError: if the file you are trying to parse can't be found
120124
"""
121125
if not isinstance(show_command, str):
122-
raise TypeError(f'show_command must be a string received a {type(show_command)}')
126+
raise TypeError(f"show_command must be a string received a {type(show_command)}")
123127

124-
with open(file_name_and_path, 'r', encoding='utf-8') as file:
128+
with open(file_name_and_path, "r", encoding="utf-8") as file:
125129
self.show_output_data = file.read()
126130

127131
return self.__parse(show_command)
@@ -139,9 +143,9 @@ def __remove_extra_spaces(string_item: str) -> str:
139143
:raises TypeError: if the string_item is not a string
140144
"""
141145
if not isinstance(string_item, str): # pragma: no cover
142-
raise TypeError(f'string_item must be a string received a {type(string_item)}')
146+
raise TypeError(f"string_item must be a string received a {type(string_item)}")
143147

144-
string_item = ' '.join(string_item.split())
148+
string_item = " ".join(string_item.split())
145149
return string_item
146150

147151
def __parse(self, show_command: str) -> dict:
@@ -157,13 +161,14 @@ def __parse(self, show_command: str) -> dict:
157161
:raises ModuleNotFoundError: If it can not find a command to NOS mapping
158162
"""
159163
if not isinstance(show_command, str): # pragma: no cover
160-
raise TypeError(f'show_command must be a string received a {type(show_command)}')
164+
raise TypeError(f"show_command must be a string received a {type(show_command)}")
161165

162166
mock_device = self.MockDevice(self.show_output_data)
163167
try:
164168
found_parser = get_parser(self.__remove_extra_spaces(show_command), self.mock_pyats_device)[0]
165169
return found_parser(device=mock_device).parse()
166170

167171
except Exception as error:
168-
raise ModuleNotFoundError(f'Could not find module_name for command {show_command} '
169-
f'for nos {self.nos} from genie: {error}') from error
172+
raise ModuleNotFoundError(
173+
f"Could not find module_name for command {show_command} " f"for nos {self.nos} from genie: {error}"
174+
) from error
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""
22
Holds the version information for the package
33
"""
4+
45
__copyright__ = "Copyright (c) 2020 - 2025, Benjamin P. Trachtenberg, Brett Gianpetro"
5-
__status__ = 'prod'
6+
__status__ = "prod"
67
__version_info__ = (1, 4, 1)
7-
__version__ = '.'.join(map(str, __version_info__))
8+
__version__ = ".".join(map(str, __version_info__))

0 commit comments

Comments
 (0)