Browse Source

Python "Create Project" wizards (part 3): `flask`, `gcpfunction`, `pyramid`, `python`, `quart`, `rq`, `sanic` (#56563)

Updated getting started wizards for Python platforms: `flask`,
`gcpfunction`, `pyramid`, `python`, `quart`, `rq`, `sanic`
Making sure the feature checkboxes are there and work and also a
"Verify" section is present.
Anton Pirker 1 year ago
parent
commit
ebd28c8c3e

+ 0 - 3
static/app/components/onboarding/productSelection.tsx

@@ -134,17 +134,14 @@ export const platformProductAvailability = {
     ProductSolution.PERFORMANCE_MONITORING,
     ProductSolution.PROFILING,
   ],
-  'python-pyramid': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
   'python-quart': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
   'python-rq': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
-  'python-sanic': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
   'python-serverless': [
     ProductSolution.PERFORMANCE_MONITORING,
     ProductSolution.PROFILING,
   ],
   'python-tornado': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
   'python-starlette': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
-  'python-tryton': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
   'python-wsgi': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
   'java-spring-boot': [ProductSolution.PERFORMANCE_MONITORING],
 } as Record<PlatformKey, ProductSolution[]>;

+ 0 - 1
static/app/gettingStartedDocs/python/bottle.tsx

@@ -8,7 +8,6 @@ import {t, tct} from 'sentry/locale';
 // Configuration Start
 const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
     # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
     traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%

+ 54 - 32
static/app/gettingStartedDocs/python/flask.tsx

@@ -6,16 +6,22 @@ import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
+const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
+    # of transactions for performance monitoring.
+    traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
     # of sampled transactions.
     # We recommend adjusting this value in production.
     profiles_sample_rate=1.0,`;
 
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
+const introduction = (
+  <p>
+    {tct('The Flask integration adds support for the [link:Flask Framework].', {
+      link: <ExternalLink href="https://flask.palletsprojects.com" />,
+    })}
+  </p>
+);
 
 export const steps = ({
   sentryInitContent,
@@ -27,11 +33,10 @@ export const steps = ({
     description: (
       <p>
         {tct(
-          'The Flask integration adds support for the [flaskWebFrameworkLink:Flask Web Framework].',
+          'Install [sentrySdkCode:sentry-sdk] from PyPI with the [sentryFlaskCode:flask] extra:',
           {
-            flaskWebFrameworkLink: (
-              <ExternalLink href="https://flask.palletsprojects.com/en/2.3.x/" />
-            ),
+            sentrySdkCode: <code />,
+            sentryFlaskCode: <code />,
           }
         )}
       </p>
@@ -39,25 +44,21 @@ export const steps = ({
     configurations: [
       {
         language: 'bash',
-        description: (
-          <p>
-            {tct(
-              'Install [sentrySdkCode:sentry-sdk] from PyPI with the [sentryFlaskCode:flask] extra:',
-              {
-                sentrySdkCode: <code />,
-                sentryFlaskCode: <code />,
-              }
-            )}
-          </p>
-        ),
         code: "pip install --upgrade 'sentry-sdk[flask]'",
       },
     ],
   },
   {
     type: StepType.CONFIGURE,
-    description: t(
-      'To configure the SDK, initialize it with the integration before or after your app has been initialized:'
+    description: (
+      <p>
+        {tct(
+          'If you have the [codeFlask:flask] package in your dependencies, the Flask integration will be enabled automatically when you initialize the Sentry SDK. Initialize the Sentry SDK before your app has been initialized:',
+          {
+            codeFlask: <code />,
+          }
+        )}
+      </p>
     ),
     configurations: [
       {
@@ -65,7 +66,6 @@ export const steps = ({
         code: `
 import sentry_sdk
 from flask import Flask
