Facundo Batista: PyCamp 2018

Pasó una nueva edición del mejor evento del año, el PyCamp!

Como siempre, lleno de Python, pero también de mil cosas más.

A nivel Python, estuve laburando en fades un poco, pero más que nada difundiéndolo y haciendo que todos, todos, todos, estén al tanto de las bondades del sistemita... un poco denso, estuve, sí :p. También llevé como proyecto a linkode pero acá el que estuvo laburando (en la migración del mismo a Python 3) fue Matías, un capo.

También estuve en largas charlas sobre cual va a ser el futuro de la lista de correo de PyAr (estuvimos analizando opciones), y el diseño del sitio web de gestión para la Asociación Civil Python Argentina. Y después yendo y viniendo por ahí, ayudando a gente en cosas puntuales que necesitaban, charlando, aprendiendo, disfrutando.

La típica grupal

Fuera de lo que es Python o programación en sí, podemos separar las actividades en dos grupos: juegos de mesa y resto.

El primer juego de mesa al que jugué, valga la cacofonía, fue el Belfort, al cual ya jugué varias veces y me encanta. Gané por lejos. Otro repetido fue el Galaxy Trucker, pero en este si juegan Sofia o Fisa no tenés chance. Otro en el que fui vapuleado fue (nuevo para mí) el Age of War. Y también jugué al Timeline (de inventos), gané el primero, el segundo quedé como cuarto.

Actividades sociales por fuera de los juegos de mesa también hubieron un montón. Aprendí a hacer malabares rebotando pelotitas contra el piso (sólo, con dos y tres pelotitas, y grupal, de a 3, 4 o 5 personas, haciendo combinaciones superlocas, armando y desarmando coreografías, fue muy divertido). Aprendí arquería con arcos de verdad (gracias Joaco por las clases). Jugué al basquet (y me raspé una rodilla y rompí una zapatilla). Armé un campeonato de ping-pong, pero perdí en la segunda ronda, 18-21 en el tercer partido, contra el que finalmente ganó el torneo. Hicimos música a cuatro manos en un piano. Montonazazazo de actividades.

Nos agarraste trabajandoHaciendo música

Obviamente, como en todo PyCamp, también hicimos una reunión de PyAr. Charlamos sobre los próximos eventos, algunos anuncios operativos de esos días, y algunos detalles más, pero lo principal fue el balance del PyCamp: qué estuvo bueno, qué estuvo fantástico, en qué cosas debemos mejorar. Nos llevamos un par de ideas para el PyCamp del año que viene, tanto en la preparatoria de las semanas anteriores, como mejoras a hacerle al bot del PyCamp.

Como nota de color, una tarde fuimos a buscar a unos chicos que llegaban a la terminal de Baradero, y al volver nos quedamos en el barro. Estuve 25 minutos tratando de sacar el auto de donde se había empantanado (en dos lugares distintos, imposibles), y al final salí victorioso. Pero me tembló hasta el culo por un par de horas....

Los que fueron magos en algún punto del eventoAlecu y el ventilagón, que fue uno de los proyectos

También, pero más importante, quiero destacar que brillamos en nuestras métricas de diversidad (gracias PSF por las becas para esto): fuimos un 25% de mujeres, y 50% de gente que era su primer PyCamp. Un éxito.

Pero no todo es brillar, especialmente cuando se corta la luz en todo el barrio! Fueron un par de horas, cuando anochecía, pero no nos amedrentamos y seguimos pycampeando casi como si nada hubiera pasado...

Se nos cortó la luzHicimos basquet, malabares, pingpong, espadas... y arquería

Para cerrar, les dejo las fotos mías (más algunas que saqué del grupo de Telegram), las de Yami (fotógrafa oficial), y les prometo el video presentación de todo lo que hicimos (cuando José Luis lo procese, digamos todos "gracias José Luis").

Mariano Guerra: Riak Core Tutorial Part 2: Starting

This is part of a series, see the previous one at Riak Core Tutorial Part 1: Setup

Creating our Project

Now that we have our tools and our template installed we can start by asking rebar3 to create a new project we will call tanodb using the riak_core template we just installed:

rebar3 new rebar3_riak_core name=tanodb

If it fails saying it can't find rebar3 check that it's in your $PATH environment variable and that you have Erlang activated.

The output should be something like this:

===> Writing tanodb/apps/tanodb/src/tanodb.app.src
===> Writing tanodb/apps/tanodb/src/tanodb.erl
===> Writing tanodb/apps/tanodb/src/tanodb_app.erl
===> Writing tanodb/apps/tanodb/src/tanodb_sup.erl
===> Writing tanodb/apps/tanodb/src/tanodb_console.erl
===> Writing tanodb/apps/tanodb/src/tanodb_vnode.erl
===> Writing tanodb/rebar.config
===> Writing tanodb/.editorconfig
===> Writing tanodb/.gitignore
===> Writing tanodb/README.rst
===> Writing tanodb/Makefile
===> Writing tanodb/config/admin_bin
===> Writing tanodb/priv/01-tanodb.schema
===> Writing tanodb/config/advanced.config
===> Writing tanodb/config/vars.config
===> Writing tanodb/config/vars_dev1.config
===> Writing tanodb/config/vars_dev2.config
===> Writing tanodb/config/vars_dev3.config

