Skip to content

Commit

Permalink
Add mock API for testing purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
khwilson committed May 9, 2021
1 parent 6ad6256 commit e1f54fc
Show file tree
Hide file tree
Showing 8 changed files with 295 additions and 12 deletions.
221 changes: 220 additions & 1 deletion poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ isort = "^5.8.0"
mypy = "^0.812"
pytest = "^6.2.3"
python-dotenv = "^0.17.0"
fastapi = "^0.64.0"
uvicorn = {extras = ["standard"], version = "^0.13.4"}

[tool.poetry.scripts]
ipums = "ipumspy.cli:ipums_group"
Expand Down
16 changes: 9 additions & 7 deletions src/ipumspy/api/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,12 @@ def retrieve_previous_extracts(
collections = [collection]

# TODO: Wrap results in Extract objects.
return {
collection: self.get(
self.base_url,
params={"collection": collection, "limit": limit, "version": "v1"},
).json()
for collection in collections
}
output = {}
for collection in collections:
output.update(
self.get(
self.base_url,
params={"collection": collection, "limit": limit, "version": "v1"},
).json()
)
return output
1 change: 1 addition & 0 deletions src/ipumspy/api/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def __init__(self):
def __init_subclass__(cls, collection: str, **kwargs):
super().__init_subclass__(**kwargs)
cls.collection = collection
BaseExtract._collection_to_extract[collection] = cls

def build(self) -> Dict[str, Any]:
"""
Expand Down
2 changes: 1 addition & 1 deletion src/ipumspy/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,4 +347,4 @@ def convert_command(


if __name__ == "__main__":
ipums_group()
ipums_group()
Empty file added tests/__init__.py
Empty file.
37 changes: 37 additions & 0 deletions tests/mock_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os
from typing import Dict, Optional

from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel

load_dotenv(".env.test")

app = FastAPI()


class ExtractSpec(BaseModel):
description: str
data_format: str
data_structure: Dict[str, dict]
samples: Dict[str, dict]
variables: Dict[str, dict]


@app.post("/extracts")
async def submit_extract(
collection: str, extract: ExtractSpec, request: Request, version: str = "v1",
):
if request.headers["Authorization"] != os.environ.get("IPUMS_API_KEY"):
raise HTTPException(403, "Incorrect api key")
return {"number": 10}


@app.get("/extracts")
async def retrieve_previous_extracts(
collection: str, request: Request, limit: int = 10, version: str = "v1",
):
if request.headers["Authorization"] != os.environ.get("IPUMS_API_KEY"):
raise HTTPException(403, "Incorrect api key")

return {collection: list(range(10))}
28 changes: 25 additions & 3 deletions tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import os
import subprocess
import time

import pytest

from ipumspy.api import CpsExtract, IpumsApiClient, OtherExtract


@pytest.fixture(scope="module")
def mock_api() -> str:
# TODO: Would be good to randomly assign a port and return it
p = subprocess.Popen(
["uvicorn", "tests.mock_api:app", "--host", "127.0.0.1", "--port", "8989"]
)
time.sleep(1) # Give it enough time to warm up
try:
yield "http://127.0.0.1:8989/extracts"
finally:
p.kill()


@pytest.fixture(scope="function")
def api_client(environment_variables) -> IpumsApiClient:
return IpumsApiClient(os.environ.get("IPUMS_API_KEY"))
def api_client(environment_variables, mock_api: str) -> IpumsApiClient:
client = IpumsApiClient(os.environ.get("IPUMS_API_KEY"))
client.base_url = mock_api
return client


def test_cps_build_extract():
Expand All @@ -17,6 +34,7 @@ def test_cps_build_extract():
extract = CpsExtract(
["cps1976_01s", "cps1976_02b"], ["YEAR", "MISH", "AGE", "RACE", "UH_SEX_B1"],
)
assert extract.collection == "cps"
assert extract.build() == {
"data_structure": {"rectangular": {"on": "P"}},
"samples": {"cps1976_01s": {}, "cps1976_02b": {}},
Expand All @@ -42,10 +60,14 @@ def test_submit_extract(api_client: IpumsApiClient):
)

api_client.submit_extract(extract)
assert extract.extract_id is not None
assert extract.extract_id == 10


def test_retrieve_previous_extracts(api_client: IpumsApiClient):
previous = api_client.retrieve_previous_extracts(collection="cps")
assert "cps" in previous
assert len(previous["cps"]) == 10

previous = api_client.retrieve_previous_extracts()
assert "cps" in previous
assert len(previous["cps"]) == 10

0 comments on commit e1f54fc

Please sign in to comment.