-from sentry_sdk.integrations.flask import FlaskIntegration
 
 sentry_sdk.init(
 ${sentryInitContent}
@@ -92,15 +92,39 @@ app = Flask(__name__)
     configurations: [
       {
         language: 'python',
-        code: `
-@app.route('/debug-sentry')
-def trigger_error():
-  division_by_zero = 1 / 0
+        code: `from flask import Flask
+import sentry_sdk
+
+sentry_sdk.init(
+${sentryInitContent}
+)
+
+app = Flask(__name__)
+
+@app.route("/")
+def hello_world():
+  1/0  # raises an error
+  return "<p>Hello, World!</p>"
         `,
       },
     ],
-    additionalInfo: t(
-      'Visiting this route will trigger an error that will be captured by Sentry.'
+    additionalInfo: (
+      <span>
+        <p>
+          {tct(
+            'When you point your browser to [link:http://localhost:5000/] a transaction in the Performance section of Sentry will be created.',
+            {
+              link: <ExternalLink href="http://localhost:5000/" />,
+            }
+          )}
+        </p>
+        <p>
+          {t(
+            'Additionally, an error event will be sent to Sentry and will be connected to the transaction.'
+          )}
+        </p>
+        <p>{t('It takes a couple of moments for the data to appear in Sentry.')}</p>
+      </span>
     ),
   },
 ];
@@ -113,10 +137,7 @@ export function GettingStartedWithFlask({
 }: ModuleProps) {
   const otherConfigs: string[] = [];
 
-  let sentryInitContent: string[] = [
-    `    dsn="${dsn}",`,
-    `    integrations=[FlaskIntegration()],`,
-  ];
+  let sentryInitContent: string[] = [`    dsn="${dsn}",`];
 
   if (activeProductSelection.includes(ProductSolution.PERFORMANCE_MONITORING)) {
     otherConfigs.push(performanceConfiguration);
@@ -130,6 +151,7 @@ export function GettingStartedWithFlask({
 
   return (
     <Layout
+      introduction={introduction}
       steps={steps({
         sentryInitContent: sentryInitContent.join('\n'),
       })}

+ 3 - 5
static/app/gettingStartedDocs/python/gcpfunctions.tsx

@@ -11,17 +11,15 @@ import {t, tct} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 
 // Configuration Start
+const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
+    # of transactions for performance monitoring.
+    traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
     # of sampled transactions.
     # We recommend adjusting this value in production.
     profiles_sample_rate=1.0,`;
 
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 export const steps = ({
   dsn,
   sentryInitContent,

+ 56 - 47
static/app/gettingStartedDocs/python/pyramid.tsx

@@ -2,29 +2,14 @@ import ExternalLink from 'sentry/components/links/externalLink';
 import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout';
 import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
 import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
-import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
-
-const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
-    # of sampled transactions.
-    # We recommend adjusting this value in production.
-    profiles_sample_rate=1.0,`;
-
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 const introduction = (
   <p>
-    {tct(
-      'The Pyramid integration adds support for the [link:Pyramid Web Framework]. It requires Pyramid 1.6 or later.',
-      {
-        link: <ExternalLink href="https://trypyramid.com/" />,
-      }
-    )}
+    {tct('The Pyramid integration adds support for the [link:Pyramid Web Framework].', {
+      link: <ExternalLink href="https://trypyramid.com/" />,
+    })}
   </p>
 );
 
@@ -45,58 +30,82 @@ export const steps = ({
   },
   {
     type: StepType.CONFIGURE,
-    description: t(
-      'To configure the SDK, initialize it with the integration before or after your app has been created:'
+    description: (
+      <p>
+        {tct(
+          'If you have the [codePyramid:pyramid] package in your dependencies, the Pyramid integration will be enabled automatically when you initialize the Sentry SDK. Initialize the Sentry SDK before your app has been initialized:',
+          {
+            codePyramid: <code />,
+          }
+        )}
+      </p>
     ),
     configurations: [
       {
         language: 'python',
         code: `
 from pyramid.config import Configurator
-from wsgiref.simple_server import make_server
-
 import sentry_sdk
-from sentry_sdk.integrations.pyramid import PyramidIntegration
 
 sentry_sdk.init(
 ${sentryInitContent}
 )
 
-def sentry_debug(request):
-    division_by_zero = 1 / 0
-
 with Configurator() as config:
-    config.add_route('sentry-debug', '/')
-    config.add_view(sentry_debug, route_name='sentry-debug')
-    app = config.make_wsgi_app()
+    # ...
+      `,
+      },
+    ],
+  },
+  {
+    type: StepType.VERIFY,
+    description: t(
+      'You can easily verify your Sentry installation by creating a view that triggers an error:'
+    ),
+    configurations: [
+      {
+        language: 'python',
+        code: `from wsgiref.simple_server import make_server
+from pyramid.config import Configurator
+from pyramid.response import Response
+
+sentry_sdk.init(
+${sentryInitContent}
+)
+
+def hello_world(request):
+    1/0  # raises an error
+    return Response('Hello World!')
+
+if __name__ == '__main__':
+    with Configurator() as config:
+        config.add_route('hello', '/')
+        config.add_view(hello_world, route_name='hello')
+        app = config.make_wsgi_app()
+
     server = make_server('0.0.0.0', 6543, app)
     server.serve_forever()
-      `,
+        `,
       },
     ],
+    additionalInfo: (
+      <p>
+        {tct(
+          'When you point your browser to [link:http://localhost:6543/] an error event will be sent to Sentry.',
+          {
+            link: <ExternalLink href="http://localhost:6543/" />,
+          }
+        )}
+      </p>
+    ),
   },
 ];
 // Configuration End
 
-export function GettingStartedWithPyramid({
-  dsn,
-  activeProductSelection = [],
-  ...props
-}: ModuleProps) {
+export function GettingStartedWithPyramid({dsn, ...props}: ModuleProps) {
   const otherConfigs: string[] = [];
 
-  let sentryInitContent: string[] = [
-    `    dsn="${dsn}",`,
-    `    integrations=[PyramidIntegration()],`,
-  ];
-
-  if (activeProductSelection.includes(ProductSolution.PERFORMANCE_MONITORING)) {
-    otherConfigs.push(performanceConfiguration);
-  }
-
-  if (activeProductSelection.includes(ProductSolution.PROFILING)) {
-    otherConfigs.push(profilingConfiguration);
-  }
+  let sentryInitContent: string[] = [`    dsn="${dsn}",`];
 
   sentryInitContent = sentryInitContent.concat(otherConfigs);
 

+ 3 - 5
static/app/gettingStartedDocs/python/python.tsx

@@ -5,17 +5,15 @@ import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
+const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
+    # of transactions for performance monitoring.
+    traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
     # of sampled transactions.
     # We recommend adjusting this value in production.
     profiles_sample_rate=1.0,`;
 
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 export const steps = ({
   sentryInitContent,
 }: {

+ 63 - 14
static/app/gettingStartedDocs/python/quart.tsx

@@ -8,28 +8,22 @@ import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
+const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
+    # of transactions for performance monitoring.
+    traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
     # of sampled transactions.
     # We recommend adjusting this value in production.
     profiles_sample_rate=1.0,`;
 
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 const introduction = (
   <Fragment>
     <p>
-      {tct(
-        'The Quart integration adds support for the Quart Web Framework. We support Quart versions 0.16.1 and higher.',
-        {
-          link: <ExternalLink href="https://gitlab.com/pgjones/quart" />,
-        }
-      )}
+      {tct('The Quart integration adds support for the [link:Quart Web Framework].', {
+        link: <ExternalLink href="https://quart.palletsprojects.com/" />,
+      })}
     </p>
-    {t('A Python version of "3.7" or higher is also required.')}
   </Fragment>
 );
 
@@ -40,11 +34,21 @@ export const steps = ({
 }): LayoutProps['steps'] => [
   {
     type: StepType.INSTALL,
-    description: <p>{tct('Install [code:sentry-sdk] from PyPI:', {code: <code />})}</p>,
+    description: (
+      <p>
+        {tct(
+          'Install [sentrySdkCode:sentry-sdk] from PyPI with the [sentryQuartCode:quart] extra:',
+          {
+            sentrySdkCode: <code />,
+            sentryQuartCode: <code />,
+          }
+        )}
+      </p>
+    ),
     configurations: [
       {
         language: 'bash',
-        code: '$ pip install --upgrade sentry-sdk',
+        code: '$ pip install --upgrade sentry-sdk[quart]',
       },
     ],
   },
@@ -70,6 +74,51 @@ app = Quart(__name__)
       },
     ],
   },
+  {
+    type: StepType.VERIFY,
+    description: t(
+      'You can easily verify your Sentry installation by creating a route that triggers an error:'
+    ),
+    configurations: [
+      {
+        language: 'python',
+        code: `from quart import Quart
+import sentry_sdk
+
+sentry_sdk.init(
+${sentryInitContent}
+)
+
+app = Quart(__name__)
+
+@app.route("/")
+async def hello():
+    1/0  # raises an error
+    return {"hello": "world"}
+
+app.run()
+        `,
+      },
+    ],
+    additionalInfo: (
+      <span>
+        <p>
+          {tct(
+            'When you point your browser to [link:http://localhost:5000/] a transaction in the Performance section of Sentry will be created.',
+            {
+              link: <ExternalLink href="http://localhost:5000/" />,
+            }
+          )}
+        </p>
+        <p>
+          {t(
+            'Additionally, an error event will be sent to Sentry and will be connected to the transaction.'
+          )}
+        </p>
+        <p>{t('It takes a couple of moments for the data to appear in Sentry.')}</p>
+      </span>
+    ),
+  },
 ];
 // Configuration End
 

