fix: Apply black formatting to resolve CI formatting issues
This commit is contained in:
@@ -238,7 +238,12 @@ def generate_all(
|
|||||||
|
|
||||||
@main.command("auth")
|
@main.command("auth")
|
||||||
@click.argument("scheme_name")
|
@click.argument("scheme_name")
|
||||||
@click.option("--type", "auth_type", type=click.Choice(["apiKey", "bearer", "basic"]), help="Authentication type")
|
@click.option(
|
||||||
|
"--type",
|
||||||
|
"auth_type",
|
||||||
|
type=click.Choice(["apiKey", "bearer", "basic"]),
|
||||||
|
help="Authentication type",
|
||||||
|
)
|
||||||
@click.option("--header", help="Header name for API key", default="X-API-Key")
|
@click.option("--header", help="Header name for API key", default="X-API-Key")
|
||||||
@click.option("--token", help="Bearer token or API key value")
|
@click.option("--token", help="Bearer token or API key value")
|
||||||
@click.option("--username", help="Username for Basic auth")
|
@click.option("--username", help="Username for Basic auth")
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from .exceptions import AuthConfigError, MissingSecuritySchemeError
|
|||||||
|
|
||||||
class AuthType(str, Enum):
|
class AuthType(str, Enum):
|
||||||
"""Types of authentication."""
|
"""Types of authentication."""
|
||||||
|
|
||||||
API_KEY = "apiKey"
|
API_KEY = "apiKey"
|
||||||
BEARER = "bearer"
|
BEARER = "bearer"
|
||||||
BASIC = "basic"
|
BASIC = "basic"
|
||||||
@@ -131,6 +132,7 @@ class AuthConfig:
|
|||||||
return {"Authorization": f"{method['token_prefix']} {method['token']}"}
|
return {"Authorization": f"{method['token_prefix']} {method['token']}"}
|
||||||
elif method["type"] == AuthType.BASIC:
|
elif method["type"] == AuthType.BASIC:
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
credentials = f"{method['username']}:{method['password']}"
|
credentials = f"{method['username']}:{method['password']}"
|
||||||
encoded = base64.b64encode(credentials.encode()).decode()
|
encoded = base64.b64encode(credentials.encode()).decode()
|
||||||
return {"Authorization": f"Basic {encoded}"}
|
return {"Authorization": f"Basic {encoded}"}
|
||||||
@@ -222,19 +224,19 @@ class AuthConfig:
|
|||||||
String containing pytest auth code.
|
String containing pytest auth code.
|
||||||
"""
|
"""
|
||||||
if method["type"] == AuthType.API_KEY:
|
if method["type"] == AuthType.API_KEY:
|
||||||
return f'''
|
return f"""
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def api_key_headers():
|
def api_key_headers():
|
||||||
return {{"{method['header_name']}": "{method['api_key']}"}}
|
return {{"{method['header_name']}": "{method['api_key']}"}}
|
||||||
'''
|
"""
|
||||||
elif method["type"] == AuthType.BEARER:
|
elif method["type"] == AuthType.BEARER:
|
||||||
return f'''
|
return f"""
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def bearer_headers():
|
def bearer_headers():
|
||||||
return {{"Authorization": "{method['token_prefix']} {method['token']}"}}
|
return {{"Authorization": "{method['token_prefix']} {method['token']}"}}
|
||||||
'''
|
"""
|
||||||
elif method["type"] == AuthType.BASIC:
|
elif method["type"] == AuthType.BASIC:
|
||||||
return f'''
|
return f"""
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -242,7 +244,7 @@ def basic_headers():
|
|||||||
credentials = f"{{"{method['username']}"}}:{{"{method['password']}"}}"
|
credentials = f"{{"{method['username']}"}}:{{"{method['password']}"}}"
|
||||||
encoded = base64.b64encode(credentials.encode()).decode()
|
encoded = base64.b64encode(credentials.encode()).decode()
|
||||||
return {{"Authorization": f"Basic {{encoded}}"}}
|
return {{"Authorization": f"Basic {{encoded}}"}}
|
||||||
'''
|
"""
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def _generate_jest_auth(self, method: Dict[str, Any]) -> str:
|
def _generate_jest_auth(self, method: Dict[str, Any]) -> str:
|
||||||
@@ -255,24 +257,24 @@ def basic_headers():
|
|||||||
String containing Jest auth code.
|
String containing Jest auth code.
|
||||||
"""
|
"""
|
||||||
if method["type"] == AuthType.API_KEY:
|
if method["type"] == AuthType.API_KEY:
|
||||||
return f'''
|
return f"""
|
||||||
const getApiKeyHeaders = () => ({{
|
const getApiKeyHeaders = () => ({{
|
||||||
"{method['header_name']}": process.env.API_KEY || "{method['api_key']}",
|
"{method['header_name']}": process.env.API_KEY || "{method['api_key']}",
|
||||||
}});
|
}});
|
||||||
'''
|
"""
|
||||||
elif method["type"] == AuthType.BEARER:
|
elif method["type"] == AuthType.BEARER:
|
||||||
return f'''
|
return f"""
|
||||||
const getBearerHeaders = () => ({{
|
const getBearerHeaders = () => ({{
|
||||||
Authorization: `${{process.env.TOKEN_PREFIX || "{method['token_prefix']}"}} ${{process.env.TOKEN || "{method['token']}"}}`,
|
Authorization: `${{process.env.TOKEN_PREFIX || "{method['token_prefix']}"}} ${{process.env.TOKEN || "{method['token']}"}}`,
|
||||||
}});
|
}});
|
||||||
'''
|
"""
|
||||||
elif method["type"] == AuthType.BASIC:
|
elif method["type"] == AuthType.BASIC:
|
||||||
return f'''
|
return f"""
|
||||||
const getBasicHeaders = () => {{
|
const getBasicHeaders = () => {{
|
||||||
const credentials = Buffer.from(`${{process.env.USERNAME || "{method['username']}"}}:${{process.env.PASSWORD || "{method['password']}"}}`).toString('base64');
|
const credentials = Buffer.from(`${{process.env.USERNAME || "{method['username']}"}}:${{process.env.PASSWORD || "{method['password']}"}}`).toString('base64');
|
||||||
return {{ Authorization: `Basic ${{credentials}}` }};
|
return {{ Authorization: `Basic ${{credentials}}` }};
|
||||||
}};
|
}};
|
||||||
'''
|
"""
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def _generate_go_auth(self, method: Dict[str, Any]) -> str:
|
def _generate_go_auth(self, method: Dict[str, Any]) -> str:
|
||||||
@@ -285,23 +287,23 @@ const getBasicHeaders = () => {{
|
|||||||
String containing Go auth code.
|
String containing Go auth code.
|
||||||
"""
|
"""
|
||||||
if method["type"] == AuthType.API_KEY:
|
if method["type"] == AuthType.API_KEY:
|
||||||
return f'''
|
return f"""
|
||||||
func getAPIKeyHeaders() map[string]string {{
|
func getAPIKeyHeaders() map[string]string {{
|
||||||
return map[string]string{{
|
return map[string]string{{
|
||||||
"{method['header_name']}": os.Getenv("API_KEY"),
|
"{method['header_name']}": os.Getenv("API_KEY"),
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
'''
|
"""
|
||||||
elif method["type"] == AuthType.BEARER:
|
elif method["type"] == AuthType.BEARER:
|
||||||
return '''
|
return """
|
||||||
func getBearerHeaders() map[string]string {
|
func getBearerHeaders() map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
"Authorization": fmt.Sprintf("%s %s", os.Getenv("TOKEN_PREFIX"), os.Getenv("TOKEN")),
|
"Authorization": fmt.Sprintf("%s %s", os.Getenv("TOKEN_PREFIX"), os.Getenv("TOKEN")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
"""
|
||||||
elif method["type"] == AuthType.BASIC:
|
elif method["type"] == AuthType.BASIC:
|
||||||
return '''
|
return """
|
||||||
func getBasicHeaders(username, password string) map[string]string {
|
func getBasicHeaders(username, password string) map[string]string {
|
||||||
auth := username + ":" + password
|
auth := username + ":" + password
|
||||||
encoded := base64.StdEncoding.EncodeToString([]byte(auth))
|
encoded := base64.StdEncoding.EncodeToString([]byte(auth))
|
||||||
@@ -309,5 +311,5 @@ func getBasicHeaders(username, password string) map[string]string {
|
|||||||
"Authorization": "Basic " + encoded,
|
"Authorization": "Basic " + encoded,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
"""
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -3,34 +3,41 @@
|
|||||||
|
|
||||||
class SpecParserError(Exception):
|
class SpecParserError(Exception):
|
||||||
"""Base exception for spec parser errors."""
|
"""Base exception for spec parser errors."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidOpenAPISpecError(SpecParserError):
|
class InvalidOpenAPISpecError(SpecParserError):
|
||||||
"""Raised when OpenAPI specification is invalid."""
|
"""Raised when OpenAPI specification is invalid."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UnsupportedVersionError(SpecParserError):
|
class UnsupportedVersionError(SpecParserError):
|
||||||
"""Raised when OpenAPI version is not supported."""
|
"""Raised when OpenAPI version is not supported."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AuthConfigError(Exception):
|
class AuthConfigError(Exception):
|
||||||
"""Base exception for auth configuration errors."""
|
"""Base exception for auth configuration errors."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MissingSecuritySchemeError(AuthConfigError):
|
class MissingSecuritySchemeError(AuthConfigError):
|
||||||
"""Raised when security scheme is not defined in spec."""
|
"""Raised when security scheme is not defined in spec."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GeneratorError(Exception):
|
class GeneratorError(Exception):
|
||||||
"""Base exception for generator errors."""
|
"""Base exception for generator errors."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TemplateRenderError(GeneratorError):
|
class TemplateRenderError(GeneratorError):
|
||||||
"""Raised when template rendering fails."""
|
"""Raised when template rendering fails."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ class SpecParser:
|
|||||||
raise InvalidOpenAPISpecError(f"Specification file not found: {self.spec_path}")
|
raise InvalidOpenAPISpecError(f"Specification file not found: {self.spec_path}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.spec_path, 'r', encoding='utf-8') as f:
|
with open(self.spec_path, "r", encoding="utf-8") as f:
|
||||||
if self.spec_path.suffix in ['.yaml', '.yml']:
|
if self.spec_path.suffix in [".yaml", ".yml"]:
|
||||||
return yaml.safe_load(f) or {}
|
return yaml.safe_load(f) or {}
|
||||||
elif self.spec_path.suffix == '.json':
|
elif self.spec_path.suffix == ".json":
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
else:
|
else:
|
||||||
return yaml.safe_load(f) or {}
|
return yaml.safe_load(f) or {}
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ class GoGenerator:
|
|||||||
|
|
||||||
return generated_files
|
return generated_files
|
||||||
|
|
||||||
def _group_endpoints_by_path(self, endpoints: List[Dict[str, Any]]) -> Dict[str, List[Dict[str, Any]]]:
|
def _group_endpoints_by_path(
|
||||||
|
self, endpoints: List[Dict[str, Any]]
|
||||||
|
) -> Dict[str, List[Dict[str, Any]]]:
|
||||||
"""Group endpoints by their path.
|
"""Group endpoints by their path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -133,7 +135,7 @@ class GoGenerator:
|
|||||||
test_name = self._generate_test_name(endpoint)
|
test_name = self._generate_test_name(endpoint)
|
||||||
params = self._generate_params(endpoint)
|
params = self._generate_params(endpoint)
|
||||||
|
|
||||||
test_code = f'''
|
test_code = f"""
|
||||||
func Test{test_name}(t *testing.T) {{
|
func Test{test_name}(t *testing.T) {{
|
||||||
client := &http.Client{{Timeout: 10 * time.Second}}
|
client := &http.Client{{Timeout: 10 * time.Second}}
|
||||||
url := baseURL + "{endpoint['path']}"
|
url := baseURL + "{endpoint['path']}"
|
||||||
@@ -162,7 +164,7 @@ func Test{test_name}(t *testing.T) {{
|
|||||||
t.Errorf("Expected status code in [200, 201, 204], got %d", resp.StatusCode)
|
t.Errorf("Expected status code in [200, 201, 204], got %d", resp.StatusCode)
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
'''
|
"""
|
||||||
return test_code
|
return test_code
|
||||||
|
|
||||||
def _generate_test_name(self, endpoint: Dict[str, Any]) -> str:
|
def _generate_test_name(self, endpoint: Dict[str, Any]) -> str:
|
||||||
@@ -200,7 +202,15 @@ func Test{test_name}(t *testing.T) {{
|
|||||||
|
|
||||||
if param["in"] == "path":
|
if param["in"] == "path":
|
||||||
params.append(f'{param_name} := "test_{param_name}"')
|
params.append(f'{param_name} := "test_{param_name}"')
|
||||||
params.append('url = strings.Replace(url, "' + '{' + param_name + '}' + '", ' + param_name + ', 1)')
|
params.append(
|
||||||
|
'url = strings.Replace(url, "'
|
||||||
|
+ "{"
|
||||||
|
+ param_name
|
||||||
|
+ "}"
|
||||||
|
+ '", '
|
||||||
|
+ param_name
|
||||||
|
+ ", 1)"
|
||||||
|
)
|
||||||
|
|
||||||
elif param["in"] == "query":
|
elif param["in"] == "query":
|
||||||
params.append(f'q := url.Values{{{param_name}: []string{{"test"}}}}')
|
params.append(f'q := url.Values{{{param_name}: []string{{"test"}}}}')
|
||||||
@@ -222,6 +232,14 @@ func Test{test_name}(t *testing.T) {{
|
|||||||
parts = []
|
parts = []
|
||||||
|
|
||||||
for param in path_params:
|
for param in path_params:
|
||||||
parts.append('strings.Replace(url, "' + '{' + param['name'] + '}' + '", "test_' + param['name'] + '", 1)')
|
parts.append(
|
||||||
|
'strings.Replace(url, "'
|
||||||
|
+ "{"
|
||||||
|
+ param["name"]
|
||||||
|
+ "}"
|
||||||
|
+ '", "test_'
|
||||||
|
+ param["name"]
|
||||||
|
+ '", 1)'
|
||||||
|
)
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ class JestGenerator:
|
|||||||
self.output_dir = Path(output_dir)
|
self.output_dir = Path(output_dir)
|
||||||
self.mock_server_url = mock_server_url
|
self.mock_server_url = mock_server_url
|
||||||
self.env = Environment(
|
self.env = Environment(
|
||||||
loader=FileSystemLoader(str(Path(__file__).parent.parent.parent / "templates" / "jest")),
|
loader=FileSystemLoader(
|
||||||
|
str(Path(__file__).parent.parent.parent / "templates" / "jest")
|
||||||
|
),
|
||||||
trim_blocks=True,
|
trim_blocks=True,
|
||||||
lstrip_blocks=True,
|
lstrip_blocks=True,
|
||||||
)
|
)
|
||||||
@@ -113,7 +115,7 @@ class JestGenerator:
|
|||||||
endpoint_path = endpoint["path"]
|
endpoint_path = endpoint["path"]
|
||||||
endpoint_method = endpoint["method"]
|
endpoint_method = endpoint["method"]
|
||||||
|
|
||||||
test_code = f'''
|
test_code = f"""
|
||||||
describe('{describe_name}', () => {{
|
describe('{describe_name}', () => {{
|
||||||
it('should {endpoint_method.upper()} {endpoint_path}', async () => {{
|
it('should {endpoint_method.upper()} {endpoint_path}', async () => {{
|
||||||
const response = await request(baseUrl)
|
const response = await request(baseUrl)
|
||||||
@@ -122,7 +124,7 @@ describe('{describe_name}', () => {{
|
|||||||
expect([200, 201, 204]).toContain(response.status);
|
expect([200, 201, 204]).toContain(response.status);
|
||||||
}});
|
}});
|
||||||
}});
|
}});
|
||||||
'''
|
"""
|
||||||
return test_code
|
return test_code
|
||||||
|
|
||||||
def _generate_test_name(self, endpoint: Dict[str, Any]) -> str:
|
def _generate_test_name(self, endpoint: Dict[str, Any]) -> str:
|
||||||
@@ -161,7 +163,7 @@ describe('{describe_name}', () => {{
|
|||||||
parts.append(f'{param_name}="test_{param_name}"')
|
parts.append(f'{param_name}="test_{param_name}"')
|
||||||
|
|
||||||
elif param["in"] == "query":
|
elif param["in"] == "query":
|
||||||
parts.append(f'{param_name}')
|
parts.append(f"{param_name}")
|
||||||
|
|
||||||
if parts:
|
if parts:
|
||||||
return ", {" + ", ".join(parts) + "}"
|
return ", {" + ", ".join(parts) + "}"
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ class PytestGenerator:
|
|||||||
self.output_dir = Path(output_dir)
|
self.output_dir = Path(output_dir)
|
||||||
self.mock_server_url = mock_server_url
|
self.mock_server_url = mock_server_url
|
||||||
self.env = Environment(
|
self.env = Environment(
|
||||||
loader=FileSystemLoader(str(Path(__file__).parent.parent.parent / "templates" / "pytest")),
|
loader=FileSystemLoader(
|
||||||
|
str(Path(__file__).parent.parent.parent / "templates" / "pytest")
|
||||||
|
),
|
||||||
trim_blocks=True,
|
trim_blocks=True,
|
||||||
lstrip_blocks=True,
|
lstrip_blocks=True,
|
||||||
)
|
)
|
||||||
@@ -160,7 +162,7 @@ def test_{test_name}(base_url, {params}):
|
|||||||
params.append(f'{param_name}="test_{param_name}"')
|
params.append(f'{param_name}="test_{param_name}"')
|
||||||
|
|
||||||
elif param["in"] == "query":
|
elif param["in"] == "query":
|
||||||
params.append(f'{param_name}=None')
|
params.append(f"{param_name}=None")
|
||||||
|
|
||||||
return ", ".join(params)
|
return ", ".join(params)
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class MockServerGenerator:
|
|||||||
|
|
||||||
spec_info = self.spec_parser.get_info()
|
spec_info = self.spec_parser.get_info()
|
||||||
|
|
||||||
compose_content = f'''version: '3.8'
|
compose_content = f"""version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mock-server:
|
mock-server:
|
||||||
@@ -147,7 +147,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./:/app
|
- ./:/app
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
'''
|
"""
|
||||||
|
|
||||||
output_path.write_text(compose_content)
|
output_path.write_text(compose_content)
|
||||||
return output_path
|
return output_path
|
||||||
@@ -168,7 +168,7 @@ services:
|
|||||||
|
|
||||||
spec_info = self.spec_parser.get_info()
|
spec_info = self.spec_parser.get_info()
|
||||||
|
|
||||||
dockerfile_content = f'''FROM stoplight/prism:latest
|
dockerfile_content = f"""FROM stoplight/prism:latest
|
||||||
|
|
||||||
LABEL maintainer="developer@example.com"
|
LABEL maintainer="developer@example.com"
|
||||||
LABEL description="Mock server for {spec_info['title']} API"
|
LABEL description="Mock server for {spec_info['title']} API"
|
||||||
@@ -180,7 +180,7 @@ COPY openapi.yaml .
|
|||||||
EXPOSE {self.DEFAULT_PORT}
|
EXPOSE {self.DEFAULT_PORT}
|
||||||
|
|
||||||
CMD ["mock", "--spec", "openapi.yaml", "--port", "{self.DEFAULT_PORT}", "--host", "0.0.0.0"]
|
CMD ["mock", "--spec", "openapi.yaml", "--port", "{self.DEFAULT_PORT}", "--host", "0.0.0.0"]
|
||||||
'''
|
"""
|
||||||
|
|
||||||
output_path.write_text(dockerfile_content)
|
output_path.write_text(dockerfile_content)
|
||||||
return output_path
|
return output_path
|
||||||
@@ -199,7 +199,7 @@ CMD ["mock", "--spec", "openapi.yaml", "--port", "{self.DEFAULT_PORT}", "--host"
|
|||||||
else:
|
else:
|
||||||
output_path = self.output_dir / "start-mock-server.sh"
|
output_path = self.output_dir / "start-mock-server.sh"
|
||||||
|
|
||||||
script_content = f'''#!/bin/bash
|
script_content = f"""#!/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ docker compose up -d mock-server
|
|||||||
|
|
||||||
echo "Mock server started successfully!"
|
echo "Mock server started successfully!"
|
||||||
echo "To stop: docker compose down"
|
echo "To stop: docker compose down"
|
||||||
'''
|
"""
|
||||||
|
|
||||||
output_path.write_text(script_content)
|
output_path.write_text(script_content)
|
||||||
output_path.chmod(0o755)
|
output_path.chmod(0o755)
|
||||||
|
|||||||
Reference in New Issue
Block a user