codecraftai-webworks 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccai/webworks/__init__.py +34 -0
- ccai/webworks/asgi/__init__.py +89 -0
- ccai/webworks/asgi/application.py +513 -0
- ccai/webworks/asgi/backgroundtasks.py +161 -0
- ccai/webworks/asgi/bodyreader.py +464 -0
- ccai/webworks/asgi/constants.py +99 -0
- ccai/webworks/asgi/errorhandler.py +565 -0
- ccai/webworks/asgi/exceptions.py +232 -0
- ccai/webworks/asgi/httphandler.py +421 -0
- ccai/webworks/asgi/lifespanhandler.py +319 -0
- ccai/webworks/asgi/responsesender.py +218 -0
- ccai/webworks/asgi/scopeparser.py +384 -0
- ccai/webworks/asgi/ssehandler.py +428 -0
- ccai/webworks/asgi/websockethandler.py +545 -0
- ccai/webworks/authentication/__init__.py +263 -0
- ccai/webworks/authentication/apikey.py +398 -0
- ccai/webworks/authentication/authenticator.py +84 -0
- ccai/webworks/authentication/basic.py +351 -0
- ccai/webworks/authentication/bearer.py +644 -0
- ccai/webworks/authentication/blueprints/__init__.py +107 -0
- ccai/webworks/authentication/blueprints/apikey.py +548 -0
- ccai/webworks/authentication/blueprints/basic.py +280 -0
- ccai/webworks/authentication/blueprints/bearer.py +813 -0
- ccai/webworks/authentication/blueprints/magiclink.py +719 -0
- ccai/webworks/authentication/blueprints/oauth2.py +1324 -0
- ccai/webworks/authentication/blueprints/oauthclient.py +1634 -0
- ccai/webworks/authentication/blueprints/oidc.py +496 -0
- ccai/webworks/authentication/blueprints/responses.py +102 -0
- ccai/webworks/authentication/blueprints/schemas.py +264 -0
- ccai/webworks/authentication/blueprints/security.py +997 -0
- ccai/webworks/authentication/blueprints/session.py +845 -0
- ccai/webworks/authentication/core.py +309 -0
- ccai/webworks/authentication/digest.py +871 -0
- ccai/webworks/authentication/errors.py +755 -0
- ccai/webworks/authentication/hmac_auth.py +665 -0
- ccai/webworks/authentication/middleware.py +651 -0
- ccai/webworks/authentication/oauth.py +772 -0
- ccai/webworks/authentication/oauth2.py +1171 -0
- ccai/webworks/authentication/oidc.py +1374 -0
- ccai/webworks/authentication/session.py +742 -0
- ccai/webworks/authentication/system.py +203 -0
- ccai/webworks/configuration/__init__.py +131 -0
- ccai/webworks/configuration/core.py +350 -0
- ccai/webworks/configuration/exceptions.py +145 -0
- ccai/webworks/configuration/lifecycle.py +530 -0
- ccai/webworks/configuration/model.py +665 -0
- ccai/webworks/configuration/registry.py +1244 -0
- ccai/webworks/configuration/schema.py +496 -0
- ccai/webworks/configuration/sources.py +1991 -0
- ccai/webworks/configuration/watcher.py +441 -0
- ccai/webworks/devexp/__init__.py +7 -0
- ccai/webworks/devexp/cli/__init__.py +7 -0
- ccai/webworks/devexp/cli/command.py +66 -0
- ccai/webworks/devexp/cli/config.py +207 -0
- ccai/webworks/devexp/cli/database.py +589 -0
- ccai/webworks/devexp/cli/exitcodes.py +30 -0
- ccai/webworks/devexp/cli/generators.py +387 -0
- ccai/webworks/devexp/cli/group.py +93 -0
- ccai/webworks/devexp/cli/output.py +179 -0
- ccai/webworks/devexp/cli/routes.py +459 -0
- ccai/webworks/devexp/cli/scaffolding.py +309 -0
- ccai/webworks/devexp/cli/shell.py +406 -0
- ccai/webworks/devexp/cli/webworkscli.py +196 -0
- ccai/webworks/devexp/debug/__init__.py +8 -0
- ccai/webworks/devexp/debug/debugger.py +389 -0
- ccai/webworks/devexp/debug/errorhandler.py +942 -0
- ccai/webworks/devexp/debug/inspector.py +526 -0
- ccai/webworks/devexp/logging/__init__.py +7 -0
- ccai/webworks/devexp/logging/devlogger.py +490 -0
- ccai/webworks/devexp/server/__init__.py +10 -0
- ccai/webworks/devexp/server/asyncservercore.py +271 -0
- ccai/webworks/devexp/server/devserver.py +751 -0
- ccai/webworks/devexp/server/filewatcher.py +417 -0
- ccai/webworks/devexp/server/httpprotocolhandler.py +1072 -0
- ccai/webworks/devexp/server/lifespanmanager.py +261 -0
- ccai/webworks/devexp/server/requestlogger.py +227 -0
- ccai/webworks/devexp/server/servecommand.py +157 -0
- ccai/webworks/devexp/testing/__init__.py +8 -0
- ccai/webworks/devexp/testing/assertions.py +261 -0
- ccai/webworks/devexp/testing/fixtures.py +433 -0
- ccai/webworks/devexp/testing/testclient.py +520 -0
- ccai/webworks/devexp/testing/testresponse.py +124 -0
- ccai/webworks/endpoints/__init__.py +43 -0
- ccai/webworks/endpoints/accesspolicy.py +27 -0
- ccai/webworks/endpoints/blueprint.py +770 -0
- ccai/webworks/endpoints/constraints.py +199 -0
- ccai/webworks/endpoints/descriptor.py +369 -0
- ccai/webworks/endpoints/doc.py +35 -0
- ccai/webworks/endpoints/endpoint.py +854 -0
- ccai/webworks/endpoints/exceptions.py +56 -0
- ccai/webworks/endpoints/merging.py +148 -0
- ccai/webworks/endpoints/ratelimit.py +57 -0
- ccai/webworks/endpoints/registry.py +466 -0
- ccai/webworks/endpoints/rest/__init__.py +118 -0
- ccai/webworks/endpoints/rest/collectionendpoint.py +473 -0
- ccai/webworks/endpoints/rest/errors.py +240 -0
- ccai/webworks/endpoints/rest/exceptions.py +126 -0
- ccai/webworks/endpoints/rest/middleware.py +678 -0
- ccai/webworks/endpoints/rest/models.py +647 -0
- ccai/webworks/endpoints/rest/negotiation.py +120 -0
- ccai/webworks/endpoints/rest/resourceendpoint.py +488 -0
- ccai/webworks/endpoints/rest/serialization.py +559 -0
- ccai/webworks/endpoints/rest/validation.py +607 -0
- ccai/webworks/endpoints/restblueprint.py +457 -0
- ccai/webworks/endpoints/restendpoint.py +577 -0
- ccai/webworks/endpoints/router.py +54 -0
- ccai/webworks/extensibility/__init__.py +7 -0
- ccai/webworks/extensibility/applifecyclehooks.py +161 -0
- ccai/webworks/extensibility/componenthooks.py +321 -0
- ccai/webworks/extensibility/configuration.py +280 -0
- ccai/webworks/extensibility/context.py +187 -0
- ccai/webworks/extensibility/datastructures.py +116 -0
- ccai/webworks/extensibility/decorators.py +68 -0
- ccai/webworks/extensibility/exceptions.py +185 -0
- ccai/webworks/extensibility/extension.py +123 -0
- ccai/webworks/extensibility/hookmanager.py +302 -0
- ccai/webworks/extensibility/loader.py +372 -0
- ccai/webworks/extensibility/manifest.py +271 -0
- ccai/webworks/extensibility/registry.py +624 -0
- ccai/webworks/extensibility/requestlifecyclehooks.py +165 -0
- ccai/webworks/flash.py +404 -0
- ccai/webworks/openapi/__init__.py +145 -0
- ccai/webworks/openapi/assets.py +408 -0
- ccai/webworks/openapi/cache.py +193 -0
- ccai/webworks/openapi/cli.py +381 -0
- ccai/webworks/openapi/configuration.py +227 -0
- ccai/webworks/openapi/generator.py +845 -0
- ccai/webworks/openapi/grouping.py +105 -0
- ccai/webworks/openapi/redoc.py +240 -0
- ccai/webworks/openapi/schemaconverter.py +455 -0
- ccai/webworks/openapi/securityschemes.py +225 -0
- ccai/webworks/openapi/static/manifest.json +28 -0
- ccai/webworks/openapi/static/redoc/redoc.standalone.js +1832 -0
- ccai/webworks/openapi/static/swagger-ui/favicon-32x32.png +0 -0
- ccai/webworks/openapi/static/swagger-ui/swagger-ui-bundle.js +2 -0
- ccai/webworks/openapi/static/swagger-ui/swagger-ui.css +3 -0
- ccai/webworks/openapi/swaggerui.py +473 -0
- ccai/webworks/openapi/validation.py +340 -0
- ccai/webworks/persona/__init__.py +13 -0
- ccai/webworks/persona/lifecycle.py +124 -0
- ccai/webworks/prodserver/__init__.py +8 -0
- ccai/webworks/prodserver/applicationloader.py +370 -0
- ccai/webworks/prodserver/asyncworker.py +162 -0
- ccai/webworks/prodserver/connectionmanager.py +525 -0
- ccai/webworks/prodserver/exceptions.py +43 -0
- ccai/webworks/prodserver/geventworker.py +163 -0
- ccai/webworks/prodserver/healthchecker.py +205 -0
- ccai/webworks/prodserver/metricscollector.py +431 -0
- ccai/webworks/prodserver/processmanager.py +551 -0
- ccai/webworks/prodserver/productionserver.py +557 -0
- ccai/webworks/prodserver/reloadcoordinator.py +174 -0
- ccai/webworks/prodserver/requesttracer.py +362 -0
- ccai/webworks/prodserver/resourcelimiter.py +433 -0
- ccai/webworks/prodserver/serverconfig.py +288 -0
- ccai/webworks/prodserver/shutdowncoordinator.py +304 -0
- ccai/webworks/prodserver/signalhandler.py +173 -0
- ccai/webworks/prodserver/sslmanager.py +364 -0
- ccai/webworks/prodserver/structuredlogger.py +373 -0
- ccai/webworks/prodserver/syncworker.py +133 -0
- ccai/webworks/prodserver/worker.py +221 -0
- ccai/webworks/prodserver/workermanager.py +474 -0
- ccai/webworks/prodserver/workerstate.py +57 -0
- ccai/webworks/routing/__init__.py +101 -0
- ccai/webworks/routing/converters.py +233 -0
- ccai/webworks/routing/dispatcher.py +681 -0
- ccai/webworks/routing/exceptions.py +329 -0
- ccai/webworks/routing/headers.py +188 -0
- ccai/webworks/routing/matcher.py +377 -0
- ccai/webworks/routing/middleware/__init__.py +590 -0
- ccai/webworks/routing/middleware/cors.py +167 -0
- ccai/webworks/routing/middleware/errornormalization.py +155 -0
- ccai/webworks/routing/middleware/logging.py +147 -0
- ccai/webworks/routing/middlewareadapters.py +635 -0
- ccai/webworks/routing/middlewarecontext.py +126 -0
- ccai/webworks/routing/middlewarefactory.py +53 -0
- ccai/webworks/routing/middlewareregistry.py +379 -0
- ccai/webworks/routing/multipart.py +411 -0
- ccai/webworks/routing/queryparams.py +128 -0
- ccai/webworks/routing/request.py +720 -0
- ccai/webworks/routing/response.py +557 -0
- ccai/webworks/routing/router.py +711 -0
- ccai/webworks/security/__init__.py +154 -0
- ccai/webworks/security/accesspolicy.py +551 -0
- ccai/webworks/security/auditlogger.py +421 -0
- ccai/webworks/security/authenticationmanager.py +106 -0
- ccai/webworks/security/authenticationprovider.py +601 -0
- ccai/webworks/security/authorizationengine.py +273 -0
- ccai/webworks/security/csrf.py +932 -0
- ccai/webworks/security/decorators.py +184 -0
- ccai/webworks/security/errors.py +228 -0
- ccai/webworks/security/jsonwebtoken.py +943 -0
- ccai/webworks/security/middleware.py +277 -0
- ccai/webworks/security/passwords.py +265 -0
- ccai/webworks/security/policyattachment.py +193 -0
- ccai/webworks/security/policyfactories.py +86 -0
- ccai/webworks/security/securitycontext.py +141 -0
- ccai/webworks/security/signedserializer.py +279 -0
- ccai/webworks/static/gallery.html +172 -0
- ccai/webworks/static/javascript/README.md +92 -0
- ccai/webworks/static/javascript/charts/core/chartmodel.js +162 -0
- ccai/webworks/static/javascript/charts/core/chartpart.js +97 -0
- ccai/webworks/static/javascript/charts/core/chartregistry.js +59 -0
- ccai/webworks/static/javascript/charts/core/jsonsource.js +83 -0
- ccai/webworks/static/javascript/charts/core/renderers/area.js +347 -0
- ccai/webworks/static/javascript/charts/core/renderers/bar.js +283 -0
- ccai/webworks/static/javascript/charts/core/renderers/beeswarm.js +314 -0
- ccai/webworks/static/javascript/charts/core/renderers/boxplot.js +425 -0
- ccai/webworks/static/javascript/charts/core/renderers/bullet.js +318 -0
- ccai/webworks/static/javascript/charts/core/renderers/bump.js +304 -0
- ccai/webworks/static/javascript/charts/core/renderers/calendarheatmap.js +264 -0
- ccai/webworks/static/javascript/charts/core/renderers/cdf.js +286 -0
- ccai/webworks/static/javascript/charts/core/renderers/chord.js +278 -0
- ccai/webworks/static/javascript/charts/core/renderers/cohort.js +218 -0
- ccai/webworks/static/javascript/charts/core/renderers/contour.js +480 -0
- ccai/webworks/static/javascript/charts/core/renderers/control.js +267 -0
- ccai/webworks/static/javascript/charts/core/renderers/curve.js +332 -0
- ccai/webworks/static/javascript/charts/core/renderers/density.js +498 -0
- ccai/webworks/static/javascript/charts/core/renderers/dothistogram.js +305 -0
- ccai/webworks/static/javascript/charts/core/renderers/dotplot.js +275 -0
- ccai/webworks/static/javascript/charts/core/renderers/errorbar.js +286 -0
- ccai/webworks/static/javascript/charts/core/renderers/faceted.js +215 -0
- ccai/webworks/static/javascript/charts/core/renderers/flowchart.js +457 -0
- ccai/webworks/static/javascript/charts/core/renderers/flowmap.js +1322 -0
- ccai/webworks/static/javascript/charts/core/renderers/forest.js +323 -0
- ccai/webworks/static/javascript/charts/core/renderers/freqresponse.js +531 -0
- ccai/webworks/static/javascript/charts/core/renderers/funnel.js +222 -0
- ccai/webworks/static/javascript/charts/core/renderers/funnelplot.js +288 -0
- ccai/webworks/static/javascript/charts/core/renderers/gantt.js +420 -0
- ccai/webworks/static/javascript/charts/core/renderers/gauge.js +238 -0
- ccai/webworks/static/javascript/charts/core/renderers/geomap.js +1004 -0
- ccai/webworks/static/javascript/charts/core/renderers/glyph.js +271 -0
- ccai/webworks/static/javascript/charts/core/renderers/heatmap.js +297 -0
- ccai/webworks/static/javascript/charts/core/renderers/heatmaptable.js +666 -0
- ccai/webworks/static/javascript/charts/core/renderers/hexbin.js +389 -0
- ccai/webworks/static/javascript/charts/core/renderers/hierlayout.js +1101 -0
- ccai/webworks/static/javascript/charts/core/renderers/histogram.js +595 -0
- ccai/webworks/static/javascript/charts/core/renderers/horizon.js +306 -0
- ccai/webworks/static/javascript/charts/core/renderers/iconarray.js +204 -0
- ccai/webworks/static/javascript/charts/core/renderers/journey.js +534 -0
- ccai/webworks/static/javascript/charts/core/renderers/kanban.js +241 -0
- ccai/webworks/static/javascript/charts/core/renderers/kpi.js +257 -0
- ccai/webworks/static/javascript/charts/core/renderers/line.js +244 -0
- ccai/webworks/static/javascript/charts/core/renderers/loglog.js +290 -0
- ccai/webworks/static/javascript/charts/core/renderers/lollipop.js +217 -0
- ccai/webworks/static/javascript/charts/core/renderers/marimekko.js +193 -0
- ccai/webworks/static/javascript/charts/core/renderers/matrix.js +223 -0
- ccai/webworks/static/javascript/charts/core/renderers/mosaic.js +212 -0
- ccai/webworks/static/javascript/charts/core/renderers/network.js +529 -0
- ccai/webworks/static/javascript/charts/core/renderers/ohlc.js +222 -0
- ccai/webworks/static/javascript/charts/core/renderers/parallel.js +322 -0
- ccai/webworks/static/javascript/charts/core/renderers/pareto.js +258 -0
- ccai/webworks/static/javascript/charts/core/renderers/phase.js +273 -0
- ccai/webworks/static/javascript/charts/core/renderers/pie.js +216 -0
- ccai/webworks/static/javascript/charts/core/renderers/pixel.js +230 -0
- ccai/webworks/static/javascript/charts/core/renderers/polar.js +480 -0
- ccai/webworks/static/javascript/charts/core/renderers/qqplot.js +336 -0
- ccai/webworks/static/javascript/charts/core/renderers/radar.js +339 -0
- ccai/webworks/static/javascript/charts/core/renderers/resource.js +337 -0
- ccai/webworks/static/javascript/charts/core/renderers/ridgeline.js +313 -0
- ccai/webworks/static/javascript/charts/core/renderers/rug.js +203 -0
- ccai/webworks/static/javascript/charts/core/renderers/sankey.js +448 -0
- ccai/webworks/static/javascript/charts/core/renderers/scatter.js +320 -0
- ccai/webworks/static/javascript/charts/core/renderers/scorecard.js +288 -0
- ccai/webworks/static/javascript/charts/core/renderers/slope.js +266 -0
- ccai/webworks/static/javascript/charts/core/renderers/smith.js +307 -0
- ccai/webworks/static/javascript/charts/core/renderers/sparkline.js +244 -0
- ccai/webworks/static/javascript/charts/core/renderers/spectrogram.js +278 -0
- ccai/webworks/static/javascript/charts/core/renderers/spiral.js +273 -0
- ccai/webworks/static/javascript/charts/core/renderers/splom.js +382 -0
- ccai/webworks/static/javascript/charts/core/renderers/step.js +268 -0
- ccai/webworks/static/javascript/charts/core/renderers/streamgraph.js +323 -0
- ccai/webworks/static/javascript/charts/core/renderers/strip.js +289 -0
- ccai/webworks/static/javascript/charts/core/renderers/survival.js +286 -0
- ccai/webworks/static/javascript/charts/core/renderers/ternary.js +308 -0
- ccai/webworks/static/javascript/charts/core/renderers/timeline.js +363 -0
- ccai/webworks/static/javascript/charts/core/renderers/tornado.js +238 -0
- ccai/webworks/static/javascript/charts/core/renderers/tree.js +966 -0
- ccai/webworks/static/javascript/charts/core/renderers/upset.js +271 -0
- ccai/webworks/static/javascript/charts/core/renderers/vectorfield.js +422 -0
- ccai/webworks/static/javascript/charts/core/renderers/venn.js +299 -0
- ccai/webworks/static/javascript/charts/core/renderers/violin.js +414 -0
- ccai/webworks/static/javascript/charts/core/renderers/volume.js +207 -0
- ccai/webworks/static/javascript/charts/core/renderers/voronoi.js +341 -0
- ccai/webworks/static/javascript/charts/core/renderers/waffle.js +144 -0
- ccai/webworks/static/javascript/charts/core/renderers/waterfall.js +286 -0
- ccai/webworks/static/javascript/charts/core/renderers/wordcloud.js +233 -0
- ccai/webworks/static/javascript/charts/core/renderregistry.js +72 -0
- ccai/webworks/static/javascript/charts/core/scales.js +301 -0
- ccai/webworks/static/javascript/charts/core/svgdraw.js +255 -0
- ccai/webworks/static/javascript/charts/index.js +115 -0
- ccai/webworks/static/javascript/charts/mjchart.js +300 -0
- ccai/webworks/static/javascript/charts/mjchartdatatable.js +83 -0
- ccai/webworks/static/javascript/charts/mjchartlegend.js +97 -0
- ccai/webworks/static/javascript/charts/mjcharttitle.js +82 -0
- ccai/webworks/static/javascript/components/mjaccordion.js +168 -0
- ccai/webworks/static/javascript/components/mjactivityfeed.js +558 -0
- ccai/webworks/static/javascript/components/mjalert.js +198 -0
- ccai/webworks/static/javascript/components/mjappbar.js +274 -0
- ccai/webworks/static/javascript/components/mjappshell.js +627 -0
- ccai/webworks/static/javascript/components/mjaspectratio.js +101 -0
- ccai/webworks/static/javascript/components/mjassetpicker.js +586 -0
- ccai/webworks/static/javascript/components/mjavatar.js +287 -0
- ccai/webworks/static/javascript/components/mjbadge.js +244 -0
- ccai/webworks/static/javascript/components/mjbranchgraph.js +327 -0
- ccai/webworks/static/javascript/components/mjbreadcrumb.js +226 -0
- ccai/webworks/static/javascript/components/mjbuildstatusboard.js +504 -0
- ccai/webworks/static/javascript/components/mjbulkactionbar.js +396 -0
- ccai/webworks/static/javascript/components/mjburndownchart.js +298 -0
- ccai/webworks/static/javascript/components/mjbutton.js +221 -0
- ccai/webworks/static/javascript/components/mjcalendar.js +747 -0
- ccai/webworks/static/javascript/components/mjcaptcha.js +442 -0
- ccai/webworks/static/javascript/components/mjcard.js +235 -0
- ccai/webworks/static/javascript/components/mjcarousel.js +414 -0
- ccai/webworks/static/javascript/components/mjcascadingselect.js +300 -0
- ccai/webworks/static/javascript/components/mjcharactercounter.js +379 -0
- ccai/webworks/static/javascript/components/mjchatcomposer.js +554 -0
- ccai/webworks/static/javascript/components/mjchatmessage.js +682 -0
- ccai/webworks/static/javascript/components/mjcheckboxgroup.js +398 -0
- ccai/webworks/static/javascript/components/mjchip.js +280 -0
- ccai/webworks/static/javascript/components/mjcodeeditor.js +465 -0
- ccai/webworks/static/javascript/components/mjcolorpicker.js +641 -0
- ccai/webworks/static/javascript/components/mjcolumnpicker.js +534 -0
- ccai/webworks/static/javascript/components/mjcombobox.js +542 -0
- ccai/webworks/static/javascript/components/mjcommandpalette.js +681 -0
- ccai/webworks/static/javascript/components/mjcomments.js +705 -0
- ccai/webworks/static/javascript/components/mjcontextmenu.js +563 -0
- ccai/webworks/static/javascript/components/mjcopybutton.js +285 -0
- ccai/webworks/static/javascript/components/mjcumulativeflow.js +287 -0
- ccai/webworks/static/javascript/components/mjdatatable.js +933 -0
- ccai/webworks/static/javascript/components/mjdatepicker.js +595 -0
- ccai/webworks/static/javascript/components/mjdependencygraph.js +434 -0
- ccai/webworks/static/javascript/components/mjdiagram.js +1092 -0
- ccai/webworks/static/javascript/components/mjdialog.js +424 -0
- ccai/webworks/static/javascript/components/mjdisclosure.js +278 -0
- ccai/webworks/static/javascript/components/mjdisclosurebutton.js +264 -0
- ccai/webworks/static/javascript/components/mjdivider.js +158 -0
- ccai/webworks/static/javascript/components/mjdocklayout.js +95 -0
- ccai/webworks/static/javascript/components/mjdownloadbutton.js +282 -0
- ccai/webworks/static/javascript/components/mjdrawer.js +413 -0
- ccai/webworks/static/javascript/components/mjdropzone.js +521 -0
- ccai/webworks/static/javascript/components/mjemptystate.js +163 -0
- ccai/webworks/static/javascript/components/mjenvpromotionchart.js +345 -0
- ccai/webworks/static/javascript/components/mjerrormessage.js +284 -0
- ccai/webworks/static/javascript/components/mjfab.js +241 -0
- ccai/webworks/static/javascript/components/mjfavoritebutton.js +355 -0
- ccai/webworks/static/javascript/components/mjfeed.js +299 -0
- ccai/webworks/static/javascript/components/mjfieldset.js +272 -0
- ccai/webworks/static/javascript/components/mjfilebrowser.js +683 -0
- ccai/webworks/static/javascript/components/mjfilepicker.js +504 -0
- ccai/webworks/static/javascript/components/mjfilterpanel.js +564 -0
- ccai/webworks/static/javascript/components/mjfooternav.js +165 -0
- ccai/webworks/static/javascript/components/mjform.js +288 -0
- ccai/webworks/static/javascript/components/mjganttchart.js +317 -0
- ccai/webworks/static/javascript/components/mjgauge.js +327 -0
- ccai/webworks/static/javascript/components/mjgrid.js +141 -0
- ccai/webworks/static/javascript/components/mjhelptext.js +192 -0
- ccai/webworks/static/javascript/components/mjhero.js +253 -0
- ccai/webworks/static/javascript/components/mjimage.js +291 -0
- ccai/webworks/static/javascript/components/mjinlineedit.js +439 -0
- ccai/webworks/static/javascript/components/mjkanban.js +615 -0
- ccai/webworks/static/javascript/components/mjlabel.js +181 -0
- ccai/webworks/static/javascript/components/mjlightbox.js +508 -0
- ccai/webworks/static/javascript/components/mjlink.js +210 -0
- ccai/webworks/static/javascript/components/mjlist.js +265 -0
- ccai/webworks/static/javascript/components/mjlistbox.js +450 -0
- ccai/webworks/static/javascript/components/mjlocalepicker.js +639 -0
- ccai/webworks/static/javascript/components/mjmap.js +714 -0
- ccai/webworks/static/javascript/components/mjmarkdowneditor.js +599 -0
- ccai/webworks/static/javascript/components/mjmaskedinput.js +533 -0
- ccai/webworks/static/javascript/components/mjmasterdetail.js +589 -0
- ccai/webworks/static/javascript/components/mjmediaobject.js +102 -0
- ccai/webworks/static/javascript/components/mjmediaplayer.js +575 -0
- ccai/webworks/static/javascript/components/mjmentioninput.js +657 -0
- ccai/webworks/static/javascript/components/mjmenu.js +396 -0
- ccai/webworks/static/javascript/components/mjmenubar.js +355 -0
- ccai/webworks/static/javascript/components/mjmenubutton.js +430 -0
- ccai/webworks/static/javascript/components/mjmilestonetimeline.js +301 -0
- ccai/webworks/static/javascript/components/mjnavstepper.js +287 -0
- ccai/webworks/static/javascript/components/mjnotificationcenter.js +626 -0
- ccai/webworks/static/javascript/components/mjnumberfield.js +521 -0
- ccai/webworks/static/javascript/components/mjotpinput.js +435 -0
- ccai/webworks/static/javascript/components/mjoverlay.js +219 -0
- ccai/webworks/static/javascript/components/mjpagination.js +385 -0
- ccai/webworks/static/javascript/components/mjpasswordfield.js +434 -0
- ccai/webworks/static/javascript/components/mjpipelinechart.js +279 -0
- ccai/webworks/static/javascript/components/mjpopover.js +425 -0
- ccai/webworks/static/javascript/components/mjprogress.js +250 -0
- ccai/webworks/static/javascript/components/mjquerybuilder.js +613 -0
- ccai/webworks/static/javascript/components/mjradiogroup.js +349 -0
- ccai/webworks/static/javascript/components/mjrating.js +433 -0
- ccai/webworks/static/javascript/components/mjreleasecalendar.js +328 -0
- ccai/webworks/static/javascript/components/mjrichtexteditor.js +493 -0
- ccai/webworks/static/javascript/components/mjroadmapchart.js +308 -0
- ccai/webworks/static/javascript/components/mjrowselector.js +319 -0
- ccai/webworks/static/javascript/components/mjscrollarea.js +170 -0
- ccai/webworks/static/javascript/components/mjsearchinput.js +432 -0
- ccai/webworks/static/javascript/components/mjsearchresults.js +451 -0
- ccai/webworks/static/javascript/components/mjsegmentedcontrol.js +332 -0
- ccai/webworks/static/javascript/components/mjselect.js +747 -0
- ccai/webworks/static/javascript/components/mjsharebutton.js +369 -0
- ccai/webworks/static/javascript/components/mjsidenav.js +301 -0
- ccai/webworks/static/javascript/components/mjskeleton.js +184 -0
- ccai/webworks/static/javascript/components/mjskiplink.js +144 -0
- ccai/webworks/static/javascript/components/mjslider.js +494 -0
- ccai/webworks/static/javascript/components/mjsortcontrol.js +275 -0
- ccai/webworks/static/javascript/components/mjspacer.js +82 -0
- ccai/webworks/static/javascript/components/mjsparkline.js +312 -0
- ccai/webworks/static/javascript/components/mjsplitbutton.js +445 -0
- ccai/webworks/static/javascript/components/mjsplitpane.js +386 -0
- ccai/webworks/static/javascript/components/mjstack.js +104 -0
- ccai/webworks/static/javascript/components/mjstatusbar.js +210 -0
- ccai/webworks/static/javascript/components/mjsurface.js +132 -0
- ccai/webworks/static/javascript/components/mjtable.js +541 -0
- ccai/webworks/static/javascript/components/mjtabs.js +311 -0
- ccai/webworks/static/javascript/components/mjtagpicker.js +979 -0
- ccai/webworks/static/javascript/components/mjtextarea.js +378 -0
- ccai/webworks/static/javascript/components/mjtextfield.js +359 -0
- ccai/webworks/static/javascript/components/mjtoast.js +246 -0
- ccai/webworks/static/javascript/components/mjtoastregion.js +373 -0
- ccai/webworks/static/javascript/components/mjtoc.js +380 -0
- ccai/webworks/static/javascript/components/mjtogglebutton.js +212 -0
- ccai/webworks/static/javascript/components/mjtokeninput.js +609 -0
- ccai/webworks/static/javascript/components/mjtoolbar.js +263 -0
- ccai/webworks/static/javascript/components/mjtooltip.js +365 -0
- ccai/webworks/static/javascript/components/mjtour.js +677 -0
- ccai/webworks/static/javascript/components/mjtransferlist.js +920 -0
- ccai/webworks/static/javascript/components/mjtreegrid.js +546 -0
- ccai/webworks/static/javascript/components/mjtreenav.js +573 -0
- ccai/webworks/static/javascript/components/mjtreeselector.js +918 -0
- ccai/webworks/static/javascript/components/mjtypedfield.js +323 -0
- ccai/webworks/static/javascript/components/mjuploadbutton.js +476 -0
- ccai/webworks/static/javascript/components/mjvalidationsummary.js +288 -0
- ccai/webworks/static/javascript/components/mjvelocitychart.js +300 -0
- ccai/webworks/static/javascript/components/mjvirtuallist.js +465 -0
- ccai/webworks/static/javascript/components/mjwizard.js +326 -0
- ccai/webworks/static/javascript/components/mjworkflowdiagram.js +430 -0
- ccai/webworks/static/javascript/core/anchoring.js +149 -0
- ccai/webworks/static/javascript/core/announcer.js +61 -0
- ccai/webworks/static/javascript/core/basestyles.js +77 -0
- ccai/webworks/static/javascript/core/collection.js +115 -0
- ccai/webworks/static/javascript/core/contextmenu.js +299 -0
- ccai/webworks/static/javascript/core/focustrap.js +241 -0
- ccai/webworks/static/javascript/core/forminternals.js +144 -0
- ccai/webworks/static/javascript/core/intl.js +132 -0
- ccai/webworks/static/javascript/core/mjelement.js +475 -0
- ccai/webworks/static/javascript/core/overlay.js +188 -0
- ccai/webworks/static/javascript/core/registry.js +46 -0
- ccai/webworks/static/javascript/index.js +207 -0
- ccai/webworks/static/styles/base.css +129 -0
- ccai/webworks/static/styles/tokens.css +189 -0
- ccai/webworks/templating/__init__.py +174 -0
- ccai/webworks/templating/cache.py +296 -0
- ccai/webworks/templating/config.py +178 -0
- ccai/webworks/templating/context.py +548 -0
- ccai/webworks/templating/engine.py +326 -0
- ccai/webworks/templating/escaping.py +245 -0
- ccai/webworks/templating/exceptions.py +386 -0
- ccai/webworks/templating/filters.py +337 -0
- ccai/webworks/templating/jinja2_adapter.py +637 -0
- ccai/webworks/templating/loader.py +351 -0
- ccai/webworks/templating/mako_adapter.py +326 -0
- ccai/webworks/templating/registry.py +246 -0
- ccai/webworks/templating/renderer.py +416 -0
- ccai/webworks/templating/response.py +341 -0
- ccai/webworks/templating/wiring.py +178 -0
- ccai/webworks/urlnodemap/__init__.py +43 -0
- ccai/webworks/urlnodemap/exceptions.py +101 -0
- ccai/webworks/urlnodemap/pathutils.py +194 -0
- ccai/webworks/urlnodemap/urlnode.py +461 -0
- ccai/webworks/urlnodemap/urlnodemap.py +430 -0
- ccai/webworks/webapplication.py +1041 -0
- ccai/webworks/wellknown.py +51 -0
- ccai/webworks/wsgi/__init__.py +101 -0
- ccai/webworks/wsgi/application.py +399 -0
- ccai/webworks/wsgi/bodyparser.py +482 -0
- ccai/webworks/wsgi/connectionmanager.py +536 -0
- ccai/webworks/wsgi/constants.py +51 -0
- ccai/webworks/wsgi/environparser.py +573 -0
- ccai/webworks/wsgi/errorhandler.py +285 -0
- ccai/webworks/wsgi/exceptions.py +244 -0
- ccai/webworks/wsgi/httpparser.py +666 -0
- ccai/webworks/wsgi/httpwriter.py +314 -0
- ccai/webworks/wsgi/middleware.py +93 -0
- ccai/webworks/wsgi/response.py +276 -0
- ccai/webworks/wsgi/responseiterator.py +233 -0
- ccai/webworks/wsgi/server.py +728 -0
- ccai/webworks/wsgi/serverconfig.py +347 -0
- ccai/webworks/wsgi/socketlistener.py +406 -0
- ccai/webworks/wsgi/startresponse.py +319 -0
- ccai/webworks/wsgi/worker.py +768 -0
- ccai/webworks/wsgi/workermanager.py +490 -0
- codecraftai_webworks-1.4.0.dist-info/METADATA +71 -0
- codecraftai_webworks-1.4.0.dist-info/RECORD +495 -0
- codecraftai_webworks-1.4.0.dist-info/WHEEL +4 -0
- codecraftai_webworks-1.4.0.dist-info/licenses/LICENSE.md +204 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: webworks
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Package containing web application infrastructure for the ccai framework.
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Code Craft AI LLC
|
|
7
|
+
|
|
8
|
+
This package provides web application infrastructure including:
|
|
9
|
+
|
|
10
|
+
- ASGI application layer (HTTP handlers, WebSocket, SSE, background tasks)
|
|
11
|
+
- WSGI application layer (server, workers, middleware, request/response handling)
|
|
12
|
+
- Web application persona system for establishing application identity
|
|
13
|
+
- Authentication infrastructure with pluggable authenticators
|
|
14
|
+
- Endpoint routing and access policy enforcement
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__author__ = "Code Craft AI LLC"
|
|
18
|
+
__copyright__ = "Copyright 2025, Code Craft AI LLC"
|
|
19
|
+
__credits__ = []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from ccai.webworks.wellknown import (
|
|
23
|
+
THISWEBAPPLICATION_SINGLETON,
|
|
24
|
+
ThisWebApplicationSingleton
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Import authentication module for convenient access
|
|
28
|
+
from ccai.webworks import authentication
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"authentication",
|
|
32
|
+
"THISWEBAPPLICATION_SINGLETON",
|
|
33
|
+
"ThisWebApplicationSingleton"
|
|
34
|
+
]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ASGI Layer package.
|
|
3
|
+
|
|
4
|
+
This package provides the Asynchronous Server Gateway Interface (ASGI)
|
|
5
|
+
application interface that enables the web framework to communicate with
|
|
6
|
+
ASGI-compliant web servers.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from ccai.webworks.asgi.scopeparser import ScopeParser
|
|
10
|
+
from ccai.webworks.asgi.bodyreader import BodyReader, UploadedFile
|
|
11
|
+
from ccai.webworks.asgi.responsesender import ResponseSender
|
|
12
|
+
from ccai.webworks.asgi.httphandler import HTTPHandler
|
|
13
|
+
from ccai.webworks.asgi.websockethandler import WebSocketHandler, WebSocketConnection
|
|
14
|
+
from ccai.webworks.asgi.errorhandler import ErrorHandler, ErrorResponse, HTTPException
|
|
15
|
+
from ccai.webworks.asgi.ssehandler import SSEHandler, SSEEvent
|
|
16
|
+
from ccai.webworks.asgi.backgroundtasks import BackgroundTasks
|
|
17
|
+
from ccai.webworks.asgi.lifespanhandler import LifespanHandler
|
|
18
|
+
from ccai.webworks.asgi.application import (
|
|
19
|
+
ASGIApplication,
|
|
20
|
+
UnknownScopeTypeError,
|
|
21
|
+
get_asgi_application,
|
|
22
|
+
create_asgi_application,
|
|
23
|
+
reset_singleton_application,
|
|
24
|
+
get_application_variable,
|
|
25
|
+
)
|
|
26
|
+
from ccai.webworks.asgi.constants import (
|
|
27
|
+
SCOPE_REQUEST,
|
|
28
|
+
SCOPE_ROUTE,
|
|
29
|
+
SCOPE_PATH_PARAMS,
|
|
30
|
+
SCOPE_ERROR,
|
|
31
|
+
SCOPE_DEBUG,
|
|
32
|
+
WS_CLOSE_NORMAL,
|
|
33
|
+
WS_CLOSE_GOING_AWAY,
|
|
34
|
+
WS_CLOSE_PROTOCOL_ERROR,
|
|
35
|
+
WS_CLOSE_UNSUPPORTED_DATA,
|
|
36
|
+
WS_CLOSE_INTERNAL_ERROR,
|
|
37
|
+
)
|
|
38
|
+
from ccai.webworks.asgi.exceptions import (
|
|
39
|
+
ASGIError,
|
|
40
|
+
BadRequestBody,
|
|
41
|
+
ClientDisconnected,
|
|
42
|
+
RequestEntityTooLarge,
|
|
43
|
+
WebSocketError,
|
|
44
|
+
LifespanError,
|
|
45
|
+
StartupError,
|
|
46
|
+
ShutdownError,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"ASGIApplication",
|
|
52
|
+
"UnknownScopeTypeError",
|
|
53
|
+
"get_asgi_application",
|
|
54
|
+
"create_asgi_application",
|
|
55
|
+
"reset_singleton_application",
|
|
56
|
+
"get_application_variable",
|
|
57
|
+
"ScopeParser",
|
|
58
|
+
"BodyReader",
|
|
59
|
+
"UploadedFile",
|
|
60
|
+
"ResponseSender",
|
|
61
|
+
"HTTPHandler",
|
|
62
|
+
"WebSocketHandler",
|
|
63
|
+
"WebSocketConnection",
|
|
64
|
+
"ErrorHandler",
|
|
65
|
+
"ErrorResponse",
|
|
66
|
+
"HTTPException",
|
|
67
|
+
"SSEHandler",
|
|
68
|
+
"SSEEvent",
|
|
69
|
+
"BackgroundTasks",
|
|
70
|
+
"LifespanHandler",
|
|
71
|
+
"SCOPE_REQUEST",
|
|
72
|
+
"SCOPE_ROUTE",
|
|
73
|
+
"SCOPE_PATH_PARAMS",
|
|
74
|
+
"SCOPE_ERROR",
|
|
75
|
+
"SCOPE_DEBUG",
|
|
76
|
+
"WS_CLOSE_NORMAL",
|
|
77
|
+
"WS_CLOSE_GOING_AWAY",
|
|
78
|
+
"WS_CLOSE_PROTOCOL_ERROR",
|
|
79
|
+
"WS_CLOSE_UNSUPPORTED_DATA",
|
|
80
|
+
"WS_CLOSE_INTERNAL_ERROR",
|
|
81
|
+
"ASGIError",
|
|
82
|
+
"BadRequestBody",
|
|
83
|
+
"ClientDisconnected",
|
|
84
|
+
"RequestEntityTooLarge",
|
|
85
|
+
"WebSocketError",
|
|
86
|
+
"LifespanError",
|
|
87
|
+
"StartupError",
|
|
88
|
+
"ShutdownError",
|
|
89
|
+
]
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ASGI Application module.
|
|
3
|
+
|
|
4
|
+
This module provides the ASGIApplication class that serves as the main
|
|
5
|
+
entry point for ASGI servers. It implements the ASGI 3.0 specification
|
|
6
|
+
and dispatches requests to the appropriate handlers based on scope type.
|
|
7
|
+
|
|
8
|
+
This module also provides server integration functions:
|
|
9
|
+
- get_asgi_application(): Returns a configured ASGIApplication instance
|
|
10
|
+
- create_asgi_application(): Factory function for creating new instances
|
|
11
|
+
- application: Module-level variable for ASGI server convention
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from typing import Any, Awaitable, Callable, Dict, Optional
|
|
16
|
+
|
|
17
|
+
from ccai.webworks.asgi.constants import (
|
|
18
|
+
SCOPE_TYPE_HTTP,
|
|
19
|
+
SCOPE_TYPE_WEBSOCKET,
|
|
20
|
+
SCOPE_TYPE_LIFESPAN,
|
|
21
|
+
)
|
|
22
|
+
from ccai.webworks.asgi.httphandler import HTTPHandler
|
|
23
|
+
from ccai.webworks.asgi.websockethandler import WebSocketHandler
|
|
24
|
+
from ccai.webworks.asgi.lifespanhandler import LifespanHandler
|
|
25
|
+
from ccai.webworks.asgi.errorhandler import ErrorHandler
|
|
26
|
+
from ccai.webworks.asgi.exceptions import ASGIError
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Type aliases for clarity
|
|
30
|
+
ReceiveCallable = Callable[[], Awaitable[Dict[str, Any]]]
|
|
31
|
+
SendCallable = Callable[[Dict[str, Any]], Awaitable[None]]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class UnknownScopeTypeError(ASGIError):
|
|
35
|
+
"""
|
|
36
|
+
Exception raised when an unknown scope type is received.
|
|
37
|
+
|
|
38
|
+
This exception is raised when the ASGI application receives a scope
|
|
39
|
+
with a type that it does not know how to handle.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, scope_type: str):
|
|
43
|
+
"""
|
|
44
|
+
Construct an UnknownScopeTypeError.
|
|
45
|
+
|
|
46
|
+
:param scope_type: The unknown scope type that was received.
|
|
47
|
+
"""
|
|
48
|
+
self._scope_type = scope_type
|
|
49
|
+
message = f"Unknown ASGI scope type: {scope_type}"
|
|
50
|
+
super().__init__(message)
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def scope_type(self) -> str:
|
|
55
|
+
"""
|
|
56
|
+
Get the unknown scope type.
|
|
57
|
+
|
|
58
|
+
:returns: The unknown scope type string.
|
|
59
|
+
"""
|
|
60
|
+
return self._scope_type
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ASGIApplication:
|
|
64
|
+
"""
|
|
65
|
+
ASGI application callable that bridges ASGI servers to the framework.
|
|
66
|
+
|
|
67
|
+
This class implements the ASGI 3.0 specification and serves as the
|
|
68
|
+
main entry point for ASGI servers. It dispatches requests to the
|
|
69
|
+
appropriate handlers based on the scope type (http, websocket, lifespan).
|
|
70
|
+
|
|
71
|
+
The application supports:
|
|
72
|
+
- HTTP request/response cycles
|
|
73
|
+
- WebSocket connections
|
|
74
|
+
- Lifespan events (startup/shutdown)
|
|
75
|
+
- Async handlers and middleware
|
|
76
|
+
- Custom error handling
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def __init__(
|
|
80
|
+
self,
|
|
81
|
+
http_handler: Optional[HTTPHandler] = None,
|
|
82
|
+
websocket_handler: Optional[WebSocketHandler] = None,
|
|
83
|
+
lifespan_handler: Optional[LifespanHandler] = None,
|
|
84
|
+
error_handler: Optional[ErrorHandler] = None,
|
|
85
|
+
debug: bool = False,
|
|
86
|
+
logger: Optional[logging.Logger] = None,
|
|
87
|
+
):
|
|
88
|
+
"""
|
|
89
|
+
Construct an ASGI application.
|
|
90
|
+
|
|
91
|
+
:param http_handler: Handler for HTTP requests. If None, a default
|
|
92
|
+
handler will be created.
|
|
93
|
+
:param websocket_handler: Handler for WebSocket connections. If None,
|
|
94
|
+
a default handler will be created.
|
|
95
|
+
:param lifespan_handler: Handler for lifespan events. If None, a
|
|
96
|
+
default handler will be created.
|
|
97
|
+
:param error_handler: Handler for errors. If None, a default handler
|
|
98
|
+
will be created.
|
|
99
|
+
:param debug: If True, include stack traces in error responses.
|
|
100
|
+
:param logger: Logger for application logging. If None, a default
|
|
101
|
+
logger will be created.
|
|
102
|
+
"""
|
|
103
|
+
self._debug = debug
|
|
104
|
+
|
|
105
|
+
if logger is None:
|
|
106
|
+
self._logger = logging.getLogger(__name__)
|
|
107
|
+
else:
|
|
108
|
+
self._logger = logger
|
|
109
|
+
|
|
110
|
+
if http_handler is None:
|
|
111
|
+
self._http_handler = HTTPHandler(debug=debug)
|
|
112
|
+
else:
|
|
113
|
+
self._http_handler = http_handler
|
|
114
|
+
|
|
115
|
+
if websocket_handler is None:
|
|
116
|
+
self._websocket_handler = WebSocketHandler(debug=debug, logger=self._logger)
|
|
117
|
+
else:
|
|
118
|
+
self._websocket_handler = websocket_handler
|
|
119
|
+
|
|
120
|
+
if lifespan_handler is None:
|
|
121
|
+
self._lifespan_handler = LifespanHandler(logger=self._logger)
|
|
122
|
+
else:
|
|
123
|
+
self._lifespan_handler = lifespan_handler
|
|
124
|
+
|
|
125
|
+
if error_handler is None:
|
|
126
|
+
self._error_handler = ErrorHandler(debug=debug, logger=self._logger)
|
|
127
|
+
else:
|
|
128
|
+
self._error_handler = error_handler
|
|
129
|
+
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def debug(self) -> bool:
|
|
134
|
+
"""
|
|
135
|
+
Get the debug mode setting.
|
|
136
|
+
|
|
137
|
+
:returns: True if debug mode is enabled.
|
|
138
|
+
"""
|
|
139
|
+
return self._debug
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def logger(self) -> logging.Logger:
|
|
143
|
+
"""
|
|
144
|
+
Get the logger instance.
|
|
145
|
+
|
|
146
|
+
:returns: Logger instance.
|
|
147
|
+
"""
|
|
148
|
+
return self._logger
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def http_handler(self) -> HTTPHandler:
|
|
152
|
+
"""
|
|
153
|
+
Get the HTTP handler.
|
|
154
|
+
|
|
155
|
+
:returns: HTTPHandler instance.
|
|
156
|
+
"""
|
|
157
|
+
return self._http_handler
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def websocket_handler(self) -> WebSocketHandler:
|
|
161
|
+
"""
|
|
162
|
+
Get the WebSocket handler.
|
|
163
|
+
|
|
164
|
+
:returns: WebSocketHandler instance.
|
|
165
|
+
"""
|
|
166
|
+
return self._websocket_handler
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def lifespan_handler(self) -> LifespanHandler:
|
|
170
|
+
"""
|
|
171
|
+
Get the lifespan handler.
|
|
172
|
+
|
|
173
|
+
:returns: LifespanHandler instance.
|
|
174
|
+
"""
|
|
175
|
+
return self._lifespan_handler
|
|
176
|
+
|
|
177
|
+
@property
|
|
178
|
+
def error_handler(self) -> ErrorHandler:
|
|
179
|
+
"""
|
|
180
|
+
Get the error handler.
|
|
181
|
+
|
|
182
|
+
:returns: ErrorHandler instance.
|
|
183
|
+
"""
|
|
184
|
+
return self._error_handler
|
|
185
|
+
|
|
186
|
+
async def __call__(
|
|
187
|
+
self,
|
|
188
|
+
scope: Dict[str, Any],
|
|
189
|
+
receive: ReceiveCallable,
|
|
190
|
+
send: SendCallable,
|
|
191
|
+
) -> None:
|
|
192
|
+
"""
|
|
193
|
+
ASGI application entry point.
|
|
194
|
+
|
|
195
|
+
This method is called by the ASGI server for each connection.
|
|
196
|
+
It dispatches to the appropriate handler based on the scope type.
|
|
197
|
+
|
|
198
|
+
:param scope: ASGI scope dictionary containing connection metadata.
|
|
199
|
+
:param receive: Async callable to receive messages from the client.
|
|
200
|
+
:param send: Async callable to send messages to the client.
|
|
201
|
+
|
|
202
|
+
:raises UnknownScopeTypeError: If the scope type is not recognized.
|
|
203
|
+
"""
|
|
204
|
+
scope_type = scope.get("type", "")
|
|
205
|
+
|
|
206
|
+
if scope_type == SCOPE_TYPE_HTTP:
|
|
207
|
+
await self._handle_http(scope, receive, send)
|
|
208
|
+
elif scope_type == SCOPE_TYPE_WEBSOCKET:
|
|
209
|
+
await self._handle_websocket(scope, receive, send)
|
|
210
|
+
elif scope_type == SCOPE_TYPE_LIFESPAN:
|
|
211
|
+
await self._handle_lifespan(scope, receive, send)
|
|
212
|
+
else:
|
|
213
|
+
await self._handle_unknown(scope, receive, send)
|
|
214
|
+
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
async def _handle_http(
|
|
218
|
+
self,
|
|
219
|
+
scope: Dict[str, Any],
|
|
220
|
+
receive: ReceiveCallable,
|
|
221
|
+
send: SendCallable,
|
|
222
|
+
) -> None:
|
|
223
|
+
"""
|
|
224
|
+
Handle HTTP request/response cycle.
|
|
225
|
+
|
|
226
|
+
Delegates to the HTTP handler and uses the error handler for
|
|
227
|
+
any unhandled exceptions that propagate up.
|
|
228
|
+
|
|
229
|
+
:param scope: ASGI HTTP scope dictionary.
|
|
230
|
+
:param receive: Async receive callable.
|
|
231
|
+
:param send: Async send callable.
|
|
232
|
+
"""
|
|
233
|
+
try:
|
|
234
|
+
await self._http_handler.handle(scope, receive, send)
|
|
235
|
+
except Exception as exc:
|
|
236
|
+
# Use the error handler for any exceptions that propagate up
|
|
237
|
+
await self._error_handler.handle_http_error(exc, send, scope)
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
async def _handle_websocket(
|
|
241
|
+
self,
|
|
242
|
+
scope: Dict[str, Any],
|
|
243
|
+
receive: ReceiveCallable,
|
|
244
|
+
send: SendCallable,
|
|
245
|
+
) -> None:
|
|
246
|
+
"""
|
|
247
|
+
Handle WebSocket connection.
|
|
248
|
+
|
|
249
|
+
Delegates to the WebSocket handler and uses the error handler for
|
|
250
|
+
any unhandled exceptions that propagate up.
|
|
251
|
+
|
|
252
|
+
:param scope: ASGI WebSocket scope dictionary.
|
|
253
|
+
:param receive: Async receive callable.
|
|
254
|
+
:param send: Async send callable.
|
|
255
|
+
"""
|
|
256
|
+
try:
|
|
257
|
+
await self._websocket_handler.handle(scope, receive, send)
|
|
258
|
+
except Exception as exc:
|
|
259
|
+
# Use the error handler for any exceptions that propagate up
|
|
260
|
+
await self._error_handler.handle_websocket_error(exc, send, scope)
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
async def _handle_lifespan(
|
|
264
|
+
self,
|
|
265
|
+
scope: Dict[str, Any],
|
|
266
|
+
receive: ReceiveCallable,
|
|
267
|
+
send: SendCallable,
|
|
268
|
+
) -> None:
|
|
269
|
+
"""
|
|
270
|
+
Handle lifespan startup/shutdown events.
|
|
271
|
+
|
|
272
|
+
:param scope: ASGI lifespan scope dictionary.
|
|
273
|
+
:param receive: Async receive callable.
|
|
274
|
+
:param send: Async send callable.
|
|
275
|
+
"""
|
|
276
|
+
await self._lifespan_handler.handle(scope, receive, send)
|
|
277
|
+
return
|
|
278
|
+
|
|
279
|
+
async def _handle_unknown(
|
|
280
|
+
self,
|
|
281
|
+
scope: Dict[str, Any],
|
|
282
|
+
receive: ReceiveCallable,
|
|
283
|
+
send: SendCallable,
|
|
284
|
+
) -> None:
|
|
285
|
+
"""
|
|
286
|
+
Handle unknown scope type.
|
|
287
|
+
|
|
288
|
+
This method is called when the scope type is not recognized.
|
|
289
|
+
It raises an UnknownScopeTypeError.
|
|
290
|
+
|
|
291
|
+
:param scope: ASGI scope dictionary.
|
|
292
|
+
:param receive: Async receive callable.
|
|
293
|
+
:param send: Async send callable.
|
|
294
|
+
|
|
295
|
+
:raises UnknownScopeTypeError: Always raised for unknown scope types.
|
|
296
|
+
"""
|
|
297
|
+
scope_type = scope.get("type", "")
|
|
298
|
+
self._logger.warning(f"Received unknown ASGI scope type: {scope_type}")
|
|
299
|
+
raise UnknownScopeTypeError(scope_type)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# =============================================================================
|
|
303
|
+
# Module-level application variable for ASGI server convention
|
|
304
|
+
# =============================================================================
|
|
305
|
+
|
|
306
|
+
# Module-level application variable for ASGI servers.
|
|
307
|
+
# This follows the convention used by ASGI servers like Uvicorn, Hypercorn,
|
|
308
|
+
# and Daphne where they look for an 'application' variable in the module.
|
|
309
|
+
# This variable is initialized to None and can be set by calling
|
|
310
|
+
# get_asgi_application() or create_asgi_application().
|
|
311
|
+
application: Optional[ASGIApplication] = None
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
# =============================================================================
|
|
315
|
+
# Singleton instance for get_asgi_application()
|
|
316
|
+
# =============================================================================
|
|
317
|
+
|
|
318
|
+
_singleton_application: Optional[ASGIApplication] = None
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
# =============================================================================
|
|
322
|
+
# Server Integration Functions
|
|
323
|
+
# =============================================================================
|
|
324
|
+
|
|
325
|
+
def get_asgi_application(
|
|
326
|
+
debug: bool = False,
|
|
327
|
+
lifespan_enabled: bool = True,
|
|
328
|
+
**kwargs: Any,
|
|
329
|
+
) -> ASGIApplication:
|
|
330
|
+
"""
|
|
331
|
+
Get the ASGI application callable.
|
|
332
|
+
|
|
333
|
+
This is the main entry point for ASGI servers. It returns a singleton
|
|
334
|
+
ASGIApplication instance, creating it on first call. Subsequent calls
|
|
335
|
+
return the same instance.
|
|
336
|
+
|
|
337
|
+
This function is useful when you want to ensure only one application
|
|
338
|
+
instance exists throughout the application lifecycle.
|
|
339
|
+
|
|
340
|
+
:param debug: If True, include stack traces in error responses.
|
|
341
|
+
Only used on first call when creating the instance.
|
|
342
|
+
:param lifespan_enabled: If True, enable lifespan protocol support.
|
|
343
|
+
Only used on first call when creating the instance.
|
|
344
|
+
:param kwargs: Additional keyword arguments passed to ASGIApplication.
|
|
345
|
+
Only used on first call when creating the instance.
|
|
346
|
+
|
|
347
|
+
:returns: Configured ASGIApplication instance.
|
|
348
|
+
|
|
349
|
+
Example usage with Uvicorn:
|
|
350
|
+
|
|
351
|
+
# In your application module (e.g., app.py):
|
|
352
|
+
from ccai.webworks.asgi import get_asgi_application
|
|
353
|
+
|
|
354
|
+
application = get_asgi_application(debug=True)
|
|
355
|
+
|
|
356
|
+
# Run with: uvicorn app:application
|
|
357
|
+
"""
|
|
358
|
+
global _singleton_application
|
|
359
|
+
global application
|
|
360
|
+
|
|
361
|
+
if _singleton_application is None:
|
|
362
|
+
_singleton_application = create_asgi_application(
|
|
363
|
+
debug=debug,
|
|
364
|
+
lifespan_enabled=lifespan_enabled,
|
|
365
|
+
**kwargs,
|
|
366
|
+
)
|
|
367
|
+
# Also set the module-level application variable
|
|
368
|
+
application = _singleton_application
|
|
369
|
+
|
|
370
|
+
return _singleton_application
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def create_asgi_application(
|
|
374
|
+
config: Optional[Dict[str, Any]] = None,
|
|
375
|
+
debug: bool = False,
|
|
376
|
+
lifespan_enabled: bool = True,
|
|
377
|
+
http_handler: Optional[HTTPHandler] = None,
|
|
378
|
+
websocket_handler: Optional[WebSocketHandler] = None,
|
|
379
|
+
lifespan_handler: Optional[LifespanHandler] = None,
|
|
380
|
+
error_handler: Optional[ErrorHandler] = None,
|
|
381
|
+
logger: Optional[logging.Logger] = None,
|
|
382
|
+
) -> ASGIApplication:
|
|
383
|
+
"""
|
|
384
|
+
Application factory for creating ASGI applications.
|
|
385
|
+
|
|
386
|
+
Each call creates a new application instance. This is useful for
|
|
387
|
+
testing or when you need multiple isolated application instances.
|
|
388
|
+
|
|
389
|
+
The factory supports two ways of configuration:
|
|
390
|
+
1. Using the config dict parameter
|
|
391
|
+
2. Using individual keyword arguments
|
|
392
|
+
|
|
393
|
+
If both are provided, keyword arguments take precedence over config dict.
|
|
394
|
+
|
|
395
|
+
:param config: Optional configuration dictionary with keys:
|
|
396
|
+
- debug: bool - Enable debug mode
|
|
397
|
+
- lifespan_enabled: bool - Enable lifespan protocol
|
|
398
|
+
- http_handler: HTTPHandler instance
|
|
399
|
+
- websocket_handler: WebSocketHandler instance
|
|
400
|
+
- lifespan_handler: LifespanHandler instance
|
|
401
|
+
- error_handler: ErrorHandler instance
|
|
402
|
+
- logger: Logger instance
|
|
403
|
+
:param debug: If True, include stack traces in error responses.
|
|
404
|
+
:param lifespan_enabled: If True, enable lifespan protocol support.
|
|
405
|
+
If False, lifespan events are ignored.
|
|
406
|
+
:param http_handler: Custom HTTP handler instance.
|
|
407
|
+
:param websocket_handler: Custom WebSocket handler instance.
|
|
408
|
+
:param lifespan_handler: Custom lifespan handler instance.
|
|
409
|
+
:param error_handler: Custom error handler instance.
|
|
410
|
+
:param logger: Logger instance for application logging.
|
|
411
|
+
|
|
412
|
+
:returns: New ASGIApplication instance.
|
|
413
|
+
|
|
414
|
+
Example usage:
|
|
415
|
+
|
|
416
|
+
# Create application with config dict
|
|
417
|
+
app = create_asgi_application(config={
|
|
418
|
+
"debug": True,
|
|
419
|
+
"lifespan_enabled": True,
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
# Create application with keyword arguments
|
|
423
|
+
app = create_asgi_application(debug=True, lifespan_enabled=True)
|
|
424
|
+
|
|
425
|
+
# Create application for testing (new instance each time)
|
|
426
|
+
def test_something():
|
|
427
|
+
app = create_asgi_application(debug=True)
|
|
428
|
+
# ... test code ...
|
|
429
|
+
"""
|
|
430
|
+
# Merge config dict with keyword arguments (kwargs take precedence)
|
|
431
|
+
effective_config: Dict[str, Any] = {}
|
|
432
|
+
|
|
433
|
+
if config is not None:
|
|
434
|
+
effective_config.update(config)
|
|
435
|
+
|
|
436
|
+
# Override with explicit keyword arguments
|
|
437
|
+
effective_debug = debug
|
|
438
|
+
if "debug" in effective_config and debug is False:
|
|
439
|
+
effective_debug = effective_config["debug"]
|
|
440
|
+
|
|
441
|
+
effective_lifespan_enabled = lifespan_enabled
|
|
442
|
+
if "lifespan_enabled" in effective_config and lifespan_enabled is True:
|
|
443
|
+
effective_lifespan_enabled = effective_config["lifespan_enabled"]
|
|
444
|
+
|
|
445
|
+
effective_http_handler = http_handler
|
|
446
|
+
if effective_http_handler is None and "http_handler" in effective_config:
|
|
447
|
+
effective_http_handler = effective_config["http_handler"]
|
|
448
|
+
|
|
449
|
+
effective_websocket_handler = websocket_handler
|
|
450
|
+
if effective_websocket_handler is None and "websocket_handler" in effective_config:
|
|
451
|
+
effective_websocket_handler = effective_config["websocket_handler"]
|
|
452
|
+
|
|
453
|
+
effective_lifespan_handler = lifespan_handler
|
|
454
|
+
if effective_lifespan_handler is None and "lifespan_handler" in effective_config:
|
|
455
|
+
effective_lifespan_handler = effective_config["lifespan_handler"]
|
|
456
|
+
|
|
457
|
+
effective_error_handler = error_handler
|
|
458
|
+
if effective_error_handler is None and "error_handler" in effective_config:
|
|
459
|
+
effective_error_handler = effective_config["error_handler"]
|
|
460
|
+
|
|
461
|
+
effective_logger = logger
|
|
462
|
+
if effective_logger is None and "logger" in effective_config:
|
|
463
|
+
effective_logger = effective_config["logger"]
|
|
464
|
+
|
|
465
|
+
# Create the lifespan handler with enabled/disabled support
|
|
466
|
+
if effective_lifespan_handler is None:
|
|
467
|
+
effective_lifespan_handler = LifespanHandler(
|
|
468
|
+
logger=effective_logger,
|
|
469
|
+
enabled=effective_lifespan_enabled,
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
# Create the application
|
|
473
|
+
app = ASGIApplication(
|
|
474
|
+
http_handler=effective_http_handler,
|
|
475
|
+
websocket_handler=effective_websocket_handler,
|
|
476
|
+
lifespan_handler=effective_lifespan_handler,
|
|
477
|
+
error_handler=effective_error_handler,
|
|
478
|
+
debug=effective_debug,
|
|
479
|
+
logger=effective_logger,
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
return app
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def reset_singleton_application() -> None:
|
|
486
|
+
"""
|
|
487
|
+
Reset the singleton application instance.
|
|
488
|
+
|
|
489
|
+
This function is primarily intended for testing purposes. It clears
|
|
490
|
+
the singleton instance so that the next call to get_asgi_application()
|
|
491
|
+
will create a new instance.
|
|
492
|
+
|
|
493
|
+
:returns: None
|
|
494
|
+
"""
|
|
495
|
+
global _singleton_application
|
|
496
|
+
global application
|
|
497
|
+
|
|
498
|
+
_singleton_application = None
|
|
499
|
+
application = None
|
|
500
|
+
|
|
501
|
+
return
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
def get_application_variable() -> Optional[ASGIApplication]:
|
|
505
|
+
"""
|
|
506
|
+
Get the current value of the module-level application variable.
|
|
507
|
+
|
|
508
|
+
This function provides a way to access the module-level application
|
|
509
|
+
variable from other modules without import-time binding issues.
|
|
510
|
+
|
|
511
|
+
:returns: The current ASGIApplication instance, or None if not set.
|
|
512
|
+
"""
|
|
513
|
+
return application
|