Skip to content

Commit b6057cf

Browse files
author
jguerreiro
committed
feat(pygitguardian): add has_policy_breaks and port to pytest
fix(readme): fix readme badges fix(readme): remove \n between badges fix(models): fix small documentation typos fix(readme): fix readme link
1 parent c91ce00 commit b6057cf

29 files changed

+1859
-906
lines changed

.github/workflows/test-lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
pipenv install --system --dev --skip-lock
4646
- name: Test with pytest
4747
run: |
48-
pipenv run coverage run --source pygitguardian -m nose tests
48+
pipenv run coverage run --source pygitguardian -m pytest --disable-pytest-warnings
4949
pipenv run coverage report --fail-under=80
5050
pipenv run coverage xml
5151
- uses: codecov/codecov-action@v1

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ coverage.xml
115115
.hypothesis/
116116
.pytest_cache/
117117

118+
# Pylinting
119+
.mypy_cache
120+
118121
# Catch sensitive files
119122
.env
120123
secrets.py

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pipenv run pre-commit install -f --hook-type commit-msg --hook-type pre-commit
2323

2424
## Testing
2525

26-
Pygitguardian testing is done with `nosetest`. You should make sure your changes don't report any error on
26+
Pygitguardian testing is done with `pytest`. You should make sure your changes don't report any error on:
2727

