Welcome! Submit your posts for the next ElixirWeekly!

Sobelow, the Phoenix vulnerability scanner - v0.2.5

Changes include:

  • Flag for an additional SQL injection vector
  • Small addition to XSS checks
  • Minor bug fixes and refactoring

You can now install with mix archive.install hex sobelow, and if you want (or need) to install an older version, you can do so with mix archive.install hex sobelow 0.2.4.

retort 2.1.0

Install: https://hex.pm/packages/retort/2.1.0
Docs: https://hexdocs.pm/retort/2.1.0
Changes: https://github.com/C-S-D/retort/compare/v2.0.0...v2.1.0



  • Extract Retort.Resources.timeout/2 to Retort.Resources.Timeout.get_or_default(module, function). Retort.Resources.Timeout also has functions for deleting and putting module-wide and function name specific timeouts, to make testing easier and less boiler plate needed in override examples.
  • Retort.Resources.Timeout.delete(module) will delete timeouts set by Retort.Resources.Timeout.put(module, timeout) OR Retort.Resources.Timeout.put(module, function_name, timeout).
  • Retort.Resources.Timeout.delete(module, timeout) will delete timeout set by Retort.Resources.Timeout.put(module, function_name, timeout) OR remove the timeout for function_name and leave it for the other function names when Retort.Resources.Timeout.put(module, timeout) is called.
  • Retort.Resources.Timeout.put(module, timeout) will set the timeout for all Retort.Client.Generic calls by module that called use Retort.Resources.
  • Retort.Resources.Timeout.put(module, function_name, timeout) will set the timeout for all Retort.Client.Generic function_name calls by module that called use Retort.Resources.
  • Retort.Resources.Timeout.put(module, function_name, timeout, func) will only temporarily Retort.Resources.Timeout.put/3, but for the duration passed function only. This can be used to test timeout handling.
  • Update to credo 0.7.4.

Bug Fixes

  • Fix formatting of timeout override example code.


  • Retort.Resources.timeout(module, function_name) is deprecated; use Retort.Resources.Timeout.get_or_default(module, function_name) instead.

Elixir - GenStateMachine


Shameless plug: Check out @elixirstatus' other community project:

Credo, a new static code analysis tool that acts as a code linter, but also focusses on teaching coding practices and code consistency.

When to use processes in Elixir - Part 2: Running concurrent tasks

In the second instalment of “When to use processes in Elixir” I wrote about using processes to run concurrent tasks.


In case you missed it, you could already send emails with attachments using Swoosh 0.8, all adapters supported

Checkout docs at https://github.com/swoosh/swoosh#attachments

The adapters list:

  • SMTP Swoosh.Adapters.SMTP
  • Sendgrid Swoosh.Adapters.Sendgrid
  • Mandrill Swoosh.Adapters.Mandrill
  • Mailgun Swoosh.Adapters.Mailgun
  • Postmark Swoosh.Adapters.Postmark
  • SparkPost Swoosh.Adapters.SparkPost

Startup Job, a sample project to search startup jobs

Hi there,

I just published my first Phoenix project Startup Job, an umbrella project to search startup jobs which scraped from various websites.

You can find out more on the GitHub repo.

Streaming Data with Ecto

Let’s build a small CSV exporter to show how you can stream data from your database using Ecto!

Blog: Poncho Projects

New blog post on Embedded-Elixir - Why we prefer ponchos over umbrellas on Nerves-based projects. http://embedded-elixir.com/post/2017-05-19-poncho-projects/

Sobelow - 0.2.3

The Phoenix Framework vulnerability scanner - Source

Updates include minor bug fixes, and checks for some types of command injection.

Shameless plug: Check out @elixirstatus' other community project:

Credo, a new static code analysis tool that acts as a code linter, but also focusses on teaching coding practices and code consistency.

retort 2.0.0





  • Document Retort.Resources
  • Update to alembic 3.3.0
  • Drop the need for changeset_render by using JaSerializer.Formatter.Utils.format_key directly to make it the same as calcinator.
  • Update to calcinator 3.0.0
  • Retort.Response.Error.to_calcinator_error(Retort.Response.t, Ecto.Changeset.t) will convert Retort.Response.t data Alembic.Document.t errors to a Calcinator error. If the Alembic.Error.t format is unrecognized, it is assumed to be convertable to Ecto.Changeset.t errors using Retort.Response.Error.Ecto.Changeset.add_alembic_errors(changeset, errors)

