NAME

PAGI::FastAPI::Context - Request and Response Lifecycle Context for PAGI::FastAPI

VERSION

Version v1.0.0

SYNOPSIS

# Inspecting Request Parameters
my $user_id = $c->path_param('id');
my $limit   = $c->query_param('limit');
my $name    = $c->body('name');

# Generic Parameter Fallback (Path -> Query -> Body)
my $token   = $c->param('token');

# Headers & Scope
my $ua      = $c->header('User-Agent');
my $scope   = $c->scope;

# Stash Storage
$c->stash->{user} = { id => 42, role => 'admin' };

# Modifying Response State
$c->status(201);
$c->set_header('X-Custom-Header' => 'value');

DESCRIPTION

PAGI::FastAPI::Context encapsulates the request environment, parsed parameters, payload data, and response state for an individual HTTP exchange processed by PAGI::FastAPI.

An instance of this context is passed as the primary argument to route handlers, middleware functions, and dependency blocks.

METHODS

new(%args)

Constructor called internally by PAGI::FastAPI. Accepts named arguments:

  • scope - PAGI environment HashRef.

  • query_params - HashRef of validated query parameters.

  • path_params - HashRef of route path variables.

  • body - Decoded payload body (HashRef, ArrayRef, or Scalar).

  • status - Initial HTTP response code (default: 200).

  • res_headers - Initial response headers ArrayRef (default: []).

  • stash - Context-bound storage HashRef (default: {}).

scope()

Returns the raw PAGI scope HashRef for the current request.

sleep($seconds)

await $c->sleep(1);

Asynchronously pauses execution for the given number of seconds without blocking the event loop.

Uses Future::IO under the hood to ensure non-blocking sleep operations.

  • $seconds

    Number of seconds to sleep (fractional seconds like 0.5 are supported).

Returns a Future that completes when the specified sleep duration has elapsed.

status([ $code ])

Gets or sets the HTTP status code for the response.

$c->status(403);
my $code = $c->status; # 403

pagi_context

my $pagi_ctx = $c->pagi_context;

Returns the underlying low-level PAGI::Context instance associated with the current HTTP request. Useful for low-level protocol inspection, raw environment access, or invoking protocol-specific extension methods.

csrf_token

my $token = $c->csrf_token;

Retrieves the active Anti-CSRF token for the current request.

This method transparently attempts to resolve the token from three potential locations in order of precedence:

1. Direct Scope Environment: $scope->{'pagi.csrf_token'} (set directly by PAGI::Middleware::CSRF).
2. PAGI Context Environment: $pagi_context->env->{'pagi.csrf_token'}.
3. Session Storage Fallback: $scope->{'pagi.session'}{'csrf_token'} (set by session management middleware).

Returns the scalar token string if found, or undef if no token is available or if CSRF/Session middleware is not active for the request.

Example Usage (Embedding in HTML forms):

$app->get('/form', handler => async sub ($c) {
    my $token = $c->csrf_token // '';
    return $c->html(qq{
        <form method="POST" action="/submit">
            <input type="hidden" name="csrf_token" value="$token">
            <button type="submit">Submit</button>
        </form>
    });
});

csrf_verify($token)

my $is_valid = $c->csrf_verify($submitted_token);

Explicitly validates the given $token against the current request's CSRF state by delegating to the underlying low-level PAGI::Context instance.

Accepts a scalar token string $token. Returns a true value if the token signature and expiration are valid; returns false otherwise.

Dies with "PAGI context is not set" if invoked when no low-level PAGI::Context instance is associated with $c.

Example Usage (Manual Verification):

$app->post('/api/action', handler => async sub ($c) {
    my $token = $c->body('csrf_token');

    unless ($c->csrf_verify($token)) {
        $c->status(403);
        return { error => 'Invalid or missing CSRF token' };
    }

    return { status => 'success' };
});

res_headers()

Returns the current list of outgoing response header pairs as an ArrayRef of tuple pairs [ [$name, $val], ... ].

set_header($key, $val)

Appends an outgoing HTTP header pair to the response headers list.

$c->set_header('X-Frame-Options' => 'DENY');

header($name)

Case-insensitively searches incoming request headers (from $c->scope->{headers}) and returns its scalar value, or undef if missing.

my $auth = $c->header('Authorization');

html($content, %options)

$app->get('/about', handler => async sub ($c) {
    return $c->html('<h1>About Us</h1>');
});

Returns an HTTP response with the Content-Type header automatically set to text/html; charset=utf-8.

Accepts the HTML content string as the first parameter, followed by optional named parameters:

  • status (Optional)

    Integer HTTP status code. Defaults to 200.

  • headers (Optional)

    ArrayRef of additional header key-value pairs.

Returns a PAGI::FastAPI::Response object.

sse($code)

$app->get('/api/v1/metrics', handler => async sub ($c) {
    return $c->sse(async sub ($stream) {
        while (1) {
            await $stream->send_json({ cpu => 42 });
            await $c->sleep(1);
        }
    });
});

Creates and returns a Server-Sent Events (SSE) response object.

Accepts an async generator coderef that receives an SSE stream handler as its first argument.

  • $code

    An async sub coderef that defines the event streaming loop. The callback receives an instance of PAGI::SSE, offering methods such as send_event(), send_json(), send(), keepalive(), and close().

Returns an instance of PAGI::FastAPI::Response::SSE.

path_params()

Returns the HashRef containing all parsed path parameters.

path_param($key)

Returns a specific parsed path parameter by name, or undef if absent.

query_params()

Returns the HashRef containing all parsed query parameters.

query_param($key)

Returns a specific parsed query parameter by name, or undef if absent.

body([ $key ])

If called without parameters, returns the full raw/decoded request body.

If called with a $key parameter and the body is a HashRef, returns the value for that key, or undef if missing or if the body is not a HashRef.

my $full_body = $c->body;
my $user_name = $c->body('username');

param($key)

Convenience parameter accessor that checks parameter stores in priority order:

1. Path parameters (path_param) 2. Query parameters (query_param) 3. JSON/Body fields (body($key))

Returns the first matching non-undef value, or undef if the key is not present in any store.

stash()

Returns a HashRef tied to the lifecycle of this context. Useful for sharing data between middleware, dependency injection blocks, and final route handlers.

$c->stash->{db_session} = $db;

AUTHOR

Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>

REPOSITORY

https://github.com/manwar/PAGI-FastAPI

BUGS

Please report any bugs or feature requests through the web interface at https://github.com/manwar/PAGI-FastAPI/issues. I will be notified and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc PAGI::FastAPI::Context

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright (C) 2026 Mohammad Sajid Anwar.

This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License (2.0).