Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
DamianCzajkowski committed May 9, 2024
0 parents commit af60e1d
Show file tree
Hide file tree
Showing 19 changed files with 1,261 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/code_quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Code Quality

on:
push:
branches:
- "*"
tags:
- "*"

jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch
- name: Build the package
run: |
hatch build
- name: Run linter
run: |
hatch run ruff check .
39 changes: 39 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Publish on PyPI

on:
release:
types:
- published

jobs:
build-and-publish:
name: Build and publish to PyPI
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@master

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.12"

- name: Install Hatch
run: |
python -m pip install --upgrade pip
pip install hatch
- name: Build with Hatch
run: |
hatch build
- name: Publish distribution to PyPI
uses: pypa/[email protected]
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: dist
verbose: true

- name: Clean distribution directory
run: rm -rf dist/*
33 changes: 33 additions & 0 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Run Tests

on:
push:
branches:
- "*"
tags:
- "*"

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch
- name: Build the package
run: |
hatch build
- name: Run tests
run: |
hatch run test
61 changes: 61 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# Serverless directories
.serverless

.ruff_cache/
node_modules/
__pycache__

.DS_Store
.env
.pytest_cache
.python-version

package
*.zip

# Ignore the .terraform directory
.terraform/

# Ignore Terraform lock files
.terraform.lock.hcl

# Ignore all .tfstate files
*.tfstate
*.tfstate.*

# Ignore crash log files
crash.log

# Ignore any .tfvars files that may contain sensitive data
*.tfvars

# Ignore override files as they are usually used to override resources locally
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Ignore CLI configuration files
.terraformrc
terraform.rc

# pytest-cov
.coverage
29 changes: 29 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
BSD 3-Clause License

Copyright (c) 2024, Mirumee Labs
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Ariadne AWS Lambda Extension

This package extends the Ariadne library by adding a GraphQL HTTP handler designed for use in AWS Lambda environments. It enables easy integration of GraphQL services with AWS serverless infrastructure, making it straightforward to deploy GraphQL APIs without worrying about the underlying server management.

## Introduction

This project provides an extension to the Ariadne GraphQL library, specifically tailored for deploying GraphQL APIs on AWS Lambda. It simplifies handling GraphQL requests by providing a custom HTTP handler that seamlessly integrates with the AWS Lambda and API Gateway, allowing developers to focus on their GraphQL schema and resolvers instead of server and infrastructure management.

## Installation

To install the extension, use pip:

```bash
pip install ariadne-lambda
```

## Quick Start

Here's a basic example of how to use the extension in your AWS Lambda function:

```python
from typing import Any

from ariadne import QueryType, gql, make_executable_schema
from ariadne_lambda.graphql import GraphQLLambda
from asgiref.sync import async_to_sync
from aws_lambda_powertools.utilities.typing import LambdaContext

type_defs = gql(
"""
type Query {
hello: String!
}
"""
)
query = QueryType()


@query.field("hello")
def resolve_hello(_, info):
request = info.context["request"]
user_agent = request.headers.get("user-agent", "guest")
return "Hello, %s!" % user_agent


schema = make_executable_schema(type_defs, query)
graphql_app = GraphQLLambda(schema=schema)


def graphql_http_handler(event: dict[str, Any], context: LambdaContext):
return async_to_sync(graphql_app)(event, context)
```

## Documentation

For full documentation on Ariadne, visit [Ariadne's Documentation](https://ariadnegraphql.org/docs/). For details on AWS Lambda, refer to the [AWS Lambda Developer Guide](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html).

## Features

- Easy integration with AWS Lambda and API Gateway.
- Support for GraphQL queries and mutations.
- Customizable context and error handling.
- Seamless extension of the Ariadne library for serverless applications.

## Contributing

We welcome all contributions to Ariadne! If you've found a bug or issue, feel free to use [GitHub issues](https://github.com/mirumee/ariadne-lambda/issues). If you have any questions or feedback, don't hesitate to catch us on [GitHub discussions](https://github.com/mirumee/ariadne/discussions/).

For guidance and instructions, please see [CONTRIBUTING.md](CONTRIBUTING.md).

Also make sure you follow [@AriadneGraphQL](https://twitter.com/AriadneGraphQL) on Twitter for latest updates, news and random musings!

**Crafted with ❤️ by [Mirumee Software](http://mirumee.com)**
[email protected]
4 changes: 4 additions & 0 deletions ariadne_lambda/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from ariadne_lambda.graphql import GraphQLLambda
from ariadne_lambda.http_handler import GraphQLAWSAPIHTTPGatewayHandler

__all__ = ["GraphQLLambda", "GraphQLAWSAPIHTTPGatewayHandler"]
55 changes: 55 additions & 0 deletions ariadne_lambda/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from abc import abstractmethod
from inspect import isawaitable
from typing import Any

from ariadne.asgi.handlers.base import GraphQLHandler
from aws_lambda_powertools.utilities.typing import LambdaContext


class GraphQLLambdaHandler(GraphQLHandler):
@abstractmethod
async def handle(self, event: dict, context: LambdaContext):
"""An entrypoint for the AWS Lambda connection handler.
This method is called by Ariadne AWS Lambda GraphQL application. Subclasses
are expected to handle specific event content based on the gateway of invocation
triggeting the lambda function (e.g. API Gateway, ALB, etc.).
# Required arguments
`event`: The AWS Lambda event dictionary.
`context`: The AWS Lambda context object.
"""
raise NotImplementedError(
"Subclasses of GraphQLLambdaHandler must implement the 'handle' method"
)

async def get_context_for_request(
self,
request: Any,
data: dict,
) -> Any:
"""Return the context value for the request.
This method is called by the handler to get the context value for the
request. Subclasses can override it to provide custom context value
based on the request.
# Required arguments
`request`: The request object as defined by the 'handle' method.
`data`: GraphQL data from connection.
"""
if callable(self.context_value):
try:
context = self.context_value(request, data) # type: ignore
except TypeError: # TODO: remove in 0.20
context = self.context_value(request) # type: ignore

if isawaitable(context):
context = await context
return context

return self.context_value or {"request": request}
Loading

0 comments on commit af60e1d

Please sign in to comment.