Queremos armar una red en la cual tenemos proyectos y usuarios obtenidos a través de Github, cada usuario va a poder puntuar y comentar sobre proyectos. Se les va a recomendar proyectos en los que puede participar o que le interese el contenido según la gente que sigue (que contribuyó a dichos proyectos) y sus preferencias de idiomas de programación. Los datos los obtenemos a través de la api de github dónde vamos a buscar los repositorios con la mayor cantidad de estrellas y sus contribuidores para generar los datos con los que vamos a llenar las tablas. Los usuarios se autenticarían a traves de su cuenta de Github de donde obtenemos la informacion que necesitemos de su cuenta. Las bases de datos que vamos a usar son MongoDB y Neo4j. MongoDB vamos a utilizarlo para guardar los datos de los repositorios, los usuarios, los comentarios y puntajes sin ningún tipo de relación. Mientras que Neo4j se ocupará de guardar exclusivamente las relaciones entre nuestras entidades utilizando unicamente un id.
- Tener instalado python3 (3.9.0)
- Tener instalado pip3
- Tener instalado docker (opcional)
Para la parte de persistencia hay que tener MongoDB y Neo4j instalados. La manera recomendada es usando docker con los siguentes comandos:
MongoDB
- Descargar la version oficial de MongoDB
docker pull mongo
- Levantar el contenedor
docker run --name Mymongo -p 27017:27017 -d mongo
Neo4j
- Descargar la version oficial de Neo4j
docker pull neo4j
- Levantar el contenedor
docker run --name Myneo4j -p 7474:7474 -p 7687:7687 --env=NEO4J_AUTH=none -d neo4j
Python
Para instalar las dependencias hay que ejecutar el siguiente comando desde la carpeta raíz del proyecto:
pip3 install -r requirements.txt
Env
Hay que crear un archivo '.env' (con punto previo pero sin extensión) en la carpeta raíz del proyecto con la siguiente estructura:
SERVER_HOST=127.0.0.1
PORT=8000
MONGO_DETAILS=mongodb://localhost:27017
NEO4J_DETAILS=neo4j://localhost:7687
NEO4J_USER=admin
NEO4J_PASS=admin
GITHUB_API_TOKEN=**token propio para acceder al api de github**
Esos datos corresponden al proyecto corriendo en una computadora local con los puertos por defecto como fueron establecidos en la sección de persistencia
El token de github se puede obtener siguiendo las instrucciones del siguiente link
- Encender los contenedores de docker si no lo estaban
docker start Mymongo
docker start Myneo4j
- Desde la caperta raíz del proyecto, levantar el api con el siguiente comando:
python3 main.py
Luego se podrá acceder al api desde el navegador en el url y puerto utilizado en el archivo '.env', por defecto http://localhost:8000/docs
Se puede agregar información a las bases de datos de dos maneras.
-
Utilizando el endpoint
/register
del api que recibe el nombre de un usuario de github y lo agrega junto con sus repos. Ademas agrega usuarios seguidos por este usuario en profundidad hasta una determinada profundidad.En otras palabras, se agrega a los usuarios que este sigue, a los usuarios que siguen los usuarios que este sigue, y asi sucesivamente hasta una determinada profundidad.
-
Utilizando el endpoint
/populate_databases
del api. Este funciona de manera similar al/register
, pero en vez de utilizar un usuario de base, utiliza los dueños de las 10 repos con más estrellas de todo Github.Termina generando al rededor 350 usuarios y 2000 repositorios y puede llegar a tardar unos 10min.
La siguiente lista consiste de todos los endpoints del api, lo que hacen y ejemplos de parámetros para cada uno.
User register
-
POST /register
Recibe un usuario de github y lo registra a la aplicación siguiendo el formato mencionado en la sección anterior.
Necesita un cuerpo con el siguiente formato:
{ "username": "nombre_del_usuario" }
Repos
-
GET /repos
Devuelve un arreglo con todos los repos de la aplicación.
-
GET /repos/{username}/{reponame}
Devuelve la información de un repo en particular.
username
es el nombre del dueño del repo yreponame
es el nombre del repo.Por ejemplo para ver la información de este repo en particular se tendría que hacer un
GET
al endpoint/repos/MatiMonaco/BD2-SMS-2021
-
GET /repos/{username}/{reponame}/reviews
Similar al anterior, pero devuelve todas las reseñas hechas a un repositorio.
Users
-
GET /users
Devuelve un arreglo con todos los usuarios de la aplicación.
-
GET /users/{username}
Devuelve la información de un usuario en particular.
-
PUT /users/{username}
Permite cambiar la información de un usuario en particular.
Necesita un cuerpo con el siguiente formato:
{ "name": "Nombre Apellido", "avatar_url": "url a la foto", "bio": "Texto descriptivo del usuario", "languages": ["Lenguajes", "que", "utiliza", "el", "usuario"], "following": 0, "followers": 0, "html_url": "url al perfil de github del usuario" }
-
GET /users/{username}/following
Devuelve un arreglo de usuarios seguidos por el usuario que recibe por url.
-
GET /users/{username}/followed_by
Devuelve un arreglo de usuarios que siguen al usuario que recibe por url.
-
POST /users/{username}/follow/{other_username}
Hace que el usuario
username
siga al usuarioother_username
. -
POST /users/{username}/unfollow/{other_username}
Hace que el usuario
username
deje de seguir al usuarioother_username
. -
GET /users/{username}/reviews
Devuelve un arreglo de todas las reseñas hechas por el usuario.
-
GET /users/{username}/recommended/repos
Devuelve un arreglo de repositorios recomendados para el usuario
username
ordenados por nuestro algoritmo de recomendación. -
GET /users/{username}/recommended/users
Devuelve un arreglo de usuarios recomendados para el usuario
username
ordenados por nuestro algoritmo de recomendación.
Reviews
-
POST /reviews
Crea una reseña a una repo.
Necesita un cuerpo con el siguiente formato:
{ "reviewer": "username de la persona haciendo la reseña", "repo_name": "nombre completo del repositorio (ej: MatiMonaco/BD2-SMS-2021)", "score": 5, "comment": "comentario acerca del repositorio" }
con el valor
score
siendo un numero con decimales entre 0 y 5. -
PUT /reviews/{review_id}
Permite cambiar la información de una reseña en particular.
Necesita un cuerpo con el siguiente formato:
{ "score": 5, "comment": "un comentario" }
Ambos parámetros son opcionales, dejando el valor anterior en su ausencia.
-
DELETE /reviews/{review_id}
Borra una reseña.