Package: notion-oauth-handler
notion-oauth-handlerPython server/handler of Notion's OAuth 2 for public integrationsProvides:basic code for handling OAuth in Notion;a configurable HTTP server that can be extended by plugging in custom application code via Python entrypoints;aboilerplateto be used as a starting point for your integration.PrerequisitesFirst of all you will need to create a public integration in Notion
and save its ID and secret key.Notion OAuth requires an HTTPS URL.
This means you will need to register a domain name
and create a valid certificate for it.
There is no way to fully test it using127.0.0.1:8000!UsageThere is a wide range of different ways you can usenotion-oauth-handlerin your project, but we'll cover just the two main options here.As a standalone serverTo integratenotion-oauth-handlerinto your app you will need to do the following:implement a "consumer" class (by subclassingNotionOAuthConsumeror its existing subclasses)
that will accept user tokens and save them somewhere in your app (e.g. in a database)define custom methods for the main web server view (subclass ofNotionOAuthRedirectView)add entrypoints for these classes to your python packagedefine yournotion-oauth-handlerconfigurationrun your web serverSee the corresponding sections below for mnore in-depth descriptionsAs part of an existingaiohttpapplicationIn this case you will still need to:define the consumer and view classesand register them as package entrypoints
from the above description, but plugging the handler into your app is
entirely up to you.Seemake_app in the default app moduleConsumer classThis class defines how the authentication info is handled (e.g. saved to a database).
You can also add some external API hooks here.
This is the place to define any actions that need to be taken
when a user grants access to your public integration.fromnotion_oauth_handler.core.dtoimportAuthRedirectInfo,TokenResponseInfofromnotion_oauth_handler.core.consumerimportDefaultNotionOAuthConsumerclassMyAppNotionOAuthConsumer(DefaultNotionOAuthConsumer):asyncdefconsume_redirect_error(self,error_text:str)->None:# Optional.# What to do if an error has been raised.# Log it, call an API hook, whatever.passasyncdefconsume_token_info(self,token_info:TokenResponseInfo,state_info:AuthRedirectInfo)->None:# Required.# The main logic goes here.# `token_info` contains the user access token received from Notion# while `state_info.state` is the data intially passed to Notion in the URL# (e.g. it may contain a user or app ID or something like that)passFor a bit more flexibility you can use the parent class,NotionOAuthConsumer,
and redefine some more of its methods.Web view classIn the basic scenario, you only need to define the server's responses,
without any token-handling logic here.fromhttpimportHTTPStatusfromaiohttp.webimportResponsefromnotion_oauth_handler.core.dtoimportTokenResponseInfofromnotion_oauth_handler.server.auth_viewimportDefaultNotionOAuthRedirectViewclassMyAppNotionOAuthRedirectView(DefaultNotionOAuthRedirectView):asyncdefmake_access_denied_response(self,error_text:str)->Response:returnself.make_response(text='MyApp says: Error',status=HTTPStatus.FORBIDDEN)asyncdefmake_auth_response(self,token_info:TokenResponseInfo)->Response:returnself.make_response(text='MyApp says: OK',status=HTTPStatus.OK)One possibility is to generate a redirect or link back to your main app here.
Whether to return HTML, JSON or plain  text here is completely up to you.Try to stick to the idea that there should be any complex business logic
for token handling here - all that should go into your consumer class.Registering entrypointsOnce you've defined all the logic in the classes above,
you need to make them available fornotion-auth-handlerby declaring them as entrypoints in your Python project configurationIf you are using asetup.cfgfile for all your settings,
then it will look like this:[options.entry_points]# Your app-specific entrypoints (if any)# ...# Notion OAuth entrypointsnotion_oauth_handler.consumer=my_app=my_app.web.notion_auth.consumer:MyAppNotionOAuthConsumernotion_oauth_handler.auth_view=my_app=my_app.web.notion_auth.view:MyAppNotionOAuthRedirectViewAnd for asetup.pyfile, like this:fromsetuptoolsimportsetupsetup(# Your project settings# ...entry_points={'notion_oauth_handler.consumer':['my_app = my_app.web.notion_auth.consumer:MyAppNotionOAuthConsumer',],'notion_oauth_handler.auth_view':['my_app = my_app.web.notion_auth.view:MyAppNotionOAuthRedirectView',],},)wheremy_app.web.notion_auth.consumer:MyAppNotionOAuthConsumerandmy_app.web.notion_auth.view:MyAppNotionOAuthRedirectViewindicate
where to find these classes in your code.Configuration fileNow you need to tellnotion-auth-handler, which of the possibly many
implementation entrypoints to call, which url paths to use in the server,
how to connect to your Notion integration, etc.
This is done via a configuration file.Seethe boilerplate config filefor all the options.Note that all public Notion integrations are required to have "Terms of Use"
and "Privacy Policy" documents.
Since using the standalone server mode assumes that you don't have another
web server,notion-auth-handlercan host these documents for you.
See the[notion_oauth_handler.documents]section of the example configuration file.Web servernotion-oauth-handlercan run in practically any setup,
but a sampleGunicornconfiguratuon fileis included just for convenience.