CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-treq

High-level Twisted HTTP Client API for asynchronous HTTP requests in Python

Overview
Eval results
Files

cookies.mddocs/

Cookie Management

Cookie handling utilities for creating scoped cookies and managing cookie jars with proper domain and security attribute handling. treq provides convenient functions for working with HTTP cookies in Twisted applications.

Capabilities

Scoped Cookie Creation

Creates cookies properly scoped to a URL's origin with appropriate security attributes.

def scoped_cookie(origin, name, value):
    """
    Create a cookie scoped to a given URL's origin.
    
    The cookie is automatically configured with appropriate domain, port,
    and security settings based on the origin URL. HTTPS origins result
    in secure cookies that won't be sent over HTTP.
    
    Parameters:
    - origin: str or EncodedURL - URL specifying domain and port for cookie
    - name: str - Cookie name
    - value: str - Cookie value
    
    Returns:
    Cookie - Cookie object ready for insertion into CookieJar
    """

Cookie Search

Searches cookie jars for cookies matching specified criteria.

def search(jar, *, domain, name=None):
    """
    Search for cookies in a cookie jar.
    
    Finds cookies that match the given domain and optionally
    a specific cookie name.
    
    Parameters:
    - jar: CookieJar - Cookie jar to search
    - domain: str - Domain to match (keyword-only parameter)
    - name: str or None - Specific cookie name to find (optional)
    
    Returns:
    Iterator of Cookie objects matching the criteria
    """

Usage Examples

Basic Cookie Management

from treq.cookies import scoped_cookie, search
from http.cookiejar import CookieJar
import treq
from twisted.internet import defer

@defer.inlineCallbacks
def basic_cookie_usage():
    # Create a cookie jar
    jar = CookieJar()
    
    # Create scoped cookies
    session_cookie = scoped_cookie("https://example.com", "session", "abc123")
    preference_cookie = scoped_cookie("https://example.com", "theme", "dark")
    
    # Add cookies to jar
    jar.set_cookie(session_cookie)
    jar.set_cookie(preference_cookie)
    
    # Use cookies in requests
    response = yield treq.get("https://example.com/profile", cookies=jar)
    
    # Search for specific cookies
    session_cookies = list(search(jar, domain="example.com", name="session"))
    print(f"Found {len(session_cookies)} session cookies")
    
    # Search for all cookies from domain
    all_cookies = list(search(jar, domain="example.com"))
    print(f"Total cookies for example.com: {len(all_cookies)}")

Secure Cookie Handling

from treq.cookies import scoped_cookie
from http.cookiejar import CookieJar

def setup_secure_cookies():
    jar = CookieJar()
    
    # HTTPS origin creates secure cookie
    secure_cookie = scoped_cookie("https://secure-api.com", "api_token", "secret123")
    print(f"Secure cookie: {secure_cookie.secure}")  # True
    
    # HTTP origin creates non-secure cookie
    basic_cookie = scoped_cookie("http://local-dev.com", "debug", "enabled")
    print(f"Basic cookie secure: {basic_cookie.secure}")  # False
    
    jar.set_cookie(secure_cookie)
    jar.set_cookie(basic_cookie)
    
    return jar

@defer.inlineCallbacks
def use_secure_cookies():
    jar = setup_secure_cookies()
    
    # Secure cookie sent to HTTPS endpoint
    response = yield treq.get("https://secure-api.com/data", cookies=jar)
    
    # Non-secure cookie sent to HTTP endpoint
    response = yield treq.get("http://local-dev.com/debug", cookies=jar)

Session Management with Cookies

from treq.cookies import scoped_cookie, search
from http.cookiejar import CookieJar
from treq.client import HTTPClient
from twisted.web.client import Agent

class SessionManager:
    def __init__(self, base_url):
        self.base_url = base_url
        self.jar = CookieJar()
        self.client = HTTPClient(Agent(reactor), cookiejar=self.jar)
    
    @defer.inlineCallbacks
    def login(self, username, password):
        """Login and establish session."""
        response = yield self.client.post(
            f"{self.base_url}/login",
            data={'username': username, 'password': password}
        )
        
        if response.code == 200:
            # Session cookie automatically stored in jar
            # Extract domain from base_url for search
            from urllib.parse import urlparse
            domain = urlparse(self.base_url).netloc
            session_cookies = list(search(self.jar, domain=domain, name="session"))
            if session_cookies:
                print("Login successful - session established")
                return True
        
        print("Login failed")
        return False
    
    @defer.inlineCallbacks
    def make_authenticated_request(self, path):
        """Make request with session cookies."""
        response = yield self.client.get(f"{self.base_url}{path}")
        return response
    
    def logout(self):
        """Clear session cookies."""
        # Remove all cookies for this domain
        from urllib.parse import urlparse
        domain = urlparse(self.base_url).netloc
        cookies_to_remove = list(search(self.jar, domain=domain))
        for cookie in cookies_to_remove:
            self.jar.clear(cookie.domain, cookie.path, cookie.name)

@defer.inlineCallbacks
def session_example():
    session = SessionManager("https://api.example.com")
    
    # Login
    success = yield session.login("user", "password")
    if success:
        # Make authenticated requests
        profile = yield session.make_authenticated_request("/profile")
        data = yield profile.json()
        print(f"User profile: {data}")
        
        # Logout
        session.logout()

Cross-Domain Cookie Management

from treq.cookies import scoped_cookie, search
from http.cookiejar import CookieJar

