Metadata-Version: 2.1
Name: syngenta_digital_alc
Version: 1.0.6
Summary: DRY approach to working with AWS Lambdas
Home-page: https://github.com/syngenta-digital/alc-python.git
Author: Paul Cruse III, Technical Lead, Syngenta Digital
Author-email: paul.cruse@syngenta.com
License: UNKNOWN
Description: # Syngenta Digital ALC (AWS Lambda Client)
        Auto-loading, self-validating, minimalist python framework for AWS Lambdas
        
        ## Features
        
          * Automatic routing based on folder structure
          * Remove unnecessary boilerplate from your development process
          * Ease-of-use with the [serverless framework](https://www.serverless.com/)
          * Local development support
        
        ## Philosophy
        
        The alc philosophy is to provide a self evident tool for use with amazon lambdas.
        
        The alc encourages you to use small, internally routed API lambdas in a normalized OOP way.
        
        In addition, it makes things like routing and validating API requests less cumbersome and time consuming.
        
        ## Installation
        
        This is a [python](https://www.python.org/) module available through the
        [pypi registry](https://pypi.org).
        
        Before installing, [download and install python](https://www.python.org/downloads/).
        python 3 or higher is required.
        
        
        Installation is done using the
        [`pip install`](https://packaging.python.org/tutorials/installing-packages/) command:
        
        ```bash
        $ pip install syngenta_digital_alc
        ```
        
        or
        
        ```bash
        $ pipenv install syngenta_digital_alc
        ```
        
        ## Basic Usage
        
        ### apigateway events
        
        `NOTE`: This packages assumes you are using a monolithic, internally routed lambda with [serverless framework](https://www.serverless.com/) and you have a folder structure which puts all your endpoint files in one sub directory tied to a custom domain on apigateway.
        
        0. Setting Up the Monolithic Internally Routed Lambda
        
        ```yml
        functions:
            v1-apigateway-handler:
                handler: application.v1.handler.apigateway._router.route
                events:
                    - http:
                        path: /v1/
                        method: ANY
                    - http:
                        path: /v1/{proxy+}
                        method: ANY    
        ```
        
        1. Initialize the Router
        
        ```python
        import os
        
        from syngenta_digital_alc.apigateway.router import Router
        
        # must pass current service, version of API and where handlers are located
        def route(event, context):
            router = Router(
                base_path='{}/{}'.format(os.environ['service'], 'v1'),
                handler_path='application.v1.controller.apigateway',
                schema_path='application/openapi.yml',
                event=event,
                context=context
            )
            return router.route()    
        
        # examples of how router routes (called route -> will import):
        # api.url.com/service/v1 -> application.v1.handler.apigateway.__init__.py
        # api.url.com/service/v1/hello -> application.v1.handler.apigateway.hello.py
        # api.url.com/service/v1/hello-world -> application.v1.handler.apigateway.hello_world.py
        
        # @NOTE: router will always match HTTP Method with function name
        # @NOTE: router does NOT support path parameters (please use query strings)
        ```
        
        Option Name   | Required | Type   | Default | Description
        :-----------  | :------- | :----- | :------ | :----------
        `event`       | true     | dict   | n/a     | event object passed into lambda
        `base_path`   | true     | string | n/a     | apigateway base path for the custom domain
        `handler_path`| true     | string | n/a     | project path of where the endpoint files
        `schema_path` | false    | string | null    | path where your schema file can found (accepts JSON as well)
        `before_all`  | false    | string | null    | before all middleware function to run before all routes (after validation occurs)
        `after_all`   | false    | string | null    | after all middleware function to run after all routes
        
        2. Create handler file with matching methods and requirements
        
        ```python
        from syngenta_digital_alc.apigateway.handler_requirements import handler_requirements
        
        @handler_requirements(
            required_headers=['x-login-token', 'x-permission-token'],
            available_headers=['id', 'overwrite'],
            required_params=['id', 'overwrite'],
            available_params=['id', 'overwrite'],
            required_body='v1-post-example-request'
        )
        def post(request, response):
            response.body = business_layer.some_function(request.body)
            response.code = 201
        ```
        
        ***Endpoint Requirement Options***
        
        Option Name        | Type   | Description
        :-----------       | :----- | :----------
        `required_body`    | string | the components schema key name
        `available_params` | list   | list of available query string params for that method on that endpoint
        `required_params`  | list   | list of required query string params for that method on that endpoint
        `available_headers`| list   | list of available headers for that method on that endpoint
        `required_headers` | list   | list of required headers for that method on that endpoint
        
        
        ***Request Properties***
        
        Property Name       | Description
        :-----------        | :-------   
        `method`            | method id of apigateway event
        `resource`          | resource handle of apigateway event
        `authorizer`        | authorizer of apigateway event (will default to use headers if using with [serverless offline](https://www.npmjs.com/package/serverless-offline))
        `headers`           | headers of apigateway event
        `params`            | query string params of apigateway event
        `path`              | path arguments of apigateway event
        `json`              | body of apigateway event parsed as JSON
        `xml`               | body of apigateway event parsed as XML
        `body`              | body of apigateway event will be parsed based on context headers
        `request`           | full request broken down as an object literal
        
        
        ***Response Properties***
        
        Property Name       | Description
        :-----------        | :-------   
        `headers`           | headers you want to send in response
        `code`              | status code of response (will default to 204 if no content && will default 400 if errors found in response)
        `authorizer`        | authorizer of apigateway event (will default to use headers if using with [serverless offline](https://www.npmjs.com/package/serverless-offline))
        `has_errors()`      | function will tell you if errors in the response
        `set_error()`       | function will set error key and message
        
        ### sqs events
        
        0. Setting Up your lambda to listen to the Queue
        
        ```yml
        functions:
            v1-sqs-subscription:
                name: v1-sqs-subscription
                handler: application.v1.handler.sqs.listener.listen
                events:
                    - sqs:
                        arn:
                            Fn::GetAtt: [ ExampleQueue, 'Arn' ]
        ```
        
        1. Initialize the Event and Iterate over the Records
        
        ```python
        from syngenta_digital_alc.sqs.handler_requirements import handler_requirements
        
        @handler_requirements()
        def handle_sqs_trigger(event):
            records = event.records
            for sqs_record in records:
                some_func(sqs_record)
        ```
        
        ***Event Client Properties***
        
        Property Name   | Description
        :-----------    | :-------   
        `records`       | list of record objects
        `raw_records`   | jus the raw record from the original request
        
        
        ***Record Properties***
        
        Property Name       | Description
        :-----------        | :-------   
        `message_id`        | message id of sqs record
        `receipt_handle`    | receipt handle of sqs record
        `body`              | body of sqs record (will automatically decode JSON)
        `raw_body`          | body of sqs record
        `attributes`        | attributes of sqs record
        `message_attributes`| message attributes of sqs record
        `md5_of_body`       | md5 of body of sqs record
        `source`            | source of sqs record
        `source_arn`        | source ARN of sqs record
        `region`            | region of sqs record
        
        ### dynamodb events
        
        0. Setting Up your lambda to listen to the Queue
        
        ```yml
        functions:
            v1-dynamodb-stream:
                name: v1-dynamodb-stream
                handler: application.v1.handler.dynamodb.streamer.stream
                events:
                    - stream:
                        type: dynamodb
                        arn:
                            Fn::GetAtt: [ DynamoDbTableExample, 'Arn' ]
        ```
        
        1. Initialize the Event and Iterate over the Records
        
        ```python
        from syngenta_digital_alc.dynamodb.handler_requirements import handler_requirements
        
        @handler_requirements()
        def handle_sqs_trigger(event):
            records = event.records
            for sqs_record in records:
                some_func(sqs_record)
        ```
        
        ***Event Client Properties***
        
        Property Name   | Description
        :-----------    | :-------   
        `records`       | list of record objects
        `raw_records`   | jus the raw record from the original request
        
        
        ***Record Properties***
        
        Property Name                  | Description
        :-----------                   | :-------   
        `event_id`                     | event id of dynamodb record
        `event_name`                   | event name of dynamodb record
        `event_source`                 | event source  of dynamodb record
        `keys`                         | keys of dynamodb record (will convert ddb json)
        `old_image`                    | old image of dynamodb record
        `new_image`                    | new image of dynamodb record
        `raw_body`                     | raw of body of dynamodb record
        `event_source_arn`             | event source ARN of dynamodb record
        `event_version`                | event version of dynamodb record
        `stream_view_type`             | stream view type version of dynamodb record
        `size_bytes`                   | size bytes of dynamodb record
        `approximate_creation_datetime`| approximate creation date time of dynamodb record
        
        
        ### s3 events
        
        0. Setting Up your lambda to listen to the Queue
        
        ```yml
        functions:
            v1-s3-handler:
                name: v1-s3-handler
                handler: application.v1.handler.s3.handler.handle
                events:
                    - s3: photos
        ```
        
        1. Initialize the Event and Iterate over the Records
        
        ```python
        from syngenta_digital_alc.s3.handler_requirements import handler_requirements
        
        @handler_requirements()
        def handle_sqs_trigger(event):
            records = event.records
            for sqs_record in records:
                some_func(sqs_record)
        ```
        
        ***Event Client Properties***
        
        Property Name   | Description
        :-----------    | :-------   
        `records`       | list of record objects
        `raw_records`   | jus the raw record from the original request
        
        
        ***Record Properties***
        
        Property Name                 | Description
        :-----------                  | :-------   
        `event_time`                  | event time of s3 record
        `event_name`                  | event name of s3 record
        `event_source`                | event source  of s3 record
        `region`                      | region of s3 record (will convert ddb json)
        `request_parameters`          | request parameters of s3 record
        `response_elements`           | response elements of s3 record
        `configuration_id`            | configuration id of s3 record
        `object`                      | object of s3 record
        `bucket`                      | bucket of s3 record
        `s3_schema_version`           | s3 schema version of s3 record
        
        ## Contributing
        If you would like to contribute please make sure to follow the established patterns and unit test your code:
        
        ### Unit Testing
        To run unit test, enter command:
        ```bash
        RUN_MODE=unittest python -m unittest discover
        
Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Requires-Python: >=3.0
Description-Content-Type: text/markdown
