def test_large_json_request(sentry_init, capture_events, route, get_client): sentry_init(integrations=[PyramidIntegration()]) data = {"foo": {"bar": "a" * 2000}} @route("/") def index(request): assert request.json == data assert request.text == json.dumps(data) assert not request.POST capture_message("hi") return Response("ok") events = capture_events() client = get_client() client.post("/", content_type="application/json", data=json.dumps(data)) event, = events assert event["_meta"]["request"]["data"]["foo"]["bar"] == { "": { "len": 2000, "rem": [["!limit", "x", 509, 512]] } } assert len(event["request"]["data"]["foo"]["bar"]) == 512
def test_files_and_form(sentry_init, capture_events, route, get_client): sentry_init(integrations=[PyramidIntegration()], request_bodies="always") data = {"foo": "a" * 2000, "file": (BytesIO(b"hello"), "hello.txt")} @route("/") def index(request): capture_message("hi") return Response("ok") events = capture_events() client = get_client() client.post("/", data=data) event, = events assert event["_meta"]["request"]["data"]["foo"] == { "": {"len": 2000, "rem": [["!limit", "x", 509, 512]]} } assert len(event["request"]["data"]["foo"]) == 512 assert event["_meta"]["request"]["data"]["file"] == { "": {"len": 0, "rem": [["!raw", "x", 0, 0]]} } assert not event["request"]["data"]["file"]
def test_has_context(route, get_client, sentry_init, capture_events): sentry_init(integrations=[PyramidIntegration()]) events = capture_events() @route("/message/{msg}") def hi2(request): capture_message(request.matchdict["msg"]) return Response("hi") client = get_client() client.get("/message/yoo") event, = events assert event["message"] == "yoo" assert event["request"] == { "env": { "SERVER_NAME": "localhost", "SERVER_PORT": "80" }, "headers": { "Content-Length": "0", "Content-Type": "", "Host": "localhost" }, "method": "GET", "query_string": "", "url": "http://localhost/message/yoo", } assert event["transaction"] == "hi2"
def test_view_exceptions( get_client, route, sentry_init, capture_events, capture_exceptions ): sentry_init(integrations=[PyramidIntegration()]) events = capture_events() exceptions = capture_exceptions() add_breadcrumb({"message": "hi"}) @route("/errors") def errors(request): add_breadcrumb({"message": "hi2"}) 1 / 0 client = get_client() with pytest.raises(ZeroDivisionError): client.get("/errors") error, = exceptions assert isinstance(error, ZeroDivisionError) event, = events breadcrumb, = event["breadcrumbs"] assert breadcrumb["message"] == "hi2" assert event["exception"]["values"][0]["mechanism"]["type"] == "pyramid"
def test_error_in_errorhandler( sentry_init, pyramid_config, capture_events, route, get_client ): sentry_init(integrations=[PyramidIntegration()]) @route("/") def index(request): raise ValueError() def error_handler(err, request): 1 / 0 pyramid_config.add_view(error_handler, context=ValueError) events = capture_events() client = get_client() with pytest.raises(ZeroDivisionError): client.get("/") event1, event2 = events exception, = event1["exception"]["values"] assert exception["type"] == "ValueError" exception = event2["exception"]["values"][0] assert exception["type"] == "ZeroDivisionError"
def initialize_sentry_integration(): # pragma: no cover """\ Used to optionally initialize the Sentry service with this app. See https://docs.sentry.io/platforms/python/pyramid/ """ # This function is not under coverage because it is boilerplate # from the Sentry documentation. try: import sentry_sdk from sentry_sdk.integrations.pyramid import PyramidIntegration from sentry_sdk.integrations.celery import CeleryIntegration except ImportError: # This is an optional feature to be used when the dependency # and configuration are available. return # bail out early try: dsn = os.environ['SENTRY_DSN'] except KeyError: warnings.warn( "Sentry is not configured because SENTRY_DSN " "was not supplied.", AppStartUpWarning, ) else: sentry_sdk.init( dsn=dsn, integrations=[PyramidIntegration(), CeleryIntegration()], )
def includeme(config): # Initialize sentry and stash it in the registry sentry_sdk.init( dsn=config.registry.settings.get("sentry.dsn"), release=config.registry.settings.get("warehouse.commit"), transport=config.registry.settings.get("sentry.transport"), before_send=before_send, attach_stacktrace=True, integrations=[ # This allows us to not create a tween # and a tween handler as it automatically # integrates with pyramid PyramidIntegration(), CeleryIntegration(), SqlalchemyIntegration(), LoggingIntegration(), ], ) config.registry["sentry"] = sentry_sdk # Create a request method that'll get us the Sentry SDK in each request. config.add_request_method(_sentry, name="sentry", reify=True) # Wrap the WSGI object with the middle to catch any exceptions we don't # catch elsewhere. config.add_wsgi_middleware(SentryWsgiMiddleware)
def test_error_in_authenticated_userid( sentry_init, pyramid_config, capture_events, route, get_client ): from sentry_sdk.integrations.logging import LoggingIntegration sentry_init( send_default_pii=True, integrations=[ PyramidIntegration(), LoggingIntegration(event_level=logging.ERROR), ], ) logger = logging.getLogger("test_pyramid") class AuthenticationPolicy(object): def authenticated_userid(self, request): logger.error("failed to identify user") pyramid_config.set_authorization_policy(ACLAuthorizationPolicy()) pyramid_config.set_authentication_policy(AuthenticationPolicy()) events = capture_events() client = get_client() client.get("/message") assert len(events) == 1
def test_transaction_style( sentry_init, get_client, capture_events, transaction_style, expected_transaction ): sentry_init(integrations=[PyramidIntegration(transaction_style=transaction_style)]) events = capture_events() client = get_client() client.get("/message") event, = events assert event["transaction"] == expected_transaction
def initialize_sentry_sdk(self): import sentry_sdk from sentry_sdk.integrations.pyramid import PyramidIntegration from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration # Patch MAX_STRING_LENGTH to prevent clipping of big error messages, # especially for mako template tracebacks. sentry_sdk.utils.MAX_STRING_LENGTH = 8192 sentry_sdk.init( self.options['dsn'], integrations=[ PyramidIntegration(), SqlalchemyIntegration(), ], ignore_errors=[KeyboardInterrupt], environment=self.options['environment'], shutdown_timeout=self.options['shutdown_timeout'], ) ts = Setting.__table__ qs = ts.select().where(sqlalchemy.and_( ts.c.component == 'core', ts.c.name == 'instance_id')) event_user = None def add_instance_id(event, hint): nonlocal event_user if event_user is None: try: row = self.env.core.DBSession.connection() \ .execute(qs).fetchone() except sqlalchemy.exc.ProgrammingError: logger.debug( "Failed to get instance_id, the database may not " "have been initialized yet") except Exception: logger.error("Got an exception while getting instance_id") else: if row is not None: instance_id = json.loads(row.value) event_user = dict(id=instance_id) else: logger.debug("Missing instance_id") if event_user is not None: event['user'] = event_user return event with sentry_sdk.configure_scope() as scope: scope.add_event_processor(add_instance_id)
def __init__(self, env, settings): super(SentryComponent, self).__init__(env, settings) if 'dsn' in self.options: sentry_sdk.init( self.options['dsn'], integrations=[ PyramidIntegration(), SqlalchemyIntegration(), ], environment=self.options['environment'], shutdown_timeout=self.options['shutdown_timeout'], )
def main(global_config, **settings): """ Connect to sentry """ sentry_sdk.init( dsn="https://[email protected]/1845128", integrations=[PyramidIntegration()] ) """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: config.include('.models') config.include('pyramid_jinja2') config.include('.routes') config.scan() return config.make_wsgi_app()
def configure(self): super(Portal, self).configure() self.configure_zca() mimetypes.add_type('application/font-woff', '.woff') mimetypes.add_type('application/x-font-ttf', '.ttf') registry = pyramid.registry.Registry( bases=(zope.component.getGlobalSiteManager(),)) if self.settings.get('sentry.dsn', None): version = sw.allotmentclub.version.__version__ sentry_sdk.init( release=f"sw-allotmentclub-backend@{version}", dsn=self.settings['sentry.dsn'], integrations=[PyramidIntegration(), SqlalchemyIntegration()]) self.config = config = pyramid.config.Configurator( settings=self.settings, registry=registry) config.setup_registry(settings=self.settings) config.include('pyramid_beaker') config.include('pyramid_exclog') config.include('pyramid_tm') if self.testing: config.include('pyramid_mailer.testing') elif config.registry.settings.get('mail.enable') == 'false': config.include('sw.allotmentclub.printmailer') else: config.include('sw.allotmentclub.logmailer') # self.add_csrf_check() config.add_renderer( 'json', risclog.sqlalchemy.serializer.json_renderer_factory( serializer=json_serializer)) config.set_default_permission('view') config.set_authentication_policy(SessionAuthenticationPolicy()) config.set_authorization_policy(ACLAuthorizationPolicy()) config.set_root_factory( sw.allotmentclub.browser.auth.get_default_context) config.add_request_method( sw.allotmentclub.browser.auth.get_user, 'user', property=True) self.add_routes() config.scan(package=sw.allotmentclub.browser, ignore=sw.allotmentclub.SCAN_IGNORE_TESTS)
def main(global_config: Dict[str, str], **settings: str) -> PrefixMiddleware: """Configure and return a Pyramid WSGI application.""" settings["tildes.open_registration"] = asbool( settings.get("tildes.open_registration", "false")) config = Configurator(settings=settings) config.include("cornice") config.include("pyramid_session_redis") config.include("pyramid_webassets") # include database first so the session and querying are available config.include("tildes.database") config.include("tildes.auth") config.include("tildes.jinja") config.include("tildes.json") config.include("tildes.request_methods") config.include("tildes.routes") config.include("tildes.tweens") config.add_webasset("javascript", Bundle(output="js/tildes.js")) config.add_webasset("javascript-third-party", Bundle(output="js/third_party.js")) config.add_webasset("css", Bundle(output="css/tildes.css")) config.add_webasset("site-icons-css", Bundle(output="css/site-icons.css")) config.scan("tildes.views") config.add_static_view("images", "/images") if settings.get("sentry_dsn"): sentry_sdk.init( dsn=settings["sentry_dsn"], integrations=[PyramidIntegration()], ignore_errors=[ValidationError], ) app = config.make_wsgi_app() force_port = global_config.get("prefixmiddleware_force_port") if force_port: prefixed_app = PrefixMiddleware(app, force_port=force_port) else: prefixed_app = PrefixMiddleware(app) return prefixed_app
def test_tween_ok(sentry_init, pyramid_config, capture_exceptions, route, get_client): sentry_init(integrations=[PyramidIntegration()]) errors = capture_exceptions() @route("/") def index(request): raise Exception() pyramid_config.add_tween( "tests.integrations.pyramid.test_pyramid.tween_factory", under=pyramid.tweens.INGRESS, ) client = get_client() client.get("/") assert not errors
def main(global_config, **settings): settings.update(parse_settings(settings)) config = Configurator(settings=settings) config.include("cornice") config.include("cornice_swagger") config.include("documentstore.pyramid_prometheus") config.scan() config.add_renderer("xml", XMLRenderer) config.add_renderer("text", PlainTextRenderer) mongo = adapters.MongoDB( settings["kernel.app.mongodb.dsn"], settings["kernel.app.mongodb.dbname"], options={ "replicaSet": settings["kernel.app.mongodb.replicaset"], "readPreference": settings["kernel.app.mongodb.readpreference"], "w": settings["kernel.app.mongodb.writeto"], }, ) if settings["kernel.app.mongodb.transactions.enabled"]: Session = adapters.TransactionalSession.partial(mongo) else: Session = adapters.Session.partial(mongo) LOGGER.warning( "transactional support is disabled and it may cause data loss. " "If the app is running in production, this is a huge mistake" ) config.add_request_method( lambda request: services.get_handlers(Session), "services", reify=True ) if settings["kernel.app.sentry.enabled"]: if settings["kernel.app.sentry.dsn"]: sentry_sdk.init( dsn=settings["kernel.app.sentry.dsn"], integrations=[PyramidIntegration(transaction_style="route_pattern")], release=f"scielo-kernel@{VERSION}", environment=settings["kernel.app.sentry.environment"], ) else: LOGGER.info("cannot setup Sentry: the dsn was not provided") return config.make_wsgi_app()
def test_errorhandler_ok(sentry_init, pyramid_config, capture_exceptions, route, get_client): sentry_init(integrations=[PyramidIntegration()]) errors = capture_exceptions() @route("/") def index(request): raise Exception() def errorhandler(exc, request): return Response("bad request") pyramid_config.add_view(errorhandler, context=Exception) client = get_client() client.get("/") assert not errors
def __init__(self, env, settings): super(SentryComponent, self).__init__(env, settings) if 'dsn' in self.options: # Patch MAX_STRING_LENGTH to prevent clipping of big error messages, # especially for mako template tracebacks. sentry_sdk.utils.MAX_STRING_LENGTH = 8192 sentry_sdk.init( self.options['dsn'], integrations=[ PyramidIntegration(), SqlalchemyIntegration(), ], ignore_errors=[KeyboardInterrupt], environment=self.options['environment'], shutdown_timeout=self.options['shutdown_timeout'], )
def test_flask_empty_json_request(sentry_init, capture_events, route, get_client, data): sentry_init(integrations=[PyramidIntegration()]) @route("/") def index(request): assert request.json == data assert request.text == json.dumps(data) assert not request.POST capture_message("hi") return Response("ok") events = capture_events() client = get_client() response = client.post("/", content_type="application/json", data=json.dumps(data)) assert response[1] == "200 OK" event, = events assert event["request"]["data"] == data
def test_bad_request_not_captured(sentry_init, pyramid_config, capture_events, route, get_client): import pyramid.httpexceptions as exc sentry_init(integrations=[PyramidIntegration()]) events = capture_events() @route("/") def index(request): raise exc.HTTPBadRequest() def errorhandler(exc, request): return Response("bad request") pyramid_config.add_view(errorhandler, context=exc.HTTPBadRequest) client = get_client() client.get("/") assert not events
def test_errorhandler_500(sentry_init, pyramid_config, capture_exceptions, route, get_client): sentry_init(integrations=[PyramidIntegration()]) errors = capture_exceptions() @route("/") def index(request): 1 / 0 def errorhandler(exc, request): return Response("bad request", status=500) pyramid_config.add_view(errorhandler, context=Exception) client = get_client() app_iter, status, headers = client.get("/") assert b"".join(app_iter) == b"bad request" assert status.lower() == "500 internal server error" (error, ) = errors assert isinstance(error, ZeroDivisionError)
def main(global_config, **settings): dsn = settings.get("sentry.dsn") or os.environ.get("SENTRY_DSN") if dsn: sentry_sdk.init( dsn=dsn, integrations=[ LoggingIntegration(), PyramidIntegration(), ], send_default_pii=True, request_bodies="always", environment=settings.get("sentry.environment"), ) config = Configurator( autocommit=True, settings=settings, authentication_policy=AuthenticationPolicy(settings['auth.file'], __name__), authorization_policy=AuthorizationPolicy(), route_prefix=ROUTE_PREFIX, ) config.include('pyramid_exclog') config.include("cornice") config.add_forbidden_view(forbidden) config.add_request_method(request_params, 'params', reify=True) config.add_request_method(authenticated_role, reify=True) config.add_request_method(check_accreditation) config.add_renderer('json', JSON(serializer=simplejson.dumps)) config.add_renderer('prettyjson', JSON(indent=4, serializer=simplejson.dumps)) config.add_renderer('jsonp', JSONP(param_name='opt_jsonp', serializer=simplejson.dumps)) config.add_renderer('prettyjsonp', JSONP(indent=4, param_name='opt_jsonp', serializer=simplejson.dumps)) # search for plugins plugins = settings.get('plugins') and settings['plugins'].split(',') for entry_point in iter_entry_points('openprocurement.audit.api.plugins'): if not plugins or entry_point.name in plugins: plugin = entry_point.load() plugin(config) pass # CouchDB connection aserver, server, db = set_api_security(settings) config.registry.couchdb_server = server if aserver: config.registry.admin_couchdb_server = aserver config.registry.db = db # readjust couchdb json decoder couchdb_json_decode() # Document Service key config.registry.docservice_url = settings.get('docservice_url') config.registry.docservice_username = settings.get('docservice_username') config.registry.docservice_password = settings.get('docservice_password') config.registry.docservice_upload_url = settings.get('docservice_upload_url') # config.registry.docservice_key = dockey = Signer(settings.get('dockey', '').decode('hex')) # config.registry.keyring = keyring = {} # dockeys = settings.get('dockeys') if 'dockeys' in settings else dockey.hex_vk() # for key in dockeys.split('\0'): # keyring[key[:8]] = Verifier(key) signing_key = settings.get('dockey', '') signer = SigningKey(signing_key, encoder=HexEncoder) if signing_key else SigningKey.generate() config.registry.docservice_key = signer verifier = signer.verify_key config.registry.keyring = { verifier.encode(encoder=HexEncoder)[:8].decode(): verifier } dockeys = settings.get('dockeys', '') for key in dockeys.split('\0'): if key: config.registry.keyring[key[:8]] = VerifyKey(key, encoder=HexEncoder) # migrate data if not os.environ.get('MIGRATION_SKIP'): for entry_point in iter_entry_points('openprocurement.audit.api.migrations'): plugin = entry_point.load() plugin(config.registry) config.registry.server_id = settings.get('id', '') # search subscribers subscribers_keys = [k for k in settings if k.startswith('subscribers.')] for k in subscribers_keys: subscribers = settings[k].split(',') for subscriber in subscribers: for entry_point in iter_entry_points('openprocurement.{}'.format(k), subscriber): if entry_point: plugin = entry_point.load() plugin(config) config.registry.health_threshold = float(settings.get('health_threshold', 512)) config.registry.health_threshold_func = settings.get('health_threshold_func', 'all') config.registry.update_after = asbool(settings.get('update_after', True)) config.registry.disable_opt_fields_filter = asbool(settings.get('disable_opt_fields_filter', False)) return config.make_wsgi_app()
def init_sentry(dsn): """ Helper function that initializes sentry SDK if a dsn is specified. """ if dsn: sentry_sdk.init( dsn, integrations=[PyramidIntegration(), SqlalchemyIntegration()])
######### sentry.io logging import sentry_sdk, os from sentry_sdk.integrations.pyramid import PyramidIntegration if 'SENTRY_DNS_MICHELANGLO' in os.environ: #this is not in the config file due to security as this github repo is public. sentry_sdk.init( dsn=os.environ['SENTRY_DNS_MICHELANGLO'], integrations=[PyramidIntegration()] ) from pyramid.config import Configurator from pyramid.session import SignedCookieSessionFactory def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(settings=settings) my_session_factory = SignedCookieSessionFactory('TIM barrels') ##temporary data config.set_session_factory(my_session_factory) config.include('.models') config.include('pyramid_mako') config.include('.routes') config.include('.security') config.include('.scheduler') config.scan() return config.make_wsgi_app()
from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response from sentry_sdk.integrations.pyramid import PyramidIntegration import sentry_sdk def hello_world(request): return 1 / 0 return Response('<h1>Hello world!</h1>') def test_func(request): return Response("<h1>Hi!, this is Paras Jain</h1>") if __name__ == '__main__': with Configurator() as config: config.add_route('', '/') config.add_view(hello_world, route_name='') config.add_route('test', '/test') config.add_view(test_func, route_name='test') sentry_sdk.init(dsn="", integrations=[PyramidIntegration()]) app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever()
def main(global_config, **settings): """ Return a Pyramid WSGI application. """ settings['config_uri'] = global_config['__file__'] # here we create the engine and bind it to the (not really a) session # factory settings = set_config(settings) if not session_maker_is_initialized(): configure_engine(settings) if settings.get('assembl_debug_signal', False): from assembl.lib import signals signals.listen() import os if 'UWSGI_ORIGINAL_PROC_NAME' in os.environ: # uwsgi does not load logging properly from pyramid.paster import setup_logging setup_logging(global_config['__file__']) # Sentry import sentry_sdk from sentry_sdk.integrations.pyramid import PyramidIntegration if settings.get('sentry_dsn', ''): sentry_sdk.init(dsn=settings['sentry_dsn'], integrations=[PyramidIntegration()]) from views.traversal import root_factory config = Configurator(registry=getGlobalSiteManager()) config.setup_registry(settings=settings, root_factory=root_factory) config.add_translation_dirs('assembl:locale/') config.set_locale_negotiator(my_locale_negotiator) config.add_tween('assembl.tweens.logging.logging_tween_factory', over="pyramid_tm.tm_tween_factory") config.include('.auth') config.include('.models') config.include('.indexing') config.include('.lib.logging') # Tasks first, because it includes ZCA registration (for now) config.include('.tasks') config.include('.lib.zmqlib') session_factory = session_factory_from_settings(settings) config.set_session_factory(session_factory) if not settings.get('nosecurity', False): # import after session to delay loading of BaseOps from auth.util import authentication_callback auth_policy_name = settings.get( "auth_policy_class", "assembl.auth.util.UpgradingSessionAuthenticationPolicy") auth_policy = resolver.resolve(auth_policy_name)( callback=authentication_callback) config.set_authentication_policy(auth_policy) config.set_authorization_policy(ACLAuthorizationPolicy()) # ensure default roles and permissions at startup from models import get_session_maker if not settings.get('in_migration', False): with transaction.manager: session = get_session_maker() from .lib.migration import bootstrap_db_data bootstrap_db_data(session, settings['config_uri'] != "testing.ini") config.add_static_view('static', 'static', cache_max_age=3600) config.add_static_view('static2', 'static2', cache_max_age=3600) config.include('.graphql') # This MUST be above views import config.include('cornice') # REST services library. # config.include('.lib.alembic') # config.include('.lib.email') config.include('.lib') config.include('.views') # jinja2 config.include('pyramid_jinja2') config.add_jinja2_extension('jinja2.ext.i18n') # Mailer config.include('pyramid_mailer') config.include('.view_def') wsgi_app = config.make_wsgi_app() if asbool(settings.get('sqltap', False)): import sqltap.wsgi wsgi_app = sqltap.wsgi.SQLTapMiddleware(wsgi_app) return wsgi_app
def main(global_config, **settings): del global_config # Unused if len(os.environ.get('SENTRY_URL', '')) > 0: sentry_sdk.init(dsn=os.environ.get('SENTRY_URL', ''), integrations=[PyramidIntegration()]) """ This function returns a Pyramid WSGI application. """ config = Configurator( root_factory=Root, settings=settings, locale_negotiator=locale_negotiator, authentication_policy=create_authentication(settings)) if os.environ.get('ALLOW_CORS', '0') == '1': config.add_subscriber(add_cors_headers_response_callback, NewRequest) if os.environ.get('DEBUG_TOOLBAR', '0') == '1': config.get_settings()['debugtoolbar.hosts'] = ['0.0.0.0/0'] config.include('pyramid_debugtoolbar') # Workaround to not have the error: distutils.errors.DistutilsArgError: no commands supplied distutils.core._setup_stop_after = 'config' config.add_route("lux_get_thumbnail", "/printproxy/thumbnail", request_method="GET") # overwrite print routes config.add_route("lux_printproxy_report_create", "/printproxy/report.{format}", request_method="POST") config.add_route("lux_printproxy_status", "/printproxy/status/{ref}.json", request_method="GET") config.add_route("lux_printproxy_report_get", "/printproxy/report/{ref}", request_method="GET") config.add_route("lux_printproxy_report_cancel", "/printproxy/cancel/{ref}", request_method="DELETE") config.include('c2cgeoportal_geoportal') distutils.core._setup_stop_after = None add_mako_renderer(config, '.appcache') config.add_translation_dirs('geoportailv3_geoportal:locale/') add_interface(config, 'main', INTERFACE_TYPE_NGEO_CATALOGUE, default=True) # ping routes config.add_route("ping", "/ping") # mymaps routes config.add_route("mymaps", "/mymaps", request_method="HEAD") config.add_route("mymaps_image", "/", request_method="HEAD") config.add_route("mymaps_get_full_mymaps", "mymaps/get_full_mymaps", request_method="GET") config.add_route("mymaps_getcategories", "mymaps/categories", request_method="GET") config.add_route("mymaps_getallcategories", "mymaps/allcategories", request_method="GET") config.add_route("generate_symbol_file", "/mymaps/generate_symbol_file", request_method="GET") config.add_route("mymaps_getpublicmaps", "/mymaps/public_maps", request_method="GET") config.add_route("mymaps_getpublicategories", "/mymaps/public_categories", request_method="GET") config.add_route("mymaps_getmaps", "/mymaps/maps", request_method="GET") config.add_route("mymaps_features", "/mymaps/features/{map_id}", request_method="GET") config.add_route("mymaps_map_info", "/mymaps/map_info/{map_id}", request_method="GET") config.add_route("predefined_wms", "/predefined_wms", request_method="GET") config.add_route("mymaps_create", "/mymaps/create", request_method="POST") config.add_route("mymaps_rate", "/mymaps/rate/{map_id}") config.add_route("mymaps_update", "/mymaps/update/{map_id}", request_method="PUT") config.add_route("get_gpx", "/mymaps/get_gpx/{map_id}", request_method="GET") config.add_route("mymaps_map", "/mymaps/map/{map_id}", request_method="GET") config.add_route("mymaps_comment", "/mymaps/comment/{map_id}", request_method="POST") config.add_route("mymaps_upload_image", "/mymaps/upload_image", request_method="POST") config.add_route("mymaps_upload_symbol", "/mymaps/upload_symbol", request_method="POST") config.add_route("mymaps_get_image", "/mymaps/images/{filename}", request_method="GET") config.add_route("mymaps_get_symbol", "/mymaps/symbol/{symbol_id}", request_method="GET") config.add_route("mymaps_users_categories", "/mymaps/get_users_categories", request_method="GET") config.add_route("mymaps_get_symbols", "/mymaps/symbols", request_method="GET") config.add_route("mymaps_delete", "/mymaps/delete/{map_id}", request_method="DELETE") config.add_route("mymaps_delete_all_features", "/mymaps/delete_all_features/{map_id}", request_method="DELETE") config.add_route("mymaps_delete_feature", "/mymaps/delete_feature/{feature_id}", request_method="DELETE") config.add_route("mymaps_save_feature", "/mymaps/save_feature/{map_id}", request_method="POST") config.add_route("mymaps_save_features", "/mymaps/save_features/{map_id}", request_method="POST") config.add_route("mymaps_save_order", "/mymaps/save_order/{map_id}", request_method="POST") config.add_route("mymaps_save_offline", "/mymaps/save_offline", request_method="POST") config.add_route("mymaps_copy", "/mymaps/copy/{map_id}", request_method="POST") config.add_route("exportgpxkml", "/mymaps/exportgpxkml", request_method="POST") config.add_route("get_arrow_color", "/mymaps/getarrow") config.add_route("getroute", "/mymaps/getroute") config.add_route("getremoteroute", "/router/getroute") # geocoder routes config.add_route("reverse_geocode", "/geocode/reverse") config.add_route("geocode", "/geocode/search") config.add_route("feedback", "/feedback") config.add_route("feedbackanf", "/feedbackanf") config.add_route("feedbackcrues", "/feedbackcrues") config.add_route("feedbackage", "/feedbackage") # user config routes config.add_route("get_userconfig", "/get_userconfig", request_method="GET") config.add_route("save_userconfig", "/save_userconfig", request_method="POST") config.add_route("delete_userconfig", "/delete_userconfig", request_method="DELETE") config.add_route("apply_mvt_config", "/apply_mvt_config", request_method="GET") # pag routes config.add_route("pag_url", "/pag") # pag routes config.add_route("pag_report", "/pag/report/{oid}.pdf") # pag routes config.add_route("casipo_url", "/casipo") # pag routes config.add_route("casipo_report", "/casipo/report/{oid}.pdf") # pds routes config.add_route("pds_url", "/pds") # pag routes config.add_route("pds_report", "/pds/report/{oid}.pdf") config.add_route("pag_files", "/pag/files/{_file}") config.add_route("get_png", "/legends/get") config.add_route("get_html", "/legends/get_html") config.add_route("get_metadata", "/getMetadata") # full text search routes config.add_route("fulltextsearch", "/fulltextsearch") # layer search routes config.add_route("layersearch", "/layersearch") # cms search routes config.add_route("cmssearch", "/cmssearch") # cms search routes config.add_route("featuresearch", "/featuresearch") # jsapi routes config.add_route('jsapiloader', '/apiv3loader.js') config.add_route('jsapiexample', '/api-example') config.add_route('jsapilayers', '/jsapilayers') config.add_route('jsapilayersfull', '/jsapilayersfull') config.add_route('jsapithemesfull', '/jsapithemesfull') config.add_route("echocsv", "/profile/echocsv", request_method="POST") config.add_route('getuserinfo', '/getuserinfo') config.add_route('wms', '/ogcproxywms') config.add_route('wmspoi', '/wmspoi') config.add_route('https_proxy', '/httpsproxy') config.add_route('download_sketch', '/downloadsketch') config.add_route('download', '/download') config.add_route('download_pdf', '/downloadpdf') config.add_route('download_measurement', '/downloadmeasurement') config.add_route('preview_measurement', '/previewmeasurement') config.add_route('qr', '/qr') config.add_route('getfeatureinfo', '/getfeatureinfo') config.add_route('getbuswidget', '/getbuswidget') config.add_route('getpoitemplate', '/getpoitemplate') config.add_route('getremotetemplate', '/getremotetemplate') config.add_route('isthemeprivate', '/isthemeprivate') config.add_route('download_resource', '/downloadresource') config.add_route('upload_vt_style', '/uploadvtstyle') config.add_route('delete_vt_style', '/deletevtstyle') config.add_route('get_vt_style', '/getvtstyle') # Service worker config.add_route('sw', '/sw.js') config.add_static_view('proj/{version}', path='geoportailv3_geoportal:jsapi/') # Appcache manifest config.add_route('appcache', '/geoportailv3.appcache') # ldap from geoportailv3_geoportal.views.authentication import ldap_user_validator, \ get_user_from_request ldap_settings = config.get_settings()['ldap'] if ldap_settings: config.include('pyramid_ldap3') """Config the ldap connection. """ config.ldap_setup( ldap_settings['url'], ldap_settings['bind'], ldap_settings['passwd'], use_pool= False, # avoid errors like LDAPMaximumRetriesError and LDAPResponseTimeoutError ) ldap_settings['filter_tmpl'] = ldap_settings['filter_tmpl'].replace( '%%', '%') config.ldap_set_login_query( ldap_settings['base_dn'], filter_tmpl=ldap_settings['filter_tmpl'], scope=ldap.SUBTREE, ) config.set_request_property(get_user_from_request, name='user', reify=True) set_user_validator(config, ldap_user_validator) # json json_renderer = JSON() json_renderer.add_adapter(datetime.date, datetime_adapter) json_renderer.add_adapter(datetime.datetime, datetime_adapter) json_renderer.add_adapter(Decimal, decimal_adapter) config.add_renderer('json', json_renderer) # mailer mail_config = config.get_settings()['mailer'].copy() maildir = os.environ.get('MAILER_DIRECTORY', None) if maildir: # To deliver emails to a directory (for local dev) mail_config['transport.use'] = 'maildir' mail_config['transport.directory'] = maildir global mailer mailer = Mailer(mail_config) mailer.start() # Add custom table in admin interace, that means re-add all normal table from c2cgeoform.routes import register_models from c2cgeoportal_commons.models.main import (Role, LayerWMS, LayerWMTS, Theme, LayerGroup, LayerV1, Interface, OGCServer, Functionality, RestrictionArea) from c2cgeoportal_commons.models.static import User from geoportailv3_geoportal.models import LuxDownloadUrl, \ LuxMeasurementLoginCommune, LuxMeasurementDirectory, LuxGetfeatureDefinition, \ LuxPrintServers, LuxPredefinedWms, LuxLayerExternalWMS, LuxLayerInternalWMS register_models( config, ( ('themes', Theme), ('layer_groups', LayerGroup), # ('layers_wms', LayerWMS), removed we use LuxLayerExternalWMS and LuxLayerInternalWMS instead ('layers_wmts', LayerWMTS), ('layers_v1', LayerV1), ('ogc_servers', OGCServer), ('restriction_areas', RestrictionArea), ('users', User), ('roles', Role), ('functionalities', Functionality), ('interfaces', Interface), ('lux_download_url', LuxDownloadUrl), ('lux_measurement_login_commune', LuxMeasurementLoginCommune), ('lux_measurement_directory', LuxMeasurementDirectory), ('lux_getfeature_definition', LuxGetfeatureDefinition), ('lux_print_servers', LuxPrintServers), ('lux_predefined_wms', LuxPredefinedWms), ('lux_layer_external_wms', LuxLayerExternalWMS), ('lux_layer_internal_wms', LuxLayerInternalWMS), ), 'admin') # scan view decorator for adding routes config.scan() return config.make_wsgi_app()
def includeme(config: Optional[pyramid.config.Configurator] = None) -> None: """Initialize the Sentry intergation.""" global _client_setup sentry_url = config_utils.env_or_config(config, "SENTRY_URL", "c2c.sentry.url") if sentry_url is not None and not _client_setup: client_info: MutableMapping[str, Any] = { key[14:].lower(): value for key, value in os.environ.items() if key.startswith("SENTRY_CLIENT_") } # Parse bool for key in ( "with_locals", "default_integrations", "send_default_pii", "debug", "attach_stacktrace", "propagate_traces", "auto_enabling_integrations", "auto_session_tracking", ): if key in client_info: client_info[key] = client_info[key].lower() in ("1", "t", "true") # Parse int for key in ("max_breadcrumbs", "shutdown_timeout", "transport_queue_size"): if key in client_info: client_info[key] = int(client_info[key]) # Parse float for key in ("sample_rate", "traces_sample_rate"): if key in client_info: client_info[key] = float(client_info[key]) git_hash = config_utils.env_or_config(config, "GIT_HASH", "c2c.git_hash") if git_hash is not None and not ("release" in client_info and client_info["release"] != "latest"): client_info["release"] = git_hash client_info["ignore_errors"] = client_info.pop("ignore_exceptions", "SystemExit").split(",") tags = { key[11:].lower(): value for key, value in os.environ.items() if key.startswith("SENTRY_TAG_") } sentry_logging = LoggingIntegration( level=logging.DEBUG, event_level=config_utils.env_or_config(config, "SENTRY_LEVEL", "c2c.sentry_level", "ERROR").upper(), ) traces_sample_rate = float( config_utils.env_or_config(config, "SENTRY_TRACES_SAMPLE_RATE", "c2c.sentry_traces_sample_rate", "0.0")) sentry_sdk.init( dsn=sentry_url, integrations=[ sentry_logging, PyramidIntegration(), SqlalchemyIntegration(), RedisIntegration() ], traces_sample_rate=traces_sample_rate, before_send=_create_before_send_filter(tags), **client_info, ) _client_setup = True excludes = config_utils.env_or_config(config, "SENTRY_EXCLUDES", "c2c.sentry.excludes", "sentry_sdk").split(",") for exclude in excludes: ignore_logger(exclude) LOG.info("Configured sentry reporting with client=%s and tags=%s", repr(client_info), repr(tags))
def make_app(self, settings=None): settings = dict(self._settings, **settings) settings['mako.directories'] = 'nextgisweb:templates/' is_debug = self.env.core.debug # If debug is on, add mako-filter that checks # if the line was translated before output. if is_debug: settings['mako.default_filters'] = ['tcheck', 'h'] settings['mako.imports'] = settings.get('mako.imports', []) \ + ['from nextgisweb.i18n import tcheck', ] # If pyramid config doesn't state otherwise, use locale from, # core component, while this is not clear why we need that. plockey = 'pyramid.default_locale_name' if plockey not in settings and self.env.core.locale_default is not None: settings[plockey] = self.env.core.locale_default sentry_dsn = 'sentry_dsn' if sentry_dsn in settings: sentry_sdk.init( settings[sentry_dsn], integrations=[PyramidIntegration()], ) config = Configurator(settings=settings) # Substitute localizer from pyramid with our own, original is # too tied to translationstring, that works strangely with string # interpolation via % operator. def localizer(request): return request.env.core.localizer(request.locale_name) config.add_request_method(localizer, 'localizer', property=True) # TODO: Need to get rid of translation dirs! # Currently used only to search for jed-files. for pkg in pkginfo.packages: dirname = resource_filename(pkg, 'locale') if os.path.isdir(dirname): config.add_translation_dirs(dirname) config.add_route_predicate('client', ClientRoutePredicate) config.add_view_predicate('method', RequestMethodPredicate) config.add_view_predicate('json', JsonPredicate) config.add_request_method( lambda request: request.path_info.lower().startswith('/api/'), 'is_api', property=True, reify=True) self.error_handlers = list() @self.error_handlers.append def api_error_handler(request, err_info, exc, exc_info): if request.is_api or request.is_xhr: return exception.json_error_response(request, err_info, exc, exc_info, debug=is_debug) def error_handler(request, err_info, exc, exc_info, **kwargs): for handler in self.error_handlers: result = handler(request, err_info, exc, exc_info) if result is not None: return result config.registry.settings['error.err_response'] = error_handler config.registry.settings['error.exc_response'] = error_handler config.include(exception) # Access to Env through request.env config.add_request_method(lambda req: self._env, 'env', property=True) config.include(pyramid_tm) config.include(pyramid_mako) # Filter for quick translation. Defines function tr, which we can use # instead of request.localizer.translate in templates. def tr_subscriber(event): event['tr'] = event['request'].localizer.translate config.add_subscriber(tr_subscriber, BeforeRender) assert 'secret' in settings, 'Secret not set!' authn_policy = AuthenticationPolicy(settings=settings) config.set_authentication_policy(authn_policy) authz_policy = ACLAuthorizationPolicy() config.set_authorization_policy(authz_policy) # Help self.help_page = {} for key in settings.keys(): if key.startswith('help_page'): hploc = key.split('.')[-1] self.help_page[hploc] = settings[key] # To not clear static cache by hand make it so that # URLs are different. Use md5 hash from all installed packages # which we can get with pip freeze. pip freeze # also returns current commit for packages from # VCS, this also helps. # This could've been done better, but right now simply # redirect sys.stdout to StringIO, run pip freeze and # return sys.stdout to initial state. try: from pip._internal import main as pip_main except ImportError: from pip import main as pip_main stdout = sys.stdout static_key = '' try: buf = StringIO() sys.stdout = buf with warnings.catch_warnings(): warnings.filterwarnings( 'ignore', r'DEPRECATION: Python 2\.7 will reach') pip_main([ 'freeze', ]) h = md5() h.update(buf.getvalue()) static_key = '/' + h.hexdigest() finally: sys.stdout = stdout self.distinfo = [] # Read installed packages from pip freeze buf.seek(0) for line in buf: line = line.strip().lower() dinfo = None mpkg = re.match(r'(.+)==(.+)', line) if mpkg: dinfo = DistInfo(name=mpkg.group(1), version=mpkg.group(2), commit=None) mgit = re.match(r'-e\sgit\+.+\@(.{8}).{32}\#egg=(\w+).*$', line) if mgit: dinfo = DistInfo(name=mgit.group(2), version=get_distribution( mgit.group(2)).version, commit=mgit.group(1)) if dinfo is not None: self.distinfo.append(dinfo) else: self.logger.warn("Could not parse pip freeze line: %s", line) config.add_static_view('/static%s/asset' % static_key, 'nextgisweb:static', cache_max_age=3600) config.add_route('amd_package', '/static%s/amd/*subpath' % static_key) \ .add_view('nextgisweb.views.amd_package') for comp in self._env.chain('setup_pyramid'): comp.setup_pyramid(config) def html_error_handler(request, err_info, exc, exc_info): return exception.html_error_response(request, err_info, exc, exc_info, debug=is_debug) self.error_handlers.append(html_error_handler) def amd_base(request): amds = [] for comp in self._env.chain('amd_base'): amds.extend(comp.amd_base) return amds config.add_request_method(amd_base, 'amd_base', property=True, reify=True) config.add_renderer('json', json_renderer) return config
def main(global_config, **settings): dsn = settings.get("sentry.dsn", None) if dsn: LOGGER.info("Init sentry sdk for {}".format(dsn)) sentry_sdk.init( dsn=dsn, integrations=[ LoggingIntegration(level=None, event_level=None), PyramidIntegration() ], send_default_pii=True, request_bodies="always", environment=settings.get("sentry.environment", None), debug=settings.get("sentry.debug", False), ) config = Configurator( autocommit=True, settings=settings, authentication_policy=AuthenticationPolicy(settings["auth.file"], __name__), authorization_policy=AuthorizationPolicy(), route_prefix=ROUTE_PREFIX, ) config.include("pyramid_exclog") config.include("cornice") config.add_forbidden_view(forbidden) config.add_view(precondition, context=HTTPPreconditionFailed) config.add_request_method(request_params, "params", reify=True) config.add_request_method(authenticated_role, reify=True) config.add_request_method(check_accreditations) config.add_request_method(get_currency_rates, name="currency_rates", reify=True) config.add_renderer("json", JSON(serializer=simplejson.dumps)) config.add_renderer("prettyjson", JSON(indent=4, serializer=simplejson.dumps)) config.add_renderer( "jsonp", JSONP(param_name="opt_jsonp", serializer=simplejson.dumps)) config.add_renderer( "prettyjsonp", JSONP(indent=4, param_name="opt_jsonp", serializer=simplejson.dumps)) # search for plugins plugins = settings.get("plugins") and [ plugin.strip() for plugin in settings["plugins"].split(",") ] for entry_point in iter_entry_points("openprocurement.api.plugins"): if not plugins or entry_point.name in plugins: plugin = entry_point.load() plugin(config) # CouchDB connection aserver, server, db = set_api_security(settings) config.registry.couchdb_server = server if aserver: config.registry.admin_couchdb_server = aserver config.registry.db = db # CouchDB specific databases connections config.registry.databases = Databases( admin_connection=aserver or server, connection=server, migrations=settings.get("couchdb.migrations_db_name"), frameworks=settings.get("couchdb.frameworks_db_name"), submissions=settings.get("couchdb.submissions_db_name"), qualifications=settings.get("couchdb.qualifications_db_name"), agreements=settings.get("couchdb.agreements_db_name"), transfers=settings.get("couchdb.transfers_db_name"), plans=settings.get("couchdb.plans_db_name"), contracts=settings.get("couchdb.contracts_db_name"), ) # readjust couchdb json decoder couchdb_json_decode() # Document Service key config.registry.docservice_url = settings.get("docservice_url") config.registry.docservice_username = settings.get("docservice_username") config.registry.docservice_password = settings.get("docservice_password") config.registry.docservice_upload_url = settings.get( "docservice_upload_url") signing_key = settings.get('dockey', '') signer = SigningKey( signing_key, encoder=HexEncoder) if signing_key else SigningKey.generate() config.registry.docservice_key = signer verifier = signer.verify_key config.registry.keyring = { verifier.encode(encoder=HexEncoder)[:8].decode(): verifier } dockeys = settings.get('dockeys', '') for key in dockeys.split('\0'): if key: config.registry.keyring[key[:8]] = VerifyKey(key, encoder=HexEncoder) # migrate data if not os.environ.get("MIGRATION_SKIP"): for entry_point in iter_entry_points("openprocurement.api.migrations"): plugin = entry_point.load() plugin(config.registry) config.registry.server_id = settings.get("id", "") # search subscribers subscribers_keys = [k for k in settings if k.startswith("subscribers.")] for k in subscribers_keys: subscribers = settings[k].split(",") for subscriber in subscribers: for entry_point in iter_entry_points( "openprocurement.{}".format(k), subscriber): if entry_point: plugin = entry_point.load() plugin(config) config.registry.health_threshold = float( settings.get("health_threshold", 512)) config.registry.health_threshold_func = settings.get( "health_threshold_func", "all") config.registry.update_after = asbool(settings.get("update_after", True)) return config.make_wsgi_app()