AWS Lambda & API Gateway support for ASGI

Overview

Mangum

Package version Build Status

PyPI - Python Version

Mangum is an adapter for using ASGI applications with AWS Lambda & API Gateway. It is intended to provide an easy-to-use, configurable wrapper for any ASGI application deployed in an AWS Lambda function to handle API Gateway requests and responses.

Documentation: https://mangum.io/

Features

  • API Gateway support for HTTP and REST APIs.

  • Compatibility with ASGI application frameworks, such as Starlette, FastAPI, and Quart.

  • Support for binary media types and payload compression in API Gateway using GZip or Brotli.

  • Works with existing deployment and configuration tools, including Serverless Framework and AWS SAM.

  • Startup and shutdown lifespan events.

Requirements

Python 3.6+

Installation

pip install mangum

Example

from mangum import Mangum

async def app(scope, receive, send):
    await send(
        {
            "type": "http.response.start",
            "status": 200,
            "headers": [[b"content-type", b"text/plain; charset=utf-8"]],
        }
    )
    await send({"type": "http.response.body", "body": b"Hello, world!"})


handler = Mangum(app)

Or using a framework.

from fastapi import FastAPI
from mangum import Mangum

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

handler = Mangum(app)
Comments
  • Refactor handlers to be separate from core logic

    Refactor handlers to be separate from core logic

    Okay here is a BIG one. This refactors out all of the logic for each event source into their own classes. This helps encapsulate all the messy logic for each event source into one place. It also makes it easier to add new event sources as we choose. I namespaced the handlers with "AWS" with thoughts that this could actually apply to other serverless implementations over on Azure, GCP, etc. if needed.

    I wanted to get this in front of you sooner rather than later so you could take a look. It needs a couple more lines of coverage and I'm going to go back and look through some of the issues to make sure I have them covered in tests and they're still working (regression is no good)

    It might be easier to look at the repo at my commit, not just the changes.

    Let me know what you think, big changes like this are scary but it feels a lot cleaner.

    opened by four43 17
  • AWS WebSocket support

    AWS WebSocket support

    I've removed the existing WebSocket support as part of https://github.com/jordaneremieff/mangum/issues/127 with the intention of developing it outside of this package, then later migrating it back in (if it makes sense to do so). My main concern is that I want to avoid impacting the stability of the HTTP implementation which is the primary use-case, and the maintenance burden was too much for the amount of capacity I have to spare currently. I also want to re-design it with broadcast support as an initial requirement rather than a feature added on later.

    I think a new project might use Mangum as a dependency, or could end up looking something like this:

    from mangum import Mangum
    from mangum_ws import MangumWebSocket
    
    def handler(event, context):
        if 'eventType' in event['requestContext']:
            asgi_handler = MangumWebSocket(app)
        else:
            asgi_handler = Mangum(app)
    
        return asgi_handler(event, context)
    

    Not really sure. I haven't been motivated to take this up for awhile, but if anyone wants to give it a shot I can help where possible.

    feature websockets 
    opened by jordaneremieff 17
  • Deploying FastAPI as Lambda Function

    Deploying FastAPI as Lambda Function

    from fastapi import FastAPI
    from mangum import Mangum
    
    app = FastAPI()
    
    @app.get("/")
    def hello_world():
        return {"hello": "world"}
    
    handler = Mangum(app)
    

    ERROR:

    [ERROR] TypeError: __call__() takes 2 positional arguments but 4 were given
    Traceback (most recent call last):
      File "/var/task/mangum/__init__.py", line 123, in __call__
        raise exc
      File "/var/task/mangum/__init__.py", line 118, in __call__
        response = self.asgi(*args, **kwargs)
      File "/var/task/mangum/__init__.py", line 178, in asgi
        response = asgi_cycle(self.app, body=body)
      File "/var/task/mangum/__init__.py", line 38, in __call__
        asgi_instance = app(self.scope, self.receive, self.send)
    

    I tried this, but could not import AWSLambdaAdapter

    from mangum.platforms.aws.adapter import AWSLambdaAdapter
    

    Can you please provide a working example of this?

    opened by chgangaraju 17
  • Problems with FastAPI/Starlette Gzip middleware

    Problems with FastAPI/Starlette Gzip middleware

    (First off, awesome package. Being able to use an actual framework on Lambda without writing any 'transformation' code myself has been incredible.)

    I'm attempting to use Starlette's GZipMiddleware with FastAPI right now, and our front-end is sending a accept-encoding: gzip, deflate, br header.

    When I configure the middleware like so...

    APP = FastAPI()
    # ... other middleware
    APP.add_middleware(
        GZipMiddleware,
        minimum_size=512,
    )
    HANDLER = Mangum(APP, enable_lifespan=False)
    

    ... I receive the following error.

    Exception in ASGI application
    
    Traceback (most recent call last):
      File "/var/task/mangum/protocols/http.py", line 39, in run
        await app(self.scope, self.receive, self.send)
      File "/var/task/fastapi/applications.py", line 142, in __call__
        await super().__call__(scope, receive, send)  # pragma: no cover
      File "/var/task/starlette/applications.py", line 134, in __call__
        await self.error_middleware(scope, receive, send)
      File "/var/task/starlette/middleware/errors.py", line 178, in __call__
        raise exc from None
      File "/var/task/starlette/middleware/errors.py", line 156, in __call__
        await self.app(scope, receive, _send)
      File "/var/task/starlette/middleware/base.py", line 26, in __call__
        await response(scope, receive, send)
      File "/var/task/starlette/responses.py", line 200, in __call__
        await send({"type": "http.response.body", "body": b"", "more_body": False})
      File "/var/task/starlette/middleware/errors.py", line 153, in _send
        await send(message)
      File "/var/task/mangum/protocols/http.py", line 97, in send
        self.response["body"] = body.decode()
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
    

    I had initially thought it might be due to the minimum_size parameter but removing that did not work. If I removed the middleware completely then my Lambda works perfectly fine.

    I'm a little confused by the "body": b"" part, since this Lambda is returning data, and when I test locally running the same APP with uvicorn I have no issues - body is compressed and status code is 200.

    Is there something I need to do to configure Mangum for compression? Am I reading the stack trace wrong?

    ** FastAPI 0.48.0 Mangum 0.7.0 Python 3.6.8

    opened by kevlarr 15
  • Gracefully hanlde exceptions that happen after successful request.

    Gracefully hanlde exceptions that happen after successful request.

    With the current implementation, any exception in the ASGI app will make mangum return a response with 500, even though the application may have already correctly generated a valid response. In those cases we want to return the valid response and log the error, rather than fail.

    One example where this would manifest: failures in BackgroundTasks in FastAPI.

    This makes it inline with running FastAPI (and other ASGI) applications standalone where failures in the background tasks will return not make the whole request fail.

    opened by tasn 12
  • issue in reading .woff/.ttf/.woff2 (font extension) files

    issue in reading .woff/.ttf/.woff2 (font extension) files

    Hi. There is an issue in reading font files from the AWS API gateway proxied to AWS Lambda. It is reading it as a text file.

    in protocols/http.py body is not encoded in base64 body = base64.b64encode(body) and giving error in self.response["body"] = body.decode()

    It should return header with content-type as font/*

    opened by arvindjangra1996 12
  • 🚧 Add event source detection

    🚧 Add event source detection

    • add event source types
    • add event source detection
    • use event source type in scope creation

    This PR is a one-step closet to support different event sources.

    Also, we should construct responses according to the request type, that work is out of the PR scope though.

    opened by emcpow2 11
  • Double url-encoding of query string with ALB

    Double url-encoding of query string with ALB

    I've found that if I send a get request to FastAPI like GET eg.com/something?name=John+Smith then the database query generated uses literally John+Smith. Same situation using %20.

    It seems that Mangum is doing a second round of url-encoding on the query strings, so when FastAPI (or whatever might sit in the middle) decodes the query string it gets the once-encoded version back.

    I'm working with an Application Load Balancer.

    I'm not 100% sure what the correct behaviour should be, or whether the URL encoding behaviour should be different between API gateway and ALB.

    I'll create a pull request with a failing test for this in a moment.

    Some references:

    https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html "If the query parameters are URL-encoded, the load balancer does not decode them. You must decode them in your Lambda function."

    with ALB source, serverless-wsgi decodes and then encodes the query strings before passing off to WSGI: https://github.com/logandk/serverless-wsgi/blob/f8d5a92f63901ed25d1a09ae19fcaa791e22436f/serverless_wsgi.py#L82-L93

    Related issues from serverless-express https://github.com/vendia/serverless-express/issues/241 https://github.com/vendia/serverless-express/issues/219

    bug 
    opened by jurasofish 10
  • [Feature Request] Support for custom loggers

    [Feature Request] Support for custom loggers

    We are using the logger from aws-lambda-powertools-python. It's a logging tool from AWS, that can be quite helpful when it comes to debugging, especially when using CloudWatch Log Insights.

    I would like to use this logger with Mangum as well.

    I was thinking the constructor could accept a logger_class parameter, which when set is used instead of logging.getLogger. Alternatively, following logging.setLoggerClass, a function that can set which logger is used in adapter.get_logger.

    I tried using logging.setLoggerClass directly, but that results in a RecursionError; the AWS logger doesn't inherit logging.Logger properly, but instead instantiates an internal logger from logging.getLogger. If you think I should report the recursion error on the AWS repo instead, please let me know. I am quite new to Python, and don't know whether this behavior acceptable.

    feature 
    opened by aksel 10
  • Feature - Websockets

    Feature - Websockets

    Issue #132

    This is an attempt to re-introduce WebSockets support in the project. It's still just a draft, but I wanted to put something together as soon as possible to discuss and shape the solution. The implementation is basically the same as the one present in this branch. The PR was getting way too big, and I decided to drop the support to broadcast for now. Maybe we can handle this in another PR/issue.

    I've left a few TODO comments in the code on points where we should keep an eye, but overall my main questions would be these:

    • What's the best approach to instantiate the WebSocketCycle? Right now, I'm picking the protocol based on the lambda event. I think it's the best solution from the user standpoint, as the configuration stays the same as it already is, and we can support both HTTP and WebSocket connections in the same ASGI app. But it's possible to use a separate adaptor class as well.
    • The Scope format is slightly different for the WebSocket connection, but I kept using the same as HTTP.
    • Binary payloads seem to be unsupported by API GW. They suggest a workaround, though. Not sure if we should try to support this.
    • Subprotocols won't be supported, as the application is only called on the MESSAGE event (but the HTTP headers are exchanged on CONNECT).
    websockets 
    opened by eduardovra 9
  • Support multiple serverless platforms

    Support multiple serverless platforms

    This comment [1] explains how to use Mangum with the serverless framework. Since serverless supports multiple providers (e.g., Azure), would it be possible that Mangum enables ASGI support for other providers too?

    [1] https://dev.to/anilgrexit/comment/gkfo

    feature 
    opened by lsorber 9
  • question:  If my API already has a base64-encoded PNG, how ought it return it?

    question: If my API already has a base64-encoded PNG, how ought it return it?

    One API endpoint I have receives a base64-encoded PNG. Can I return the data via mangum with content-type image/png without having to first base64-decode it?

    opened by jrobbins-LiveData 0
  • Overwriting read-only Lambda@Edge headers

    Overwriting read-only [email protected] headers

    Hooking up a Mangum lambda to CloudFront as EventType: origin-request returns a 502 response: "The Lambda function result failed validation: The function tried to add, delete, or change a read-only header."

    According to the documentation, the Content-Length Header is one of the read-only headers for origin-request events. Not quite sure why. But it's certainly one of the headers returned when calling the lambda. I use the lambda to handle API requests, so it needs IncludeBody, which is only available with origin-request.

    I was able to get around this by hijacking the response:

    def handler(event, context):
        response = Mangum(app, lifespan="off")(event, context)
        if 'headers' in response:
            response['headers'].pop('content-length')
        return response
    
    help wanted improvement 
    opened by UnderSampled 2
  • Multiple event loops in custom handlers

    Multiple event loops in custom handlers

    Discussed in https://github.com/jordaneremieff/mangum/discussions/256

    Originally posted by jrobbins-LiveData March 20, 2022 The Mangum doc shows this example of how one might handle a custom event:

    def handler(event, context):
        if event.get("some-key"):
            # Do something or return, etc.
            return
    
        asgi_handler = Mangum(app)
        response = asgi_handler(event, context) # Call the instance with the event arguments
    
        return response
    

    I need to handle an incoming AWS EventBridge event. I want to invoke the same method that my HTTP API handler is also invoking -- and it is an async method.

    Here's what I am using

    def handler(event: LambdaEvent, context: LambdaContext) -> dict:
        if "requestContext" in event:
            logger.debug("HTTP API")
            response = fastapi_handler(event, context)
        else:
            logger.debug("Not HTTP API")
            loop = asyncio.get_event_loop()
            response = loop.run_until_complete(app_logic())
        return response
    

    My question(s): Is this the correct pattern to use? In the Mangum source, I see code like this, so I am trying to fit in. My code seems to work, but I read in the Python docs that get_event_loop() is

    Deprecated since version 3.10: Deprecation warning is emitted if there is no running event loop. In future Python releases, this function will be an alias of get_running_loop().

    Which made me wonder if I were doing this correctly?

    help wanted improvement 
    opened by jordaneremieff 1
  • api_gateway_base_path not supported for ALB?

    api_gateway_base_path not supported for ALB?

    Summary

    • Mangum supports events from AWS API Gateway and AWS ALB.
    • Mangum has a api_gateway_base_path argument to strip the prefix of the http path before passing to the underlying app
    • api_gateway_base_path works as expected for API Gateway events
    • As far as I can tell, api_gateway_base_path does not work for ALB events.

    I looked at https://mangum.io/http/ and the GitHub issues and couldn't find this mentioned anywhere.

    My Setup

    • Python 3.9
    • mangum 0.12.4
    • starlette 0.17.1

    Simplified version of my lambda handler:

    def public_foo_function:
        print("Public foo function")
    
    def private_bar_function:
        print("Private bar function")
    
    app = Starlette(
        routes=[
            Route(
                path="/public/foo",
                endpoint=public_foo_function,
            ),
            Route(
                path="/private/bar",
                endpoint=private_bar_function,
            ),
        ]
    )
    
    mangum = Mangum(
        app,
        api_gateway_base_path="/prefix",
    )
    
    def main(event, context):
        return mangum(event, context)
    

    An external API Gateway v2 HTTP has a route /prefix/public/{proxy+} integrated with the lambda. An internal ALB has a listener rule /prefix/private/* integrated with the lambda.

    Requests to <api gateway url>/prefix/public/foo arrive in the lambda and public_foo_function is called, as expected.

    From within my VPC, internal requests to <alb url>/prefix/private/bar arrive in the lambda and Starlette returns Not Found 404. This is unexpected.

    As a workaround, if I change the private route in Starlette app from /private/bar to /prefix/private/bar, private_bar_function is called.

    Considerations

    api_gateway_base_path does have 'api gateway' in the name, and ALB is not an API Gateway. So there's an argument it could be intentional?

    But, I expected mangum to behave consistently for all of its supported input events.

    improvement 
    opened by ShedPlant 2
  • Will this project accept PR for supporting another vendor apart from AWS?

    Will this project accept PR for supporting another vendor apart from AWS?

    I was trying to use ASGI in aliyun fc, a serverless service that is similar to aws lambda, and found this library.

    it seems that Mangum only supports aws for now. Will this project accept PR for supporting another vendor apart from AWS?

    maybe 
    opened by CNLHC 1
  • Silencing scope error for ariadne

    Silencing scope error for ariadne

    Hi! Thank you for creating this framework. I'm currently using ariadne to manage a graphql lambda.

    For every execution I get a stack trace:

    ERROR:mangum.lifespan:Exception in 'lifespan' protocol.
    Traceback (most recent call last):
      File "/Users/lilja/Library/Caches/pypoetry/virtualenvs/backend-dmp__8h8-py3.8/lib/python3.8/site-packages/mangum/protocols/lifespan.py", line 93, in run
        await self.app({"type": "lifespan"}, self.receive, self.send)
      File "/Users/lilja/Library/Caches/pypoetry/virtualenvs/backend-dmp__8h8-py3.8/lib/python3.8/site-packages/ariadne/asgi.py", line 94, in __call__
        raise ValueError("Unknown scope type: %r" % (scope["type"],))
    ValueError: Unknown scope type: 'lifespan'
    

    However, the lambda/mangum executes as the rest of the code as usual and I have correct graphql output.

    I'm not up-to-speed with asgi stuff and don't really know what this means, is there a way to silence this error? Should I create a github issue with the other framework in question?

    raised error in question: https://github.com/mirumee/ariadne/blob/master/ariadne/asgi.py#L113

    How I use mangum

    async def setup() -> GraphQL:
        session = ClientSession()
        schema_file = os.environ.get("SCHEMA_FILE", "../schema.graphql")
    
        async with session:
            engine = await setup_graphql(session, schema_file)
            return GraphQL(engine, debug=production)
    
    
    def lambda_handler(event: Dict[str, Any], context: Any):
        graphql_app = asyncio.get_event_loop().run_until_complete(setup())
        handler_fn = Mangum(graphql_app)
        return add_cors_headers(handler_fn(event, context))
    
    
    def add_cors_headers(ret_value: Dict[str, Dict]) -> Dict[str, Dict]:
        ret_value["headers"]["Access-Control-Allow-Origin"] = "*"
    
        return ret_value
    
    bug 
    opened by Lilja 1
Releases(0.17.0)
  • 0.17.0(Nov 27, 2022)

    What's Changed

    • Remove 3.6 reference from frameworks docs by @aminalaee in https://github.com/jordaneremieff/mangum/pull/278
    • Add new blog post to external links by @aminalaee in https://github.com/jordaneremieff/mangum/pull/279
    • Add exclude_headers parameter by @aminalaee in https://github.com/jordaneremieff/mangum/pull/280

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.16.0...0.17.0

    Source code(tar.gz)
    Source code(zip)
  • 0.16.0(Oct 26, 2022)

    What's Changed

    • Link to deployment tutorial by @simonw in https://github.com/jordaneremieff/mangum/pull/274
    • Added text_mime_types argument by @georgebv in https://github.com/jordaneremieff/mangum/pull/277

    New Contributors

    • @georgebv made their first contribution in https://github.com/jordaneremieff/mangum/pull/277

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.15.1...0.16.0

    Source code(tar.gz)
    Source code(zip)
  • 0.15.1(Aug 7, 2022)

    What's Changed

    • Mention that Django works fine too by @WhyNotHugo in https://github.com/jordaneremieff/mangum/pull/261
    • Add vnd.oai.openapi to mime type list that are not base64 encoded by @khamaileon in https://github.com/jordaneremieff/mangum/pull/271

    New Contributors

    • @WhyNotHugo made their first contribution in https://github.com/jordaneremieff/mangum/pull/261
    • @khamaileon made their first contribution in https://github.com/jordaneremieff/mangum/pull/271

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.15.0...0.15.1

    Source code(tar.gz)
    Source code(zip)
  • 0.15.0(Apr 24, 2022)

    What's Changed

    • :recycle: Relax type annotations, refactor custom handler inferences, naming by @jordaneremieff in https://github.com/jordaneremieff/mangum/pull/259

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.14.1...0.15.0

    Source code(tar.gz)
    Source code(zip)
  • 0.14.1(Mar 7, 2022)

    What's Changed

    • :pushpin: Remove references to Python 3.6, update setup.py. by @jordaneremieff in https://github.com/jordaneremieff/mangum/pull/246

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.14.0...0.14.1

    Source code(tar.gz)
    Source code(zip)
  • 0.14.0(Mar 3, 2022)

    What's Changed

    • Removing Websocket from docs by @aminalaee in https://github.com/jordaneremieff/mangum/pull/241
    • Replace abstract handlers, customer handlers, type annotations, refactoring. by @jordaneremieff in https://github.com/jordaneremieff/mangum/pull/242

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.13.0...0.14.0

    Source code(tar.gz)
    Source code(zip)
  • 0.13.0(Feb 25, 2022)

    What's Changed

    • Remove WebSocket support and misc cleanup/removals by @jordaneremieff in https://github.com/jordaneremieff/mangum/pull/234
    • Replace awslambdaric-stubs with new types, refactor import style. by @jordaneremieff in https://github.com/jordaneremieff/mangum/pull/235
    • Improve logging by @aminalaee in https://github.com/jordaneremieff/mangum/pull/230

    New Contributors

    • @aminalaee made their first contribution in https://github.com/jordaneremieff/mangum/pull/230

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.12.4...0.13.0

    Source code(tar.gz)
    Source code(zip)
  • 0.12.4(Feb 7, 2022)

    What's Changed

    • HTTP Gateway V2: Remove use of obsolete multiValueHeaders by @IlyaSukhanov in https://github.com/jordaneremieff/mangum/pull/216
    • mypy - Argument "api_gateway_base_path" to "Mangum" has incompatible type "str"; expected "Dict[str, Any]" by @relsunkaev in https://github.com/jordaneremieff/mangum/pull/220
    • Added explicit python3.9 and 3.10 support by @relsunkaev in https://github.com/jordaneremieff/mangum/pull/224
    • Fix aws_api_gateway handler not accepting combined headers and multiValueHeaders by @Feriixu in https://github.com/jordaneremieff/mangum/pull/229

    New Contributors

    • @IlyaSukhanov made their first contribution in https://github.com/jordaneremieff/mangum/pull/216
    • @relsunkaev made their first contribution in https://github.com/jordaneremieff/mangum/pull/220
    • @Feriixu made their first contribution in https://github.com/jordaneremieff/mangum/pull/229

    Full Changelog: https://github.com/jordaneremieff/mangum/compare/0.12.3...0.12.4

    Source code(tar.gz)
    Source code(zip)
  • 0.12.3(Oct 6, 2021)

  • 0.12.2(Aug 11, 2021)

  • 0.12.1(Jul 23, 2021)

  • 0.12.0(Jul 16, 2021)

  • 0.11.0(Mar 19, 2021)

    0.11.0

    • Remove deprecated enable_lifespan parameter #109.

    • Include API Gateway v2 event cookies in scope headers #153. Thanks araki-yzrh!

    • Support ELB and fix APIGW v2 cookies response #155. Thanks araki-yzrh!

    • Add flake8 to CI checks #157. Thanks emcpow2!

    • Add type hints for lambda handler context parameter #158. Thanks emcpow2!

    • Extract ASGI scope creation into function #162. Thanks emcpow2!

    0.10.0

    • Remove WebSocket support to focus on HTTP #127.

    • Support multiValue headers in response #129. Thanks @koxudaxi!

    • Fix duplicate test names #134. Thanks @a-feld!

    • Run tests and release package using GitHub Actions #131. Thanks @simonw!

    • Only prefix a slash on the api_gateway_base_path if needed #138. Thanks @dspatoulas!

    • Add support to Brotli compress #139. Thanks @fullonic!

    0.9.2

    • Make boto3 dependency optional #115

    0.9.1

    • Bugfix lifespan startup behaviour and refactor lifespan cycle, deprecate enable_lifespan parameter, document protocols. #108

    0.9.0

    • Resolve issue with rawQueryString in HTTP APIs using wrong type #105

    • Implement new WebSocket storage backends for managing connections (PostgreSQL, Redis, DyanmoDB, S3, SQlite) using a single dsn configuration parameter #103

    pre-0.9.0

    I did not maintain a CHANGELOG prior to 0.9.0, however, I still would like to include a thank you to following people:

    @lsorber @SKalt @koxudaxi @zachmullen @remorses @allan-simon @jaehyeon-kim

    Your contributions to previous releases have greatly improved this project and are very much appreciated.

    Special thanks to @tomchristie for all of his support, encouragement, and guidance early on, and @rajeev for inspiring this project.

    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Oct 3, 2020)

  • 0.9.0(May 9, 2020)

    • Improve documentation (https://github.com/erm/mangum/issues/48)

    • Resolve issue with rawQueryString in HTTP APIs using wrong type (https://github.com/erm/mangum/issues/105)

    • Implement new WebSocket storage backends for managing connections (PostgreSQL, Redis, DyanmoDB, S3, SQlite) using a single dsn configuration parameter (https://github.com/erm/mangum/issues/100)

    • Refactor ASGI lifespan handlers and automatically detect if lifespan is supported by an application (https://github.com/erm/mangum/issues/62)

    • Decouple WebSocket support from DynamoDB to allow alternative WebSocket storage backends (https://github.com/erm/mangum/issues/52)

    • Improving logging throughout the various classes

    Source code(tar.gz)
    Source code(zip)
  • 0.9.0b1(May 3, 2020)

    • Refactor ASGI lifespan handlers and automatically detect if lifespan is supported by an application (https://github.com/erm/mangum/issues/62)

    • Decouple WebSocket support from DyanmoDB to allow alternative WebSocket storage backends (https://github.com/erm/mangum/issues/52)

    • Implement new WebSocket storage backends for managing connections (PostgreSQL, Redis, DyanmoDB, S3, SQlite)

    • Improving logging throughout the various classes

    Source code(tar.gz)
    Source code(zip)
Owner
Jordan Eremieff
Hello
Jordan Eremieff
A utility for mocking out the Python Requests library.

Responses A utility library for mocking out the requests Python library. Note Responses requires Python 2.7 or newer, and requests = 2.0 Installing p

Sentry 3.8k Jan 02, 2023
Generic automation framework for acceptance testing and RPA

Robot Framework Introduction Installation Example Usage Documentation Support and contact Contributing License Introduction Robot Framework is a gener

Robot Framework 7.7k Dec 31, 2022
Robyn is an async Python backend server with a runtime written in Rust, btw.

Robyn is an async Python backend server with a runtime written in Rust, btw. Python server running on top of of Rust Async RunTime. Installation

Sanskar Jethi 1.8k Dec 30, 2022
Green is a clean, colorful, fast python test runner.

Green -- A clean, colorful, fast python test runner. Features Clean - Low redundancy in output. Result statistics for each test is vertically aligned.

Nathan Stocks 756 Dec 22, 2022
PyQaver is a PHP like WebServer for Python.

PyQaver is a PHP like WebServer for Python.

Dev Bash 7 Apr 25, 2022
a socket mock framework - for all kinds of socket animals, web-clients included

mocket /mɔˈkɛt/ A socket mock framework for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support ...and then MicroPytho

Giorgio Salluzzo 249 Dec 14, 2022
A test fixtures replacement for Python

factory_boy factory_boy is a fixtures replacement based on thoughtbot's factory_bot. As a fixtures replacement tool, it aims to replace static, hard t

FactoryBoy project 3k Jan 05, 2023
An HTTP server to easily download and upload files.

httpsweet An HTTP server to easily download and upload files. It was created with flexibility in mind, allowing be used in many different situations,

Eloy 17 Dec 23, 2022
Sixpack is a language-agnostic a/b-testing framework

Sixpack Sixpack is a framework to enable A/B testing across multiple programming languages. It does this by exposing a simple API for client libraries

1.7k Dec 24, 2022
Coroutine-based concurrency library for Python

gevent Read the documentation online at http://www.gevent.org. Post issues on the bug tracker, discuss and ask open ended questions on the mailing lis

gevent 5.9k Dec 28, 2022
livereload server in python (MAINTAINERS NEEDED)

LiveReload Reload webpages on changes, without hitting refresh in your browser. Installation python-livereload is for web developers who know Python,

Hsiaoming Yang 977 Dec 14, 2022
splinter - python test framework for web applications

splinter - python tool for testing web applications splinter is an open source tool for testing web applications using Python. It lets you automate br

Cobra Team 2.6k Dec 27, 2022
Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes in a variety of languages.

Mimesis - Fake Data Generator Description Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes

Isaak Uchakaev 3.8k Jan 01, 2023
Hypothesis is a powerful, flexible, and easy to use library for property-based testing.

Hypothesis Hypothesis is a family of testing libraries which let you write tests parametrized by a source of examples. A Hypothesis implementation the

Hypothesis 6.4k Jan 01, 2023
Let your Python tests travel through time

FreezeGun: Let your Python tests travel through time FreezeGun is a library that allows your Python tests to travel through time by mocking the dateti

Steve Pulec 3.5k Jan 09, 2023
The successor to nose, based on unittest2

Welcome to nose2 nose2 is the successor to nose. It's unittest with plugins. nose2 is a new project and does not support all of the features of nose.

738 Jan 09, 2023
The lightning-fast ASGI server. 🦄

The lightning-fast ASGI server. Documentation: https://www.uvicorn.org Community: https://discuss.encode.io/c/uvicorn Requirements: Python 3.6+ (For P

Encode 6k Jan 03, 2023
Waitress - A WSGI server for Python 2 and 3

Waitress Waitress is a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in t

Pylons Project 1.2k Dec 30, 2022
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 871 Dec 25, 2022
FastWSGI - An ultra fast WSGI server for Python 3

FastWSGI - An ultra fast WSGI server for Python 3

James Roberts 343 Dec 22, 2022