Note

The content of this chapter is in the 01-template branch.

https://gitlab.com/marianoguerra/tanodb/tree/01-template

Building and Running

Before explaining what the files mean so you get an idea what just happened let's run it!

cd tanodb
make
make console

make runs rebar3 commands to build a release of our project, for that it uses a tool called relx.

The initial build may take a while since it has to fetch all the dependencies and build them.

After the release is built (you can check the result by inspecting the folder _build/default/rel/tanodb/) we can run it.

When we run make console we get some noisy output that should end with something like this:

Eshell V9.3  (abort with ^G)
(tanodb@127.0.0.1)1>

This is the Erlang shell, something like a REPL connected to our system, we now can test our system by calling tanodb:ping() on it.

(tanodb@127.0.0.1)1> tanodb:ping().
{pong,1347321821914426127719021955160323408745312813056}

The response is the atom pong and a huge number that we will explain later, but to make it short, it's the id of the process that replied to us.

Exploring the Template Files

The template created a lot of files and if you are like me, you don't like things that make magic and don't explain what's going on, that's why we will get a brief overview of the files created here.

First this files are created:

apps/tanodb/src/tanodb.app.src
apps/tanodb/src/tanodb.erl
apps/tanodb/src/tanodb_app.erl
apps/tanodb/src/tanodb_sup.erl
apps/tanodb/src/tanodb_console.erl
apps/tanodb/src/tanodb_vnode.erl

Those are the meat of this project, the source code we start with, if you know a little of erlang you will recognice many of them, let's explain them briefly, if you think you need more information I recommend you this awesome book which you can read online: Learn You Some Erlang for great good!

tanodb.app.src
This file is "The Application Resource File", you can read it, it's quite self descriptive. You can read more about it in the Building OTP Applications Section of Learn You Some Erlang or in the man page for app in the Erlang documentation.
tanodb.erl
This file is the main API of our application, here we expose all the things you can ask our application to do, for now it can only handle the ping() command but we will add some more in the future.
tanodb_app.erl
This file implements the application behavior it's a set of callbacks that the Erlang runtime calls to start and stop our application.
tanodb_sup.erl
This file implements the supervisor behavior it's a set of callbacks that the Erlang runtime calls to build the supervisor hierarchy.
tanodb_console.erl
This file is specific to riak_core, it's a set of callbacks that will be called by the tanodb-admin command.
tanodb_vnode.erl
This file is specific to riak_core, it implements the riak_code_vnode behavior, which is a set of callbacks that riak_core will call to accomplish different tasks, it's the main file we will edit to add new features.

Those were the source code files, but the template also created other files, let's review them

rebar.config
This is the file that rebar3 reads to get information about our project like dependencies and build configuration, you can read more about it on the rebar3 documentation
.editorconfig
This file describes the coding style for this project, if your text editor understands editorconfig files then it will change it's setting for this project to the ones described in this file, read more about editor config on the editorconfig website
.gitignore
A file to tell git which files to ignore from the repository.
README.rst
The README of the project
Makefile
A make file with some targets that will make it easier to achieve some complex tasks without copying and pasting too much.
config/admin_bin
A template for the tanodb-admin command.
priv/01-tanodb.schema
The cuttlefish schema file that describes what configuration our application supports, it starts with some example configuration fields that we will use as the application grows.
config/advanced.config
This file is where we configure some advanced things of our application that don't go on our tanodb.config file, here we configure riak_core and our logging library
config/vars.config
This file contains variables used by relx to build a release, you can read more about it in the rebar3 release documentation

The following files are like vars.config but with slight differences to allow running more than one node on the same machine:

config/vars_dev1.config
config/vars_dev2.config
config/vars_dev3.config

Normally when you have a cluster for your application one operating system instance runs one instance of your application and you have many operating system instances, but to test the clustering features of riak_core we will build 3 releases of our application using offsets for ports and changing the application name to avoid collisions.

Those are all the files, follow the links to know more about them.

Playing with Clustering

Before starting to add features, let's first play with clustering so we understand all those config files above work.

Build 3 releases that can run on the same machine:

make devrel

This will build 3 releases of the application using different parameters (the dev1, dev2 and dev3 files we saw earlier) and will place them under:

_build/dev1
_build/dev2
_build/dev3

This is achived by using the profiles feature from rebar3.

Now open 3 consoles and run the following commands one on each console:

make dev1-console
make dev2-console
make dev3-console

This will start the 3 nodes but they won't know about each other, for them to know about each other we need to "join" them, that is to tell one of them about the other two, this is achieved using the tanodb-admin command, here is how you should run it manually (don't run them):

_build/dev2/rel/tanodb/bin/tanodb-admin cluster join tanodb1@127.0.0.1
_build/dev3/rel/tanodb/bin/tanodb-admin cluster join tanodb1@127.0.0.1

We tell dev2 and dev3 to join tanodb1 (dev1), to make this easier and less error prone run the following command:

make devrel-join

Now let's check the status of the cluster:

make devrel-status

You can read the Makefile to get an idea of what those commands do, in this case devrel-status does the following:

_build/dev1/rel/tanodb/bin/tanodb-admin member-status