Bug Fixes

  • A missed rename left the application name used for Application.get_env as the original :interpreter_server_rpc instead of :retort in Retort.Resources.timeout/2.
  • Fix (Map -> map) typo in Retort.Client.Generic.start_link options.
  • Retort.Resources.client_start_link should not have been 0-arity, but 1-arity, so it can take in the client_start_link_options as an argument instead of depending on lookup by module to retrieve some hidden state.
  • Retort.Meta.valid!/2 checked if the Ecto.Repo was sandboxed with Application.get_env(:retort, Retort.Repo), which is a faithful translation of the original in :interpreter_server_rpc, but has the problem that it only works in retort itself. To allow the repo to be check to be configured, Retort.Meta.valid!/2 now takes an :ecto_repo_module option, which is check if its sandboxed if any of the :ecto_schema_modules are database-backed (have a non-blank __schema__(:source)).
  • Retort.Server.Generic.Resources.handle_method/2 converts {:error, :sandbox_token_missing} into RPC response errors instead of a CaseClauseError exception.

Incompatible Changes

  • Retort.Resources.client_start_link callback changes arity from 0 to 1 and now should take in options instead of calling Retort.Resources.client_start_link_options/0.
  • Retort.Client.Generic.start_link calls where the ecto_schema_module_by_type ecto_schema_modules are database-backed will now require :ecto_repo_module to check if the Ecto.Repo.t is sandboxed.
  • Require alembic ~> 3.3
  • changeset_render is no longer needed for Retort.Server.Generic.Resources, so Retort.Server.Generic.Resources.t has been removed and a Calcinator.t should be used as the state instead.
  • Require to calcinator ~> 3.0
  • Retort.Response.Error.Ecto.Changeset.add_alembic_errors(changeset, [Alembic.Error.t]) will convert the Alembic.Error.ts to validation errors added to the changeset. It’s a way to reverse the conversion done by Alembic.Document.from_ecto_changeset in alembic 3.3.0.
  • Retort.Response.Error.to_calcinator_error(Retort.Response.t, Ecto.Changeset.t) will convert Retort.Response.t data Alembic.Document.t errors to a Calcinator error. If the Alembic.Error.t format is unrecognized, it is assumed to be convertable to Ecto.Changeset.t errors using Retort.Response.Error.Ecto.Changeset.add_alembic_errors(changeset, errors)
  • Retort.Server.Generic.Resoruces.handle_method/2 is simplified using put_rendered_or_error/2, so that the large, duplicate cases are eliminated and error handling remains consistent across actions. For error, put_calcinator_error is called.
  • use Retort.Resources generates delete(changeset, query_options) to match the updated Calcinator.Resources.delete/2.
  • Retort.Resources.client_start_link_options now takes (module, query_options), so that if :meta exists in query_options and “beam” is set, then the pre-existing “beam” will be reused.
  • All action callbacks in Retort.Resources catch {:exit, {:timeout, _}} from the Retort.Client.Generic calls, log them, and then return {:error, :timeout}, so that Calcinator.Controller can turn it into a 504 Gateway Timeout instead of crashing the calling process.
  • All action callbacks in Retort.Resources can transform {:error, %Retort.Response.Error{}} to Calcinator errors using Retort.Client.Generic.error_to_calcinator_error.
  • meta in query_options is put back into the mergable params passed to Retort.Client.Generic calls in Retort.Resources

GraphQL Authentication with Apollo and React

In this second part of my “GraphQL Authentication” series, I dive into the front-end and wire up a simple authentication system using React and Apollo client.

Phoenix and the Frontend


calcinator 3.0.0


Bug fixes for error handling and testing support led to incompatible changes in behaviours, but use generated code is updated as well, so no changes if you only use Calcinator.Resources.Ecto.Repo.


  • Can now return (and is preferred to return instead of a timeout exit) {:error, :timeout} from all Calcinator.Resources action @callbacks.
  • When structs are deleted directly instead of changesets, there’s no way to add constraints, such as no_assoc_constraint or assoc_constraint that would transform DB errors into validation errors, so Calcinator.delete/3 generate a changeset from Calcinator.Resources.changeset(struct, %{})
  • Make the Alembic.Document.t and Alembic.Error.t that Calcinator.Controller.Error uses internally available in Calcinator.Alembic.Document and Calcinator.Alembic.Error, respectively, so they can be reused in overrides and retort.
  • Pass :meta through Calcinator.Retort.query_options, which allows pass through of meta like from Calcinator.Meta.Beam, which is necessary for indirect callbacks through RPC calls for retort.
  • Move Calcinator.Meta.Beam key to module attribute to prevent typos.
  • Calcinator.Meta.beam.put_new_lazy allows beam information to only be set in meta if its not already there to allow for loops between Calcinator servers.

