From 7bf33b713a5b58089065679336462293409cd508 Mon Sep 17 00:00:00 2001 From: dphuang2 Date: Mon, 30 Oct 2023 13:01:23 -0700 Subject: [PATCH 1/2] remove validators dependency from Python SDK --- .../languages/PythonClientCodegen.java | 2 + .../resources/python/configuration.handlebars | 13 +++- .../resources/python/poetry.lock.handlebars | 29 +------ .../resources/python/pyproject.handlebars | 1 - .../resources/python/settings.json.handlebars | 9 +++ .../python/test_check_url.handlebars | 75 +++++++++++++++++++ 6 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 generator/konfig-generator-api/src/main/resources/python/settings.json.handlebars create mode 100644 generator/konfig-generator-api/src/main/resources/python/test_check_url.handlebars diff --git a/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index 216c5f52e6..2ae7557587 100644 --- a/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -404,6 +404,7 @@ public void processOpts() { if (!generateSourceCodeOnly) { supportingFiles.add(new SupportingFile("poetry.lock." + templateExtension, "", "poetry.lock")); + supportingFiles.add(new SupportingFile("settings.json." + templateExtension, "", ".vscode/settings.json")); supportingFiles.add(new SupportingFile("pyproject." + templateExtension, "", "pyproject.toml")); // supportingFiles.add(new SupportingFile("tox." + templateExtension, "", "tox.ini")); // supportingFiles.add(new SupportingFile("test-requirements." + templateExtension, "", "test-requirements.txt")); @@ -441,6 +442,7 @@ public void processOpts() { } supportingFiles.add(new SupportingFile("test_simple." + templateExtension, testFolder, "test_simple.py")); + supportingFiles.add(new SupportingFile("test_check_url." + templateExtension, testFolder, "test_simple.py")); supportingFiles.add(new SupportingFile("test_deprecation_warning." + templateExtension, testFolder, "test_deprecation_warning.py")); supportingFiles.add(new SupportingFile("exceptions." + templateExtension, packagePath(), "exceptions.py")); diff --git a/generator/konfig-generator-api/src/main/resources/python/configuration.handlebars b/generator/konfig-generator-api/src/main/resources/python/configuration.handlebars index c6d183410e..5648e5b291 100644 --- a/generator/konfig-generator-api/src/main/resources/python/configuration.handlebars +++ b/generator/konfig-generator-api/src/main/resources/python/configuration.handlebars @@ -17,7 +17,7 @@ import urllib.parse {{/if}} -import validators +import re from urllib.parse import urlparse from http import client as http_client from {{packageName}}.exceptions_base import ApiValueError @@ -740,7 +740,10 @@ conf = {{{packageName}}}.Configuration( self._base_path = check_url(value) self.server_index = None -def check_url(url: str): +DOMAIN_REGEX = re.compile( + r'^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9](?::[0-9]{1,5})?$|^(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?::[0-9]{1,5})?$' +) +def check_url(url: str) -> str: parsed = urlparse(url) if parsed.query != '': raise InvalidHostConfigurationError(url, "query string is not allowed") @@ -748,8 +751,10 @@ def check_url(url: str): raise InvalidHostConfigurationError(url, "fragment is not allowed") if parsed.scheme not in ["http", "https"]: raise InvalidHostConfigurationError(url, 'scheme must be "http" or "https"'.format(parsed.scheme)) - if not validators.url(url): - raise InvalidHostConfigurationError(url, "invalid url") + if (parsed.netloc == ''): + raise InvalidHostConfigurationError(url, "host is not set") + if not DOMAIN_REGEX.match(parsed.netloc): + raise InvalidHostConfigurationError(url, "Invalid domain") if (url.endswith("/")): return url[:-1] return url diff --git a/generator/konfig-generator-api/src/main/resources/python/poetry.lock.handlebars b/generator/konfig-generator-api/src/main/resources/python/poetry.lock.handlebars index d1f6b4667a..bdb9e899b2 100644 --- a/generator/konfig-generator-api/src/main/resources/python/poetry.lock.handlebars +++ b/generator/konfig-generator-api/src/main/resources/python/poetry.lock.handlebars @@ -576,17 +576,6 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.5" -files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] - [[package]] name = "docutils" version = "0.20.1" @@ -1448,22 +1437,6 @@ brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotl secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -[[package]] -name = "validators" -version = "0.20.0" -description = "Python Data Validation for Humans™." -optional = false -python-versions = ">=3.4" -files = [ - {file = "validators-0.20.0.tar.gz", hash = "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a"}, -] - -[package.dependencies] -decorator = ">=3.4.0" - -[package.extras] -test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] - [[package]] name = "webencodings" version = "0.5.1" @@ -1581,4 +1554,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "a858aed6573e594478cb94a6281f6dea5bb9ced81a449e9eff25a8ab6b35aafa" +content-hash = "85adfe987c068f4f9ada61a21621f112dce3afc02e9490e3d95dbc00d246bb10" diff --git a/generator/konfig-generator-api/src/main/resources/python/pyproject.handlebars b/generator/konfig-generator-api/src/main/resources/python/pyproject.handlebars index de8b53c721..10c5a0e718 100644 --- a/generator/konfig-generator-api/src/main/resources/python/pyproject.handlebars +++ b/generator/konfig-generator-api/src/main/resources/python/pyproject.handlebars @@ -13,7 +13,6 @@ certifi = ">=2023.7.22" python-dateutil = "^2.8.2" typing_extensions = "^4.3.0" urllib3 = "^1.26.7" -validators = "^0.20.0" frozendict = "^2.3.4" aiohttp = "^3.8.4" diff --git a/generator/konfig-generator-api/src/main/resources/python/settings.json.handlebars b/generator/konfig-generator-api/src/main/resources/python/settings.json.handlebars new file mode 100644 index 0000000000..199fd258ca --- /dev/null +++ b/generator/konfig-generator-api/src/main/resources/python/settings.json.handlebars @@ -0,0 +1,9 @@ +{ + "python.testing.pytestArgs": [], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + }, + "python.formatting.provider": "none" +} \ No newline at end of file diff --git a/generator/konfig-generator-api/src/main/resources/python/test_check_url.handlebars b/generator/konfig-generator-api/src/main/resources/python/test_check_url.handlebars new file mode 100644 index 0000000000..403fd4b88c --- /dev/null +++ b/generator/konfig-generator-api/src/main/resources/python/test_check_url.handlebars @@ -0,0 +1,75 @@ +# coding: utf-8 + +{{>partial_header}} + +import unittest +from {{packageName}}.configuration import check_url +from {{packageName}}.exceptions import InvalidHostConfigurationError + + +class TestIsValidUrl(unittest.TestCase): + def test_valid_urls(self): + valid_urls = [ + "http://www.example.com", + "https://www.example.com", + "http://example.com", + "https://example.com/path/to/resource", + "http://example.com:8080", + "https://example.co.uk", + "https://subdomain.example.com", + "https://api.example.com/v1/resource", + "https://example.com/path/to/resource/123", + "https://www.example.com:8080", + "https://www.example.com:8080/path/to/resource", + "http://sub.example.com:8080", + "http://deep.sub.domain.example.com", + "http://127.0.0.1:4010", + "https://deep.sub.domain.example.com:8080/path", + "http://example.io", + "https://example.app", + ] + for url in valid_urls: + with self.subTest(url=url): + self.assertTrue(check_url(url)) + + def test_invalid_urls(self): + invalid_urls = [ + "not_a_url", + "http:/example.com", + "http://", + "http://.com", + "example.com", + "http://example.com#fragment", + "www.example.com", + "https://example.com/path/to/resource?query=value", + "https://example.com/path/to/resource?query=value&key2=value2", + "https://", + "ftp://files.example.com", + "//example.com", + "https://example,com", + "https:/example.com", + "https:// example.com", + "https://example.com path", + "http://..com", + "https://..example.com", + "http://example..com", + "https://example.com./path", + "https://example.com..", + "http://:8080", + "https://example.com:", + "http://example.com:abc", + "https://.example.com", + "http://example.", + "https:// example:8080.com", + "http:// example.com:8080/path", + "https://:8080/path", + ] + for url in invalid_urls: + with self.subTest(url=url): + with self.assertRaises(InvalidHostConfigurationError): + check_url(url) + raise Exception("URL should be invalid: " + url) + + +if __name__ == "__main__": + unittest.main() From 57da30a7f48bec0f6f45b43f62c0e2b76c60f6c8 Mon Sep 17 00:00:00 2001 From: dphuang2 Date: Mon, 30 Oct 2023 13:07:36 -0700 Subject: [PATCH 2/2] fix typo when generating test_check_url.py --- .../org/openapitools/codegen/languages/PythonClientCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index 2ae7557587..61198a5279 100644 --- a/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/generator/konfig-generator-api/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -442,7 +442,7 @@ public void processOpts() { } supportingFiles.add(new SupportingFile("test_simple." + templateExtension, testFolder, "test_simple.py")); - supportingFiles.add(new SupportingFile("test_check_url." + templateExtension, testFolder, "test_simple.py")); + supportingFiles.add(new SupportingFile("test_check_url." + templateExtension, testFolder, "test_check_url.py")); supportingFiles.add(new SupportingFile("test_deprecation_warning." + templateExtension, testFolder, "test_deprecation_warning.py")); supportingFiles.add(new SupportingFile("exceptions." + templateExtension, packagePath(), "exceptions.py"));