You should see something like this:

================================= Membership ===============
Status     Ring    Pending    Node
------------------------------------------------------------
joining     0.0%      --      'tanodb2@127.0.0.1'
joining     0.0%      --      'tanodb3@127.0.0.1'
valid     100.0%      --      'tanodb1@127.0.0.1'
------------------------------------------------------------
Valid:1 / Leaving:0 / Exiting:0 / Joining:2 / Down:0

It should say that 3 nodes are joining, now check the cluster plan:

make devrel-cluster-plan

The output should be something like this:

=============================== Staged Changes ==============
Action         Details(s)
-------------------------------------------------------------
join           'tanodb2@127.0.0.1'
join           'tanodb3@127.0.0.1'
-------------------------------------------------------------


NOTE: Applying these changes will result in 1 cluster transition

#############################################################
                         After cluster transition 1/1
#############################################################

================================= Membership ================
Status     Ring    Pending    Node
-------------------------------------------------------------
valid     100.0%     34.4%    'tanodb1@127.0.0.1'
valid       0.0%     32.8%    'tanodb2@127.0.0.1'
valid       0.0%     32.8%    'tanodb3@127.0.0.1'
-------------------------------------------------------------
Valid:3 / Leaving:0 / Exiting:0 / Joining:0 / Down:0

WARNING: Not all replicas will be on distinct nodes

Transfers resulting from cluster changes: 42
  21 transfers from 'tanodb1@127.0.0.1' to 'tanodb3@127.0.0.1'
  21 transfers from 'tanodb1@127.0.0.1' to 'tanodb2@127.0.0.1'

Now we can commit the plan:

make devrel-cluster-commit

Which should say something like:

Cluster changes committed

Now riak_core started an internal process to join the nodes to the cluster, this involve some complex processes that we will explore in the following chapters.

You should see on the consoles where the nodes are running that some logging is happening describing the process.

Check the status of the cluster again:

make devrel-status

You can see the vnodes transfering, this means the content of some virtual nodes on one tanodb node are being transferred to another tanodb node:

================================= Membership =============
Status     Ring    Pending    Node
----------------------------------------------------------
valid      75.0%     34.4%    'tanodb1@127.0.0.1'
valid       9.4%     32.8%    'tanodb2@127.0.0.1'
valid       7.8%     32.8%    'tanodb3@127.0.0.1'
----------------------------------------------------------
Valid:3 / Leaving:0 / Exiting:0 / Joining:0 / Down:0

At some point you should see something like this, which means that the nodes are joined and balanced:

================================= Membership ==============
Status     Ring    Pending    Node
-----------------------------------------------------------
valid      34.4%      --      'tanodb1@127.0.0.1'
valid      32.8%      --      'tanodb2@127.0.0.1'
valid      32.8%      --      'tanodb3@127.0.0.1'
-----------------------------------------------------------
Valid:3 / Leaving:0 / Exiting:0 / Joining:0 / Down:0

When you are bored you can stop them:

make devrel-stop

Building a Production Release

Even when our application doesn't have the features to merit a production release we are going to learn how to do it here since you can later do it at any step and get a full release of the app:

make prod-release

In that command rebar3 runs the release task using the prod profile, which has some configuration differences with the dev profiles we use so that it builds something we can unpack and run on another operating system without installing anything.

Let's package our release:

cd _build/prod/rel
tar -czf tanodb.tgz tanodb tanodb_config
cd -
mv _build/prod/rel/tanodb.tgz .

You can copy it to a clean OS and run:

tar -xzf tanodb.tgz
./tanodb/bin/tanodb console

And it runs!

Note

You should build the production release on the same operating system version you are intending to run it to avoid version problems, the main source of headaches are C extensions disagreeing on libc versions and similar.

So, even when you could build it on a version that is close and test it it's better to build releases on the same version to avoid problems. More so if you are packaging the Erlang runtime with the release as we are doing here.

Wrapping Up

Now you know how to create a riak_core app from a template, how to build a release and run it, how to build releases for a development cluster, run the nodes, join them and inspect the cluster status and how to build a production release and run it on a fresh server.

Mariano Guerra: Riak Core Tutorial Part 1: Setup

This is the first chapter in a series that will explore how to use riak_core to build a distributed key-value store.

We first need to have Erlang installed and rebar3 installed.

The Easy Way

If you don't have Erlang installed or you don't have problem to install the latest one system wide you can try installing it with your package manager:

  • For Homebrew on OS X: brew install erlang
  • For MacPorts on OS X: port install erlang
  • For Ubuntu and Debian: apt-get install erlang
  • For Fedora: yum install erlang
  • For FreeBSD: pkg install erlang

Please check that the package version is 20.x, if not, check for instructions on how to install the Erlang Solutions package for Ubuntu, CentOS, Mac OS X, Debian or Fedora here: https://www.erlang-solutions.com/resources/download.html

Setting up rebar3

Now we have Erlang, we need a build tool, we are going to use rebar3:

# download rebar3 to our bin directory
wget https://s3.amazonaws.com/rebar3/rebar3 -O $HOME/bin/rebar3

# set execution permissions for our user
chmod u+x rebar3

Just in case you have problems running the rebar3 commands with a different version, here's the version I'm using:

