From a2b543beb0e36b8ff533529bbddb602279a719ab Mon Sep 17 00:00:00 2001 From: Erik Rose Date: Tue, 24 Mar 2026 12:59:15 -0400 Subject: [PATCH] Convert Google-style docstrings to Sphinx format. Refs #60. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Standardize on ":arg", which is shorter than ":param". * Standardize on ":return" and ":raise" which are more in line with PEP 257's "don’t write “Returns the pathname …”" admonition. --- examples/backend-requests/backend-requests.py | 4 +- fastly_compute/config_store.py | 24 +++--- fastly_compute/log.py | 22 ++--- fastly_compute/requests/__init__.py | 84 +++++++++---------- fastly_compute/requests/backend.py | 17 ++-- fastly_compute/requests/exceptions.py | 38 ++++----- fastly_compute/requests/response.py | 21 ++--- fastly_compute/requests/timeout.py | 24 ++---- fastly_compute/test_server.py | 34 ++++---- fastly_compute/testing.py | 68 ++++++--------- fastly_compute/tests/test_backend_requests.py | 15 +--- fastly_compute/tests/test_log.py | 24 ++---- fastly_compute/utils.py | 10 +-- fastly_compute/wsgi.py | 15 ++-- 14 files changed, 168 insertions(+), 232 deletions(-) diff --git a/examples/backend-requests/backend-requests.py b/examples/backend-requests/backend-requests.py index 2cb2200..6e92cb3 100644 --- a/examples/backend-requests/backend-requests.py +++ b/examples/backend-requests/backend-requests.py @@ -16,9 +16,7 @@ def _map_error(e: Exception): """Return a standardized error response. - Args: - e: The exception that occurred - demo: The demo/endpoint name for this error + :arg e: The exception that occurred """ return { "error": repr(e), diff --git a/fastly_compute/config_store.py b/fastly_compute/config_store.py index 5c31135..335154d 100644 --- a/fastly_compute/config_store.py +++ b/fastly_compute/config_store.py @@ -41,11 +41,11 @@ def __init__(self, store: wit_config_store.Store): def open(cls, name: str) -> Self: """Open a config store by name. - :param name: The name of the config store + :arg name: The name of the config store :return: ConfigStore instance - :raises ~fastly_compute.exceptions.types.open_error.NotFound: If the config store doesn't exist - :raises ~fastly_compute.exceptions.types.open_error.InvalidSyntax: If the name is invalid - :raises ~fastly_compute.exceptions.types.open_error.NameTooLong: If the name is too long + :raise ~fastly_compute.exceptions.types.open_error.NotFound: If the config store doesn't exist + :raise ~fastly_compute.exceptions.types.open_error.InvalidSyntax: If the name is invalid + :raise ~fastly_compute.exceptions.types.open_error.NameTooLong: If the name is too long Example:: @@ -57,10 +57,10 @@ def open(cls, name: str) -> Self: def get(self, key: str, default: str | None = None) -> str | None: """Get a configuration value. - :param key: The configuration key - :param default: Default value if key not found + :arg key: The configuration key + :arg default: Default value if key not found :return: Configuration value or default if not found - :raises ~fastly_compute.exceptions.types.error.InvalidArgument: If the key is invalid + :raise ~fastly_compute.exceptions.types.error.InvalidArgument: If the key is invalid Example:: @@ -76,10 +76,10 @@ def get(self, key: str, default: str | None = None) -> str | None: def __contains__(self, key: str) -> bool: """Check if a key exists in the config store. - :param key: The configuration key + :arg key: The configuration key :return: True if the key exists, False otherwise - :raises ~fastly_compute.exceptions.types.error.InvalidArgument: If the key is invalid - :raises KeyError: If the key is not a str + :raise ~fastly_compute.exceptions.types.error.InvalidArgument: If the key is invalid + :raise KeyError: If the key is not a str Example:: @@ -98,8 +98,8 @@ def close(self) -> None: manager. If not called explicitly, resources will eventually be freed by the garbage collector. - Note: Attempting to use the config store after it is closed will result - in a trap. + .. note:: Attempting to use the config store after it is closed will result + in a trap. """ self._store.__exit__(None, None, None) diff --git a/fastly_compute/log.py b/fastly_compute/log.py index a550a23..e4f9bc2 100644 --- a/fastly_compute/log.py +++ b/fastly_compute/log.py @@ -60,11 +60,11 @@ def open(cls, name: str) -> Self: - It must not contain newlines (\n) or colons (:). - It must not be `stdout` or `stderr`, which are reserved for debugging. - :param name: The name of the logging endpoint + :arg name: The name of the logging endpoint :return: LogEndpoint instance - :raises ~fastly_compute.exceptions.types.open_error.NotFound: If the endpoint doesn't exist or can't be created. - :raises ~fastly_compute.exceptions.types.open_error.NameTooLong: If the name is too long. - :raises ~fastly_compute.exceptions.types.open_error.InvalidSyntax: If the name is invalid. + :raise ~fastly_compute.exceptions.types.open_error.NotFound: If the endpoint doesn't exist or can't be created. + :raise ~fastly_compute.exceptions.types.open_error.NameTooLong: If the name is too long. + :raise ~fastly_compute.exceptions.types.open_error.InvalidSyntax: If the name is invalid. Example:: @@ -78,7 +78,7 @@ def write(self, msg: bytes | str) -> None: Each call to write() with a non-empty message produces a single log event. - :param msg: The message to write (bytes or string). Strings are UTF-8 encoded. + :arg msg: The message to write (bytes or string). Strings are UTF-8 encoded. Example:: @@ -169,11 +169,11 @@ def __init__( ): """Initialize the handler. - :param default_endpoint: The default endpoint name (used when no mapper provided) - :param endpoint_mapper: Optional callable that maps logger name to endpoint name. + :arg default_endpoint: The default endpoint name (used when no mapper provided) + :arg endpoint_mapper: Optional callable that maps logger name to endpoint name. Signature: (logger_name: str) -> endpoint_name: str - :param level: Minimum logging level to handle (default: NOTSET) - :raises ValueError: If neither default_endpoint nor endpoint_mapper is provided + :arg level: Minimum logging level to handle (default: NOTSET) + :raise ValueError: If neither default_endpoint nor endpoint_mapper is provided Example:: @@ -205,7 +205,7 @@ def __init__( def _get_endpoint(self, logger_name: str) -> LogEndpoint: """Get or create an endpoint for the given logger name. - :param logger_name: Name of the logger + :arg logger_name: Name of the logger :return: LogEndpoint instance """ # Determine which endpoint to use @@ -242,7 +242,7 @@ def emit(self, record: logging.LogRecord): The endpoint is determined by calling endpoint_mapper with the logger name, or using the default_endpoint. - :param record: The log record to emit + :arg record: The log record to emit """ try: endpoint = self._get_endpoint(record.name) diff --git a/fastly_compute/requests/__init__.py b/fastly_compute/requests/__init__.py index 784cd8e..2498b93 100644 --- a/fastly_compute/requests/__init__.py +++ b/fastly_compute/requests/__init__.py @@ -100,27 +100,23 @@ def get( ) -> FastlyResponse: """Send a GET request. - Args: - url: URL for the request. Can be a path (for static backends) or full URL (for dynamic) - params: Query parameters to append to the URL - headers: HTTP headers to send with the request - fastly_backend: Static backend name (optional, will use dynamic backend if not provided) - timeout: Request timeout in seconds (requests-compatible). Can be: - - float: Single timeout for all phases - - (connect, read): Tuple for connect and read timeouts - fastly_timeout: **Fastly-only** Advanced timeout configuration with granular control - over connect_timeout, first_byte_timeout, and between_bytes_timeout - **kwargs: Additional arguments (for requests compatibility, ignored) - - Note: - The fastly_timeout parameter is Fastly-specific and will cause a TypeError - if used with the standard requests library. Use timeout for cross-platform compatibility. - - Raises: - RequestException: For general request errors - ConnectionError: For connection-related errors - Timeout: For timeout errors - ValueError: If both timeout and fastly_timeout are specified + :arg url: URL for the request. Can be a path (for static backends) or full URL (for dynamic) + :arg params: Query parameters to append to the URL + :arg headers: HTTP headers to send with the request + :arg fastly_backend: Static backend name (optional, will use dynamic backend if not provided) + :arg timeout: Request timeout in seconds (requests-compatible). Can be: + - ``float``: Single timeout for all phases + - ``(connect, read)``: Tuple for connect and read timeouts + :arg fastly_timeout: **Fastly-only** Advanced timeout configuration with granular control + over connect_timeout, first_byte_timeout, and between_bytes_timeout + + .. note:: The fastly_timeout parameter is Fastly-specific and will cause a TypeError + if used with the standard requests library. Use ``timeout`` for cross-platform compatibility. + :arg kwargs: Additional arguments (for requests compatibility, ignored) + :raise RequestException: For general request errors + :raise ConnectionError: For connection-related errors + :raise Timeout: For timeout errors + :raise ValueError: If both timeout and fastly_timeout are specified """ return request("GET", url, **kwargs) @@ -131,16 +127,15 @@ def post( ) -> FastlyResponse: """Send a POST request. - Args: - url: URL for the request - data: Form data to send in the body - json: JSON data to send in the body (mutually exclusive with data) - params: Query parameters to append to the URL - headers: HTTP headers to send with the request - fastly_backend: Static backend name (optional) - timeout: Request timeout in seconds (requests-compatible) - fastly_timeout: **Fastly-only** Advanced timeout configuration - **kwargs: Additional arguments (for requests compatibility, ignored) + :arg url: URL for the request + :arg data: Form data to send in the body + :arg json: JSON data to send in the body (mutually exclusive with data) + :arg params: Query parameters to append to the URL + :arg headers: HTTP headers to send with the request + :arg fastly_backend: Static backend name (optional) + :arg timeout: Request timeout in seconds (requests-compatible) + :arg fastly_timeout: **Fastly-only** Advanced timeout configuration + :arg kwargs: Additional arguments (for requests compatibility, ignored) """ return request("POST", url, **kwargs) @@ -193,21 +188,18 @@ def request( ) -> FastlyResponse: """Send an HTTP request. - Args: - method: HTTP method (GET, POST, PUT, DELETE, etc.) - url: URL for the request - params: Query parameters - data: Form data for the request body - json: JSON data for the request body (mutually exclusive with data) - headers: HTTP headers - fastly_backend: Static backend name (if not provided, will use dynamic backend) - timeout: Request timeout in seconds (requests-compatible) - fastly_timeout: **Fastly-only** Advanced timeout configuration - **kwargs: Additional arguments (for requests compatibility, ignored) - - Raises: - RequestException: For general request errors - ValueError: For invalid arguments + :arg method: HTTP method (GET, POST, PUT, DELETE, etc.) + :arg url: URL for the request + :arg params: Query parameters + :arg data: Form data for the request body + :arg json: JSON data for the request body (mutually exclusive with data) + :arg headers: HTTP headers + :arg fastly_backend: Static backend name (if not provided, will use dynamic backend) + :arg timeout: Request timeout in seconds (requests-compatible) + :arg fastly_timeout: **Fastly-only** Advanced timeout configuration + :arg kwargs: Additional arguments (for requests compatibility, ignored) + :raise RequestException: For general request errors + :raise ValueError: For invalid arguments """ # Validate arguments if data is not None and json is not None: diff --git a/fastly_compute/requests/backend.py b/fastly_compute/requests/backend.py index 5567946..b9df09f 100644 --- a/fastly_compute/requests/backend.py +++ b/fastly_compute/requests/backend.py @@ -46,17 +46,12 @@ def resolve_backend( Static backends must already be configured in the Fastly service. Dynamic backends are automatically registered on first use and cached for reuse. - Args: - url: The URL to request (must be full with scheme and netloc for dynamic backends) - fastly_backend: Optional static backend name - timeout_config: Optional timeout configuration for dynamic backends - - Returns: - ResolutionResult containing backend and updated parsed url - - Raises: - RequestException: If backend resolution fails - MissingSchema: If URL is missing scheme (subclass of RequestException) + :arg url: The URL to request (must be full with scheme and netloc for dynamic backends) + :arg fastly_backend: Optional static backend name + :arg timeout_config: Optional timeout configuration for dynamic backends + :return: ResolutionResult containing backend and updated parsed url + :raise RequestException: If backend resolution fails + :raise MissingSchema: If URL is missing scheme (subclass of RequestException) """ parsed = urllib.parse.urlparse(url) backend_obj: wit_backend.Backend diff --git a/fastly_compute/requests/exceptions.py b/fastly_compute/requests/exceptions.py index e8332bb..1e4fdd4 100644 --- a/fastly_compute/requests/exceptions.py +++ b/fastly_compute/requests/exceptions.py @@ -33,14 +33,11 @@ def _map_error_to_exception( ) -> RequestException: """Map WIT error to appropriate RequestException subclass. - Args: - error: The WIT error object to map - mapping: Mapping from error types to exception classes - operation: Description of operation that failed - fallback_cls: Exception class to use if no mapping found - - Returns: - Appropriate RequestException subclass instance + :arg error: The WIT error object to map + :arg mapping: Mapping from error types to exception classes + :arg operation: Description of operation that failed + :arg fallback_cls: Exception class to use if no mapping found + :return: Appropriate RequestException subclass instance """ error_type = type(error) exc_cls = mapping.get(error_type, fallback_cls) @@ -58,10 +55,9 @@ def __init__( ) -> None: """Initialize RequestException. - Args: - message: Error message - response: Optional response object that caused the error - request: Optional request object that caused the error + :arg message: Error message + :arg response: Optional response object that caused the error + :arg request: Optional request object that caused the error """ super().__init__(message) self.response: FastlyResponse | None = response @@ -73,12 +69,9 @@ def from_detailed_error( ) -> RequestException: """Create a ``requests`` exception from an ErrorWithDetail. - Args: - err: The error to map from - operation: Description of what operation failed - - Returns: - Appropriate RequestException subclass instance + :arg err: The error to map from + :arg operation: Description of what operation failed + :return: Appropriate RequestException subclass instance """ error_with_detail = err.args[0] @@ -104,12 +97,9 @@ def from_detailed_error( def from_fastly_error(cls, err: FastlyError, operation: str) -> RequestException: """Create a ``requests`` exception from a FastlyError or subclass. - Args: - err: The error to map from - operation: Description of what operation failed - - Returns: - Appropriate RequestException subclass instance + :arg err: The error to map from + :arg operation: Description of what operation failed + :return: Appropriate RequestException subclass instance """ return _map_error_to_exception( err, diff --git a/fastly_compute/requests/response.py b/fastly_compute/requests/response.py index 04deb91..9f82874 100644 --- a/fastly_compute/requests/response.py +++ b/fastly_compute/requests/response.py @@ -25,10 +25,9 @@ def __init__( ): """Initialize FastlyResponse. - Args: - wit_response: The WIT response object - response_body: The WIT response body - url: The final URL that was requested + :arg wit_response: The WIT response object + :arg response_body: The WIT response body + :arg url: The final URL that was requested """ self._wit_response: http_resp.Response = wit_response self._response_body: async_io.Pollable = response_body @@ -109,14 +108,9 @@ def text(self) -> str: def json(self, **kwargs: Any) -> Any: """Parse response body as JSON. - Args: - **kwargs: Additional arguments passed to json.loads() - - Returns: - Parsed JSON data - - Raises: - json.JSONDecodeError: If response is not valid JSON + :arg kwargs: Additional arguments passed to json.loads() + :return: Parsed JSON data + :raise json.JSONDecodeError: If response is not valid JSON """ if self._json_data is None: self._json_data = json.loads(self.text, **kwargs) @@ -140,8 +134,7 @@ def is_permanent_redirect(self) -> bool: def raise_for_status(self) -> None: """Raise an HTTPError for bad responses. - Raises: - HTTPError: If response status indicates an error + :raise HTTPError: If response status indicates an error """ if not self.ok: raise HTTPError( diff --git a/fastly_compute/requests/timeout.py b/fastly_compute/requests/timeout.py index 0ed5a47..ccd64b5 100644 --- a/fastly_compute/requests/timeout.py +++ b/fastly_compute/requests/timeout.py @@ -27,10 +27,9 @@ def __init__( ): """Initialize timeout configuration. - Args: - connect: Connection timeout in seconds (default: 30.0) - first_byte: First byte timeout in seconds (default: 60.0) - between_bytes: Between bytes timeout in seconds (default: 10.0) + :arg connect: Connection timeout in seconds (default: 30.0) + :arg first_byte: First byte timeout in seconds (default: 60.0) + :arg between_bytes: Between bytes timeout in seconds (default: 10.0) """ self.connect: float = connect self.first_byte: float = first_byte @@ -55,17 +54,12 @@ def between_bytes_ms(self) -> int: def from_requests_timeout(cls, timeout: None | float | tuple[float, float]) -> Self: """Create TimeoutConfig from requests-compatible timeout parameter. - Args: - timeout: Timeout specification in requests-compatible formats: - - None: Use default timeouts - - float: Single timeout applied to all phases - - (connect, read): Tuple with separate connect and read timeouts - - Returns: - TimeoutConfig object with appropriate timeout values - - Raises: - ValueError: If timeout format is invalid + :arg timeout: Timeout specification in requests-compatible formats: + - ``None``: Use default timeouts + - ``float``: Single timeout applied to all phases + - ``(connect, read)``: Tuple with separate connect and read timeouts + :return: TimeoutConfig object with appropriate timeout values + :raise ValueError: If timeout format is invalid """ if timeout is None: return cls() diff --git a/fastly_compute/test_server.py b/fastly_compute/test_server.py index 9d831e1..89defb5 100644 --- a/fastly_compute/test_server.py +++ b/fastly_compute/test_server.py @@ -114,11 +114,8 @@ def make_test_request_handler( ) -> type[BaseHTTPRequestHandler]: """Create a request handler class with configured responses. - Args: - responses: Dictionary mapping paths to response configurations - - Returns: - A new handler class with responses bound as a class attribute + :arg responses: Dictionary mapping paths to response configurations + :return: A new handler class with responses bound as a class attribute """ # Create a new class that inherits from our base handler # and sets the responses as a class attribute @@ -144,15 +141,21 @@ def __init__( ): """Initialize the test server. - Args: - host: The host interface to bind to (default: "127.0.0.1") - port: The port to bind to (default: 0 for auto-assignment) - responses: Optional dict mapping paths to response configs. - Each response config can contain: - - "status": HTTP status code (default: 200) - - "headers": Dict of HTTP headers - - "body": Response body (dict will be JSON-encoded) - Example: {"/api/test": {"status": 200, "body": {"success": True}}} + :arg host: The host interface to bind to (default: "127.0.0.1") + :arg port: The port to bind to (default: 0 for auto-assignment) + :arg responses: Optional dict mapping paths to response configs. + Each response config can contain... + + "status" + HTTP status code (default: 200) + "headers" + Dict of HTTP headers + "body" + Response body (dict will be JSON-encoded) + + Example:: + + {"/api/test": {"status": 200, "body": {"success": True}}} """ self.host = host self.port = port @@ -163,8 +166,7 @@ def __init__( def start(self) -> str: """Start the test server. - Returns: - The base URL of the started server (e.g., "http://127.0.0.1:12345") + :return: The base URL of the started server (e.g., "http://127.0.0.1:12345") """ if self._server is not None: raise RuntimeError("Server is already running") diff --git a/fastly_compute/testing.py b/fastly_compute/testing.py index ec5e6b2..b6bbfad 100644 --- a/fastly_compute/testing.py +++ b/fastly_compute/testing.py @@ -45,11 +45,11 @@ class ViceroyTestBase: Provides common functionality for testing Fastly Compute services. Inherit from this class and use the viceroy_server fixture. - Note: This assumes your WASM file is already built. Use your build system - (e.g., Makefile) to ensure the WASM file is up to date before running tests. + .. note:: This assumes your WASM file is already built. Use your build system + (e.g., Makefile) to ensure the WASM file is up to date before running tests. + + Example:: - Example: - ```python import pytest from fastly_compute.testing import ViceroyTestBase @@ -57,7 +57,6 @@ class TestMyService(ViceroyTestBase): def test_my_endpoint(self): response = self.get("/my-endpoint") assert response.status_code == 200 - ``` """ REQUEST_TIMEOUT = 10 @@ -86,12 +85,9 @@ def _find_free_port() -> int: def _create_viceroy_config(cls, backends: dict[str, str] | None = None) -> str: """Create a temporary viceroy configuration file. - Args: - backends: Dict mapping backend names to URLs - e.g., {"httpbin": "http://127.0.0.1:8080"} - - Returns: - Path to the temporary configuration file + :arg backends: Dict mapping backend names to URLs + e.g., {"httpbin": "http://127.0.0.1:8080"} + :return: Path to the temporary configuration file """ config_dict = {} @@ -132,9 +128,8 @@ def set_up_backends(cls, backends: dict[str, str]): Call this in setUpClass or as a class-level setup. - Args: - backends: Dict mapping backend names to URLs - e.g., {"httpbin": "http://127.0.0.1:8080"} + :arg backends: Dict mapping backend names to URLs + e.g., {"httpbin": "http://127.0.0.1:8080"} """ cls._test_backends = backends @@ -143,11 +138,10 @@ def set_up_backends(cls, backends: dict[str, str]): def viceroy_server(cls): """Start viceroy server for the duration of the test class. - Note: This assumes the WASM file already exists. Use your build system - to ensure it's built before running tests. + .. note:: This assumes the WASM file already exists. Use your build system + to ensure it's built before running tests. - Returns: - ViceroyServer: Server instance with process, base_url, and captured output + :return: Server instance with process, base_url, and captured output """ print("Starting viceroy server...") @@ -273,12 +267,9 @@ def capture_output_thread(): def get(cls, path: str, **kwargs) -> requests.Response: """Make a GET request to the viceroy server. - Args: - path: URL path to request - **kwargs: Additional arguments passed to requests.get() - - Returns: - requests.Response: The HTTP response + :arg path: URL path to request + :arg kwargs: Additional arguments passed to requests.get() + :return: The HTTP response """ return cls.request("GET", path, **kwargs) @@ -286,12 +277,9 @@ def get(cls, path: str, **kwargs) -> requests.Response: def post(cls, path: str, **kwargs) -> requests.Response: """Make a POST request to the viceroy server. - Args: - path: URL path to request - **kwargs: Additional arguments passed to requests.post() - - Returns: - requests.Response: The HTTP response + :arg path: URL path to request + :arg kwargs: Additional arguments passed to requests.post() + :return: The HTTP response """ return cls.request("POST", path, **kwargs) @@ -299,13 +287,10 @@ def post(cls, path: str, **kwargs) -> requests.Response: def request(cls, method: str, path: str, **kwargs) -> requests.Response: """Make an HTTP request to the viceroy server. - Args: - method: HTTP method (GET, POST, PUT, DELETE, etc.) - path: URL path to request - **kwargs: Additional arguments passed to requests.request() - - Returns: - requests.Response: The HTTP response + :arg method: HTTP method (GET, POST, PUT, DELETE, etc.) + :arg path: URL path to request + :arg kwargs: Additional arguments passed to requests.request() + :return: The HTTP response """ timeout = kwargs.pop("timeout", cls.REQUEST_TIMEOUT) response = requests.request( @@ -462,10 +447,11 @@ def on_viceroy(method) -> classmethod: Decorate a method with this, and it will automagically run under Viceroy when called. The method must be in a subclass of AutoViceroyTestBase. - Notes and caveats: - * Return values and raised exceptions must be pickleable. - * If the decorated method is not already a class method, we make it one, in - service to conciseness. + .. note:: + + * Return values and raised exceptions must be pickleable. + * If the decorated method is not already a class method, we make it one, in + service to conciseness. """ # TODO: Complain if the decorated method isn't in a subclass of AutoViceroyTestBase. diff --git a/fastly_compute/tests/test_backend_requests.py b/fastly_compute/tests/test_backend_requests.py index a146122..fc8ec95 100644 --- a/fastly_compute/tests/test_backend_requests.py +++ b/fastly_compute/tests/test_backend_requests.py @@ -16,12 +16,7 @@ class BackendRequestsTestBase(ViceroyTestBase): WASM_FILE = "build/backend-requests.composed.wasm" def assert_success(self, response: requests.Response) -> dict[str, Any]: - """Assert that a result represents a successful operation. - - Args: - result: Response JSON dictionary - expected_demo: Expected value of 'demo' field - """ + """Assert that a response represents a successful operation.""" # request to helper service succeeded (non-proxy) assert response.status_code == 200 @@ -42,15 +37,13 @@ def assert_success(self, response: requests.Response) -> dict[str, Any]: def assert_error( self, response: requests.Response, error_substring: str | None = None ) -> dict[str, Any]: - """Assert that a result represents an error. + """Assert that a response represents an error. The return dictionary is the transformed error, with the traceback information removed (which is too noisy to compare against). - Args: - result: Response JSON dictionary - expected_demo: Expected value of 'demo' field - error_substring: Optional substring that should appear in error message + :arg response: Response about which to assert + :arg error_substring: Optional substring that should appear in error message """ result: dict[str, Any] = response.json() error = result.get("error") diff --git a/fastly_compute/tests/test_log.py b/fastly_compute/tests/test_log.py index 784ff9f..86307ab 100644 --- a/fastly_compute/tests/test_log.py +++ b/fastly_compute/tests/test_log.py @@ -26,11 +26,8 @@ class TestLogging(AutoViceroyTestBase): def _get_logs_for_endpoint(self, endpoint_name): """Get all log messages for a specific endpoint from viceroy output. - Args: - endpoint_name: Name of the log endpoint - - Returns: - List of log messages (without the endpoint prefix) + :arg endpoint_name: Name of the log endpoint + :return: List of log messages (without the endpoint prefix) """ log_prefix = f"{endpoint_name} :: " logs = [] @@ -43,9 +40,8 @@ def _get_logs_for_endpoint(self, endpoint_name): def assert_log_message(self, endpoint_name, expected_message): """Assert that an exact log message was written to viceroy stdout. - Args: - endpoint_name: Name of the log endpoint - expected_message: Exact message expected + :arg endpoint_name: Name of the log endpoint + :arg expected_message: Exact message expected """ logs = self._get_logs_for_endpoint(endpoint_name) @@ -64,9 +60,8 @@ def assert_log_message(self, endpoint_name, expected_message): def assert_log_matches(self, endpoint_name, pattern): """Assert that a log message matching the pattern was written to viceroy stdout. - Args: - endpoint_name: Name of the log endpoint - pattern: Regex pattern to match + :arg endpoint_name: Name of the log endpoint + :arg pattern: Regex pattern to match """ logs = self._get_logs_for_endpoint(endpoint_name) @@ -86,10 +81,9 @@ def assert_log_matches(self, endpoint_name, pattern): def assert_log_count(self, endpoint_name, expected_count, pattern=None): """Assert that a specific number of log messages were written. - Args: - endpoint_name: Name of the log endpoint - expected_count: Expected number of log messages - pattern: Optional regex pattern to filter logs + :arg endpoint_name: Name of the log endpoint + :arg expected_count: Expected number of log messages + :arg pattern: Optional regex pattern to filter logs """ logs = self._get_logs_for_endpoint(endpoint_name) diff --git a/fastly_compute/utils.py b/fastly_compute/utils.py index acb6641..63f98a0 100644 --- a/fastly_compute/utils.py +++ b/fastly_compute/utils.py @@ -15,8 +15,8 @@ class _RawBodyReader(RawIOBase): def __init__(self, body_handle: async_io.Pollable, chunk_size: int = 4096): """Initialize the reader. - :param body_handle: Fastly HTTP body handle to read from - :param chunk_size: Size of chunks to read at a time (default: 4096) + :arg body_handle: Fastly HTTP body handle to read from + :arg chunk_size: Size of chunks to read at a time (default: 4096) """ self._body = body_handle self._chunk_size = chunk_size @@ -32,7 +32,7 @@ def readable(self) -> bool: def readinto(self, b) -> int: """Read up to len(b) bytes into writable buffer b. - :param b: Writable buffer to read into + :arg b: Writable buffer to read into :return: Number of bytes read, or 0 on EOF """ if self._closed: @@ -65,8 +65,8 @@ def create_body_reader( readlines(), and iteration. Note that seeking is not supported as the body is a forward-only stream. - :param body: Fastly HTTP body handle to read from - :param chunk_size: Size of chunks to read at a time (default: 4096) + :arg body: Fastly HTTP body handle to read from + :arg chunk_size: Size of chunks to read at a time (default: 4096) :return: A BufferedReader that streams the body content (WSGI compatible) Example:: diff --git a/fastly_compute/wsgi.py b/fastly_compute/wsgi.py index cca949b..ead6900 100644 --- a/fastly_compute/wsgi.py +++ b/fastly_compute/wsgi.py @@ -40,11 +40,11 @@ def serve_wsgi_request( specification, allowing any WSGI-compatible web framework to run on Fastly Compute. - :param req: Fastly HTTP request object from WIT bindings - :param body: WSGI input stream containing the request body (PEP 3333 compliant) - :param app: WSGI application callable - :param handle_errors: If True, log exceptions and return 500; otherwise let - the server or WSGI app handle them + :arg req: Fastly HTTP request object from WIT bindings + :arg body: WSGI input stream containing the request body (PEP 3333 compliant) + :arg app: WSGI application callable + :arg handle_errors: If True, log exceptions and return 500; otherwise let + the server or WSGI app handle them """ response = http_resp.Response.new() response_body = http_body.new() @@ -163,8 +163,8 @@ class WsgiHttpIncoming(WitHttpIncoming): on Fastly Compute. Subclass this and set the `app` attribute to your WSGI application. - Example: - ```python + Example:: + from flask import Flask from fastly_compute.wsgi import WsgiHttpIncoming @@ -175,7 +175,6 @@ def hello(): return "Hello, World!" HttpIncoming = WsgiHttpIncoming(app) - ``` """ def __init__(