• Stars
    star
    164
  • Rank 223,404 (Top 5 %)
  • Language
    Python
  • License
    MIT License
  • Created about 4 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Asyncio compatible SDK for aws services.

aioaws

CI Coverage pypi versions license

Asyncio compatible SDK for aws services.

This library does not depend on boto, boto3 or any of the other bloated, opaque and mind thumbing AWS SDKs. Instead, it is written from scratch to provide clean, secure and easily debuggable access to AWS services I want to use.

The library is formatted with black and includes complete type hints (mypy passes in strict-mode).

It currently supports:

  • S3 - list, delete, recursive delete, generating signed upload URLs, generating signed download URLs
  • SES - sending emails including with attachments and multipart
  • SNS - enough to get notifications about mail delivery from SES
  • AWS Signature Version 4 authentication for any AWS service (this is the only clean & modern implementation of AWS4 I know of in python, see core.py)

The only dependencies of aioaws, are:

  • aiofiles - for asynchronous reading of files
  • cryptography - for verifying SNS signatures
  • httpx - for HTTP requests
  • pydantic - for validating responses

Install

pip install aioaws

S3 Usage

import asyncio
from aioaws.s3 import S3Client, S3Config
from httpx import AsyncClient

# requires `pip install devtools`
from devtools import debug

async def s3_demo(client: AsyncClient):
    s3 = S3Client(client, S3Config('<access key>', '<secret key>', '<region>', 'my_bucket_name.com'))

    # upload a file:
    await s3.upload('path/to/upload-to.txt', b'this the content')

    # list all files in a bucket
    files = [f async for f in s3.list()]
    debug(files)
    """
    [
        S3File(
            key='path/to/upload-to.txt',
            last_modified=datetime.datetime(...),
            size=16,
            e_tag='...',
            storage_class='STANDARD',
        ),
    ]
    """
    # list all files with a given prefix in a bucket
    files = [f async for f in s3.list('path/to/')]
    debug(files)

    # # delete a file
    # await s3.delete('path/to/file.txt')
    # # delete two files
    # await s3.delete('path/to/file1.txt', 'path/to/file2.txt')
    # delete recursively based on a prefix
    await s3.delete_recursive('path/to/')

    # generate an upload link suitable for sending to a browser to enabled
    # secure direct file upload (see below)
    upload_data = s3.signed_upload_url(
        path='path/to/',
        filename='demo.png',
        content_type='image/png',
        size=123,
    )
    debug(upload_data)
    """
    {
        'url': 'https://my_bucket_name.com/',
        'fields': {
            'Key': 'path/to/demo.png',
            'Content-Type': 'image/png',
            'AWSAccessKeyId': '<access key>',
            'Content-Disposition': 'attachment; filename="demo.png"',
            'Policy': '...',
            'Signature': '...',
        },
    }
    """

    # generate a temporary link to allow yourself or a client to download a file
    download_url = s3.signed_download_url('path/to/demo.png', max_age=60)
    print(download_url)
    #> https://my_bucket_name.com/path/to/demo.png?....

async def main():
    async with AsyncClient(timeout=30) as client:
        await s3_demo(client)

asyncio.run(main())

upload_data shown in the above example can be used in JS with something like this:

const formData = new FormData()
for (let [name, value] of Object.entries(upload_data.fields)) {
  formData.append(name, value)
}
const fileField = document.querySelector('input[type="file"]')
formData.append('file', fileField.files[0])

const response = await fetch(upload_data.url, {method: 'POST', body: formData})

(in the request to get upload_data you would need to provide the file size and content-type in order for them for the upload shown here to succeed)

SES

To send an email with SES:

from pathlib import Path
from httpx import AsyncClient
from aioaws.ses import SesConfig, SesClient, SesRecipient, SesAttachment