rebar3 version

Output:

rebar 3.5.0 on Erlang/OTP 20 Erts 9.2

Install Riak Core Rebar3 Template

To create a Riak Core project from scratch we will use a template called rebar3_template_riak_core.

we need to clone its repo in a place where rebar3 can see it:

mkdir -p ~/.config/rebar3/templates
git clone https://github.com/marianoguerra/rebar3_template_riak_core.git ~/.config/rebar3/templates/rebar3_template_riak_core

The Hard Way: Building Erlang with kerl

Note

If you installed Erlang with the instructions above, skip until the Test that Everything Works section below.

If you have or want to have more than one version running side by side you can use kerl, from its github README:

Easy building and installing of Erlang/OTP instances.

Kerl aims to be shell agnostic and its only dependencies, excluding what's
required to actually build Erlang/OTP, are curl and git.

Note

On Mac you can install it with homebrew: brew install kerl

First we need to fetch kerl:

# create bin folder in our home directory if it's not already there
mkdir -p ~/bin

# cd to it
cd ~/bin

# download kerl script
curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl

# set execution permitions for our user
chmod u+x kerl

You will need to add ~/bin to your PATH variable so your shell can find the kerl script, you can do it like this in your shell:

# set the PATH environment variable to the value it had before plus a colon
# (path separator) and a new path which points to the bin folder we just
# created
PATH=$PATH:$HOME/bin

If you want to make this work every time you start a shell you need to put it it the rc file of your shell of choice, for bash it's ~/.bashrc, for zsh it's ~/.zshrc, you will have to add a line like this:

export PATH=$PATH:$HOME/bin

After this, start a new shell or source your rc file so that it picks up your new PATH variable, you can check that it's set correctly by running:

echo $PATH

And checking in the output if $HOME/bin is there (notice that $HOME will be expanded to the actual path).

Building an Erlang release with kerl

We have kerl installed and available in our shell, now we need to build an Erlang release of our choice, for this we will need a compiler and other tools and libraries needed to compile it:

This are instructions on ubuntu 17.10, check the names for those packages on your distribution.

# required: basic tools and libraries needed
# (compiler, curses for the shell, ssl for crypto)
sudo apt-get -y install build-essential m4 libncurses5-dev libssl-dev

# optonal: if you want odbc support (database connectivity)
sudo apt-get install unixodbc-dev

# optonal: if you want pdf docs you need apache fop and xslt tools and java (fop is a java project)
sudo apt-get install -y fop xsltproc default-jdk

# optional: if you want to build jinterface you need a JDK
sudo apt-get install -y default-jdk

# optional: if you want wx (desktop GUI modules)
sudo apt-get install -y libwxgtk3.0-dev

Now that we have everything we need we can finally build our Erlang release.

First we fetch an updated list of releases:

kerl update releases

The output in my case:

The available releases are:

R10B-0 R10B-10 R10B-1a R10B-2 R10B-3 R10B-4 R10B-5 R10B-6 R10B-7 R10B-8
R10B-9 R11B-0 R11B-1 R11B-2 R11B-3 R11B-4 R11B-5 R12B-0 R12B-1 R12B-2 R12B-3
R12B-4 R12B-5 R13A R13B01 R13B02-1 R13B02 R13B03 R13B04 R13B R14A R14B01
R14B02 R14B03 R14B04 R14B_erts-5.8.1.1 R14B R15B01 R15B02
R15B02_with_MSVCR100_installer_fix R15B03-1 R15B03 R15B
R16A_RELEASE_CANDIDATE R16B01 R16B02 R16B03-1 R16B03 R16B 17.0-rc1 17.0-rc2
17.0 17.1 17.3 17.4 17.5 18.0 18.1 18.2.1 18.2 18.3 19.0 19.1 19.2 19.3
20.0 20.1 20.2 20.3

Let's build the 20.3 version:

# this will take a while
kerl build 20.3 20.3

And install it:

kerl install 20.3 ~/bin/erl-20.3

Now everytime we want to use this version of Erlang we need to run:

. $HOME/bin/erl-20.3/activate

Test that Everything Works

We have installed several tools:

kerl
Let's you install multiple Erlang releases that can live side by side
Erlang 20.3
The version of erlang we are going to be using
Rebar 3
Our build tool
rebar3_template_riak_core
Rebar 3 Template that will make it easy to setup fresh riak_core projects for experimentation

Now we need to check that everything is setup correctly, we will do that by creating a template and building it.

Remember to have $HOME/bin in your $PATH and Erlang 20.3 activated, cd to a folder of your choice to hold this project and run:

rebar3 new rebar3_riak_core name=akv

Output should be similar to this one:

===> Writing akv/apps/akv/src/akv.app.src
===> Writing akv/apps/akv/src/akv.erl
===> Writing akv/apps/akv/src/akv_app.erl
===> Writing akv/apps/akv/src/akv_sup.erl
===> Writing akv/apps/akv/src/akv_console.erl
===> Writing akv/apps/akv/src/akv_vnode.erl
===> Writing akv/rebar.config
===> Writing akv/.editorconfig
===> Writing akv/.gitignore
===> Writing akv/README.rst
===> Writing akv/Makefile
===> Writing akv/config/admin_bin
===> Writing akv/priv/01-akv.schema
===> Writing akv/config/advanced.config
===> Writing akv/config/vars.config
===> Writing akv/config/vars_dev1.config
===> Writing akv/config/vars_dev2.config
===> Writing akv/config/vars_dev3.config

