OpenG2P FastAPI Common
Last updated
Last updated
This is a Python package that can be used as a library to bootstrap REST API services, based on . This page describes different concepts within the library and instructions on how to use it.
This package/library contains basic components, like Configuration helpers, Logging helpers, DB ORM helpers, Base Initializers, etc that are required to bootstrap a basic service built using Python and FastAPI. A detailed description is given below.
Component
A Component is an object that gets stored in a global registry (called Component Registry) when initialized.
Components are usually only initialized once mostly inside an Initializer class. Once initialized in Initializer, they can be obtained using the class method; <ComponentClass>.get_component()
.
A name
(optional) can be given to instances of Components so that they can be retrieved using that name if there are multiple instances of a Component. <ComponentClass>.get_component("mycomp")
.
BaseComponent
is the base Class for Components.
Service
A Service is also a Component that usually contains some logic that is executed inside a Controller.
Use <ServiceClass>.get_component()
to retrieve a service.
BaseService
is the base Class for Services.
Service is technically the same as Component. Prefer Service over Component when defining new.
Controller
In the init method of a Controller, the API Routes need to be manually added.
Use <ControllerClass>.get_component()
to retrieve a Controller.
BaseController
is the base Class for Controllers.
Settings
Settings, based on Pydantic's BaseSettings, establishes configuration options.
Configuration Parameters defined inside Settings can be loaded through Env variables / .env
file.
Settings
Class in config
can be used as the base class by other Settings classes to inherit.
BaseORMModel
BaseORMModel is an SQLAlchemy ORM Model, that can be used as a base class for other ORM Classes to inherit.
BaseExceptionHandler
BaseExceptionHandler is an Exception Handler Implementation that uses FastAPI Exception Handler at the base and handles extra exceptions defined in this module, mainly BaseAppException
.
This can also be extended to further handle custom Exceptions when defined.
Initializer
Initializer is a class that initializes all the components, services, controllers, configs, loggers, etc along with any additional Components of a particular Python Package/Module.
The Components have to be individually initialized inside the init method of an Initializer.
This section describes instructions for installing the package. Primarily intended for developers using this module to build their own projects.
Install python3 for your environment.
Set up a virtualenv in your project directory. Using:
Clone .
Then Install the common package using pip:
This section describes instructions for using the package/library. Primarily intended for developers using this module to build their own projects.
The app.py
file in the project acts as the main file which initializes all the components of the project. It should contain an Initializer
.
Initialize the Components (like Services, Controllers, etc.) inside the initialize
method of the Initializer
. Example
Note: If the Initializer is only supposed to be used by external modules to inherit/extend/use. Then do not run super().initialize()
inside the initialize
method. If the Initializer is the main Initializer that sets up the FastAPI apps etc then run super().initialize()
inside the initialize
method.
Note: Due to a limitation in the way the config is set up, the Settings.get_config()
needs to be put at the beginning of the app.py (only applies to app.py), before importing other Initializers. If your Linters/Code Formatters are throwing up an E402 error, ignore the error at the beginning of app.py. Check the above example.
If you are using the template given above, use the config file present in the src
folder of your Python package. If not, create a config.py
file in your project that looks like this.
To define configuration parameters for your project, add the properties to the above Settings class defined in config.py
. Example
The parameters defined here can be loaded through environment variables or .env
file. The environment variables can be case insensitive. For example
The environment variable prefix, myproject_
in the above example, can be configured under model_config
of Settings class, under env_prefix
.
To use this config in other components of your project like models/controllers/services, etc. use the get_config
class method of the above Settings class. Example inside a controller file
To add more APIs to your project, create controllers in the controllers
directory.
Add each API route using the add_api_route
method of the router. Example ping_controller.py
.
A Controller will automatically initialize Response models for the APIs for the following HTTP Codes: 401, 403, 404, and 500 (with the ErrorListResponse
response model defined in this module). These can be changed/updated accordingly.
Create Services in the services
directory similar to a Controller.
Example
To retrieve an instance of a Component (Service, Controller, etc) use Component.get_component()
.
Example in PingController
if you want to retrieve the PingService
.
This can be modified using the init_logger
method of an Initializer.
Use BaseORMModel
as the base class for your ORM Model.
Use BaseORMModelWithID
as the base class, to automatically add id
and active
fields to the ORM class, along with quick helper classmethods to get an object using id. Example <MyORMModel>.get_by_id(id)
.
Use BaseORMModelWithTimes
as the base class, to automatically add created_at
and updated_at
along with features of BaseORMModelWithID
.
The following Exceptions are defined by this module. When these exceptions are raised in code, they are caught and handled by BaseExceptionHandler.
The HTTP Response Payload looks like this when the following exceptions are raised. (The HTTP Response Status code is defined according to the Exception).
UnauthorizedError
Raise this to return 401 Unauthorized
HTTP response.
UnauthorizedError derives from BaseAppException.
Default error_code
is G2P-AUT-401
.
Default error_message
is Unauthorized
.
Default http_status_code
is 401
.
ForbiddenError
Raise this to return 403 Forbidden
HTTP response.
ForbiddenError derives from BaseAppException.
Default error_code
is G2P-AUT-403
.
Default error_message
is Forbidden
.
Default http_status_code
is 403
.
BadRequestError
Raise this to return 400 Bad Request
HTTP response.
BadRequestError derives from BaseAppException.
Default error_code
is G2P-REQ-400
.
Default error_message
is Bad Request
.
Default http_status_code
is 400
.
NotFoundError
Raise this to return 404 Not Found
HTTP response.
BadRequestError derives from BaseAppException.
Default error_code
is G2P-REQ-404
.
Default error_message
is Not Found
.
Default http_status_code
is 404
.
InternalServerError
Raise this to return 500 Internal Server Error
HTTP response.
InternalServerError derives from BaseAppException.
Default error_code
is G2P-REQ-500
.
Default error_message
is Internal Server Error
.
Default http_status_code
is 500
.
BaseAppException
BaseAppException is the parent for the custom exceptions. It takes an error_code
, error_message
and http_status_code
arguments. Default http_status_code
is 500. If this is manually raised in code, an error response will be returned on the API Call with the given error code, and error message, and HTTP Status will be set to the given status code.
host
Host/IP to which the HTTP server should bind to.
0.0.0.0
port
Port on which the server HTTP should run.
8000
logging_level
Logging Level. Available values DEBUG
, INFO
, WARN
, ERROR
and CRITICAL
.
INFO
logging_file_name
Path to a file where the log should should be stored. If left empty, no file logging. Stdout logging is enabled by default.
openapi_title
Title in OpenAPI Definition. This is the title field in openapi.json
generated by FastAPI. Hence also present on Swagger and API Docs.
Common
openapi_description
Description in OpenAPI
openapi_version
Version in OpenAPI
1.0.0
openapi_contact_url
Contact URL in OpenAPI
https://www.openg2p.org/
openapi_contact_email
Contact Email in OpenAPI
info@openg2p.org
openapi_license_name
License Name in OpenAPI
Mozilla Public License 2.0
openapi_license_url
License URL in OpenAPI
https://www.mozilla.org/en-US/MPL/2.0/
db_datasource
This is the property used by SQLALchemy for DB datasource. If left empty, this will be constructed, using the following db properties, like the following:
db_driver
Driver to use while connecting to Database. Configure this based on the Database being used. If using PostgreSQL, leave it as default.
postgresql+asyncpg
db_hostname
Database Host/IP
localhost
db_port
Database Port
5432
db_dbname
Database Name
db_username
Database Authentication Username
db_password
Database Authentication Password
db_logging
Database Logging. If true, all the database operations being made will be put out in the server logs. Useful while debugging.
false
A Controller is also a Component, that contains a and API Routes inside it. The APIRouter and APIs get initialized when the Controller is initialized.
Controllers also have a post_init
method that adds the APIRouter and APIs into a global . So inside an Initializer, the post_init
method can be called immediately after the Controller is initialized.
Follow the instructions here , to set up a repository with the given template and folder structure.
This Settings
class derives from .
Refer to to see the configuration properties already available in the base Settings
class.
Initialize the Controller, preferably in an Initializer like given . It is important to run the post_init
method of the Controller after initializing it since that will add the API Router of the Controller to the FastAPI App. Example
Initialize the Service in the Initializer like given .
Get the logger using logging.getLogger(__name__)
. This logger initializes JSON logging, using .
Define and ORM Models (based on ) inside the models
directory.
This module also uses the . Follow the link to understand how to use SQLAlchemy and async conventions to interact with the database. Example:
The following configuration properties are already present in the base Settings
class mentioned in .
The following properties can also be set through the environment variables, but the env_prefix
configured in your project's config Settings
will have to be used, as mentioned . Example myproject_logging_level=DEBUG
.
OpenG2P FastAPI Common Module Source Code -