global-api-tools
global-api-tools is a reusable Python library for centralized API responses, logging, and exception handling.
It gives you one place to manage:
create_responsevalue_correctionlogsExceptionHandlerunified_exception_handler
Install
pip install global-api-tools
For local development:
pip install .
Optional extras:
pip install ".[fastapi]"
pip install ".[pydantic]"
pip install ".[database]"
pip install ".[full]"
Quick usage
from fastapi import FastAPI
from global_api_tools import create_response, register_exception_handlers
app = FastAPI()
register_exception_handlers(app)
@app.get("/health")
async def health():
return create_response(200, data={"status": "ok"})
Public API
Import from the published package like this:
Use only this import style in other projects:
from global_api_tools import (
ApiError,
ErrorHandler,
ExceptionHandler,
create_response,
explain_error,
get_logger,
get_status_code,
handle_exception,
logs,
register_exception_handlers,
unified_exception_handler,
value_correction,
)
create_response
Params:
response_code: intdata: Any = Noneschema: Any | None = Nonepagination: Mapping[str, Any] | None = Noneerror_message: str | None = Noneerror_code: str | None = Nonedetails: Sequence[Mapping[str, Any]] | None = Noneas_json_response: bool = True
Usage:
from global_api_tools import create_response
return create_response(
200,
data={"name": "Aniket"},
pagination={"page": 1, "rows": 10, "total_rows": 100},
)
value_correction
Params:
data: Any
Usage:
from decimal import Decimal
from global_api_tools import value_correction
cleaned = value_correction({"amount": Decimal("10.50"), "name": " demo "})
logs
Params:
msg: object = ""type: str = "info"file_name: str | Path | None = Nonelogger: logging.Logger | None = None
Usage:
from global_api_tools import logs
logs("report created", type="info")
logs("database failed", type="error", file_name="logs/app")
get_logger
Params:
name: str = "global_api_tools"file_name: str | Path | None = None
Usage:
from global_api_tools import get_logger
logger = get_logger("my_app", file_name="logs/app.log")
logger.info("started")
unified_exception_handler
Params:
requestexc: Exception
Usage:
from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from global_api_tools import unified_exception_handler
app = FastAPI()
app.add_exception_handler(HTTPException, unified_exception_handler)
app.add_exception_handler(Exception, unified_exception_handler)
app.add_exception_handler(RequestValidationError, unified_exception_handler)
register_exception_handlers
Params:
apphandler: ErrorHandler | None = None
Usage:
from fastapi import FastAPI
from global_api_tools import register_exception_handlers
app = FastAPI()
register_exception_handlers(app)
ExceptionHandler
Params:
exc: Exception
Usage:
from global_api_tools import ExceptionHandler
try:
raise ValueError("invalid meter id")
except Exception as exc:
ExceptionHandler(exc)
handle_exception
Params:
exc: Exceptionrequest = None
Usage:
from global_api_tools import handle_exception
payload_or_response = handle_exception(ValueError("invalid input"))
explain_error
Params:
exc: Exception
Usage:
from global_api_tools import explain_error
message = explain_error(ValueError("invalid input"))
get_status_code
Params:
exc: Exception
Usage:
from global_api_tools import get_status_code
status_code = get_status_code(ValueError("invalid input"))
ErrorHandler
Params:
logger_name: str = "global_api_tools.errors"
Usage:
from global_api_tools import ErrorHandler
handler = ErrorHandler()
payload = handler.build_payload(ValueError("invalid input"))
ApiError
Params:
message: strstatus_code: int = 400code: str = "api_error"details: list[dict[str, Any]] | None = Nonelog_message: str | None = None
Usage:
from global_api_tools import ApiError
raise ApiError(
"Report is not ready.",
status_code=409,
code="report_pending",
details=[{"field": "report_id", "message": "still processing"}],
)
Error response format
Every API failure uses one consistent structure:
{
"success": false,
"status_code": 422,
"error": {
"code": "validation_error",
"type": "RequestValidationError",
"message": "One or more fields are invalid.",
"details": [
{
"field": "email",
"message": "field required"
}
]
}
}
Package structure
src/global_api_tools/
__init__.py
_compat.py
exceptions.py
logging.py
responses.py
Extending it
Add new shared functionality inside src/global_api_tools/ and re-export it from src/global_api_tools/__init__.py. That keeps imports stable across every project that uses the package.
Import Rule
For installed usage, import from global_api_tools only.
Correct:
from global_api_tools import create_response, unified_exception_handler
Do not rely on local-only paths like utils or exception_handler in other projects.
Auto Publish From prod
This repo is configured so that a merged pull request into the prod branch publishes the package to PyPI through GitHub Actions.
Required setup:
- Create the package on PyPI if needed.
- In PyPI, configure a Trusted Publisher with these values:
- Project name:
global-api-tools - Owner:
aniketmodi123 - Repository:
reusable_code_lib - Workflow:
publish-pypi.yml
- Project name:
- Before merging into
prod, increase the version inpyproject.toml. PyPI will reject duplicate versions.
Workflow file:
.github/workflows/publish-pypi.yml
Release flow:
git checkout dev
# make code changes
# update version in pyproject.toml when this is a release
git add .
git commit -m "release: 0.1.1"
git push origin dev
Then:
- Create a pull request from
devtoprod - Review and approve it
- Merge the pull request
When the PR is merged into prod, GitHub Actions will use Trusted Publishing to:
- build the wheel and source distribution
- validate the package
- upload it to PyPI
Release files for global-api-tools 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| global_api_tools-0.1.1.tar.gz | 12.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| global_api_tools-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.3 kB
Release files / global_api_tools-0.1.1.tar.gz
| Download URL | global_api_tools-0.1.1.tar.gz |
|---|---|
| Size | 12.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c99dc7e6bb8170fe18523704b85d1e78ebce43f3de99ec0935fb35e1e3871607
|
|
BLAKE2b-256 checksum How to use checksums |
7d76ffb313493b8dd594539167ea423739849f148e636ac922ca13cd35c5d8ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 28, 2026.
Transparency logRelease files / global_api_tools-0.1.1-py3-none-any.whl
| Download URL | global_api_tools-0.1.1-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ad4d7d355e36de38c79278896fc281b5a56bb10c214dfef9b679bda6bc66a66f
|
|
BLAKE2b-256 checksum How to use checksums |
a6557e4bde1a28436df5db41a6d2f4e72e7b34b4db5c5c53b373d1a35bcc3f48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 28, 2026.
Transparency log