Now let's try to build it:

cd akv
make

Output is to long to list, after it ends, near the end you should see this line:

===> release successfully created!

Now let's try to run it:

make console

Last lines should be:

Eshell V9.3  (abort with ^G)
(akv@127.0.0.1)1>

You can exit with q(). and pressing enter or hitting Ctrl-C twice.

We're ready to start!

Damián Avila: Some thoughts about the 2017 ACM Software System Award for Project Jupyter

I am very happy to inform you that Project Jupyter has been awarded the 2017 ACM Software System Award!

As part of the Jupyter Steering Council, I am one of the official recipients of the award, but I wanted to highlight that I am just one member of a large group of people (contributors and users) working together to push the Project Jupyter forward and beyond its limits.

Project Jupyter is an essential part of my life. It gave me the opportunity to work with amazing people, to learn a lot of new things, to help other people. Some years ago, I left academia for several reasons, but one of the most important ones was to find an opportunity to make a substantial impact on people’s lives. I wanted to be involved in something that could empower people to do amazing things. And I certainly believe that Project Jupyter filled that space and allowed me to achieve that goal more than I could imagine.

Read more… (3 min remaining to read)

Damián Avila: Some thoughts about the 2017 ACM Software System Award for Project Jupyter

I am very happy to inform you that Project Jupyter has been awarded the 2017 ACM Software System Award!

As part of the Jupyter Steering Council, I am one of the official recipients of the award, but I wanted to highlight that I am just one member of a large group of people (contributors and users) working together to push the Project Jupyter forward and beyond its limits.

Project Jupyter is an essential part of my life. It gave me the opportunity to work with amazing people, to learn a lot of new things, to help other people. Some years ago, I left academia for several reasons, but one of the most important ones was to find an opportunity to make a substantial impact on people’s lives. I wanted to be involved in something that could empower people to do amazing things. And I certainly believe that Project Jupyter filled that space and allowed me to achieve that goal more than I could imagine.

Read more… (3 min remaining to read)

Mariano Guerra: Creemos en la Web: Reusando HTML (de otros)

En la sección anterior vimos como reusar estilo creado por otras personas.

Como vimos, muchas paginas comparten distintos componentes y yendo un nivel mas arriba, muchas paginas tienen incluso una estructura similar, por ejemplo blogs, paginas principales de un diario, de un producto, o de un sitio de ventas online.

Si bien no hay una forma simple de reusar HTML sin acudir a funcionalidades mas avanzadas que requieran programar, existe lo que usualmente se llaman templates (plantillas), que son paginas completas o secciones grandes de paginas para copiar y modificar el contenido de manera de no empezar de cero.

En esta sección vamos a explorar algunos de esos templates, en este caso, los disponibles en la pagina del proyecto bootstrap: https://getbootstrap.com/docs/4.1/examples/

Cover

Probemos uno de los ejemplos llamado Cover, copia y pega el siguiente HTML en un proyecto thimble nuevo:

<!doctype html>
<html lang="en">
  <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <title>Titulo de Pagina</title>

        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

        <link href="style.css" rel="stylesheet">
  </head>

  <body class="text-center">

        <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
          <header class="masthead mb-auto">
                <div class="inner">
                  <h3 class="masthead-brand">Nombre</h3>
                  <nav class="nav nav-masthead justify-content-center">
                        <a class="nav-link active" href="#">Principal</a>
                        <a class="nav-link" href="#">Link 1</a>
                        <a class="nav-link" href="#">Link 2</a>
                  </nav>
                </div>
          </header>

          <main role="main" class="inner cover">
                <h1 class="cover-heading">Título</h1>
                <p class="lead">Descripción.</p>
                <p class="lead">
                  <a href="#" class="btn btn-lg btn-secondary">Acción Principal</a>
                </p>
          </main>

          <footer class="mastfoot mt-auto">
                <div class="inner">
                  <p>Template "Cover" para <a href="https://getbootstrap.com/">Bootstrap</a>, por <a href="https://twitter.com/mdo">@mdo</a>.</p>
                </div>
          </footer>
        </div>

  </body>
</html>

Y el siguiente CSS en el archivo style.css del proyecto:

/*
* Globals
*/

/* Links */
a,
a:focus,
a:hover {
  color: #fff;
}

/* Custom default button */
.btn-secondary,
.btn-secondary:hover,
.btn-secondary:focus {
  color: #333;
  text-shadow: none; /* Prevent inheritance from `body` */
  background-color: #fff;
  border: .05rem solid #fff;
}


/*
* Base structure
*/

html,
body {
  height: 100%;
  background-color: #333;
}

body {
  display: -ms-flexbox;
  display: flex;
  color: #fff;
  text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);
  box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);
}

.cover-container {
  max-width: 42em;
}


/*
* Header
*/
.masthead {
  margin-bottom: 2rem;
}

.masthead-brand {
  margin-bottom: 0;
}