+ 110 - 16
static/app/gettingStartedDocs/python/rq.tsx

@@ -6,17 +6,15 @@ import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
+const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
+    # of transactions for performance monitoring.
+    traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
     # of sampled transactions.
     # We recommend adjusting this value in production.
     profiles_sample_rate=1.0,`;
 
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 const introduction = (
   <p>
     {tct('The RQ integration adds support for the [link:RQ Job Queue System].', {
@@ -33,18 +31,28 @@ export const steps = ({
   {
     type: StepType.CONFIGURE,
     description: (
-      <p>
-        {tct('Create a file called [code:mysettings.py] with the following content:', {
-          code: <code />,
-        })}
-      </p>
+      <span>
+        <p>
+          {tct(
+            'If you have the [codeRq:rq] package in your dependencies, the RQ integration will be enabled automatically when you initialize the Sentry SDK.',
+            {
+              codeRq: <code />,
+            }
+          )}
+        </p>
+        <p>
+          {tct('Create a file called [code:mysettings.py] with the following content:', {
+            code: <code />,
+          })}
+        </p>
+      </span>
     ),
     configurations: [
       {
         language: 'python',
         code: `
+# mysettings.py
 import sentry_sdk
-from sentry_sdk.integrations.rq import RqIntegration
 
 sentry_sdk.init(
 ${sentryInitContent}
@@ -57,10 +65,99 @@ ${sentryInitContent}
         code: `
 rq worker \
 -c mysettings \  # module name of mysettings.py
---sentry-dsn=""  # only necessary for RQ < 1.0
+--sentry-dsn="..."  # only necessary for RQ < 1.0
         `,
       },
     ],
