-
Notifications
You must be signed in to change notification settings - Fork 1
Add early backends support with requests-style API #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
6d40191
Add early backends support with requests-style API
posborne 1a2b03f
Add ruff lints for docs and fix warnings
posborne affebd8
Clean up code style and formatting issues
posborne f9f6591
Improve requests library compatibility
posborne dac511d
Factor out common patterns and reduce code duplication
posborne 34e33d0
Improve URL handling and parsing
posborne ddb0591
Add documentation and type improvements
posborne 3326f71
Implement test infrastructure improvements
posborne be4ea7e
Remove backend-simple example
posborne 50287b7
Rename requests-simple to backend-requests
posborne b3ca60a
Daylight advanced timeout configuration
posborne 3ef02b9
Attempt to better map errors in backend code
posborne 1787eeb
Introduce snapshot testing and convert backend tests
posborne File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| """Simple Requests Demo - Example using fastly_compute.requests with Bottle | ||
|
|
||
| This example demonstrates the requests-compatible HTTP client for making | ||
| backend requests in Fastly Compute using Bottle (which has fewer dependencies than Flask). | ||
| """ | ||
|
|
||
| from bottle import Bottle | ||
| from wit_world.imports import compute_runtime | ||
|
|
||
| # Import Fastly Compute modules | ||
| import fastly_compute.requests as requests | ||
| from fastly_compute.wsgi import WsgiHttpIncoming | ||
|
|
||
| app = Bottle() | ||
|
|
||
|
|
||
| @app.route("/static-get") | ||
| def static_get(): | ||
| """Demo GET request using static backend.""" | ||
| try: | ||
| # Use static backend (requires 'test-be' backend in viceroy.toml) | ||
| response = requests.get("/get", backend="test-be") | ||
|
|
||
| return { | ||
| "demo": "static-get", | ||
| "backend_type": "static", | ||
| "backend_name": "test-be", | ||
| "status_code": response.status_code, | ||
| "success": response.ok, | ||
| "url": response.url, | ||
| "headers_count": len(response.headers), | ||
| "content_length": len(response.content), | ||
| "response_preview": response.text[:200] + "..." | ||
| if len(response.text) > 200 | ||
| else response.text, | ||
| } | ||
| except Exception as e: | ||
| return {"demo": "static-get", "error": str(e), "error_type": type(e).__name__} | ||
|
|
||
|
|
||
| @app.route("/static-post") | ||
| def static_post(): | ||
| """Demo POST request using static backend.""" | ||
| try: | ||
| # POST JSON data to static backend | ||
| post_data = { | ||
| "message": "Hello from Fastly Compute!", | ||
| "demo": "static-post", | ||
| "vcpu_time": compute_runtime.get_vcpu_ms(), | ||
| } | ||
|
|
||
| response = requests.post("/post", backend="test-be", json=post_data) | ||
|
|
||
| return { | ||
| "demo": "static-post", | ||
| "backend_type": "static", | ||
| "backend_name": "test-be", | ||
| "status_code": response.status_code, | ||
| "success": response.ok, | ||
| "sent_data": post_data, | ||
| "content_length": len(response.content), | ||
| "response_preview": response.text[:200] + "..." | ||
| if len(response.text) > 200 | ||
| else response.text, | ||
| } | ||
| except Exception as e: | ||
| return {"demo": "static-post", "error": str(e), "error_type": type(e).__name__} | ||
|
|
||
|
|
||
| @app.route("/dynamic-get") | ||
| def dynamic_get(): | ||
| """Demo GET request using dynamic backend.""" | ||
| from bottle import request | ||
|
|
||
| # Get target from query parameter (required) | ||
| target = request.query.get("target") | ||
| if not target: | ||
| return { | ||
| "demo": "dynamic-get", | ||
| "error": "target query parameter is required (e.g., ?target=https://http-me.fastly.dev/get)", | ||
| } | ||
|
|
||
| try: | ||
| # Make request to external service (creates dynamic backend) | ||
| response = requests.get( | ||
| target, | ||
| headers={"User-Agent": "FastlyCompute-SimpleDemo/1.0"}, | ||
| ) | ||
|
|
||
| return { | ||
| "demo": "dynamic-get", | ||
| "backend_type": "dynamic", | ||
| "target_url": target, | ||
| "status_code": response.status_code, | ||
| "success": response.ok, | ||
| "url": response.url, | ||
| "headers": dict(list(response.headers.items())[:5]), # Show first 5 headers | ||
| "content_length": len(response.content), | ||
| "response_preview": response.text[:200] + "..." | ||
| if len(response.text) > 200 | ||
| else response.text, | ||
| } | ||
| except Exception as e: | ||
| return {"demo": "dynamic-get", "error": str(e), "error_type": type(e).__name__} | ||
|
|
||
|
|
||
| @app.route("/dynamic-post") | ||
| def dynamic_post(): | ||
| """Demo POST request using dynamic backend.""" | ||
| from bottle import request | ||
|
|
||
| # Get target from query parameter (required) | ||
| target = request.query.get("target") | ||
| if not target: | ||
| return { | ||
| "demo": "dynamic-post", | ||
| "error": "target query parameter is required (e.g., ?target=https://http-me.fastly.dev/post)", | ||
| } | ||
|
|
||
| try: | ||
| # POST to external service | ||
| post_data = { | ||
| "service": "fastly-compute", | ||
| "demo": "dynamic-post", | ||
| "timestamp": compute_runtime.get_vcpu_ms(), | ||
| "message": "Dynamic backend POST from Fastly Compute", | ||
| } | ||
|
|
||
| response = requests.post( | ||
| target, | ||
| json=post_data, | ||
| headers={ | ||
| "User-Agent": "FastlyCompute-SimpleDemo/1.0", | ||
| "X-Demo": "fastly-compute-requests", | ||
| }, | ||
| ) | ||
|
|
||
| return { | ||
| "demo": "dynamic-post", | ||
| "backend_type": "dynamic", | ||
| "target_url": target, | ||
| "status_code": response.status_code, | ||
| "success": response.ok, | ||
| "sent_data": post_data, | ||
| "content_length": len(response.content), | ||
| "response_preview": response.text[:200] + "..." | ||
| if len(response.text) > 200 | ||
| else response.text, | ||
| } | ||
| except Exception as e: | ||
| return {"demo": "dynamic-post", "error": str(e), "error_type": type(e).__name__} | ||
|
|
||
|
|
||
| @app.route("/error-demo") | ||
| def error_demo(): | ||
| """Demo error handling scenarios.""" | ||
| results = [] | ||
|
|
||
| # Test case 1: Invalid static backend | ||
| try: | ||
| response = requests.get("/test", backend="nonexistent-backend") | ||
| results.append( | ||
| { | ||
| "test": "invalid-static-backend", | ||
| "status": "unexpected_success", | ||
| "status_code": response.status_code, | ||
| } | ||
| ) | ||
| except Exception as e: | ||
| results.append( | ||
| { | ||
| "test": "invalid-static-backend", | ||
| "status": "expected_error", | ||
| "error": str(e), | ||
| "error_type": type(e).__name__, | ||
| } | ||
| ) | ||
|
|
||
| # Test case 2: Invalid URL format | ||
| try: | ||
| response = requests.get("not-a-url") | ||
| results.append({"test": "invalid-url-format", "status": "unexpected_success"}) | ||
| except Exception as e: | ||
| results.append( | ||
| { | ||
| "test": "invalid-url-format", | ||
| "status": "expected_error", | ||
| "error": str(e), | ||
| "error_type": type(e).__name__, | ||
| } | ||
| ) | ||
|
|
||
| return {"demo": "error-demo", "test_results": results} | ||
|
|
||
|
|
||
| # Create the HTTP handler | ||
| HttpIncoming = WsgiHttpIncoming(app) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.