aws-easy 0.1.0.0 → 0.1.0.1
raw patch · 10 files changed
+156/−111 lines, 10 filesdep +amazonka-dynamodbdep +amazonka-s3dep +splitdep −amazonka-corenew-component:exe:aws-easy-demoPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: amazonka-dynamodb, amazonka-s3, split, unordered-containers
Dependencies removed: amazonka-core
API changes (from Hackage documentation)
- Network.AWS.Easy.Prelude: (&) :: () => a -> (a -> b) -> b
- Network.AWS.Easy.Prelude: (.~) :: () => ASetter s t a b -> b -> s -> t
- Network.AWS.Easy.Prelude: (^.) :: () => s -> Getting a s a -> a
- Network.AWS.Easy.Prelude: Beijing :: Region
- Network.AWS.Easy.Prelude: Discover :: Credentials
- Network.AWS.Easy.Prelude: Frankfurt :: Region
- Network.AWS.Easy.Prelude: FromContainer :: Credentials
- Network.AWS.Easy.Prelude: FromEnv :: Text -> Text -> Maybe Text -> Maybe Text -> Credentials
- Network.AWS.Easy.Prelude: FromFile :: Text -> FilePath -> Credentials
- Network.AWS.Easy.Prelude: FromKeys :: AccessKey -> SecretKey -> Credentials
- Network.AWS.Easy.Prelude: FromProfile :: Text -> Credentials
- Network.AWS.Easy.Prelude: FromSession :: AccessKey -> SecretKey -> SessionToken -> Credentials
- Network.AWS.Easy.Prelude: GovCloud :: Region
- Network.AWS.Easy.Prelude: GovCloudFIPS :: Region
- Network.AWS.Easy.Prelude: Ireland :: Region
- Network.AWS.Easy.Prelude: London :: Region
- Network.AWS.Easy.Prelude: Montreal :: Region
- Network.AWS.Easy.Prelude: Mumbai :: Region
- Network.AWS.Easy.Prelude: NorthCalifornia :: Region
- Network.AWS.Easy.Prelude: NorthVirginia :: Region
- Network.AWS.Easy.Prelude: Ohio :: Region
- Network.AWS.Easy.Prelude: Oregon :: Region
- Network.AWS.Easy.Prelude: SaoPaulo :: Region
- Network.AWS.Easy.Prelude: Seoul :: Region
- Network.AWS.Easy.Prelude: Singapore :: Region
- Network.AWS.Easy.Prelude: Sydney :: Region
- Network.AWS.Easy.Prelude: Tokyo :: Region
- Network.AWS.Easy.Prelude: _ServiceError :: AsError a => Prism' a ServiceError
- Network.AWS.Easy.Prelude: await :: (MonadAWS m, AWSRequest a) => Wait a -> a -> m Accept
- Network.AWS.Easy.Prelude: class AsError a
- Network.AWS.Easy.Prelude: data Credentials :: *
- Network.AWS.Easy.Prelude: data Region :: *
- Network.AWS.Easy.Prelude: data ServiceError :: *
- Network.AWS.Easy.Prelude: hasCode :: (Applicative f, Choice p) => ErrorCode -> Optic' * * p f ServiceError ServiceError
- Network.AWS.Easy.Prelude: hasStatus :: (Applicative f, Choice p) => Int -> Optic' * * p f ServiceError ServiceError
- Network.AWS.Easy.Prelude: infixl 1 &
- Network.AWS.Easy.Prelude: infixl 8 ^.
- Network.AWS.Easy.Prelude: infixr 4 .~
- Network.AWS.Easy.Prelude: send :: (MonadAWS m, AWSRequest a) => a -> m Rs a
- Network.AWS.Easy.Prelude: sinkBody :: MonadResource m => RsBody -> Sink ByteString m a -> m a
- Network.AWS.Easy.Prelude: toText :: ToText a => a -> Text
- Network.AWS.Easy.Util: intToText :: Int -> Text
- Network.AWS.Easy.Util: parseInt :: Text -> Maybe Int
- Network.AWS.Easy.Classes: class ServiceClass a where {
+ Network.AWS.Easy.Classes: class ServiceClass a where type TypedSession a :: * where {
Files
- README.md +5/−3
- app/Main.hs +109/−1
- aws-easy.cabal +12/−9
- lib/Network/AWS/Easy.hs +1/−5
- lib/Network/AWS/Easy/Classes.hs +1/−1
- lib/Network/AWS/Easy/Prelude.hs +0/−45
- lib/Network/AWS/Easy/Service.hs +1/−1
- lib/Network/AWS/Easy/TH.hs +26/−14
- lib/Network/AWS/Easy/Types.hs +1/−1
- lib/Network/AWS/Easy/Util.hs +0/−31
README.md view
@@ -1,8 +1,10 @@-# AWS Easy+# `aws-easy` -A simplified, high-level [AWS][aws] API built on top of [amazonka][amazonka]+[](https://travis-ci.org/rcook/aws-easy)+[](http://hackage.haskell.org/package/aws-easy)+[](https://raw.githubusercontent.com/rcook/aws-easy/master/LICENSE) -This is a collection of helper functions and some Template Haskell that I use regularly and has streamlined by use of the [amazonka][amazonka] framework. It was extracted from the code I wrote as part of my [AWS via Haskell][aws-via-haskell] series of blog posts.+This is a collection of helper functions and some Template Haskell that I use regularly and has streamlined my use of the [amazonka][amazonka] framework for interacting with [Amazon Web Services][aws]. It was extracted from the code I wrote as part of my [AWS via Haskell][aws-via-haskell] series of blog posts. ## Setup
app/Main.hs view
@@ -1,4 +1,112 @@+{-|+Module : Main+Description : Demo program for @aws-easy@ module+Copyright : (C) Richard Cook, 2018+License : MIT+Maintainer : rcook@rcook.org+Stability : experimental+Portability : portable++This programs lists S3 buckets and puts an item per bucket in DynamoDB.+-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+ module Main (main) where +import Control.Lens ((&), (.~), (^.))+import Control.Monad (void)+import Data.Foldable (for_)+import qualified Data.HashMap.Strict as HashMap (fromList)+import qualified Data.List.NonEmpty as NonEmpty (fromList)+import Data.List.Split (chunksOf)+import Data.Text (Text)+import qualified Data.Text as Text (pack)+import Network.AWS (Credentials(..), send)+import Network.AWS.Data (toText)+import Network.AWS.DynamoDB+ ( attributeValue+ , avS+ , batchWriteItem+ , bwiRequestItems+ , dynamoDB+ , prItem+ , putRequest+ , wrPutRequest+ , writeRequest+ )+import Network.AWS.Easy+ ( AWSConfig+ , Endpoint(..)+ , awsConfig+ , awscCredentials+ , connect+ , withAWS+ , wrapAWSService+ )+import Network.AWS.S3+ ( BucketName+ , bName+ , lbrsBuckets+ , listBuckets+ , s3+ )+import Network.AWS.Data (fromText)+import System.Environment (getEnv)++newtype TableName = TableName Text deriving Show++wrapAWSService 'dynamoDB "DynamoDBService" "DynamoDBSession"+wrapAWSService 's3 "S3Service" "S3Session"++fromRight :: b -> Either a b -> b+fromRight _ (Right value) = value+fromRight value _ = value++mkConfig :: IO AWSConfig+mkConfig = do+ regionStr <- getEnv "AWS_REGION"+ let region = fromRight+ (error $ "Unknown region " ++ regionStr) $+ fromText (Text.pack regionStr)+ return $ awsConfig (AWSRegion region)+ & awscCredentials .~ FromEnv+ "AWS_ACCESS_KEY_ID"+ "AWS_SECRET_ACCESS_KEY"+ (Just "AWS_SESSION_TOKEN")+ (Just "AWS_REGION")++getS3BucketNames :: S3Session -> IO [BucketName]+getS3BucketNames = withAWS $ do+ response <- send listBuckets+ return $ map (^. bName) (response ^. lbrsBuckets)++putDynamoDBBucketNames :: TableName -> [BucketName] -> DynamoDBSession -> IO ()+putDynamoDBBucketNames (TableName tableName) bucketNames session = for_ (chunksOf 25 bucketNames) go+ where+ go ns = (flip withAWS) session $ do+ void $ send (batchWriteItem & bwiRequestItems .~ requestItems)+ where+ requestItems = HashMap.fromList [ (tableName, writeRequests) ]+ writeRequests = NonEmpty.fromList $+ map+ (\n ->+ writeRequest &+ wrPutRequest .~ Just (putRequest & prItem .~ item n))+ ns+ item n = HashMap.fromList [ ("value", attributeValue & avS .~ Just (toText n)) ]+ main :: IO ()-main = putStrLn "Hello world"+main = do+ config <- mkConfig++ s3Session <- connect config s3Service+ bucketNames <- getS3BucketNames s3Session++ dynamoDBSession <- connect config dynamoDBService+ putDynamoDBBucketNames+ (TableName "bucket-names")+ bucketNames+ dynamoDBSession
aws-easy.cabal view
@@ -1,7 +1,7 @@ name: aws-easy-version: 0.1.0.0-synopsis: AWS Easy: Helper functions for working with amazonka-description: This package provides assorted functions and some Template Haskell to simplify working the amazonka family of packages for interacting with Amazon Web Services.+version: 0.1.0.1+synopsis: Helper function and types for working with amazonka+description: This package provides assorted functions and some Template Haskell to simplify working the @amazonka@ family of packages for interacting with Amazon Web Services. homepage: https://github.com/rcook/aws-easy#readme license: MIT license-file: LICENSE@@ -22,25 +22,28 @@ hs-source-dirs: lib ghc-options: -W -Wall -fwarn-incomplete-patterns -fwarn-unused-imports build-depends: amazonka- , amazonka-core , base >= 4.7 && < 5 , bytestring , lens , resourcet , template-haskell- , text exposed-modules: Network.AWS.Easy , Network.AWS.Easy.Classes- , Network.AWS.Easy.Prelude , Network.AWS.Easy.Service , Network.AWS.Easy.TH , Network.AWS.Easy.Types- , Network.AWS.Easy.Util -executable aws-easy-app+executable aws-easy-demo default-language: Haskell2010 hs-source-dirs: app main-is: Main.hs ghc-options: -threaded -rtsopts -with-rtsopts=-N -W -Wall -fwarn-incomplete-patterns -fwarn-unused-imports- build-depends: aws-easy+ build-depends: amazonka+ , amazonka-dynamodb+ , amazonka-s3+ , aws-easy , base >= 4.7 && < 5+ , lens+ , split+ , text+ , unordered-containers
lib/Network/AWS/Easy.hs view
@@ -1,6 +1,6 @@ {-| Module : Network.AWS.Easy-Description : Umbrella module+Description : Main @aws-easy@ module Copyright : (C) Richard Cook, 2018 License : MIT Maintainer : rcook@rcook.org@@ -10,16 +10,12 @@ module Network.AWS.Easy ( module Network.AWS.Easy.Classes- , module Network.AWS.Easy.Prelude , module Network.AWS.Easy.Service , module Network.AWS.Easy.TH , module Network.AWS.Easy.Types- , module Network.AWS.Easy.Util ) where import Network.AWS.Easy.Classes-import Network.AWS.Easy.Prelude import Network.AWS.Easy.Service import Network.AWS.Easy.TH import Network.AWS.Easy.Types-import Network.AWS.Easy.Util
lib/Network/AWS/Easy/Classes.hs view
@@ -7,7 +7,7 @@ Stability : experimental Portability : portable -This modules provides service and session type classes for the "AWS via Haskell" project.+This module provides service and session type classes to support @aws-easy@'s Template Haskell functions. -} {-# LANGUAGE AllowAmbiguousTypes #-}
− lib/Network/AWS/Easy/Prelude.hs
@@ -1,45 +0,0 @@-{-|-Module : Network.AWS.Easy.Prelude-Description : Re-exports of most commonly used Amazonka functions-Copyright : (C) Richard Cook, 2018-License : MIT-Maintainer : rcook@rcook.org-Stability : experimental-Portability : portable--This module provides re-exports of most commonly used Amazonka functions as well as lens and error-handling functions.--}--module Network.AWS.Easy.Prelude- ( (^.)- , (&)- , (.~)- , _ServiceError- , AsError- , Credentials(..)- , Region(..)- , ServiceError- , await- , hasCode- , hasStatus- , send- , sinkBody- , toText- ) where--import Control.Lens ((^.), (&), (.~))-import Network.AWS- ( _ServiceError- , AsError- , Credentials(..)- , Region(..)- , ServiceError- , await- , send- , sinkBody- )-import Network.AWS.Data (toText)-import Network.AWS.Error- ( hasCode- , hasStatus- )
lib/Network/AWS/Easy/Service.hs view
@@ -7,7 +7,7 @@ Stability : experimental Portability : portable -This modules provides support for configuring and making client connections to AWS services for the "AWS via Haskell" project.+This module provides support for configuring and making client connections to AWS services using @amazonka@. -} {-# LANGUAGE AllowAmbiguousTypes #-}
lib/Network/AWS/Easy/TH.hs view
@@ -1,13 +1,13 @@ {-| Module : Network.AWS.Easy.TH-Description : Template Haskell helpers for 'Network.AWS.Easy'+Description : Template Haskell helpers for @Network.AWS.Easy@ Copyright : (C) Richard Cook, 2018 License : MIT Maintainer : rcook@rcook.org Stability : experimental Portability : portable -This modules provides Template Haskell helper functions for eliminating boilerplate+This module provides Template Haskell helper functions for generating type-safe service/session wrappers for @amazonka@. -} {-# LANGUAGE TemplateHaskell #-}@@ -21,32 +21,44 @@ import Network.AWS.Easy.Classes import Network.AWS.Easy.Types --- |Generates type-safe AWS service and session wrappers types for use with+-- |Generates type-safe AWS service and session wrapper types for use with -- 'AWSViaHaskell.AWSService.connect' and 'AWSViaHaskell.AWSService.withAWS' functions -- -- Example top-level invocation: -- -- @--- wrapAWSService \'dynamoDB \"DDBService\" \"DDBSession\"+-- {-\# LANGUAGE TemplateHaskell \#-}+-- {-\# LANGUAGE TypeFamilies \#-}+--+-- module MyApp.Services+-- ( DynamoDBService+-- , DynamoDBSession+-- , dynamoDBService+-- ) where+--+-- import Network.AWS.DynamoDB (dynamoDB)+-- import Network.AWS.Easy (wrapAWSService)+--+-- wrapAWSService \'dynamoDB \"DynamoDBService\" \"DynamoDBSession\" -- @ -- -- This will generate boilerplate like the following: -- -- @--- data DDBService = DDBService Service+-- data DynamoDBService = DynamoDBService Service ----- data DDBSession = DDBSession Session+-- data DynamoDBSession = DynamoDBSession Session ----- instance ServiceClass DDBService where--- type TypedSession DDBService = DDBSession--- rawService (DDBService x) = x--- wrappedSession = DDBSession+-- instance ServiceClass DynamoDBService where+-- type TypedSession DynamoDBService = DynamoDBSession+-- rawService (DynamoDBService x) = x+-- wrappedSession = DynamoDBSession ----- instance SessionClass DDBSession where--- rawSession (DDBSession x) = x+-- instance SessionClass DynamoDBSession where+-- rawSession (DynamoDBSession x) = x ----- dynamoDBService :: DDBService--- dynamoDBService = DDBService dynamoDB+-- dynamoDBService :: DynamoDBService+-- dynamoDBService = DynamoDBService dynamoDB -- @ wrapAWSService :: Name -- ^ Name of the amazonka 'Network.AWS.Types.Service' value to wrap
lib/Network/AWS/Easy/Types.hs view
@@ -7,7 +7,7 @@ Stability : experimental Portability : portable -This modules provides support types for the "AWS via Haskell" project.+This module provides support types for @aws-easy@. -} {-# LANGUAGE TemplateHaskell #-}
− lib/Network/AWS/Easy/Util.hs
@@ -1,31 +0,0 @@-{-|-Module : Network.AWS.Easy.Util-Description : General-purpose helper functions-Copyright : (C) Richard Cook, 2018-License : MIT-Maintainer : rcook@rcook.org-Stability : experimental-Portability : portable--This modules provides general-purpose helper functions for the "AWS via Haskell" project.--}--{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RecordWildCards #-}--module Network.AWS.Easy.Util- ( intToText- , parseInt- ) where--import Data.Text (Text)-import qualified Data.Text as Text (null, pack)-import qualified Data.Text.Read as Text (decimal)--intToText :: Int -> Text-intToText = Text.pack . show--parseInt :: Text -> Maybe Int-parseInt s = case Text.decimal s of- Left _ -> Nothing- Right (result, s') -> if Text.null s' then Just result else Nothing