{"id":7671,"library":"restfly","title":"RESTfly","description":"RESTfly (pronounced restfully) is a framework for building libraries to easily interact with RESTful APIs. It aims to simplify the creation of API interaction libraries by providing a basic scaffolding with an emphasis on simplicity and readability of the resulting code. The library is currently at version 1.5.1 and receives regular updates, ensuring active development and maintenance.","status":"active","version":"1.5.1","language":"en","source_language":"en","source_url":"https://github.com/librestfly/restfly","tags":["REST","API client","framework","HTTP"],"install":[{"cmd":"pip install restfly","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Requires Python 3.9 or newer.","package":"python","optional":false}],"imports":[{"note":"APISession is located within the `session` submodule.","wrong":"from restfly import APISession","symbol":"APISession","correct":"from restfly.session import APISession"},{"note":"APIEndpoint is located within the `endpoint` submodule.","wrong":"from restfly import APIEndpoint","symbol":"APIEndpoint","correct":"from restfly.endpoint import APIEndpoint"},{"note":"Specific HTTP status code errors are provided in the `errors` submodule for granular exception handling.","symbol":"APIError","correct":"from restfly.errors import APIError, BadRequestError, UnauthorizedError"}],"quickstart":{"code":"import os\nfrom restfly.session import APISession\nfrom restfly.endpoint import APIEndpoint\n\n# Define your base API session\nclass MyAPI(APISession):\n    _url = 'https://httpbin.org'\n    \n    # Example of adding an API key, if needed\n    def __init__(self, api_key: str = os.environ.get('MY_API_KEY', ''), **kwargs):\n        self._api_key = api_key\n        super().__init__(**kwargs)\n\n    def _build_session(self, **kwargs):\n        super()._build_session(**kwargs)\n        if self._api_key:\n            self._session.headers.update({\n                'X-API-Key': self._api_key\n            })\n\n# Define an endpoint for a specific resource\nclass StatusAPI(APIEndpoint):\n    _path = 'status'\n\n    def get_status_code(self, code: int) -> dict:\n        # _req is a protected method for making requests, leveraging _path\n        return self._req('GET', path=str(code)).json()\n\n# Instantiate and use the API\nmy_api_client = MyAPI(api_key='your_optional_api_key_here')\n\n# Link the endpoint to the API session\nmy_api_client.status = StatusAPI(my_api_client)\n\ntry:\n    # Call a simple GET request directly from the session\n    response_get = my_api_client.get('get').json()\n    print(f\"GET /get Response: {response_get.get('url')}\")\n\n    # Use the defined endpoint\n    status_200 = my_api_client.status.get_status_code(200)\n    print(f\"GET /status/200 Response: {status_200}\")\n\n    status_404 = my_api_client.status.get_status_code(404)\n    print(f\"GET /status/404 Response: {status_404}\") # This will raise an APIError\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n\n# Example of handling specific errors\nfrom restfly.errors import NotFoundError, APIError\n\ntry:\n    my_api_client.status.get_status_code(404)\nexcept NotFoundError as e:\n    print(f\"Caught specific NotFoundError: {e}\")\nexcept APIError as e:\n    print(f\"Caught generic APIError: {e}\")\n\n","lang":"python","description":"This quickstart demonstrates how to set up a basic API client using `APISession` and organize API calls with `APIEndpoint`. It includes an example of handling API keys and specific HTTP status code errors."},"warnings":[{"fix":"Implement authentication and de-authentication using context management stubs provided by RESTfly, especially for session-based APIs. Refer to 'Context handling and authentication' in the official documentation.","message":"When handling session-based authentication, developers commonly forget to explicitly log out or close sessions, potentially leading to lingering sessions. RESTfly offers context management hooks to facilitate proper authentication and de-authentication.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Catch specific `restfly.errors` exceptions (e.g., `NotFoundError`, `BadRequestError`) instead of a generic `APIError` or `requests.exceptions.HTTPError` for more precise error management.","message":"RESTfly wraps common HTTP status codes (e.g., 400, 401, 403, 404, 500) into specific exception classes (e.g., `BadRequestError`, `UnauthorizedError`, `NotFoundError`). Failing to catch these specific exceptions can lead to less granular error handling, potentially masking the true nature of API failures.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Update any hardcoded repository URLs or documentation links to the new GitHub organization: `https://github.com/librestfly/restfly`.","message":"The project repository was moved in version 1.5.0. While `pip install` typically handles this, direct clones or older documentation links referencing the previous repository location may be broken.","severity":"breaking","affected_versions":">=1.5.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Use `from restfly.session import APISession`.","cause":"Attempting to import `APISession` directly from the top-level `restfly` package instead of its specific submodule.","error":"ImportError: cannot import name 'APISession' from 'restfly'"},{"fix":"Ensure the API endpoint actually returns JSON content. For non-JSON responses, access `response.text` or `response.content`. If `_conv_json` is explicitly set to `False`, handle the raw `requests.Response` object accordingly. Consider checking `response.ok` or `response.status_code` before attempting to parse.","cause":"This typically occurs when a `requests.Response` object (which `restfly` uses internally) is returned, but the content is not JSON, or the `.json()` method is called on an empty response. It can also happen if `_conv_json` is set to `False` in the `APISession` and the result is not manually parsed.","error":"AttributeError: 'Response' object has no attribute 'json'"},{"fix":"Verify that your API key, token, or other authentication methods are correctly configured and passed in the `APISession` initialization or request headers. Use context handling for session-based authentication to ensure proper login/logout.","cause":"The API request failed due to missing or invalid authentication credentials (e.g., incorrect API key, expired token).","error":"restfly.errors.UnauthorizedError: 401 Unauthorized"}]}