fix: Apply black formatting to resolve CI formatting issues
Some checks failed
CI / test (3.10) (push) Failing after 1m21s
CI / test (3.11) (push) Failing after 1m19s
CI / test (3.9) (push) Failing after 1m22s
CI / lint (push) Failing after 43s

This commit is contained in:
CI Bot
2026-02-06 07:56:02 +00:00
parent 123a4f7d1d
commit d369d3b1f8
8 changed files with 75 additions and 39 deletions

View File

@@ -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")

View File

@@ -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 ""

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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 ""

View File

@@ -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) + "}"

View File

@@ -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)

View File

@@ -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)