.nav-masthead .nav-link {
  padding: .25rem 0;
  font-weight: 700;
  color: rgba(255, 255, 255, .5);
  background-color: transparent;
  border-bottom: .25rem solid transparent;
}

.nav-masthead .nav-link:hover,
.nav-masthead .nav-link:focus {
  border-bottom-color: rgba(255, 255, 255, .25);
}

.nav-masthead .nav-link + .nav-link {
  margin-left: 1rem;
}

.nav-masthead .active {
  color: #fff;
  border-bottom-color: #fff;
}

@media (min-width: 48em) {
  .masthead-brand {
        float: left;
  }
  .nav-masthead {
        float: right;
  }
}


/*
* Cover
*/
.cover {
  padding: 0 1.5rem;
}
.cover .btn-lg {
  padding: .75rem 1.25rem;
  font-weight: 700;
}


/*
* Footer
*/
.mastfoot {
  color: rgba(255, 255, 255, .5);
}

Debería verse algo así:

/galleries/cew/7/01-cover.png

Una vez publicado:

/galleries/cew/7/02-cover-preview.png

Actividades propuestas:

  1. Intenta cambiar el contenido para presentar un proyecto o producto que te interese.
  2. Intenta cambiarlo para que sea fondo claro con contenido oscuro.
    • Agregando estilo al final de style.css
    • Cambiando el estilo existente en style.css

Pagina Principal

Esta pagina es bastante mas larga así que vamos a probar una forma nueva.

Podes ver el resultado visitando https://marianoguerra.github.io/creemos-en-la-web/paginas/landing/

En la pagina principal hace click derecho en cada imagen y selecciona la opción "Descargar imagen como..." o similar.

Descarga todas las imágenes.

Hace click en la pagina y presiona las teclas Ctrl y "u" a la vez, esto debería abrirte una ventana nueva con el HTML la pagina. Otra forma de hacerlo en algunos navegadores es haciendo click derecho con el mouse sobre la pagina y seleccionando la opción "Ver Código" o similar.

Copia el HTML en un proyecto nuevo de thimble.

Visita la dirección: https://marianoguerra.github.io/creemos-en-la-web/paginas/landing/style.css

Copia el CSS en el archivo style.css del proyecto.

Agrega las imágenes que descargaste a un nuevo directorio llamado img, un video que muestra como:

Actividades propuestas:

  1. Intenta cambiar el contenido para presentar un proyecto o producto que te interese.
  2. Intenta cambiarlo las imágenes
    • Manteniendo los nombres de las imágenes existentes (subiendo nuevas imágenes con nombres existentes)
    • Cambiando el nombre de las imágenes en el HTML (subiendo nuevas imágenes con nombres nuevos)

Facundo Batista: Relanzamiento del Blog

Entramos en la tercer etapa de mi blog.

La primera habían sido esos textos que había escrito mientras estaba en Italia haciendo el Máster en el segundo semestre del 2002, y que colgaba de un sitio armado muy a mano.

La segunda, desde el 2004 hasta ahora, con forma propiamente de "blog", soportado por un software hecho en PHP que primero se llamó "pLog", pero que luego se renombró a "LifeType", que luego de irse quedando cada vez más y más, se murió algo así como hace 5 años.

Llegó el momento de cambiarlo por algo moderno, vivo, y mantenible. Y en lo posible, lindo.

El ciclo de la vida es renovarse

No tenía demasiados requerimientos para el nuevo sistema, pero tenía que ser en Python, liviano, y que me dejara tener toda la estructura (especialmente los textos) en algún repositorio, y con un markup decente. Elegí Nikola, un generador de sitios estáticos que cumple con todos esos requisitos, y encima fue creado por un amigo.

El tema de mantener los textos de forma estándar era un tema: en LifeType se editaban los posts directamente desde la web, y como el editor fue cambiando durante sus años de vida, los formatos de los textos (el markup HTML que tenían alrededor) eran todos diferentes. Eso, sumado a que ya que migraba quería asegurarme de no dejar basura escondida, hizo que me dedicara los últimos dos años (poquito a poquito, sin que me tome demasiado tiempo, y por eso es que tardó mucho) a ir convirtiendo a mano los más de 700 posts al nuevo formato.

Como ya tenía demasiado trabajo con la migración de estos textos, y empecé a estar presionado con la migración a un nuevo sistema (porque tanto LifeType como el server donde tenía todo montado no tenían parches de seguridad hace rato) decidí tercerizar la construcción del nuevo sitio en Nikola. Así que todo esto que ven acá fue realmente construido en su mayoría por Marian Vignau del lado estructural del blog (todo lo que tiene que ver con Nikola, mostrar las propaganditas, meter el widget de twitter, etc, etc, etc) y por Cecilia Schiebel en lo que respecta a diseño y estética.

Uno de los puntos débiles de los sitios estáticos es el sistema de comentarios. Para esto traté de ir a "lo más usado", a una especie de "default en la industria" que es Disqus. Algunas desventajas tenía, como que es medio pesado, y dicen por ahí que hace mucho tracking de la gente que lo usa. Pero no tenía ganas de invertir demasiado tiempo en eso (todavía no estoy seguro de que valga la pena mantener un sistema de comentarios! ¿pensás distinto? demostralo haciendo un comentario :p ), así que intenté ir por ahí. Es más, Marian lo integró al sitio y todo, pero después me di cuenta que los nombres de los autores originales, cuando no eran 100% ASCII, estaban rotos. Y charlando con gente de Disqus me reconocieron que es un bug, y andá a saber cuando lo van a arreglar.

