dev-job-analytics's Issues
[MVP] Modelo de datos y documentación
Para el MVP tenemos que tener claro el modelo de datos, ya que el scrapper alimentará la base de datos y por lo tanto hay que tener los schemas definidos, además de agregar a la documentación del proyecto (en gdrive) el modelo de datos a utilizar.
Ya existe un mock de datos del cual el frontend está basado:
https://github.com/dpalmasan/dev-job-analytics/blob/main/jobservatory_react/src/fakeFinalData.js
Por lo que hay que agregar la lógica de ingesta de datos a la BBDD basado en este prototipo y completar la documentación.
Crear scrapper de datos de linkedin
El scrapper debe estar conectado con la Base de Datos y debe ejecutarse en un período determinado para actualizar la base de datos.
El link funciona de esta forma
https://www.linkedin.com/jobs/search/?geoId=92000000&keywords=React.js&location=Todo%20el%20mundo
Ahi se saca el dato de todo el mundo de la tecnologia React.js (se puede hacer con navegador incognito no necesita sesion)
La forma en la que creo que serviria recibir desde el front, sigue este patron.
https://github.com/dpalmasan/dev-job-analytics/blob/main/jobservatory_react/src/fakeFinalData.js
Agregar URI del backend a configuración
Actualmente, la URI del backend está hardcodeada en el frontend. Para el release, idealmente deberíamos tener esta URI en el archivo de configuración, ya que es una parte de la configuración, por ejemplo:
Lo ideal sería quitar la URI harcodeada y hacerla parte de una configuración. Lo único fijo en la URI sería la API (el host y el puerto deberían ser parte de la configuración por ahora)
Script para crear respaldo diario de la base de datos
- Ayer
2021-09-01
tuvimos un incidente intentando eliminar algunos documentos inválidos de la DB - Por error se perdieron todos los datos de la colección scrapeada desde linkedin
Debemos crear un job que respalde la DB de forma diaria.
Implementar Scrapper con inicio de sesión
Para un scrapping adhoc, se puede utilizar Selenium para extraer el conteo de puestos teniendo sesión iniciada, por ejemplo el siguiente snippet:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
VERIFY_LOGIN_ID = "global-nav-search"
REMEMBER_PROMPT = 'remember-me-prompt__form-primary'
driver = webdriver.Chrome(ChromeDriverManager().install())
email = "EMAIL"
password = "PASSWORD"
driver.get("https://www.linkedin.com/login")
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "username")))
email_elem = driver.find_element_by_id("username")
email_elem.send_keys(email)
password_elem = driver.find_element_by_id("password")
password_elem.send_keys(password)
password_elem.submit()
driver.get("https://www.linkedin.com/jobs/search/?geoId=92000000&keywords=React.js&location=Todo%20el%20mundo")
element = driver.find_element_by_tag_name("small")
print(element.text)
Se puede implementar una clase nueva, algo como LoggedInLinkedinScrapper
para extraer estos resultados.
Crear tests para backend
Por completitud, deberíamos tener tests para todo el código. Este ticket es para implementar tests en el backend. Probablemente utilizaremos mocha
.
Enlazar el fake json con datos reales desde la API
Agregar Theme a gráficos en dark cuando se pone el mouse arriba de los puntos
Repasar colores de white/black theme en graficos
Investigar como automatizar scripts de ingesta de datos
El script backfill_so_data
es fácil de automatizar porque hace un simple request sin autorización. El script problemático es el scraper de linkedin, ya que requiere logearse desde la máquina. Idea, apuntar display a una máquina local y logearse.
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--no-sandbox")
driver = webdriver.Chrome(
executable_path=os.environ.get("CHROMEDRIVER_PATH"),
chrome_options=chrome_options,
)
[MVP] Crear job para importar datos desde una fuente a la BBDD
Reemplazar mongoose con driver de mongodb
MongoDB tiene un driver oficial para las conexiones:
https://docs.mongodb.com/drivers/node/current/
Creo que tendrá sus ventajas al ser el driver oficial, por lo que más adelante sería bueno reemplazar mongoose por este driver.
Cambiar tabla por pais, con columnas hacia abajo donde salga descripcion de cada tecnologia (y sus paises)
Agregar Redux
Refactor completo de componentes, disminución de niveles y manejo de props
Añadir chequeos de coverage al código en Python
Probablemente utilizar pytest-cov. Luego se decidirá el umbral de coverage. Por otro lado, se debe dejar configurado el plugin.
Agregar una funcion en node para poder traer solo UNA tecnología, con sus países, sus preguntas y sus trabajos, cosa de que se pueda agregar una tecnología en el buscador y se sume a los 3 gráficos
Agregar github actions para PRs (CI)
Se debe aplicar CI a:
- scraper
- frontend
- backend
Actualizar script get_data para usar uri personalizada en la conexión con MongoDB
Actualmente tenemos esto:
def main():
"""Entry point."""
connect("jobservatory-manual")
with open("jobserver-config.yaml", "r") as fp:
creds = yaml.safe_load(fp)
sc = LoggedLinkedinScrapper(creds["email"], creds["password"])
import_data(
sc,
[
"React.js",
"Angular.js",
"Ruby on Rails",
"Java",
"Python",
"Data Engineer",
],
0,
)
Pero sería mejor actualizar el jobserver-config.yaml
con la opción de tener una URI personalizada y conectar a cualquier DB (local o remota)
Refactor del disenio del grafico + stats
Implementar 70% test coverage en React
Al presionar en una + del buscador, se debe poder agregar el elemento del grafico. (Hacerlo con un mock data mientras tanto)
Crear github pages para deploy de mantener (React)
- Se puede por ejemplo una página de inicio.
- Algún mensaje en caso de que no se pueda conectar con backend
- La página debe ser accesible desde github pages
Referencia:
https://www.freecodecamp.org/news/deploy-a-react-app-to-github-pages/
Eliminar fechas
Implementar Rate Limiting a los GET endpoint y eliminar POST endpoints
- Todos los
GET
endpoints tienen que tener rate limiting - Ideal que el rate limiting sea parte de la configuración
- Eliminar todos los
POST
endpoints, ya que por el momento no queremos afectar la DB
Al presionar en una X de un tag, se debe poder borrar el elemento del grafico
Completar BDD en Mongo (hacer relacion 1:N y N:1 entre tablas)
Actualizar Backend acorde al schema definido en los documentos de diseño
Hacer refactor a uso de `moment`
Tenemos varias funciones del backend que usan moment
, lo que convierte a las funciones en no idempotentes. Idealmente, deberíamos hacer la fecha una entrada a estas funciones.
conectar Stackoverflow chart con API
Eliminar fechas "Hard-codeadas" del script de backfill de SO
Podría hacerse mejor utilizando comandos de línea, por ejemplo argparse.
Cambiar el color de los textos del grafico para que esten con el ThemeContext, y asi esten sincronizados con el dark/light mode
Actualizar README general y componentes
Para el README.md
general estaría bueno poner gifs, o una vista más dinámica de la aplicación. Lo mismo para los componentes:
jobservatory_express
jobservatory_react
scrapper
Agregar más documentación de uso, y ejemplos.
Agregar pipeline CI para frontend (test + coverage)
El scraper
y el backend
tienen sus suite de pruebas, y pipeline CI configurado. Sólo queda setear CI en el frontend. Ya que @Diekrul quieres aprender sobre esto, te recomiendo tomar este issue.
Requerimientos
- Suite de pruebas creadas para el frontend
- Script creado para ejecutar pruebas (ej:
yarn test
) - Pipeline CI configurado (si quieres probar en local puedes usar esta herramienta https://github.com/nektos/act; Ojo que necesita tener
Docker
instalado). - Agregar chequeos de coverage a las pruebas (y definir un umbral, por ejemplo
85%
)
Agregar chequeos de coverage (frontend, backend, scraper)
Idealmente, queremos tener la mayoría del código cubierto por casos de prueba. Inicialmente, deberíamos apuntar a un coverage de un 85% (ideal 100%). Agregar a los linters chequeos de coverage:
- scraper (pytest-cov)
- backend (mocha)
- frontend (tengo entendido que aún no tenemos tests para esto)
Agregar tags como metodo de filtro arriba del grafico, en caso de querer sumar o restar mas tecnologias
Agregar grafico por pais y limpiar codigo en general
Subir backend a heroku
Enlazar logica de tags con filtro de todos los grafico
Eliminar las cards por ahora (no se necesitan)
Modificar la vista para aceptar 1 grafico, que contenga las 5 tecnologias a comparar
Agregar logo de jobservatory
@Diekrul Usa tus poderes de frontend jeje.
Aumentar coverage de backend a 85%
Actualmente el coverage está bajo el umbral que se decidió por acuerdo. Se deben crear tests de manera de aumentar el coverage al umbral esperado. También se debe actualizar el package.json
:
"scripts": {
"start": "node index",
"server": "nodemon index",
"test": "nyc --check-coverage --lines 75 mocha tests",
"client": "npm start --prefix ./../jobservatory",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"linter": "eslint . --ext .js,.jsx,.ts,.tsx"
},
Se debe actualizar --lines 75
a --lines 85
.
Agregar cache para requests
Podríamos considerar redis, ya que sabemos que los datos se actualizan diariamente, no tiene sentido hacer llamadas a la DB cada vez que pedimos datos si ya sabemos que estará en cache. Esto involucrará actualizar los endpoint del backend.
Agregar mapeo de tecnologías (jobservatory record, stack overflow questions)
Para frontend.
Agregar autocompletar cuando el usuario esta buscando una tecnología para agregar. Debe ser un fetch de las que tenemos para que haga match en la búsqueda
Crear configuración del proyecto para el scrapper (probablemente hecho en python)
Integrate StackOverflow to data extractors
Arreglar fallos CI en linter (frontend)
Actualizar LoggedIn Scraper para aceptar un driver de Selenium con opciones
En el deployment a heroku, me di cuenta que es mejor tener la posibilidad de agregar un driver de selenium
con opciones, por ejemplo:
class LoggedLinkedinScrapper(LinkedinScraper):
"""Implement a LinkedinScraper using identity."""
def __init__(
self,
email: str,
password: str,
driver: Optional[webdriver.chrome.webdriver.WebDriver] = None,
):
"""Start ``selenium`` driver to scrap from the web.
:param email: Email to login into Linkedin
:type email: str
:param password: Password
:type password: str
"""
self.driver = driver
if self.driver is None:
self.driver = webdriver.Chrome(ChromeDriverManager().install())
self.email = email
self.password = password
self.logged = False
De esta forma se puede hacer algo como:
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--no-sandbox")
driver = webdriver.Chrome(
executable_path=os.environ.get("CHROMEDRIVER_PATH"),
chrome_options=chrome_options,
)
sc = LoggedLinkedinScrapper(EMAIL, PASSWORD, driver)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.