async def ses_demo(client: AsyncClient):
    ses_client = SesClient(client, SesConfig('<access key>', '<secret key>', '<region>'))

    message_id = await ses_client.send_email(
        SesRecipient('[email protected]', 'Sender', 'Name'),
        'This is the subject',
        [SesRecipient('[email protected]', 'John', 'Doe')],
        'this is the plain text body',
        html_body='<b>This is the HTML body.<b>',
        bcc=[SesRecipient(...)],
        attachments=[
            SesAttachment(b'this is content', 'attachment-name.txt', 'text/plain'),
            SesAttachment(Path('foobar.png')),
        ],
        unsubscribe_link='https:://example.com/unsubscribe',
        configuration_set='SES configuration set',
        message_tags={'ses': 'tags', 'go': 'here'},
    )
    print('SES message ID:', message_id)

async def main():
    async with AsyncClient() as client:
        await ses_demo(client)

asyncio.run(main())

SNS

Receiving data about SES webhooks from SNS (assuming you're using FastAPI)

from aioaws.ses import SesWebhookInfo
from aioaws.sns import SnsWebhookError
from fastapi import Request
from httpx import AsyncClient

async_client = AsyncClient...

@app.post('/ses-webhook/', include_in_schema=False)
async def ses_webhook(request: Request):
    request_body = await request.body()
    try:
        webhook_info = await SesWebhookInfo.build(request_body, async_client)
    except SnsWebhookError as e:
        debug(message=e.message, details=e.details, headers=e.headers)
        raise ...
    
    debug(webhook_info)
    ...

See here for more information about what's provided in a SesWebhookInfo.

More Repositories

1

arq

Fast job queuing and RPC in python with asyncio and redis.
Python
1,831
star
2

watchfiles

Simple, modern and fast file watching and code reload in python.
Python
1,630
star
3

python-devtools

Dev tools for python
Python
921
star
4

dirty-equals

Doing dirty (but extremely useful) things with equals.
Python
753
star
5

pytest-pretty

pytest plugin for pretty printing the test summary.
Python
391
star
6

rtoml

A fast TOML library for python implemented in rust.
Python
298
star
7

JuliaByExample

Examples of Julia
Julia
296
star
8

dnserver

Simple development DNS server written in python
Python
139
star
9

jinjahtml-vscode

Syntax highlighting for jinja(2) html templates in vscode
JavaScript
125
star
10

smokeshow

create temporary websites
TypeScript
117
star
11

aicli

OpenAI powered AI CLI in just a few lines of code.
Python
113
star
12

buildpg

Query building for the postgresql prepared statements and asyncpg.
Python
77
star
13

nginx-pages

static site server using nginx with auto deploy via scp
Shell
67
star
14

aiohttp-vs-sanic-vs-japronto

Rough benchmarks of of aiohttp and sanic
Python
54
star
15

notbook

An argument that Jupyter Notebooks are flawed and the world needs a successor.
Python
52
star
16

pytest-speed

Modern benchmarking library for python with pytest integration.
Python
51
star
17

edge-mock

Tools for testing and developing CloudFlare worker apps.
TypeScript
50
star
18

Bokeh.jl

Bokeh Bindings for Julia
Jupyter Notebook
47
star
19

helpmanual.io

Python
43
star
20

foxglove

Python
33
star
21

xdelta3-python

Fast delta encoding in python using xdelta3
Python
30
star
22

list-python-dependencies

GitHub action to list all valid versions of dependency for a Python project
Python
28
star
23

nosht

Open Source Event Ticketing Platform, deployed at
Python
28
star
24

sasstastic

Fantastic SASS and SCSS compilation for python
Python
26
star
25

mkdocs-run-code

TypeScript
24
star
26

aiohttp-toolbox

Tools for aiohttp
Python
23
star
27

harrier

A better static site generator.
Python
21
star
28

grablib

Static asset management in python
Python
19
star
29

cloudflare-proxy

proxy requests using cloudflare worker, useful for webhooks fired to slow endpoints
JavaScript
18
star
30

edgerender

Render at the edge
TypeScript
13
star
31

cloudflare-worker-speed-test

Rust
13
star
32

coverage-badge

TypeScript
10
star
33

JellyFish.jl

approximate and phonetic matching of strings
Julia
10
star
34

aiohttp_runserver

Moved to
Python
10
star
35

async-redis

Asynchronous Python redis client
Python
9
star
36

yatl

Yet Another Template Language
TypeScript
9
star
37

django-handsontable

Django app to implement handsontable (jquery-handsontable). Uses django-rest-framework.
JavaScript
8
star
38

land-registry-price-paid-data

Land registry house price data converted to Python Pandas DataFrame
Python
8
star
39

email-forward

Docker container for email forwarding with python
Python
8
star
40

check-python-version

Check the release tag matches the library version before deploy.
Python
7
star
41

pytest-toolbox

Numerous useful plugins for pytest.
Python
7
star
42

pytest-cloudflare-worker

pytest plugin for testing cloudflare workers
Python
6
star
43

em2

Python
5
star
44

cfpypi

Private python package index using cloudflare workers
JavaScript
5
star
45

init-desktop

Python
5
star
46

donkey-make

Make for the 21st century
Rust
4
star
47

gistviewer

tool for viewing HTML file in gists
JavaScript
4
star
48

label-and-assign

GitHub action to switch labels and assignees on pull requests using comments.
Python
4
star
49

edgerender-rust

Work in progress
Rust
4
star
50

django-db-viewer

Django site for view contents of mysql, sqlite and mongdb databases and filtering the results
Python
4
star
51

password-locker

Make passwords available only when you need them (mostly for CI)
TypeScript
4
star
52

wrangler-typescript-errors

TypeScript
4
star
53

python-IR-demodulation

Python infrared remote control deamon.
Python
3
star
54

donkey-simple-old

Super simple site manager that provides a front end to generate static websites
Python
3
star
55

coverage-prepare

Convert rust coverage data to HTML reports, LCOV files or terminal tables
Rust
3
star
56

githubproxy

Proxy for GitHub that adds "Content-Type" and "Access-Control-Allow-Origin" headers.
TypeScript
3
star
57

pydantic-sandbox

me fiddling with issue templates etc for pydantic, IGNORE THIS REPO
Python
3
star
58

django-importexport

django app to export and import data to and from excel (and possibly other formats in the future
Python
2
star
59

tensorflow-gpu-py36

Python
2
star
60

logfire-python

logfire client for python
Python
2
star
61

keypress

press keys from the command line
Rust
2
star
62

rust-bench

some benchmarks of rust code
Rust
2
star
63

logfire_django_demo

Python
2
star
64

django-crud

CRUD controllers for django: Create, Retrieve, Update, Delete, List
Python
1
star
65

ci-donkey

Simple Continuous Integration system based on Django and Docker
Python
1
star
66

django-skeletal-display

django app consisting of simple display module
JavaScript
1
star
67

python-file-watcher

Python
1
star
68

csv-labels

Python
1
star
69

httpi

Rust
1
star
70

tictoc.rs

Rust
1
star
71

donkey

Like "make" but for the 21st century.
Python
1
star
72

uJSON.jl

JSON library for Julia using ultraJSON
Julia
1
star
73

donkey-simple

Experiment
JavaScript
1
star
74

testing-projects

1
star
75

TestPac.jl

Test is a demonstratoin Package, see https://github.com/samuelcolvin/julia-slideshow
Julia
1
star
76

covid-19-calcs

Jupyter Notebook
1
star
77

print-debug

Python
1
star
78

bash

unofficial mirror of bash from http://savannah.gnu.org/projects/bash/
C
1
star
79

django-websockets

Experimental websocket support for django
Python
1
star
80

alpine-nginx

Docker image of stripped down nginx server using alpine. image < 15mb
Nginx
1
star
81

pdfapi

PDF API using docker
Python
1
star
82

codeshow

very simple flask app to display just code from gists
Python
1
star
83

django-sales-estimates

Django Sales Estimates Base System
Python
1
star
84

reactstrap-toolbox

JavaScript
1
star
85

Night-Shadow

Chrome Web App: World Clock that shows an image of the world in night and day. It also displays your location and the location of your clocks.
JavaScript
1
star
86

HotDjango

Django app for displaying data - like the admin interface, but pretty and for displaying as well as editing data
Python
1
star