@defer.inlineCallbacks
def cross_domain_cookies():
    jar = CookieJar()
    
    # Create cookies for different domains
    domains = [
        "https://api.service1.com",
        "https://api.service2.com", 
        "https://subdomain.service1.com"
    ]
    
    for domain in domains:
        cookie = scoped_cookie(domain, "api_key", f"key_{domain.split('.')[1]}")
        jar.set_cookie(cookie)
    
    # Search cookies by domain
    for domain_url in domains:
        from urllib.parse import urlparse
        domain = urlparse(domain_url).netloc
        cookies = list(search(jar, domain=domain))
        print(f"{domain_url}: {len(cookies)} cookies")
        
        # Make requests with domain-specific cookies
        response = yield treq.get(f"{domain}/data", cookies=jar)

Cookie Expiration and Cleanup

from treq.cookies import scoped_cookie, search
from http.cookiejar import CookieJar
import time

def create_expiring_cookie(origin, name, value, max_age_seconds):
    """Create a cookie with expiration."""
    cookie = scoped_cookie(origin, name, value)
    
    # Set expiration time
    cookie.expires = int(time.time()) + max_age_seconds
    return cookie

@defer.inlineCallbacks
def cookie_expiration_example():
    jar = CookieJar()
    
    # Create short-lived cookie (expires in 60 seconds)
    temp_cookie = create_expiring_cookie(
        "https://example.com", 
        "temp_token", 
        "xyz789", 
        60
    )
    jar.set_cookie(temp_cookie)
    
    # Create long-lived cookie (expires in 1 hour)
    persistent_cookie = create_expiring_cookie(
        "https://example.com",
        "user_id",
        "12345",
        3600
    )
    jar.set_cookie(persistent_cookie)
    
    # Use cookies immediately
    response = yield treq.get("https://example.com/api", cookies=jar)
    
    # Later, check for expired cookies
    def cleanup_expired_cookies():
        current_time = time.time()
        expired_cookies = []
        
        for cookie in search(jar, domain="example.com"):
            if cookie.expires and cookie.expires < current_time:
                expired_cookies.append(cookie)
        
        # Remove expired cookies
        for cookie in expired_cookies:
            jar.clear(cookie.domain, cookie.path, cookie.name)
        
        print(f"Removed {len(expired_cookies)} expired cookies")
    
    # Call cleanup periodically
    cleanup_expired_cookies()

Advanced Cookie Configuration

from http.cookiejar import Cookie, CookieJar
from hyperlink import EncodedURL

def create_advanced_cookie(url, name, value, **kwargs):
    """Create cookie with advanced options."""
    url_obj = EncodedURL.from_text(url) if isinstance(url, str) else url
    
    cookie = Cookie(
        version=0,
        name=name,
        value=value,
        port=None,
        port_specified=False,
        domain=url_obj.host,
        domain_specified=True,
        domain_initial_dot=False,
        path=kwargs.get('path', '/'),
        path_specified=True,
        secure=url_obj.scheme == 'https',
        expires=kwargs.get('expires'),
        discard=kwargs.get('discard', False),
        comment=kwargs.get('comment'),
        comment_url=kwargs.get('comment_url'),
        rest={}
    )
    
    return cookie

@defer.inlineCallbacks
def advanced_cookie_usage():
    jar = CookieJar()
    
    # Cookie with specific path
    api_cookie = create_advanced_cookie(
        "https://example.com",
        "api_session",
        "session123",
        path="/api/"
    )
    jar.set_cookie(api_cookie)
    
    # Cookie that should be discarded when session ends
    temp_cookie = create_advanced_cookie(
        "https://example.com",
        "temp_data",
        "temporary",
        discard=True
    )
    jar.set_cookie(temp_cookie)
    
    # Use cookies with path-specific behavior
    api_response = yield treq.get("https://example.com/api/data", cookies=jar)
    home_response = yield treq.get("https://example.com/", cookies=jar)
    
    # API endpoint gets both cookies, home page gets only non-path-specific cookies

Types

Cookie-related types:

# Cookie types from standard library
from http.cookiejar import Cookie, CookieJar

# URL types for origins
from hyperlink import EncodedURL
OriginType = Union[str, EncodedURL]

# Cookie search results
from typing import Iterator
CookieIterator = Iterator[Cookie]

# Cookie attributes
CookieName = str
CookieValue = str

Cookie Security Best Practices

Secure Cookie Attributes

  • Secure flag: Automatically set for HTTPS origins
  • HttpOnly: Consider setting for sensitive cookies to prevent XSS access
  • SameSite: Configure appropriate SameSite policy for CSRF protection
  • Domain scoping: Use scoped_cookie() for proper domain restriction

Cookie Management

  • Expiration: Set appropriate expiration times for different cookie types
  • Cleanup: Regularly remove expired cookies to prevent jar bloat
  • Storage: Be mindful of cookie storage limits (4KB per cookie, ~300 per domain)
  • Privacy: Clear sensitive cookies when no longer needed

Cross-Origin Considerations

  • Domain matching: Understand how cookies are scoped to domains and subdomains
  • Path restrictions: Use path attributes to limit cookie scope
  • Protocol security: Secure cookies won't be sent over HTTP
  • Third-party cookies: Be aware of browser third-party cookie policies

Integration with treq

  • Automatic handling: treq automatically handles cookies when CookieJar is provided
  • Manual control: Use scoped_cookie() for precise cookie creation
  • Session persistence: Combine with HTTPClient for persistent sessions
  • Testing: Use cookie utilities in testing to simulate various cookie scenarios

Install with Tessl CLI

npx tessl i tessl/pypi-treq

docs

authentication.md

content-processing.md

cookies.md

http-client.md

http-requests.md

index.md

testing.md

tile.json