+    additionalInfo: (
+      <p>
+        {tct(
+          'Generally, make sure that the call to [code:init] is loaded on worker startup, and not only in the module where your jobs are defined. Otherwise, the initialization happens too late and events might end up not being reported.',
+          {code: <code />}
+        )}
+      </p>
+    ),
+  },
+  {
+    type: StepType.VERIFY,
+    description: (
+      <p>
+        {' '}
+        {tct(
+          'To verify, create a simple job and a [code:main.py] script that enqueues the job in RQ, then start an RQ worker to run the job:',
+          {
+            code: <code />,
+          }
+        )}
+      </p>
+    ),
+    configurations: [
+      {
+        description: <h5>{t('Job definition')}</h5>,
+        language: 'python',
+        code: `# jobs.py
+def hello(name):
+    1/0  # raises an error
+    return "Hello %s!" % name
+        `,
+      },
+      {
+        description: <h5>{t('Settings for worker')}</h5>,
+        language: 'python',
+        code: `# mysettings.py
+import sentry_sdk
+
+# Sentry configuration for RQ worker processes
+sentry_sdk.init(
+${sentryInitContent}
+)
+        `,
+      },
+      {
+        description: <h5>{t('Main Python Script')}</h5>,
+        language: 'python',
+        code: `# main.py
+from redis import Redis
+from rq import Queue
+
+from jobs import hello
+
+import sentry_sdk
+
+# Sentry configuration for main.py process (same as above)
+sentry_sdk.init(
+${sentryInitContent}
+)
+
+q = Queue(connection=Redis())
+with sentry_sdk.start_transaction(name="testing_sentry"):
+    result = q.enqueue(hello, "World")
+        `,
+      },
+    ],
+    additionalInfo: (
+      <div>
+        <p>
+          {tct(
+            'When you run [codeMain:python main.py] a transaction named [codeTrxName:testing_sentry] in the Performance section of Sentry will be created.',
+            {
+              codeMain: <code />,
+              codeTrxName: <code />,
+            }
+          )}
+        </p>
+        <p>
+          {tct(
+            'If you run the RQ worker with [codeWorker:rq worker -c mysettings] a transaction for the execution of [codeFunction:hello()] will be created. Additionally, an error event will be sent to Sentry and will be connected to the transaction.',
+            {
+              codeWorker: <code />,
+              codeFunction: <code />,
+            }
+          )}
+        </p>
+        <p>{t('It takes a couple of moments for the data to appear in Sentry.')}</p>
+      </div>
+    ),
   },
 ];
 // Configuration End