Así que fui por otro lado. Isso. Tiene la "desventaja" de que hay que hostearlo uno mismo, pero es simple, y me saco de encima tener que suscribirme a un servicio de terceros, que trackeen mis lectores, etc. No tenía una forma de importar comentarios que no sea de Disqus o Wordpress, pero como está hecho en Python, lo hice yo mismo (y lo propuse para que lo integren al sistema).

En fin. Bienvenidos al futuro (?).

Nos prometieron autos voladores y todo lo que tenemos son generadores de sitios estáticos

La estructura del sitio en sí tampoco cambió tanto. Seguimos teniendo el texto en el centro, con la barra de la derecha, aunque dejé ahí sólo lo que corresponde a contenido y moví otras cosas (licencia, rss, archivos, etc.) al footer. La búsqueda la provee Duck Duck Go (aunque le cambié recién el dominio de beta a final y está un poco confundido, vamos a darle unos días). Y en general debería verse bien más allá del tamaño de pantalla.

Obvio, me falta corregir un montón de cosas, algunas visibles y otras no, pero ya quería hacer la migración y anunciar esto (los últimos ~5 posts los tuve que hacer en los dos sistemas, encima que tengo poco tiempo, laburar duplicado no escala).

Cualquier detalle que encuentren o lo que sospechen que está roto, chiflen.

Mariano Guerra: Creemos en la Web: Reusando estilo (de otros)

Introduccion

En las secciones anteriores aprendimos como reusar el estilo guardándolo en un archivo separado y cargándolo en múltiples paginas.

A medida que vamos creando mas y mas paginas empiezan a surgir cosas comunes que se usan en casi cualquier proyecto.

Si miras con atención las paginas que visitas vas a ver que hay ciertos componentes que se repiten.

De esto te podrás imaginar que con tanto reusar estilos y llevarlos de un proyecto a otro a alguien se le habrá ocurrido la idea de hacer un archivo de estilos lo suficientemente genérico para que pueda ser el estilo inicial de mucha gente que quiere crear una pagina web nueva pero no quiere estar definiendo de cero todo cada vez que empieza.

Imaginas bien!

Hay varios, pero el mas conocido se llama bootstrap, y nos permite empezar nuestras paginas sin tener que preocuparnos por detalles que al fin del día no son tan importantes.

Mas interesante, es que como este proyecto estandariza los nombres de clases para cada estilo, hay gente que crea nuevos estilos que se cargan "sobre" bootstrap y que le cambian el aspecto sin que nosotros tengamos que hacer nada mas que agregar una linea a nuestro HTML!

Podes ver algunos ejemplos en https://bootswatch.com/

Incluyendo Bootstrap

Vamos a ver como usar esto, empecemos con un proyecto nuevo en thimble con una pagina básica:

<!doctype html>
<html>
  <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
  </head>

  <body>
        <h1>Esto es un título</h1>

        <p>Esto es un párrafo, la siguiente palabra es en <b>negrita</b>, la siguiente en <i>itálica</i></p>

        <p>Esto es otro párrafo</p>

        <p>
          Una lista no ordenada:
        </p>

        <ul>
          <li>Manzana</li>
          <li>Durazno</li>
          <li>Banana</li>
        </ul>

        <p>Una lista ordenada:</p>

        <ol>
          <li>Uno</li>
          <li>Dos</li>
          <li>Tres</li>
        </ol>

        <p>Un link a <a href="https://google.com">Google</a></p>

  </body>
</html>

Nuestra pagina de siempre, no muy linda de ver:

/galleries/cew/6/01-base.png

Ahora agregamos la hoja de estilo de bootstrap en el <head> de la pagina, debajo del tag <title>:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

Y podemos ver que ya cambio un poco:

/galleries/cew/6/02-base-bootstrap.png

Un tour por algunos componentes de bootstrap

Pero si fuera solo por eso entonces no seria tan útil, esto es solo el contenido base, bootstrap nos provee con muchos componentes estandard para usar, empecemos por las alertas:

Alertas

Agreguemos el siguiente HTML al <body> de nuestro proyecto:

<h2>Alertas</h2>

<div class="alert alert-primary" role="alert">
  Alerta principal (primary)
</div>
<div class="alert alert-secondary" role="alert">
  Alerta secundario (secondary)
</div>
<div class="alert alert-success" role="alert">
  Alerta exito (success)
</div>
<div class="alert alert-danger" role="alert">
  Alerta peligro (danger)
</div>
<div class="alert alert-warning" role="alert">
  Alerta advertencia (warning)
</div>
<div class="alert alert-info" role="alert">
  Alerta informacion (info)
</div>
<div class="alert alert-light" role="alert">
  Alerta claro (light)
</div>
<div class="alert alert-dark" role="alert">
  Alerta oscuro (dark)
</div>

<h2>Alertas con mas contenido</h2>