2828
```
2929
make test

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 gg-code / prm
3+
Copyright (c) 2020 GitGuardian
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ all:
1313
echo " make isort" # Run isort linter on python code
1414

1515
test:
16-
pipenv run nosetests $(test)
16+
pipenv run pytest --disable-pytest-warnings -vvv $(test)
1717

1818
coverage:
19-
pipenv run coverage run --source pygitguardian -m nose tests && pipenv run coverage report --fail-under=80
19+
pipenv run coverage run --source pygitguardian -m pytest --disable-pytest-warnings && pipenv run coverage report --fail-under=80
2020

2121
black:
2222
pipenv run black --config black.toml .

Pipfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ flake8 = "*"
1313
flake8-isort = "*"
1414
ipython = "*"
1515
isort = "*"
16-
nose = "*"
1716
pre-commit = "*"
17+
pytest = "*"
1818
vcrpy = "*"
19-
vcrpy-unittest = "*"

README.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
<img src="https://cdn.jsdelivr.net/gh/gitguardian/py-gitguardian/doc/logo.svg">
1+
<a href="https://gitguardian.com/"><img src="https://cdn.jsdelivr.net/gh/gitguardian/py-gitguardian/doc/logo.svg"></a>
22

3-
# GitGuardian API Client
3+
# [py-gitguardian](https://github.com/GitGuardian/py-gitguardian) - GitGuardian API Client
44

5-
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/GitGuardian/py-gitguardian/Main?color=%231B2D55&style=for-the-badge)
6-
![PyPI](https://img.shields.io/pypi/v/pygitguardian?color=%231B2D55&style=for-the-badge)
7-
![GitHub](https://img.shields.io/github/license/GitGuardian/py-gitguardian?color=%231B2D55&style=for-the-badge)
8-
![GitHub stars](https://img.shields.io/github/stars/gitguardian/py-gitguardian?color=%231B2D55&style=for-the-badge)
9-
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/gitguardian/py-gitguardian?color=%231B2D55&style=for-the-badge)
10-
![Codecov](https://img.shields.io/codecov/c/github/GitGuardian/py-gitguardian?color=%231B2D55&style=for-the-badge)
5+
[![PyPI](https://img.shields.io/pypi/v/pygitguardian?color=%231B2D55&style=for-the-badge)](https://pypi.org/project/pygitguardian/)
6+
[![License](https://img.shields.io/github/license/GitGuardian/py-gitguardian?color=%231B2D55&style=for-the-badge)](LICENSE)
7+
[![GitHub stars](https://img.shields.io/github/stars/gitguardian/py-gitguardian?color=%231B2D55&style=for-the-badge)](https://github.com/GitGuardian/py-gitguardian/stargazers)
8+
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/GitGuardian/py-gitguardian/Main?style=for-the-badge)
9+
[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/gitguardian/py-gitguardian?style=for-the-badge)](https://www.codefactor.io/repository/github/gitguardian/py-gitguardian)
10+
[![Codecov](https://img.shields.io/codecov/c/github/GitGuardian/py-gitguardian?style=for-the-badge)](https://codecov.io/gh/GitGuardian/py-gitguardian/)
1111

1212
API client library for the [GitGuardian API](https://api.gitguardian.com/).
1313

pygitguardian/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from .client import GGClient
33

44

5-
__version__ = "1.0.4"
5+
__version__ = "1.1.0"
66
GGClient._version = __version__
77

88
__all__ = [

pygitguardian/client.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import platform
22
import urllib.parse
3-
from typing import Dict, Iterable, Optional, Union
3+
from typing import Dict, List, Optional, Union
44

55
import requests
66
from requests import Response, Session, codes
@@ -24,7 +24,7 @@ def __init__(
2424
session: Optional[requests.Session] = None,
2525
user_agent: Optional[str] = None,
2626
timeout: Optional[float] = DEFAULT_TIMEOUT,
27-
) -> "GGClient":
27+
):
2828
"""
2929
:param api_key: API Key to be added to requests
3030
:param base_uri: Base URI for the API, defaults to "https://api.gitguardian.com"
@@ -65,7 +65,11 @@ def __init__(
6565
)
6666

6767
def request(
68-
self, method: str, endpoint: str, version: str = DEFAULT_API_VERSION, **kwargs
68+
self,
69+
method: str,
70+
endpoint: str,
71+
version: Optional[str] = DEFAULT_API_VERSION,
72+
**kwargs
6973
) -> Response:
7074
if version:
7175
endpoint = urllib.parse.urljoin(version + "/", endpoint)
@@ -93,7 +97,7 @@ def post(
9397
)
9498

9599
def get(
96-
self, endpoint: str, version: str = DEFAULT_API_VERSION, **kwargs
100+
self, endpoint: str, version: Optional[str] = DEFAULT_API_VERSION, **kwargs
97101
) -> Response:
98102
return self.request(method="get", endpoint=endpoint, version=version, **kwargs)
99103

@@ -141,7 +145,7 @@ def content_scan(
141145
return obj
142146

143147
def multi_content_scan(
144-
self, documents: Iterable[Dict[str, str]],
148+
self, documents: List[Dict[str, str]],
145149
) -> Union[Detail, MultiScanResult]:
146150
"""
147151
multi_content_scan handles the /multiscan endpoint of the API

pygitguardian/models.py

+35-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Dict, List, Optional
1+
from typing import ClassVar, Dict, List, Optional
22

33
from marshmallow import (
44
EXCLUDE,
@@ -14,7 +14,7 @@
1414

1515

1616
class Base:
17-
SCHEMA = None
17+
SCHEMA: ClassVar[Schema]
1818

1919
def __init__(self):
2020
self.status_code = None
@@ -204,6 +204,10 @@ def __init__(self, break_type: str, policy: str, matches: List[Match], **kwargs)
204204
self.policy = policy
205205
self.matches = matches
206206

207+
@property
208+
def is_secret(self) -> bool:
209+
return self.policy == "Secrets detection"
210+
207211
def __repr__(self):
208212
return (
209213
"break_type:{0}, "
@@ -255,19 +259,29 @@ def __init__(
255259
self.policy_breaks = policy_breaks
256260

257261
@property
258-
def has_secrets(self) -> bool:
262+
def has_policy_breaks(self) -> bool:
259263
"""has_secrets is an easy way to check if your provided document has policy breaks
260264
261265
>>> obj = ScanResult(2, [], [])
262-
>>> obj.has_secrets
266+
>>> obj.has_policy_breaks
263267
True
264268
265-
:return: true if there were policy breaks in the documents
269+
:return: true if there were policy breaks (including secrets) in the document
266270
:rtype: bool
267271
"""
268272

269273
return self.policy_break_count > 0
270274

275+
@property
276+
def has_secrets(self) -> bool:
277+
"""has_secrets is an easy way to check if your provided document has secrets
278+
279+
:return: true if there were secrets in the document
280+
:rtype: bool
281+
"""
282+
283+
return any(policy_break.is_secret for policy_break in self.policy_breaks)
284+
271285
def __repr__(self):
272286
return (
273287
"policy_break_count:{0}, "
@@ -280,7 +294,7 @@ def __repr__(self):
280294
def __str__(self):
281295
return "{0} policy breaks from the evaluated policies: {1}".format(
282296
self.policy_break_count,
283-
", ".join([policy_break.policy for policy_break in self.policy_breaks]),
297+
", ".join(policy_break.policy for policy_break in self.policy_breaks),
284298
)
285299

286300

@@ -316,20 +330,28 @@ def __init__(self, scan_results: List[ScanResult], **kwargs):
316330
self.scan_results = scan_results
317331

318332
@property
319-
def has_secrets(self) -> bool:
320-
"""has_secrets is an easy way to check if your provided document has policy breaks
333+
def has_policy_breaks(self) -> bool:
334+
"""has_policy_breaks is an easy way to check if your provided document has policy breaks
321335
322336
>>> obj = ScanResult(2, [], [])
323-
>>> obj.has_secrets
337+
>>> obj.has_policy_breaks
324338
True
325339
326-
:return: true if there were policy breaks in the documents
340+
:return: true if there were policy breaks (including secrets) in the documents
327341
:rtype: bool
328342
"""
329343

330-
return any(
331-
(len(scan_result.policy_breaks) > 0 for scan_result in self.scan_results)
332-
)
344+
return any(scan_result.has_policy_breaks for scan_result in self.scan_results)
345+
346+
@property
347+
def has_secrets(self) -> bool:
348+
"""has_secrets is an easy way to check if your provided document has secrets
349+
350+
:return: true if there were secrets in the documents
351+
:rtype: bool
352+
"""
353+
354+
return any(scan_result.has_secrets for scan_result in self.scan_results)
333355

334356
def __repr__(self):
335357
return "scan_results:{0}".format(self.scan_results)

setup.cfg

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,8 @@ max-line-length = 120
77
line_length=88
88
lines_after_imports=2
99
multi_line_output=3
10-
known_third_party=marshmallow,requests,setuptools,vcr_unittest
10+
known_third_party=marshmallow,pytest,requests,setuptools,vcr
1111
include_trailing_comma=true
1212

1313
[metadata]
1414
description-file = README.md
15-
16-
[nosetests]
17-
verbosity=2
18-
with-doctest=1

0 commit comments

Comments
 (0)