Reorg repo
This commit is contained in:
@ -1,7 +0,0 @@
|
||||
Scripts para hacer cosas con la data de nombres de Argentina.
|
||||
|
||||
Página con esto funcionando: http://nombres.ralsina.me
|
||||
|
||||
* historico/ y busqueda/ son funciones OpenFAAS para implementar el sitio
|
||||
* faas-cli (ver scripts build.sh y deploy.sh) necesita docker con buildx
|
||||
* Para hacer el deploy obviamente necesita acceso a pass para conectarse con faasd
|
@ -1,15 +0,0 @@
|
||||
#!/bin/sh -x
|
||||
set -e
|
||||
|
||||
# My FAAS is arm64, so need to install this to cross-compile
|
||||
docker run --rm --privileged \
|
||||
multiarch/qemu-user-static \
|
||||
--reset -p yes
|
||||
|
||||
# Build and deploy
|
||||
if [ ! -d template ]
|
||||
then
|
||||
faas-cli template store pull python3-flask
|
||||
fi
|
||||
faas-cli publish -f nombres.yml --platforms linux/arm64 --build-arg 'TEST_ENABLED=false'
|
||||
faas-cli deploy -f nombres.yml
|
@ -1,164 +0,0 @@
|
||||
import unicodedata
|
||||
import urllib
|
||||
from collections import namedtuple as nt
|
||||
from dataclasses import dataclass
|
||||
from json import loads
|
||||
import logging
|
||||
|
||||
import pygal
|
||||
import pyrqlite.dbapi2 as dbapi2
|
||||
import requests
|
||||
|
||||
connection = dbapi2.connect(
|
||||
host="10.61.0.1",
|
||||
user="root",
|
||||
port=4001,
|
||||
password="",
|
||||
)
|
||||
|
||||
|
||||
def remove_accents(input_str):
|
||||
nfkd_form = unicodedata.normalize("NFKD", input_str)
|
||||
return "".join([c for c in nfkd_form if not unicodedata.combining(c)])
|
||||
|
||||
|
||||
def femininidad(nombre):
|
||||
sql1 = """
|
||||
SELECT COALESCE(frecuencia,0)
|
||||
FROM mujeres WHERE nombre=:nombre
|
||||
"""
|
||||
sql2 = """
|
||||
SELECT COALESCE(frecuencia,0)
|
||||
FROM hombres WHERE nombre=:nombre
|
||||
"""
|
||||
with connection.cursor() as cursor:
|
||||
nombre = nombre.strip().split()[0].strip().upper()
|
||||
mujeres = cursor.execute(sql1, {"nombre": nombre}).fetchone()
|
||||
mujeres = 0 if mujeres is None else mujeres[0]
|
||||
hombres = cursor.execute(sql2, {"nombre": nombre}).fetchone()
|
||||
hombres = 0 if hombres is None else hombres[0]
|
||||
if hombres == mujeres == 0:
|
||||
return 0.5
|
||||
return mujeres / (hombres + mujeres)
|
||||
|
||||
|
||||
def split_por_genero(nombres):
|
||||
femeninos = []
|
||||
masculinos = []
|
||||
for n in nombres:
|
||||
fem = femininidad(n[1])
|
||||
if fem is None:
|
||||
femeninos.append(n)
|
||||
masculinos.append(n)
|
||||
elif fem >= 0.5:
|
||||
femeninos.append(n)
|
||||
else:
|
||||
masculinos.append(n)
|
||||
return {"f": femeninos, "m": masculinos}
|
||||
|
||||
|
||||
def handle(req):
|
||||
"""handle a request to the function
|
||||
Args:
|
||||
req (str): request body
|
||||
|
||||
{
|
||||
p: prefijo del nombre,
|
||||
g: genero del nombre,
|
||||
a: año de nacimiento
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
data = loads(req)
|
||||
except Exception as e:
|
||||
data = {}
|
||||
|
||||
try:
|
||||
prefijo = data.get("p") or None
|
||||
genero = data.get("g") or None
|
||||
try:
|
||||
año = int(data.get("a"))
|
||||
except Exception:
|
||||
año = None
|
||||
except Exception as e:
|
||||
prefijo = genero = año = None
|
||||
return f"{req} -- {e}", 400
|
||||
|
||||
if prefijo is not None:
|
||||
prefijo = prefijo.strip().lower()
|
||||
|
||||
if genero not in ("f", "m"):
|
||||
genero = None
|
||||
|
||||
if prefijo is None and año is None: # Totales globales
|
||||
with connection.cursor() as cursor:
|
||||
sql = """
|
||||
SELECT total, nombre
|
||||
FROM totales
|
||||
ORDER BY total DESC
|
||||
LIMIT 50
|
||||
"""
|
||||
cursor.execute(sql)
|
||||
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
|
||||
|
||||
elif prefijo is None and año is not None: # Totales por año
|
||||
with connection.cursor() as cursor:
|
||||
sql = """
|
||||
SELECT contador, nombre
|
||||
FROM nombres
|
||||
WHERE
|
||||
anio = :anio
|
||||
ORDER BY contador DESC
|
||||
LIMIT 50
|
||||
"""
|
||||
cursor.execute(sql, {"anio": año})
|
||||
datos = [(r["contador"], r["nombre"]) for r in cursor.fetchall()]
|
||||
|
||||
elif prefijo is not None and año is None:
|
||||
with connection.cursor() as cursor:
|
||||
sql = """
|
||||
SELECT total, nombre
|
||||
FROM totales
|
||||
WHERE
|
||||
nombre LIKE :nombre
|
||||
ORDER BY total DESC
|
||||
LIMIT 50
|
||||
"""
|
||||
cursor.execute(sql, {"nombre": f"{prefijo}%"})
|
||||
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
|
||||
else:
|
||||
with connection.cursor() as cursor:
|
||||
sql = """
|
||||
SELECT contador, nombre
|
||||
FROM nombres
|
||||
WHERE
|
||||
anio = :anio AND
|
||||
nombre LIKE :nombre
|
||||
ORDER BY contador DESC
|
||||
LIMIT 50
|
||||
"""
|
||||
cursor.execute(sql, {"anio": año, "nombre": f"{prefijo}%"})
|
||||
datos = [(r["contador"], r["nombre"]) for r in cursor.fetchall()]
|
||||
|
||||
if genero:
|
||||
datos = split_por_genero(datos)[genero]
|
||||
|
||||
datos = datos[:10]
|
||||
|
||||
chart = pygal.HorizontalBar(height=400, show_legend=False, show_y_labels=True)
|
||||
chart.x_labels = [nombre.title() for _, nombre in datos[::-1]]
|
||||
if len(datos) > 1:
|
||||
chart.title = f"¿Puede ser ... {datos[0][1].title()}? ¿O capaz que {datos[1][1].title()}? ¡Contáme más!"
|
||||
elif len(datos) == 1:
|
||||
chart.title = f"¡Hola {datos[0][1].title()}!"
|
||||
elif len(datos) < 1:
|
||||
chart.title = "¡No esssistís!"
|
||||
chart.add("", [contador for contador, _ in datos[::-1]])
|
||||
|
||||
return (
|
||||
chart.render(is_unicode=True),
|
||||
200,
|
||||
{"Content-Type": "image/svg+xml"},
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
from .handler import handle
|
||||
|
||||
# Test your handler here
|
||||
|
||||
# To disable testing, you can set the build_arg `TEST_ENABLED=false` on the CLI or in your stack.yml
|
||||
# https://docs.openfaas.com/reference/yaml/#function-build-args-build-args
|
||||
|
||||
|
||||
def test_handle():
|
||||
# assert handle("input") == "input"
|
||||
pass
|
@ -1,3 +0,0 @@
|
||||
pygal
|
||||
requests
|
||||
pyrqlite
|
@ -1,41 +0,0 @@
|
||||
# If you would like to disable
|
||||
# automated testing during faas-cli build,
|
||||
|
||||
# Replace the content of this file with
|
||||
# [tox]
|
||||
# skipsdist = true
|
||||
|
||||
# You can also edit, remove, or add additional test steps
|
||||
# by editing, removing, or adding new testenv sections
|
||||
|
||||
|
||||
# find out more about tox: https://tox.readthedocs.io/en/latest/
|
||||
[tox]
|
||||
envlist = lint,test
|
||||
skipsdist = true
|
||||
|
||||
[testenv:test]
|
||||
deps =
|
||||
flask
|
||||
pytest
|
||||
-rrequirements.txt
|
||||
commands =
|
||||
# run unit tests with pytest
|
||||
# https://docs.pytest.org/en/stable/
|
||||
# configure by adding a pytest.ini to your handler
|
||||
pytest
|
||||
|
||||
[testenv:lint]
|
||||
deps =
|
||||
flake8
|
||||
commands =
|
||||
flake8 .
|
||||
|
||||
[flake8]
|
||||
count = true
|
||||
max-line-length = 127
|
||||
max-complexity = 10
|
||||
statistics = true
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
select = E9,F63,F7,F82
|
||||
show-source = true
|
@ -1,5 +0,0 @@
|
||||
#!/bin/sh -x
|
||||
set -e
|
||||
|
||||
pass faas.ralsina.me | faas-cli login --password-stdin
|
||||
faas-cli deploy -f nombres.yml
|
@ -1,66 +0,0 @@
|
||||
import unicodedata
|
||||
import urllib
|
||||
from collections import defaultdict as ddict
|
||||
from dataclasses import dataclass
|
||||
from json import loads
|
||||
|
||||
import pygal
|
||||
import pyrqlite.dbapi2 as dbapi2
|
||||
import requests
|
||||
|
||||
connection = dbapi2.connect(
|
||||
host="10.61.0.1",
|
||||
user="root",
|
||||
port=4001,
|
||||
password="",
|
||||
)
|
||||
|
||||
|
||||
def remove_accents(input_str):
|
||||
nfkd_form = unicodedata.normalize("NFKD", input_str)
|
||||
return "".join([c for c in nfkd_form if not unicodedata.combining(c)])
|
||||
|
||||
|
||||
def handle(req):
|
||||
"""handle a request to the function
|
||||
Args:
|
||||
req (str): request body
|
||||
|
||||
{"i": ["nombre1, nombre2"]}
|
||||
|
||||
"""
|
||||
nombres = []
|
||||
try:
|
||||
nombres = loads(req)
|
||||
nombres = nombres["i"].split(",")
|
||||
nombres = [remove_accents(x.strip().lower()) for x in nombres]
|
||||
nombres = [n for n in nombres if n]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not nombres:
|
||||
nombres = ["maria", "juan"]
|
||||
|
||||
chart = pygal.Line(
|
||||
height=200, fill=True, human_readable=True, show_minor_x_labels=False
|
||||
)
|
||||
chart.x_labels = [str(x) for x in range(1922, 2015)]
|
||||
chart.x_labels_major = [str(x) if x % 10 == 0 else "" for x in range(1922, 2015)]
|
||||
for nombre in nombres:
|
||||
datos = ddict(int)
|
||||
with connection.cursor() as cursor:
|
||||
sql = """
|
||||
SELECT anio, contador, nombre
|
||||
FROM nombres
|
||||
WHERE nombre = :nombre
|
||||
ORDER BY anio
|
||||
"""
|
||||
cursor.execute(sql, {"nombre": nombre})
|
||||
datos.update({r["anio"]: r["contador"] for r in cursor.fetchall()})
|
||||
chart.add(nombre.title(), [datos[x] for x in range(1922, 2015)])
|
||||
|
||||
chart.x_labels = [str(n) for n in range(1922, 2015)]
|
||||
chart.x_labels_major = [str(n) for n in range(1920, 2020, 10)]
|
||||
|
||||
# return Response(chart.render(is_unicode=True), mimetype="image/svg+xml")
|
||||
return chart.render(is_unicode=True), 200, {"Content-Type": "image/svg+xml"}
|
@ -1,11 +0,0 @@
|
||||
from .handler import handle
|
||||
|
||||
# Test your handler here
|
||||
|
||||
# To disable testing, you can set the build_arg `TEST_ENABLED=false` on the CLI or in your stack.yml
|
||||
# https://docs.openfaas.com/reference/yaml/#function-build-args-build-args
|
||||
|
||||
|
||||
def test_handle():
|
||||
# assert handle("input") == "input"
|
||||
pass
|
@ -1,3 +0,0 @@
|
||||
pygal
|
||||
requests
|
||||
pyrqlite
|
@ -1,41 +0,0 @@
|
||||
# If you would like to disable
|
||||
# automated testing during faas-cli build,
|
||||
|
||||
# Replace the content of this file with
|
||||
# [tox]
|
||||
# skipsdist = true
|
||||
|
||||
# You can also edit, remove, or add additional test steps
|
||||
# by editing, removing, or adding new testenv sections
|
||||
|
||||
|
||||
# find out more about tox: https://tox.readthedocs.io/en/latest/
|
||||
[tox]
|
||||
envlist = lint,test
|
||||
skipsdist = true
|
||||
|
||||
[testenv:test]
|
||||
deps =
|
||||
flask
|
||||
pytest
|
||||
-rrequirements.txt
|
||||
commands =
|
||||
# run unit tests with pytest
|
||||
# https://docs.pytest.org/en/stable/
|
||||
# configure by adding a pytest.ini to your handler
|
||||
pytest
|
||||
|
||||
[testenv:lint]
|
||||
deps =
|
||||
flake8
|
||||
commands =
|
||||
flake8 .
|
||||
|
||||
[flake8]
|
||||
count = true
|
||||
max-line-length = 127
|
||||
max-complexity = 10
|
||||
statistics = true
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
select = E9,F63,F7,F82
|
||||
show-source = true
|
@ -1,17 +0,0 @@
|
||||
version: 1.0
|
||||
provider:
|
||||
name: openfaas
|
||||
gateway: http://pinky:8082
|
||||
functions:
|
||||
busqueda:
|
||||
lang: python3-flask
|
||||
handler: ./busqueda
|
||||
image: ralsina/nombres_busqueda:latest
|
||||
historico:
|
||||
lang: python3-flask
|
||||
handler: ./historico
|
||||
image: ralsina/nombres_historico:latest
|
||||
tapas:
|
||||
lang: python3-flask
|
||||
handler: ./tapas
|
||||
image: ralsina/tapas:latest
|
@ -1,32 +0,0 @@
|
||||
from json import loads
|
||||
from tapita import Cover
|
||||
from io import BytesIO
|
||||
import base64
|
||||
|
||||
|
||||
def handle(req):
|
||||
"""handle a request to the function
|
||||
Args:
|
||||
req (str): request body
|
||||
|
||||
{
|
||||
"title": "foo",
|
||||
"subtitle": "bar",
|
||||
"author": "bat",
|
||||
}
|
||||
"""
|
||||
try:
|
||||
args = loads(req)
|
||||
except Exception:
|
||||
return "Bad Request", 400
|
||||
|
||||
c = Cover(**args)
|
||||
byte_arr = BytesIO()
|
||||
c.image.save(byte_arr, format="JPEG")
|
||||
|
||||
# return Response(chart.render(is_unicode=True), mimetype="image/svg+xml")
|
||||
return (
|
||||
f'<img src="data:image/jpeg;base64, {base64.b64encode(byte_arr.getvalue()).decode("utf-8")}">',
|
||||
200,
|
||||
{"Content-Type": "text/html"},
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
from .handler import handle
|
||||
|
||||
# Test your handler here
|
||||
|
||||
# To disable testing, you can set the build_arg `TEST_ENABLED=false` on the CLI or in your stack.yml
|
||||
# https://docs.openfaas.com/reference/yaml/#function-build-args-build-args
|
||||
|
||||
|
||||
def test_handle():
|
||||
# assert handle("input") == "input"
|
||||
pass
|
@ -1 +0,0 @@
|
||||
tapita
|
@ -1,41 +0,0 @@
|
||||
# If you would like to disable
|
||||
# automated testing during faas-cli build,
|
||||
|
||||
# Replace the content of this file with
|
||||
# [tox]
|
||||
# skipsdist = true
|
||||
|
||||
# You can also edit, remove, or add additional test steps
|
||||
# by editing, removing, or adding new testenv sections
|
||||
|
||||
|
||||
# find out more about tox: https://tox.readthedocs.io/en/latest/
|
||||
[tox]
|
||||
envlist = lint,test
|
||||
skipsdist = true
|
||||
|
||||
[testenv:test]
|
||||
deps =
|
||||
flask
|
||||
pytest
|
||||
-rrequirements.txt
|
||||
commands =
|
||||
# run unit tests with pytest
|
||||
# https://docs.pytest.org/en/stable/
|
||||
# configure by adding a pytest.ini to your handler
|
||||
pytest
|
||||
|
||||
[testenv:lint]
|
||||
deps =
|
||||
flake8
|
||||
commands =
|
||||
flake8 .
|
||||
|
||||
[flake8]
|
||||
count = true
|
||||
max-line-length = 127
|
||||
max-complexity = 10
|
||||
statistics = true
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
select = E9,F63,F7,F82
|
||||
show-source = true
|
Reference in New Issue
Block a user