<div class="alert alert-info" role="alert">
  <h4 class="alert-heading">Titulo</h4>
  <p>Contenido principal.</p>
  <hr>
  <p class="mb-0">Contenido despues del separador.</p>
</div>

Debería verse algo así:

/galleries/cew/6/03-bs-alerts.png

Badges

Badges se traduce a medalla o distintivo, es mas fácil entender que son viéndolos que por la palabra, así que agreguemos el siguiente HTML a nuestra pagina:

<h2>Badges</h2>

<h3>Estandar</h3>

<div class="m-3">
  <span class="badge badge-primary">Principal</span>
  <span class="badge badge-secondary">Secundario</span>
  <span class="badge badge-success">Exito</span>
  <span class="badge badge-danger">Peligro</span>
  <span class="badge badge-warning">Advertencia</span>
  <span class="badge badge-info">Informacion</span>
  <span class="badge badge-light">Claro</span>
  <span class="badge badge-dark">Oscuro</span>
</div>

<h3>Pill Badges (Pastillas)</h3>

<div class="m-3">
  <span class="badge badge-pill badge-primary">Principal</span>
  <span class="badge badge-pill badge-secondary">Secundario</span>
  <span class="badge badge-pill badge-success">Exito</span>
  <span class="badge badge-pill badge-danger">Peligro</span>
  <span class="badge badge-pill badge-warning">Advertencia</span>
  <span class="badge badge-pill badge-info">Informacion</span>
  <span class="badge badge-pill badge-light">Claro</span>
  <span class="badge badge-pill badge-dark">Oscuro</span>
</div>

<h3>Links</h3>

<div class="m-3">
  <a href="#" class="badge badge-primary">Principal</a>
  <a href="#" class="badge badge-secondary">Secundario</a>
  <a href="#" class="badge badge-success">Exito</a>
  <a href="#" class="badge badge-danger">Peligro</a>
  <a href="#" class="badge badge-warning">Advertencia</a>
  <a href="#" class="badge badge-info">Informacion</a>
  <a href="#" class="badge badge-light">Claro</a>
  <a href="#" class="badge badge-dark">Oscuro</a>
</div>

Como veras rodeo los ejemplos con un div para darle mas margen, pero no uso style="margin: ..." como hasta acá, sino que uso una clase que bootstrap provee que estandariza los margenes en 6 niveles (m-0, m-1, ..., m-5). De esta manera si usamos estas clases en nuestras paginas los margenes serán consistentes y luego podremos ajustarlos en un solo lugar (la definición de .m-0, ..., .m-5 en nuestra hoja de estilos)

El resultado es algo así:

/galleries/cew/6/04-badges.png

Barra de Navegacion

Otro componente muy útil y versátil son las barras de navegación, suelen usarse en la parte superior de la pagina y en cualquier sección que tiene mas de un elemento para mostrar, como los tabs del navegador web.

<h2>Barra de Navegacion</h2>

<h3>Usando tags de lista</h3>

<ul class="nav">
  <li class="nav-item">
    <a class="nav-link active" href="#">Activo</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" href="#">Inactivo</a>
  </li>
</ul>

<h3>Usando el tag nav</h3>

<nav class="nav">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Justificado al centro</h3>

<nav class="nav justify-content-center">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Justificado a la derecha</h3>

<nav class="nav justify-content-end">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Tabs</h3>

<nav class="nav nav-tabs">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Pills</h3>

<nav class="nav nav-pills">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Tabs Expandidas (Lista)</h3>

<ul class="nav nav-tabs nav-fill">
  <li class="nav-item">
    <a class="nav-link active" href="#">Activo</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" href="#">Inactivo</a>
  </li>
</ul>

<h3>Pills Expandidas (Nav)</h3>

<nav class="nav nav-pills nav-fill">
  <a class="nav-item nav-link active" href="#">Activo</a>
  <a class="nav-item nav-link" href="#">Link</a>
  <a class="nav-item nav-link" href="#">Link</a>
  <a class="nav-item nav-link disabled" href="#">Inactivo</a>
</nav>

El resultado es algo así:

/galleries/cew/6/05-nav.png

Luego de explorar los componentes copiando y pegando los ejemplos intenta modificarlos, agregar mas items, eliminar algunos, reordenarlos etc.

Si te sentís aventurero, intenta mirar un ejemplo y luego tiperarlo por completo solo mirando el ejemplo cuando te olvides de algo o algo no funcione.

Este ejercicio es una buena forma de memorizar los conceptos básicos y de ver cuales partes pensabas que entendías pero todavía algún detalle se escapa.

Roberto Alsina: Código Charla PyDay "Como Hacer una API REST en Python, spec first"

El 4/4/2018 di una charla en un PyDay sobre como implementar una API REST a partir de una especificación hecha en Swagger/OpenAPI usando Connexion

/images/pyday-api-rest.jpg

Foto tomada por Yamila Cuestas

Si bien no pude grabar la charla (alguien en la audiencia si lo hizo, pero no me dio el video! Pasame el video, persona de la audiencia!) y no hay slides, acá está el código que mostré, que es relativamente sencillo y fácil de seguir.

Código de la charla

Cualquier cosa pregunten.

PD: Sí, podría hacer la charla en un video nuevo. Sí, me da mucha pereza.