NSJ REST Lib2
nsj-rest-lib2 is a Python library designed to enable the distribution of dynamic REST API routes. These routes are configured declaratively using JSON-based Endpoint Definition Language (EDL) files. It leverages Flask and Flask-RESTful to integrate these dynamic routes into an existing Flask application. The current version is 0.0.41, and it undergoes frequent patch updates, indicating active development.
Common errors
-
ModuleNotFoundError: No module named 'your_endpoint_module'
cause The `endpoint_module` specified in your route configuration JSON cannot be found by Python's import system.fixEnsure the Python module containing your endpoint logic is installed in your environment or its directory is added to `sys.path` before `nsj-rest-lib2` attempts to load it. -
AttributeError: type object 'YourEndpointClass' has no attribute 'your_method'
cause The `endpoint_method_name` specified in your route configuration JSON does not exist within the `endpoint_class_name` provided.fixDouble-check the spelling and case of both the class name and method name in your EDL JSON and your actual Python code. Verify the method exists within the specified class. -
pydantic.error_wrappers.ValidationError: 1 validation error for DynamicRouteConfigDTO\nuri\n field required (type=value_error.missing)
cause Your route configuration JSON is missing a required field, in this example `uri`, or has an invalid type for a field.fixConsult the `DynamicRouteConfigDTO` definition in the library's source or official examples to ensure your JSON includes all mandatory fields (e.g., `uri`, `http_method`, `endpoint_module`, `endpoint_class_name`, `endpoint_method_name`) and their values are of the correct type.
Warnings
- breaking The library is in version `0.0.x`, indicating it's in early development. API interfaces, especially the structure of the declarative JSON (EDL), may change frequently and without major version bumps. Always review release notes when upgrading.
- gotcha Incorrectly specified `endpoint_module`, `endpoint_class_name`, or `endpoint_method_name` in the EDL JSON will lead to runtime errors when the dynamic route is accessed, as the library won't be able to locate and invoke the specified Python code.
- gotcha The declarative JSON (EDL) for defining routes is validated using Pydantic. Any deviation from the expected schema, such as missing required fields or incorrect data types, will result in `pydantic.error_wrappers.ValidationError` during endpoint creation.
Install
-
pip install nsj-rest-lib2
Imports
- create_dynamic_rest_api_endpoint_from_json
from nsj_rest_lib2.util import create_dynamic_rest_api_endpoint_from_json
- register_route
from nsj_rest_lib2.register import register_route
Quickstart
import sys
from types import ModuleType
from flask import Flask
from nsj_rest_lib2.register import register_route
from nsj_rest_lib2.util import create_dynamic_rest_api_endpoint_from_json
import os
# --- Step 1: Define your endpoint logic ---
# In a real application, 'my_app_endpoints' would be a real .py file
# and MyEndpointClass would be a class defined within it.
class MyEndpointClass:
def my_dynamic_method(self):
"""A simple method to be called by the dynamic route."""
return {"message": "Hello from nsj-rest-lib2 dynamic endpoint!"}, 200
# Dynamically add this class to a mock module in sys.modules
# This allows create_dynamic_rest_api_endpoint_from_json to find it
# without needing an actual file on disk for this quickstart example.
mock_module_name = 'my_app_endpoints'
if mock_module_name not in sys.modules:
sys.modules[mock_module_name] = ModuleType(mock_module_name)
setattr(sys.modules[mock_module_name], 'MyEndpointClass', MyEndpointClass)
# --- Step 2: Initialize Flask application ---
app = Flask(__name__)
app.secret_key = os.environ.get('FLASK_SECRET_KEY', 'a_super_secret_key_for_dev') # Required for some Flask extensions
# --- Step 3: Define the declarative route configuration (EDL) ---
route_config_json = {
"uri": "/api/v1/dynamic-resource",
"http_method": "GET",
"endpoint_module": mock_module_name, # References the mock module
"endpoint_class_name": "MyEndpointClass", # Class containing the method
"endpoint_method_name": "my_dynamic_method", # Method to be called
"request_body_model_name": None,
"response_body_model_name": None,
"query_string_model_name": None,
"path_params_model_name": None,
"header_params_model_name": None,
"jwt_roles": [],
"jwt_allowed": False,
"jwt_required": False
}
# --- Step 4: Create and register the dynamic endpoint ---
dynamic_endpoint = create_dynamic_rest_api_endpoint_from_json(route_config_json)
register_route(app, dynamic_endpoint)
# --- Step 5: Run the Flask application (for demonstration) ---
# In a production environment, use a WSGI server like Gunicorn or Waitress.
if __name__ == '__main__':
print("\nFlask application running at http://127.0.0.1:5000")
print("Test with: curl http://127.0.0.1:5000/api/v1/dynamic-resource")
app.run(debug=True, port=5000)