Bug Fixes

  • The Calcinator actions @spec and @doc include (hopefully) all the errors they can return now

    • {:error, :sandbox_access_disallowed}
    • {:error, :sandbox_token_missing}
    • {:error, :timeout}
  • Ensure Calcinator.Controller actions have case clauses for all the declared return types from Calcinator calls.
  • get_related_resources could not handle has_many related resources, specifically
  • Calcinator.JaSerializer.PhoenixView.get_related_resource/3 would not allow data to be a list.
  • Calcinator.RelatedView.render with data assumes the data was singular and “links” could be added to that “data” map.
  • Calcinator.authorized did not allow the unfiltered data to be list.
  • Fix source assigns for get_related_resource example: example still used pre-open-sourcing association and id_key.
  • Fix show_relationship example that was just wrong. The same assigns as get_related_resource should be used. Since at first I couldn’t figure out why showing a relationship would need a view module and I wrote the code, I added a note explaining its for the view_module.type/0 callback since relationships are resource identifiers with id and type.
  • Calcinator.RelationshipView.data/1 assumed that [:related][:resource] was nil or a map, which didn’t handle the list for has_many relationships.

Incompatible Changes

  • Calcinator.Resources.allow_sandbox_access/1 must now return :ok | {:error, :sandbox_access_disallowed}. The previous {:already, :allowed | :owner} maps to :ok while :not_found maps to {:error, :sandbox_access_disallowed}.
  • If you previously had total coverage for all return types from Calcinator actions, they now also return {:error, :sandbox_access_disallowed} and {:error, :timeout}. Previously, instead of {:error, :sandbox_access_disallowed}, :not_found may been returned, but that was a bug that leaked an implementation detail from how DBConnection.Ownership works, so it was removed.
  • Calcinator.delete deletes a changeset instead of a resource struct
  • Calcinator.Resources.delete/1 must expect an Ecto.Changeset.tinstead of a resource struct
  • use Calcinator.Resources.Ecto.Repo generates delete/1 that expects an Ecto.Changeset.t and calls Calcinator.Resources.Ecto.Repo.delete/2, which now expects a changeset instead of resource struct as the second argument.
  • :meta is now a required key in Calcinator.Resources.query_options.
  • Calcinator.Resources.delete/2 must now accept both the Ecto.Changeset.t with any constraints and the Calcinator.Resources.query_options, so that the new meta key can be used to continue propagating the Calcinator.Meta.Beam from the original caller in a chain of calls.

Install: https://hex.pm/packages/calcinator/3.0.0

WebSockex 0.1.3

Version 0.1.3 of WebSockex was just released!

The ChangeLog for this release includes:

  • WebSockex.start_link will no longer cause the calling process to exit on connection failure and will return a proper error tuple instead.
  • Change WebSockex.Conn.RequestError to WebSockex.RequestError.
  • Add handle_connect_failure to be invoked after initiating a connection fails. Fixes #5

Checkout the v0.1.2..v0.1.3 diff for more info.

Veritaserum: Simple sentiment analisys on Elixir

Hi there!

I just published Veritaserum, a simple sentiment analisys library for Elixir.

It’s based on the AFINN-165 word list, and it also supports:

  • emojis (❤️, 😱…)
  • boosters (very, really…)
  • negators (don’t, not…)

You can check the repo on github.

Metaprogramming Without Macros

New blog post on metaprogramming without writing macros, just using quote and unquote, and functions from Code and Macro.

Supporting multiple event stores in Commanded using an adapter based approach for Elixir

Announcing the release of Commanded v0.10 with support for using Greg Young’s Event Store.

Commanded is an open-source library you can use to build Elixir applications following the Command Query Responsibility Segregation and event sourcing (CQRS/ES) pattern.

This article describes how an Elixir behaviour and adapter approach was used to support multiple event stores.

GPIO_RPI v0.2.0 released

I released a new version of my GPIO_RPI library today. It started as a fork of elixir_ale, but focuses on the Raspberry Pi only.

This new version allows setting pullup register on initialisation of a pin, allows changing of the input/output direction and mode.

GenMetrics - GenServer and GenStage runtime metrics.

New Elixir library supports the collection and publication of GenServer and GenStage runtime metrics. Metrics data are generated by an introspection agent. No instrumentation is required within the GenServer or GenStage library or within your application source code.

Built-in support for pushing metrics data to statsd agents and Datadog too.

Find out more on the GitHub repo, read the HexDocs, or sit back and enjoy a GitPitch presentation.

Take ownership of your data - Part 1

The difference between data modeling and database modeling: https://blog.digitalnatives.hu/take-ownership-of-your-data-part-1/