diff --git a/.travis.yml b/.travis.yml index bcd7b94..0f53c1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,11 @@ language: python python: - - "3.7" + - "3.7" - "3.8" services: - postgresql install: - pip install -r requirements.txt script: - - cd tests + - cd app/tests - pytest test_main.py - diff --git a/tests/__init__.py b/app/db/__init__.py similarity index 100% rename from tests/__init__.py rename to app/db/__init__.py diff --git a/app/db/database.py b/app/db/database.py new file mode 100644 index 0000000..fa5af58 --- /dev/null +++ b/app/db/database.py @@ -0,0 +1,27 @@ +import sqlalchemy +from sqlalchemy import create_engine +import databases + + +## Postgres Database +DATABASE_URL = "postgresql://yagu:yagu123@localhost:5432/universities" +# DATABASE_URL = os.environ.get("TRAVIS") +database = databases.Database(DATABASE_URL) +metadata = sqlalchemy.MetaData() + + +# SQLAlchemy database model +universities = sqlalchemy.Table( + "universities", + metadata, + sqlalchemy.Column("name", sqlalchemy.String, primary_key=True), + sqlalchemy.Column("alpha_two_code", sqlalchemy.String), + sqlalchemy.Column("country", sqlalchemy.String), + sqlalchemy.Column("web_pages", sqlalchemy.ARRAY(sqlalchemy.String)), + sqlalchemy.Column("domains", sqlalchemy.ARRAY(sqlalchemy.String)), + sqlalchemy.Column("state_province", sqlalchemy.String), +) + +engine = sqlalchemy.create_engine(DATABASE_URL) + +metadata.create_all(engine) diff --git a/app/main.py b/app/main.py index 5d37998..8b151e1 100644 --- a/app/main.py +++ b/app/main.py @@ -1,70 +1,31 @@ -import sqlalchemy -from sqlalchemy import and_, literal -from sqlalchemy import create_engine -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.dialects.postgresql import insert -import databases -import psycopg2 from fastapi import FastAPI -from fastapi_utils.tasks import repeat_every +from fastapi.responses import RedirectResponse, ORJSONResponse from typing import List, Optional +from app.db.database import universities, database +from fastapi_utils.tasks import repeat_every import requests from asyncpg.exceptions import UniqueViolationError -import os - - -## Postgres Database -# DATABASE_URL = "postgresql://user:password@host:5432/universities" -DATABASE_URL = os.environ.get("TRAVIS") -database = databases.Database(DATABASE_URL) -metadata = sqlalchemy.MetaData() - tags_metadata = [ - { - "name": "Search", - "description": "" - }, - + {"name": "Search", "description": ""}, ] -#SQLAlchemy database model -universities = sqlalchemy.Table( - "universities", - metadata, - sqlalchemy.Column("name" , sqlalchemy.String, primary_key=True), - sqlalchemy.Column("alpha_two_code", sqlalchemy.String), - sqlalchemy.Column("country" , sqlalchemy.String), - sqlalchemy.Column("web_pages" , sqlalchemy.ARRAY(sqlalchemy.String)), - sqlalchemy.Column("domains" , sqlalchemy.ARRAY(sqlalchemy.String)), - sqlalchemy.Column("state_province", sqlalchemy.String), -) - -engine = sqlalchemy.create_engine( - DATABASE_URL -) - -metadata.create_all(engine) - - -# FastAPI app = FastAPI( - title="Universities API", - openapi_tags=tags_metadata, + title="Universities API", + openapi_tags=tags_metadata, + default_response_class=ORJSONResponse, ) - -# **Database Connection** @app.on_event("startup") async def startup(): - await database.connect() + await database.connect() @app.on_event("shutdown") async def shutdown(): - await database.disconnect() + await database.disconnect() @repeat_every(seconds=86400) @@ -73,17 +34,19 @@ async def update_database(): """ Asynchronous database updater, runs itself in 86400 seconds | 1 day """ - r = requests.get("https://raw.githubusercontent.com/Hipo/university-domains-list/master/world_universities_and_domains.json") + r = requests.get( + "https://raw.githubusercontent.com/Hipo/university-domains-list/master/world_universities_and_domains.json" + ) data = r.json() for i in data: query = universities.insert().values( - country = i["country"], - name = i["name"], - web_pages = i["web_pages"], - alpha_two_code = i["alpha_two_code"], - state_province = i["state-province"], - domains = i["domains"], + country=i["country"], + name=i["name"], + web_pages=i["web_pages"], + alpha_two_code=i["alpha_two_code"], + state_province=i["state-province"], + domains=i["domains"], ) try: @@ -91,34 +54,56 @@ async def update_database(): except UniqueViolationError: pass + @app.get("/search", tags=["Search"]) -async def search(country: Optional[str] = None, name: Optional[str] = None, alpha_two_code: Optional[str] = None, domain: Optional[str] = None) : +async def search( + country: Optional[str] = None, + name: Optional[str] = None, + alpha_two_code: Optional[str] = None, + domain: Optional[str] = None, +): if country and name: - query = "SELECT * FROM universities WHERE country ILIKE '%"+country+"%' AND name ILIKE '%"+name+"%'" + query = ( + "SELECT * FROM universities WHERE country ILIKE '%" + + country + + "%' AND name ILIKE '%" + + name + + "%'" + ) return await database.fetch_all(query) elif alpha_two_code and name: - query = "SELECT * FROM universities WHERE alpha_two_code ILIKE '%"+alpha_two_code+"%' AND name ILIKE '%"+name+"%'" + query = ( + "SELECT * FROM universities WHERE alpha_two_code ILIKE '%" + + alpha_two_code + + "%' AND name ILIKE '%" + + name + + "%'" + ) return await database.fetch_all(query) elif country: - query = "SELECT * FROM universities WHERE country ILIKE '%"+country+"%'" + query = "SELECT * FROM universities WHERE country ILIKE '%" + country + "%'" return await database.fetch_all(query) elif name: - query = "SELECT * FROM universities WHERE name ILIKE '%"+name+"%'" + query = "SELECT * FROM universities WHERE name ILIKE '%" + name + "%'" return await database.fetch_all(query) elif alpha_two_code: - query = "SELECT * FROM universities WHERE alpha_two_code ILIKE '%"+alpha_two_code+"%'" + query = ( + "SELECT * FROM universities WHERE alpha_two_code ILIKE '%" + + alpha_two_code + + "%'" + ) return await database.fetch_all(query) elif domain: - query = "SELECT * FROM universities WHERE domains && '{"+domain+"}'" + query = "SELECT * FROM universities WHERE domains && '{" + domain + "}'" return await database.fetch_all(query) -@app.get("/") +@app.get("/", include_in_schema=False) async def index(): - return {"Please go to docs.": "universitiesapi.herokuapp.com/docs"} + return RedirectResponse("/docs") diff --git a/app/tests/__init__.py b/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/test_main.py b/app/tests/test_main.py new file mode 100644 index 0000000..ddec53a --- /dev/null +++ b/app/tests/test_main.py @@ -0,0 +1,143 @@ +import pytest +from fastapi.testclient import TestClient + +from app.main import app + + +@pytest.fixture(scope="module") +def base_client(): + client = TestClient(app) + yield client + + +def test_home(base_client): + "Clients" + response = base_client.get("/") + + "Status Code" + assert response.status_code == 200 + + "Response" + assert response.json() == { + "Please go to docs.": "universitiesapi.herokuapp.com/docs" + } + + +async def test_country_and_name(base_client): + "Clients" + response_one = base_client.get("/search?country=tur&name=saban") + response_two = base_client.get("/search?country=turkey&name=middle") + + "Status Code" + assert response_one.status_code == 200 + assert response_two.status_code == 200 + + "Response" + assert response_one.json() == [ + { + "name": "Sabanci University", + "alpha_two_code": "TR", + "country": "Turkey", + "web_pages": "http://www.sabanciuniv.edu.tr/http://www.sabanciuniv.edu/", + "domains": "sabanciuniv.edu.trsabanciuniv.edu", + "state_province": null, + } + ] + assert response_two.json() == [ + { + "name": "Middle East Technical University", + "alpha_two_code": "TR", + "country": "Turkey", + "web_pages": "http://www.metu.edu.tr/", + "domains": "metu.edu.tr", + "state_province": null, + } + ] + + +def test_alpha_two_code_and_name(base_client): + "Clients" + response_one = base_client.get("/search?name=krako&alpha_two_code=pl") + response_two = base_client.get("/search?name=harva&alpha_two_code=us") + + "Status Code" + assert response_one.status_code == 200 + assert response_two.status_code == 200 + + "Response" + assert response_one.json() == [ + { + "name": "Pedagogical University of Krakow", + "alpha_two_code": "PL", + "country": "Poland", + "web_pages": "http://www.wsp.krakow.pl/", + "domains": "wsp.krakow.pl", + "state_province": null, + } + ] + assert response_two.json() == [ + { + "name": "Harvard University", + "alpha_two_code": "US", + "country": "United States", + "web_pages": "http://www.harvard.edu/", + "domains": "harvard.edu", + "state_province": null, + } + ] + + +def test_country(base_client): + "Clients" + response_one = base_client.get("/search?country=United States") + response_two = base_client.get("/search?country=russia") + + "Status Code" + assert response_one.status_code == 200 + assert response_two.status_code == 200 + + "Response" + response_one_body = response_one.json() + response_two_body = response_two.json() + response_one_body[0]["country"] == "United States" + response_two_body[0]["country"] == "Russian Federation" + + +def test_name(base_client): + "Clients" + response_one = base_client.get("/search?name=University of California") + response_two = base_client.get("/search?name=Stanfo") + + "Status Code" + assert response_one.status_code == 200 + assert response_two.status_code == 200 + + "Response" + response_one_body = response_one.json() + response_two_body = response_two.json() + response_one_body[0]["name"] == "University of California, Berkeley" + response_two_body[0]["name"] == "Stanford University" + + +def test_alpha_two_code(base_client): + "Clients" + response_one = base_client.get("/search?alpha_two_code=fr") + response_two = base_client.get("/search?alpha_two_code=de") + response_three = base_client.get("/search?alpha_two_code=gr") + response_four = base_client.get("/search?alpha_two_code=il") + + "Status Code" + assert response_one.status_code == 200 + assert response_two.status_code == 200 + assert response_three.status_code == 200 + assert response_four.status_code == 200 + + "Response" + response_one_body = response_one.json() + response_two_body = response_two.json() + response_three_body = response_three.json() + response_four_body = response_four.json() + response_one_body[0]["alpha_two_code"] == "France" + response_two_body[0]["alpha_two_code"] == "Deutschland" + response_three_body[0]["alpha_two_code"] == "Greece" + response_four_body[0]["alpha_two_code"] == "Isreal" diff --git a/tests/test_main.py b/tests/test_main.py deleted file mode 100644 index 31e2cec..0000000 --- a/tests/test_main.py +++ /dev/null @@ -1,136 +0,0 @@ -from fastapi.testclient import TestClient - -from app.main import app - -client = TestClient(app) - - -def test_home(): - "Clients" - response = client.get("/") - - "Status Code" - assert response.status_code == 200 - - "Response" - assert response.json() == {"Please go to docs.":"universitiesapi.herokuapp.com/docs"} - -async def test_country_and_name(): - "Clients" - response_one = client.get("/search?country=tur&name=saban") - response_two = client.get("/search?country=turkey&name=middle") - - "Status Code" - assert response_one.status_code == 200 - assert response_two.status_code == 200 - - "Response" - assert response_one.json() == [ - { - "name": "Sabanci University", - "alpha_two_code": "TR", - "country": "Turkey", - "web_pages": "http://www.sabanciuniv.edu.tr/http://www.sabanciuniv.edu/", - "domains": "sabanciuniv.edu.trsabanciuniv.edu", - "state_province": null - } - ] - assert response_two.json() == [ - { - "name": "Middle East Technical University", - "alpha_two_code": "TR", - "country": "Turkey", - "web_pages": "http://www.metu.edu.tr/", - "domains": "metu.edu.tr", - "state_province": null - } - ] - - -def test_alpha_two_code_and_name(): - "Clients" - response_one = client.get("/search?name=krako&alpha_two_code=pl") - response_two = client.get("/search?name=harva&alpha_two_code=us") - - "Status Code" - assert response_one.status_code == 200 - assert response_two.status_code == 200 - - "Response" - assert response_one.json() == [ - { - "name": "Pedagogical University of Krakow", - "alpha_two_code": "PL", - "country": "Poland", - "web_pages": "http://www.wsp.krakow.pl/", - "domains": "wsp.krakow.pl", - "state_province": null - } - ] - assert response_two.json() == [ - { - "name": "Harvard University", - "alpha_two_code": "US", - "country": "United States", - "web_pages": "http://www.harvard.edu/", - "domains": "harvard.edu", - "state_province": null - } - ] - -def test_country(): - "Clients" - response_one = client.get("/search?country=United States") - response_two = client.get("/search?country=russia") - - "Status Code" - assert response_one.status_code == 200 - assert response_two.status_code == 200 - - "Response" - response_one_body = response_one.json() - response_two_body = response_two.json() - response_one_body[0]['country'] == "United States" - response_two_body[0]['country'] == "Russian Federation" - - -def test_name(): - "Clients" - response_one = client.get("/search?name=University of California") - response_two = client.get("/search?name=Stanfo") - - "Status Code" - assert response_one.status_code == 200 - assert response_two.status_code == 200 - - "Response" - response_one_body = response_one.json() - response_two_body = response_two.json() - response_one_body[0]['name'] == "University of California, Berkeley" - response_two_body[0]['name'] == "Stanford University" - - - -def test_alpha_two_code(): - "Clients" - response_one = client.get("/search?alpha_two_code=fr") - response_two = client.get("/search?alpha_two_code=de") - response_three = client.get("/search?alpha_two_code=gr") - response_four = client.get("/search?alpha_two_code=il") - - - "Status Code" - assert response_one.status_code == 200 - assert response_two.status_code == 200 - assert response_three.status_code == 200 - assert response_four.status_code == 200 - - "Response" - response_one_body = response_one.json() - response_two_body = response_two.json() - response_three_body = response_three.json() - response_four_body = response_four.json() - response_one_body[0]['alpha_two_code'] == "France" - response_two_body[0]['alpha_two_code'] == "Deutschland" - response_three_body[0]['alpha_two_code'] == "Greece" - response_four_body[0]['alpha_two_code'] == "Isreal"