@@ -72,10 +169,7 @@ export function GettingStartedWithRq({
 }: ModuleProps) {
   const otherConfigs: string[] = [];
 
-  let sentryInitContent: string[] = [
-    `    dsn="${dsn}",`,
-    `    integrations=[RqIntegration()],`,
-  ];
+  let sentryInitContent: string[] = [`    dsn="${dsn}",`];
 
   if (activeProductSelection.includes(ProductSolution.PERFORMANCE_MONITORING)) {
     otherConfigs.push(performanceConfiguration);

+ 64 - 66
static/app/gettingStartedDocs/python/sanic.tsx

@@ -1,54 +1,16 @@
-import {Fragment} from 'react';
-
 import ExternalLink from 'sentry/components/links/externalLink';
-import List from 'sentry/components/list';
-import ListItem from 'sentry/components/list/listItem';
 import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout';
 import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
 import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
-import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
-
-const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
-    # of sampled transactions.
-    # We recommend adjusting this value in production.
-    profiles_sample_rate=1.0,`;
-
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 const introduction = (
-  <Fragment>
-    <p>
-      {tct(
-        'The Sanic integration adds support for the [link:Sanic Web Framework]. We support the following versions:',
-        {
-          link: <ExternalLink href="https://github.com/sanic-org/sanic" />,
-        }
-      )}
-    </p>
-    <List symbol="bullet">
-      <ListItem>0.8</ListItem>
-      <ListItem>18.12</ListItem>
-      <ListItem>19.12</ListItem>
-      <ListItem>20.12</ListItem>
-      <ListItem>{t('Any version of the form "x.12" (LTS versions).')}</ListItem>
-    </List>
-    <p>
-      {tct(
-        '[strong:We do support all versions of Sanic]. However, Sanic versions between LTS releases should be considered Early Adopter. We may not support all the features in these non-LTS versions, since non-LTS versions change quickly and [link:have introduced breaking changes in the past], without prior notice.',
-        {
-          strong: <strong />,
-          link: <ExternalLink href="https://github.com/sanic-org/sanic/issues/1532" />,
-        }
-      )}
-    </p>
-    {t('A Python version of "3.6" or greater is also required.')}
-  </Fragment>
+  <p>
+    {tct('The Sanic integration adds support for the [link:Sanic Web Framework].', {
+      link: <ExternalLink href="https://github.com/sanic-org/sanic" />,
+    })}
+  </p>
 );
 
 export const steps = ({
@@ -58,11 +20,21 @@ export const steps = ({
 }): LayoutProps['steps'] => [
   {
     type: StepType.INSTALL,
-    description: <p>{tct('Install [code:sentry-sdk] from PyPI:', {code: <code />})}</p>,
+    description: (
+      <p>
+        {tct(
+          'Install [sentrySdkCode:sentry-sdk] from PyPI with the [sentrySanicCode:sanic] extra:',
+          {
+            sentrySdkCode: <code />,
+            sentrySanicCode: <code />,
+          }
+        )}
+      </p>
+    ),
     configurations: [
       {
         language: 'bash',
-        code: '$ pip install --upgrade sentry-sdk',
+        code: '$ pip install --upgrade sentry-sdk[sanic]',
       },
       {
         description: (
@@ -82,16 +54,22 @@ export const steps = ({
   },
   {
     type: StepType.CONFIGURE,
-    description: t(
-      'To configure the SDK, initialize it with the integration before or after your app has been initialized:'
+    description: (
+      <p>
+        {tct(
+          'If you have the [codeSanic:sanic] package in your dependencies, the Sanic integration will be enabled automatically when you initialize the Sentry SDK. Initialize the Sentry SDK before your app has been initialized:',
+          {
+            codeSanic: <code />,
+          }
+        )}
+      </p>
     ),
     configurations: [
       {
         language: 'python',
         code: `
-import sentry_sdk
-from sentry_sdk.integrations.sanic import SanicIntegration
 from sanic import Sanic
+import sentry_sdk
 
 sentry_sdk.init(
 ${sentryInitContent}
@@ -102,28 +80,48 @@ app = Sanic(__name__)
       },
     ],
   },
