Execute function with FastAPI features.
Project description
fastexec
Version: 0.4.0 License: MIT
Execute functions with FastAPI features—dependency injection, request/response objects, and more—without running a full server.
Summary
fastexec allows you to invoke a function as if it were a FastAPI endpoint, leveraging FastAPI's dependency-injection system. This is particularly useful for:
- Testing and debugging routes and dependencies without spinning up the entire application.
- Dry-running code that ordinarily depends on HTTP request and response objects.
- Refactoring or benchmarking your API logic in isolation.
Under the hood, fastexec uses a lightweight, mocked request context that simulates FastAPI's environment so your dependencies “just work.”
Installation
Requires Python 3.12+.
pip install fastexec
Quick Start
-
Install and Import fastexec.
-
Create your normal FastAPI dependencies and endpoints:
import fastapi from fastexec import FastExec def my_dependency(request: fastapi.Request): return request.headers.get("Authorization") async def my_endpoint(auth: str = fastapi.Depends(my_dependency)): return {"auth": auth}
-
Wrap your endpoint with
FastExec:import asyncio async def main(): app = FastExec(call=my_endpoint) result = await app.exec( headers={"Authorization": "Bearer your_token_here"}, ) print(result) # {'auth': 'Bearer your_token_here'} asyncio.run(main())
Usage
1. Define Your Dependencies and Endpoint
Just like any FastAPI route, define your standard dependencies:
def get_api_key(request: fastapi.Request):
return request.headers.get("Authorization")
def process_data(api_key: str = fastapi.Depends(get_api_key)):
# Implement your core logic
return {"authorized": bool(api_key), "api_key": api_key}
2. Create a FastExec Instance
from fastexec import FastExec
executor = FastExec(call=process_data)
The call parameter is the function or async function you want to invoke with dependency injection.
3. Execute the Function
Use the .exec() method to supply query parameters, headers, request body, or custom state:
import asyncio
async def run_logic():
result = await executor.exec(
query_params={"sort": "desc"},
headers={"Authorization": "Bearer example-token"},
body={"example": "payload"},
state={"session_id": "test_session_123"},
)
print(result)
asyncio.run(run_logic())
Arguments:
query_params: A dictionary-like object, converted into a?key=valuestyle query string for your dependencies.headers: A dictionary-like object representing HTTP headers (e.g.,"Authorization": "Bearer ...").body: JSON-serializable object or raw bytes. If it’s a dictionary or Pydantic model, it will be parsed as JSON and passed to body/request.json().state: A dictionary for per-request data stored onrequest.state.state=...on theFastExec(...)constructor sets upapp.stateglobally for your function calls.
Advanced Usage
Directly Calling Dependencies
If you want full control, you can manually create a FastAPI “dependant” object and invoke it with exec_with_dependant:
from fastexec import get_dependant, exec_with_dependant
def core_logic(data: dict = fastapi.Body(...)):
return {"processed": True, "data": data}
dependant = get_dependant(call=core_logic)
result = await exec_with_dependant(
dependant=dependant,
body={"hello": "world"},
headers={"x-api-key": "12345"},
)
print(result) # {"processed": True, "data": {"hello": "world"}}
This API is handy for low-level testing or custom injection beyond the FastExec class.
Passing Application State
You can store application-wide data in FastExec(..., state=...), which is then accessible via request.app.state in your dependencies. For example:
def read_app_name(request: fastapi.Request):
return request.app.state.app_name # app_name is set in `state=...` dict
async def example_endpoint(app_name: str = fastapi.Depends(read_app_name)):
return {"app_name": app_name}
# Setting a global app state
app_exec = FastExec(call=example_endpoint, state={"app_name": "Test App"})
result = await app_exec.exec()
# result == {"app_name": "Test App"}
Including request.state
When you call .exec(), you can also attach per-request state. This becomes available as request.state:
result = await app_exec.exec(
state={"session_id": "session_001"},
)
# Access `request.state.session_id` inside your dependencies
Examples
See the tests folder for full examples of how to wire up multiple dependencies, mock request bodies, pass custom state, handle async routes, and more.
Contributing
- Fork this repo.
- Create a feature branch and make changes.
- Install dev requirements:
poetry install -E all --with dev
- Run Tests:
make pytest - Open a Pull Request. :rocket:
License
fastexec is distributed under the terms of the MIT License.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastexec-0.4.0.tar.gz.
File metadata
- Download URL: fastexec-0.4.0.tar.gz
- Upload date:
- Size: 5.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.0 CPython/3.12.8 Darwin/24.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0114efac48e31c816484b2a555fd7c99f08f8de2126390e19ca247c58f00dc0f
|
|
| MD5 |
da086235e44d9fa79ac027d6484f03e0
|
|
| BLAKE2b-256 |
0b4649d3897cf7447217ab1c4cacac2aed0ffc6df7c6b32070ec29fd5f72e835
|
File details
Details for the file fastexec-0.4.0-py3-none-any.whl.
File metadata
- Download URL: fastexec-0.4.0-py3-none-any.whl
- Upload date:
- Size: 7.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.0 CPython/3.12.8 Darwin/24.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fb539e207a0b19f7da7306a537edf660d33d0e8052e2dec1ac9d22f00cfac76
|
|
| MD5 |
e9aa3eb59755c0901c3a1608fdfa3430
|
|
| BLAKE2b-256 |
7140dd9f43b0c168c26870ed750a8ee52421a06c2662b18041fa2a7d766564f2
|