Package: awesome-sso
Awesome SSOA library designed to host common components for a cluster of microservices sharing a single sign on.FeatureA common exception class, supporting both status code and custom error code to map to more detailed error message
or serve as i18n key.A common FastAPI app for interaction with service, like login ,registration and unregistration.a connector for minio object store.a connector for beanie, a mongo odm compatible with pydantic.UsageInstallationpip install awesome-ssoExceptionsUsing fast API as example, we may simply throw exception with a proper status code, and an optional error code. We may
also supply arbitrary key value in args dict, to help frontend render better error message.fromawesome_sso.exceptionsimportNotFoundfromfastapiimportAPIRouterrouter=APIRouter()@router.get('/transactions')defget(id:str):try:obj=find_by_id(id)exceptExceptionase:raiseNotFound(message='transaction not found'%id,error_code='A0001',args={id:id})...And we may implement a common error handler to convert all these errors to proper response schemafromawesome_sso.exceptionsimportHTTPExceptionfromfastapi.requestsimportRequestfromfastapi.responsesimportJSONResponse@app.exception_handler(HTTPException)asyncdefhttp_exception_handler(request:Request,exc:HTTPException):returnJSONResponse(status_code=exc.status_code,content={'detail':exc.detail,'error_code':exc.error_code,})This would result in a response with status code 404, and body{"status_code":404,"detail":{"message":"transaction not found","id":"some_id"},"error_code":"A0001"}With this response, frontend can decide to simply render detail, or map it to detailed message. If error_code "A0001"
correspond to the following i18 n entry"error.A0001":{"en-US":"transaction can not be found with supplied {id}: {message}"}we may format message accordingly witherrorMessage=formatMessage({id:`error.${error.data.error_code}`},error.data.detail);Note that error code is not supplied, is default to status code. So it is always safe to simply use error_code in
frontend to decide what to render.Data StoreMiniorefer totests/test_minio.pyMongorefer totests/service/test_user.pyfrombeanieimportinit_beaniefrommotor.motor_asyncioimportAsyncIOMotorClientfromawesome_sso.service.user.schemaimportAwesomeUserdefinit_mongo():settings=YOUR_SETTINGS()models=[AwesomeUser]cli=AsyncIOMotorClient(settings.mongodb_dsn)awaitinit_beanie(database=cli[settings.mongodb_db_name],document_models=models,)formodelinmodels:awaitmodel.get_motor_collection().drop()awaitmodel.get_motor_collection().drop_indexes()Serviceconfigure service settingsfromawesome_sso.service.settingsimportSettingssettings=Settings()settings.init_app(symmetric_key='YOUR_SYMMETRIC_KEY',# to encode and decode service tokenpublic_key='YOUR_PUBLIC_KEY',# to decode the token signed by ssouser_model=USER_MODEL,# user orm needs to inherit AwesomeUser from `awesome_sso.user.schema`service_name='YOUR_SERVICE_NAME',# for service discovery, to recognize servicesso_domain='YOUR_SSO_DOMAIN',# for service registration and sync user)initial service and mount to your applicationfromawesome_sso.serviceimportServicefromfastapiimportFastAPIapp=FastAPI()service=Service()service.init_app(YOUR_FASTAPI_APP)app.mount('/YOUR/PATH',YOUR_FASTAPI_APP)then open the api doc, you will see the apis inawesome_sso.service.user.routeDevelopmentInstalling Poetrycreate your own environment for poetry, and simply run:pip install poetryalternatively, you can refer topoetry's official pageto be able to usepoedirectly,pip install poethepoetContributingproject setup:poetry installcreate your own branch to start developing new feature.before creating pr, make sure you passpoe lintand./run_test.sh.what happened inside./run_test.shis that a minio server is setup for you temporarily, and teardown and unit
test is finished.notice thatpoe testwould also work if you already have a minio up and running. You need the following env
variable:MINIO_ACCESS_KEY,MINIO_SECRET_KEY,MINIO_ADDRESSupon runningpoe test.for a list of available poe command,poeafter you submit a pr, you should check if pipeline is successful.Releasingpoetry version [new_version]git commit -m"Bump version"git push origin developcreate new releaseon github.Create release off develop branch, auto generate notes, and review release note.Publish release