easy-awscr
Version, currently 2.0.012 versions
- 2.0.0latestSep 30, 2026
- 1.0.0not indexedOct 1, 2026
- 0.5.1Aug 10, 2026
- 0.5.0not indexedAug 12, 2026
- 0.4.0not indexedAug 12, 2026
- 0.3.3not indexedAug 12, 2026
- 0.3.2not indexedAug 12, 2026
- 0.3.1not indexedAug 12, 2026
- 0.3.0not indexedAug 12, 2026
- 0.2.1not indexedAug 12, 2026
- 0.2.0not indexedAug 12, 2026
- 0.1.0not indexedAug 12, 2026
github.com/philipp-classen/easy-awscr
Simplify AWS S3 and CloudWatch on Crystal
Installation
# Add this to your shard.yml
dependencies:
easy-awscr:
github: philipp-classen/easy-awscr
version: ~> 2.0.0Then run:
shards installshard.yml
- Crystal
>= 1.11.0- License
- MIT
- Author
- Philipp Claßen
Dependencies
Runtime Dependencies
- awscr-s3*github: taylorfinnell/awscr-s3, commit: 38b76cd7a109001caa8ece02916b4e0bfc9bf7d8
- aws-credentials*github: y2k2mt/aws-credentials.cr, commit: 8b1853609c069a1e70b967a7d654e07a0dbdbcfc
- awscr-cloudwatch1.0.0github: philipp-classen/awscr-cloudwatch
Development Dependencies
- ameba~> 1.7.0github: crystal-ameba/amebadev
README
easy-awscr
A Crystal shard intended to provide basic AWS functionality:
- S3 (based on awscr-s3)
- CloudWatch metrics and alarms (based on awscr-cloudwatch)
- Credentials (based on aws-credentials)
The idea is to simplify the setup:
- It should work out of the box
- The library should take care of acquiring and refreshing AWS credentials
It is not intended to be feature-rich, but rather to put the existing pieces together.
Currently, it is expected to work on an EC2 instance (using IAM roles) or in a local setup
where you provide credentials either through environment variables or through ~/.aws/config.
Apart from the low-level API, there are some higher-level APIs provided:
- S3
- support for streaming uploads
- CloudWatch
- periodic uploads of aggregated counters
Installation
-
Add the dependency to your
shard.yml:dependencies: easy-awscr: github: philipp-classen/easy-awscr -
Run
shards install
Usage
require "easy-awscr" loads all sub-projects. If you want to keep control over
what gets loaded, select the sub-project you need explicitly, e.g.
require "easy-awscr/s3" or require "easy-awscr/cloudwatch".
require "easy-awscr/s3"
client = EasyAwscr::S3::Client.new
# create a test bucket
test_bucket = "some-test-bucket-#{rand(10000000)}"
client.put_bucket(test_bucket)
if client.list_buckets.buckets.includes?(test_bucket)
puts "Found!"
else
raise "Something went wrong"
end
# upload text and read the content again
# Note: Crystal uses Int32 for strings and arrays. It will work up to around 2gb.
client.put_object(test_bucket, "some_file", "Yes, it worked!")
content = client.get_object(test_bucket, "some_file").body
puts "Did it work? #{content}"
# Otherwise, can upload a large file like this ...
File.open("/path/some/big/file_over_4gb.txt") do |io|
success = client.upload_file("bucket1", "obj", io)
p success # => true
end
# ... and download it again by streaming into a file again.
File.open("/path/some/big/file-downloaded.txt", "w") do |io|
client.get_object(test_bucket, "some_file") do |resp|
IO.copy(resp.body_io, io)
end
end
# If you do not know the size in advance, you can use the streaming API:
client.stream_to_s3(test_bucket, "some_file") do |io|
io.puts "Some content"
end
# Or like this if you need more flexibility over the lifecycle:
io = client.stream_to_s3(test_bucket, "some_file", auto_close: false) { |io| io }
io.puts "Some content"
io.close
# list all files (optionally you can filter with `prefix` and limit with `max_keys`)
all_files = [] of String
client.list_objects(test_bucket).each do |batch|
all_files.concat(batch.contents.map &.key)
end
p! all_files
# delete the file
client.delete_object(test_bucket, "some_file")
# delete the test bucket
client.delete_bucket(test_bucket)
CloudWatch
require "easy-awscr/cloudwatch"
client = EasyAwscr::CloudWatch::Client.new
stats = client.get_metric_statistics("MyApp", "requests.total",
start_time: Time.utc - 1.hour, end_time: Time.utc, period: 5.minutes, statistics: ["Sum"])
stats.datapoints.each { |dp| puts "#{dp.timestamp}: #{dp.sum}" }
# Time series for many metrics over any time range. Paging is done for you and the points come one by one.
metrics = ["requests.total", "requests.errors"].map { |name| Awscr::CloudWatch::Metric.new("MyApp", name) }
client.each_datapoint(metrics, stat: "Sum", period: 1.hour, start_time: Time.utc - 30.days, end_time: Time.utc) do |metric, time, value|
puts "#{metric.metric_name} #{time}: #{value}"
end
# each_metric_data does the same for your own MetricDataQuery list (e.g. metric math).
client.put_metric_alarm("MyApp-HighErrorRate",
namespace: "MyApp", metric_name: "requests.errors", statistic: "Sum", period: 1.minute,
evaluation_periods: 3, threshold: 100, comparison_operator: "GreaterThanThreshold")
# On top of that, Counters provides a higher-level API:
# - events are aggregated in memory and uploaded once a minute (one aggregated data point per metric)
# - configure once, then only count (safe from any fiber)
metrics = EasyAwscr::CloudWatch::Counters.new("MyApp", dimensions: {"Environment" => "Dev"})
metrics.count("requests.total")
metrics.count("requests.bytes_processed", 512)
metrics.close # uploads what is left, e.g. at shutdown
# Note: If needed, there is also low-level access to the native client of the
# `awscr-cloudwatch` library:
client.with_native_client do |native_client|
# ...
end
See Awscr::CloudWatch::MetricClient and Awscr::CloudWatch::AlarmClient for
all parameters.
Development
The bulk of the work is done by the libraries aws-credentials.cr, awscr-s3
and awscr-cloudwatch.
How to run tests
Run tests:
crystal spec --verbose --tag '~slow'
Run all tests, including slow, memory-intensive test:
crystal spec --verbose
Warning: The slow tests upload multi-GB files. They are meant for real AWS. Be aware that they might overwhelm a resourced-constrained test environment.
Note: alias for these commands can also be found in the Makefile (e.g. make test).
The specs run against an AWS-compatible service provided by the test environment. Without one, the affected tests are skipped:
EASY_AWSCR_SPEC_USE_S3_MOCK=1runs the S3 specs, andEASY_AWSCR_SPEC_USE_CLOUDWATCH_MOCK=1the CloudWatch specs, against a local mock (e.g. started withmake start-moto).AWS_ENDPOINT_URLpoints the specs at a different mock (default:http://127.0.0.1:4566).EASY_AWSCR_SPEC_USE_NATIVE_AWS__I_KNOW_THE_RISK__=1runs them against a real AWS account. Be careful: that publishes metrics, which cannot be deleted again.
The tests write only into buckets, namespaces and alarms with a
test-easy-awscr-tmp prefix. Buckets, objects and alarms are deleted again.
Published metrics stay behind in the account.
Contributing
- Fork it (https://github.com/philipp-classen/easy-awscr/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Philipp Claßen - creator and maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
2.0.0- Tagged
- Sep 30, 2026
- Commit
2738066edbaa- Crystal
>= 1.11.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/philipp-classen/easy-awscr
Metadata
- Created
- Aug 12, 2026
- Updated
- Nov 7, 2026
- Synced
- Nov 7, 2026
- Versions
- 12