Package: mauth-client
MAuth Client PythonMAuth Client Python is an authentication library to manage the information needed to both sign and authenticate requests and responses for Medidata's MAuth authentication system.Pre-requisitesTo use MAuth Authenticator you will need:An MAuth app IDAn MAuth private key (with the public key registered with Medidata's MAuth server)InstallationTo resolve packages using pip, add the following to ~/.pip/pip.conf:[global]
index-url = https://<username>:<password>@mdsol.jfrog.io/mdsol/api/pypi/pypi-packages/simple/Install using pip:$ pip install mauth-clientOr directly from GitHub:$ pip install git+https://github.com/mdsol/mauth-client-python.gitThis will also install the dependencies.To resolve using a requirements file, the index URL can be specified in the first line of the file:--index-url https://<username>:<password>@mdsol.jfrog.io/mdsol/api/pypi/pypi-packages/simple/
mauth-client==<latest version>UsageSigning Outgoing Requestsimportrequestsfrommauth_client.requests_mauthimportMAuth# MAuth configurationAPP_UUID="<MAUTH_APP_UUID>"private_key=open("private.key","r").read()mauth=MAuth(APP_UUID,private_key)# Call an MAuth protected resource, in this case an iMedidata API# listing the studies for a particular useruser_uuid="10ac3b0e-9fe2-11df-a531-12313900d531"url="https://innovate.imedidata.com/api/v2/users/{}/studies.json".format(user_uuid)# Make the requests call, passing the auth clientresult=requests.get(url,auth=mauth)# Print resultsifresult.status_code==200:print([r["uuid"]forrinresult.json()["studies"]])print(result.text)Themauth_sign_versionsoption can be set as an environment variable to specify protocol versions to sign outgoing requests:KeyValueMAUTH_SIGN_VERSIONS(optional)Comma-separated protocol versions to sign requests. Defaults tov1.This option can also be passed to the constructor:mauth_sign_versions="v1,v2"mauth=MAuth(APP_UUID,private_key,mauth_sign_versions)Authenticating Incoming RequestsMAuth Client Python supports AWS Lambda functions and Flask applications to authenticate MAuth signed requests.The following variables arerequiredto be configured in the environment variables:KeyValueAPP_UUIDAPP_UUID for the AWS Lambda functionPRIVATE_KEYEncrypted private key for the APP_UUIDMAUTH_URLMAuth service URL (e.g.https://mauth-innovate.imedidata.com)The following variables can optionally be set in the environment variables:KeyValueMAUTH_API_VERSION(optional)MAuth API version. Onlyv1exists as of this writing. Defaults tov1.MAUTH_MODE(optional)Method to authenticate requests.localorremote. Defaults tolocal.V2_ONLY_AUTHENTICATE(optional)Authenticate requests with only V2. Defaults toFalse.AWS Lambda functionsfrommauth_client.lambda_authenticatorimportLambdaAuthenticatorauthenticator=LambdaAuthenticator(method,url,headers,body)authentic,status_code,message=authenticator.is_authentic()app_uuid=authenticator.get_app_uuid()WSGI ApplicationsTo apply to a WSGI application you should use theMAuthWSGIMiddleware. You
can make certain paths exempt from authentication by passing theexemptoption with a set of paths to exempt.Here is an example for Flask. Note that requesting app's UUID and the
protocol version will be added to the request environment for successfully
authenticated requests.fromflaskimportFlask,request,jsonifyfrommauth_client.constsimportENV_APP_UUID,ENV_PROTOCOL_VERSIONfrommauth_client.middlewaresimportMAuthWSGIMiddlewareapp=Flask("MyApp")app.wsgi_app=MAuthWSGIMiddleware(app.wsgi_app,exempt={"/app_status"})@app.get("/")defroot():returnjsonify({"msg":"authenticated","app_uuid":request.environ[ENV_APP_UUID],"protocol_version":request.environ[ENV_PROTOCOL_VERSION],})@app.get("/app_status")return"this route is exempt from authentication"ASGI ApplicationsTo apply to an ASGI application you should use theMAuthASGIMiddleware. You
can make certain paths exempt from authentication by passing theexemptoption with a set of paths to exempt.Here is an example for FastAPI. Note that requesting app's UUID and the
protocol version will be added to the ASGIscopefor successfully
authenticated requests.fromfastapiimportFastAPI,Requestfrommauth_client.constsimportENV_APP_UUID,ENV_PROTOCOL_VERSIONfrommauth_client.middlewaresimportMAuthASGIMiddlewareapp=FastAPI()app.add_middleware(MAuthASGIMiddleware,exempt={"/app_status"})@app.get("/")asyncdefroot(request:Request):return{"msg":"authenticated","app_uuid":request.scope[ENV_APP_UUID],"protocol_version":request.scope[ENV_PROTOCOL_VERSION],}@app.get("/app_status")asyncdefapp_status():return{"msg":"this route is exempt from authentication",}ContributingSeeCONTRIBUTING