+  {
+    type: StepType.VERIFY,
+    description: t(
+      'You can easily verify your Sentry installation by creating a route that triggers an error:'
+    ),
+    configurations: [
+      {
+        language: 'python',
+        code: `from sanic import Sanic
+from sanic.response import text
+
+sentry_sdk.init(
+${sentryInitContent}
+)
+
+app = Sanic(__name__)
+
+@app.get("/")
+async def hello_world(request):
+    1 / 0  # raises an error
+    return text("Hello, world.")
+        `,
+      },
+    ],
+    additionalInfo: (
+      <p>
+        {tct(
+          'When you point your browser to [link:http://localhost:8000/] an error will be sent to Sentry.',
+          {
+            link: <ExternalLink href="http://localhost:8000/" />,
+          }
+        )}
+      </p>
+    ),
+  },
 ];
 // Configuration End
 
-export function GettingStartedWithSanic({
-  dsn,
-  activeProductSelection = [],
-  ...props
-}: ModuleProps) {
+export function GettingStartedWithSanic({dsn, ...props}: ModuleProps) {
   const otherConfigs: string[] = [];
 
-  let sentryInitContent: string[] = [
-    `    dsn="${dsn}",`,
-    `    integrations=[SanicIntegration()],`,
-  ];
-
-  if (activeProductSelection.includes(ProductSolution.PERFORMANCE_MONITORING)) {
-    otherConfigs.push(performanceConfiguration);
-  }
-
-  if (activeProductSelection.includes(ProductSolution.PROFILING)) {
-    otherConfigs.push(profilingConfiguration);
-  }
+  let sentryInitContent: string[] = [`    dsn="${dsn}",`];
 
   sentryInitContent = sentryInitContent.concat(otherConfigs);
 

+ 40 - 5
static/app/gettingStartedDocs/python/serverless.tsx

@@ -8,17 +8,15 @@ import {ProductSolution} from 'sentry/components/onboarding/productSelection';
 import {t, tct} from 'sentry/locale';
 
 // Configuration Start
+const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
+    # of transactions for performance monitoring.
+    traces_sample_rate=1.0,`;
 
 const profilingConfiguration = `    # Set profiles_sample_rate to 1.0 to profile 100%
     # of sampled transactions.
     # We recommend adjusting this value in production.
     profiles_sample_rate=1.0,`;
 
-const performanceConfiguration = `    # Set traces_sample_rate to 1.0 to capture 100%
-    # of transactions for performance monitoring.
-    # We recommend adjusting this value in production.
-    traces_sample_rate=1.0,`;
-
 export const steps = ({
   sentryInitContent,
 }: {
@@ -68,6 +66,43 @@ def my_function(...): ...
       },
     ],
   },
+  {
+    type: StepType.VERIFY,
+    description: (
+      <p>
+        {tct(
+          'Wrap a functions with the [code:serverless_function] that triggers an error:',
+          {
+            code: <code />,
+          }
+        )}
+      </p>
+    ),
+    configurations: [
+      {
+        language: 'python',
+        code: `import sentry_sdk
+from sentry_sdk.integrations.serverless import serverless_function
+
+sentry_sdk.init(
+${sentryInitContent}
+)
+
+@serverless_function
+def my_function(...):
+    1/0  # raises an error
+      `,
+      },
+    ],
+    additionalInfo: (
+      <p>
+        {tct(
+          'Now deploy your function. When you now run your function an error event will be sent to Sentry.',
+          {}
+        )}
+      </p>
+    ),
+  },
 ];
 // Configuration End
 

Some files were not shown because too many files changed in this diff