Skip to content

Commit

Permalink
Bump fastapi[all] from 0.82.0 to 0.89.1 (#2246)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Thomas <[email protected]>
Co-authored-by: Thomas <[email protected]>
Co-authored-by: Adam Sachs <[email protected]>
  • Loading branch information
4 people authored Mar 6, 2023
1 parent be67604 commit 98663d3
Show file tree
Hide file tree
Showing 20 changed files with 105 additions and 97 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/backend_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ jobs:
matrix:
python_version: ["3.8.14", "3.9.14", "3.10.7"]
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 20
# In PRs run with the "unsafe" label, or run on a "push" event to main
if: contains(github.event.pull_request.labels.*.name, 'run unsafe ci checks') || github.event_name == 'push'
steps:
Expand Down Expand Up @@ -232,7 +232,7 @@ jobs:
matrix:
python_version: ["3.8.14", "3.9.14", "3.10.7"]
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 20
# In PRs run with the "unsafe" label, or run on a "push" event to main
if: contains(github.event.pull_request.labels.*.name, 'run unsafe ci checks') || github.event_name == 'push'
steps:
Expand Down Expand Up @@ -263,7 +263,7 @@ jobs:
External-SaaS-Connectors:
needs: Build
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 20
# In PRs run with the "unsafe" label, or run on a "push" event to main
if: contains(github.event.pull_request.labels.*.name, 'run unsafe ci checks') || github.event_name == 'push'
permissions:
Expand Down
6 changes: 2 additions & 4 deletions noxfiles/test_setup_nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ def pytest_ctl(session: Session, mark: str, coverage_arg: str) -> None:
"-f",
INTEGRATION_COMPOSE_FILE,
"up",
"-d",
"--wait",
IMAGE_NAME,
)
session.run(*start_command, external=True)
session.run(*LOGIN, external=True)
run_command = (
"docker",
"exec",
Expand All @@ -60,7 +61,6 @@ def pytest_ctl(session: Session, mark: str, coverage_arg: str) -> None:
"OKTA_CLIENT_TOKEN",
"-e",
"BIGQUERY_CONFIG",
"--rm",
CI_ARGS_EXEC,
CONTAINER_NAME,
"pytest",
Expand Down Expand Up @@ -123,7 +123,6 @@ def pytest_ops(session: Session, mark: str, coverage_arg: str) -> None:
"BIGQUERY_KEYFILE_CREDS",
"-e",
"BIGQUERY_DATASET",
"--rm",
CI_ARGS_EXEC,
CONTAINER_NAME,
"pytest",
Expand Down Expand Up @@ -154,7 +153,6 @@ def pytest_ops(session: Session, mark: str, coverage_arg: str) -> None:
"VAULT_NAMESPACE",
"-e",
"VAULT_TOKEN",
"--rm",
CI_ARGS_EXEC,
CONTAINER_NAME,
"pytest",
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ colorama>=0.4.3
cryptography==38.0.3
dask==2022.9.2
deepdiff==5.8.1
fastapi[all]==0.82.0
fastapi[all]==0.89.1
fastapi-caching[redis]==0.3.0
fastapi-pagination[sqlalchemy]~= 0.10.0
fideslang==1.3.3
Expand Down
1 change: 1 addition & 0 deletions src/fides/api/ops/api/v1/endpoints/connection_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ def patch_connections(
CONNECTION_BY_KEY,
dependencies=[Security(verify_oauth_client, scopes=[CONNECTION_DELETE])],
status_code=HTTP_204_NO_CONTENT,
response_model=None,
)
def delete_connection(
connection_key: FidesKey, *, db: Session = Depends(deps.get_db)
Expand Down
1 change: 1 addition & 0 deletions src/fides/api/ops/api/v1/endpoints/user_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def update_user_password(
urls.USER_FORCE_PASSWORD_RESET,
dependencies=[Security(verify_oauth_client, scopes=[USER_PASSWORD_RESET])],
status_code=HTTP_200_OK,
response_model=UserResponse,
)
def force_update_password(
*,
Expand Down
42 changes: 24 additions & 18 deletions src/fides/api/ops/service/connectors/fides/fides_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

from typing import Any, Dict, List, Optional

import requests
from httpx import AsyncClient
import httpx
from httpx import AsyncClient, Client, HTTPStatusError, Request, RequestError, Timeout
from loguru import logger
from requests import PreparedRequest, Request, RequestException, Session

from fides.api.ctl.utils.errors import FidesError
from fides.api.ops.api.v1 import urn_registry as urls
Expand All @@ -32,16 +31,20 @@

class FidesClient:
"""
A helper client class to broker communications between Fides servers.
A helper client to broker communications between Fides servers.
"""

def __init__(
self,
uri: str,
username: str,
password: str,
connection_read_timeout: float = 30.0,
):
self.session = Session()
# Enable setting a custom `read` timeout
# to account for privacy request executions
self.session = Client(timeout=Timeout(5.0, read=connection_read_timeout))

self.uri = uri
self.username = username
self.password = password
Expand All @@ -55,14 +58,14 @@ def login(self) -> None:
self.username,
)
try:
response = requests.post(
response = httpx.post(
f"{self.uri}{urls.V1_URL_PREFIX}{urls.LOGIN}", json=ul.dict()
)
except RequestException as e:
except RequestError as e:
logger.error("Error logging in on remote Fides {}: {}", self.uri, str(e))
raise e

if response.ok:
if response.is_success:
self.token = response.json()["token_data"]["access_token"]
logger.info(
"Successfully logged in to remote fides {} with username '{}'",
Expand All @@ -81,21 +84,21 @@ def authenticated_request(
query_params: Optional[Dict[str, Any]] = {},
data: Optional[Any] = None,
json: Optional[Any] = None,
) -> PreparedRequest:
) -> Request:

if not self.token:
raise FidesError(
f"Unable to create authenticated request. No token for Fides connector for server {self.uri}"
)

req: PreparedRequest = Request(
req: Request = self.session.build_request(
method=method,
url=f"{self.uri}{path}",
headers=headers,
params=query_params,
data=data,
json=json,
).prepare()
)
req.headers["Authorization"] = f"Bearer {self.token}"
return req

Expand All @@ -117,15 +120,17 @@ def create_privacy_request(
external_id,
self.uri,
)
request: PreparedRequest = self.authenticated_request(
request: Request = self.authenticated_request(
method="POST",
path=urls.V1_URL_PREFIX + urls.PRIVACY_REQUEST_AUTHENTICATED,
json=[pr.dict()],
)
response = self.session.send(request)
if not response.ok:

if not response.is_success:
logger.error("Error creating privacy request on remote Fides {}", self.uri)
response.raise_for_status()

if response.json()["failed"]:
# TODO better handle errored state here?
raise FidesError(
Expand Down Expand Up @@ -199,7 +204,7 @@ async def poll_for_request_completion(
f"Privacy request [{privacy_request_id}] on remote Fides {self.uri} is in an unknown state. Look at the remote Fides for more information."
)

def request_status(self, privacy_request_id: str = None) -> List[Dict[str, Any]]:
def request_status(self, privacy_request_id: str = "") -> List[Dict[str, Any]]:
"""
Return privacy request object that tracks its status
"""
Expand All @@ -215,15 +220,16 @@ def request_status(self, privacy_request_id: str = None) -> List[Dict[str, Any]]
self.uri,
)

request: PreparedRequest = self.authenticated_request(
request: Request = self.authenticated_request(
method="GET",
path=urls.V1_URL_PREFIX + urls.PRIVACY_REQUESTS,
query_params={"request_id": privacy_request_id}
if privacy_request_id
else None,
)
response = self.session.send(request, timeout=5)
if not response.ok:
response = self.session.send(request)

if not response.is_success:
logger.error(
"Error retrieving status of privacy request [{}] on remote Fides {}",
privacy_request_id,
Expand Down Expand Up @@ -266,7 +272,7 @@ def retrieve_request_results(
headers={"Authorization": f"Bearer {self.token}"},
)
response = self.session.send(request)
except requests.exceptions.HTTPError as e:
except HTTPStatusError as e:
logger.error(
"Error retrieving data from child server for privacy request {}: {}",
privacy_request_id,
Expand Down
7 changes: 7 additions & 0 deletions src/fides/api/ops/service/connectors/fides_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,18 @@ def query_config(self, node: TraversalNode) -> QueryConfig[Any]:
def create_client(self) -> FidesClient:
"""Returns a client used to connect to a Fides instance"""
config = FidesConnectorSchema(**self.configuration.secrets or {})

# use polling_timeout here to provide a base read timeout
# on the HTTP client underlying the FidesClient, since even
# in non-polling context, we may hit a blocking HTTP call
# e.g., in privacy request creation we can block until completion
client = FidesClient(
uri=config.uri,
username=config.username,
password=config.password,
connection_read_timeout=self.polling_timeout,
)

client.login()
return client

Expand Down
9 changes: 7 additions & 2 deletions src/fides/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ def check_server_health(server_url: str, verbose: bool = True) -> requests.Respo
return health_response


def compare_application_versions(server_version: str, cli_version: str) -> bool:
"""Normalize and compare application versions."""
normalize_version = lambda v: str(v).replace(".dirty", "", 1)
return normalize_version(server_version) == normalize_version(cli_version)


def check_server(cli_version: str, server_url: str, quiet: bool = False) -> None:
"""Runs a health check and a version check against the server."""

Expand All @@ -82,8 +88,7 @@ def check_server(cli_version: str, server_url: str, quiet: bool = False) -> None
raise SystemExit(1)

server_version = health_response.json()["version"]
normalize_version = lambda v: str(v).replace(".dirty", "", 1)
if normalize_version(server_version) == normalize_version(cli_version):
if compare_application_versions(server_version, cli_version):
if not quiet:
echo_green(
"Server is reachable and the client/server application versions match."
Expand Down
4 changes: 3 additions & 1 deletion src/fides/lib/oauth/schemas/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def __init__(
)

async def __call__(self, request: Request) -> Optional[str]:
authorization: str = request.headers.get("Authorization")
authorization: Optional[str] = request.headers.get("Authorization")
if not authorization:
raise InvalidAuthorizationSchemeError()
scheme, param = get_authorization_scheme_param(authorization)
if not authorization or scheme.lower() != "bearer":
if self.auto_error:
Expand Down
33 changes: 10 additions & 23 deletions tests/ctl/cli/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

import click
import pytest
from requests_mock import Mocker

import fides.cli.utils as utils
from fides.core.config import FidesConfig, get_config
from fides.core.config import FidesConfig
from tests.ctl.conftest import orig_requests_get


Expand All @@ -24,42 +23,30 @@ def test_check_server_bad_ping(test_client, monkeypatch) -> None:

@pytest.mark.unit
@pytest.mark.parametrize(
"server_version, cli_version, expected_output, quiet",
"server_version, cli_version, expected_result",
[
("1.6.0+7.ge953df5", "1.6.0+7.ge953df5", "application versions match", False),
("1.6.0+7.ge953df5", "1.6.0+9.ge953df5", "Mismatched versions!", False),
("1.6.0+7.ge953df5", "1.6.0+7.ge953df5", True),
("1.6.0+7.ge953df5", "1.6.0+9.ge953df5", False),
(
"1.6.0+7.ge953df5",
"1.6.0+7.ge953df5.dirty",
"application versions match",
False,
True,
),
(
"1.6.0+7.ge953df5.dirty",
"1.6.0+7.ge953df5",
"application versions match",
False,
True,
),
("1.6.0+7.ge953df5", "1.6.0+7.ge953df5.dirty", None, True),
],
)
def test_check_server_version_comparisons(
requests_mock: Mocker,
capsys: pytest.CaptureFixture,
server_version: str,
cli_version: str,
expected_output: str,
quiet: bool,
expected_result: str,
) -> None:
"""Check that comparing versions works"""
fake_url = "http://fake_address:8080"
requests_mock.get(f"{fake_url}/health", json={"version": server_version})
utils.check_server(cli_version, "http://fake_address:8080", quiet=quiet)
captured = capsys.readouterr()
if expected_output is None:
assert captured.out == ""
else:
assert expected_output in captured.out
"""Check that version comparison works."""
actual_result = utils.compare_application_versions(server_version, cli_version)
assert expected_result == actual_result


@pytest.mark.unit
Expand Down
14 changes: 9 additions & 5 deletions tests/ctl/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,22 @@

@pytest.fixture(scope="session")
def monkeysession():
"""monkeypatch fixture at the session level instead of the function level"""
"""
Monkeypatch at the session level instead of the function level.
Automatically undoes the monkeypatching when the session finishes.
"""
mpatch = MonkeyPatch()
yield mpatch
mpatch.undo()


@pytest.fixture(autouse=True, scope="session")
def monkeypatch_requests(test_client, monkeysession) -> None:
"""The requests library makes requests against the running webserver
which talks to the application db. This monkeypatching operation
makes `requests` calls from src/fides/core/api.py in a test
context talk to the test db instead"""
"""
Some places within the application, for example `fides.core.api`, use the `requests`
library to interact with the webserver. This fixture patches those `requests` calls
so that all of those tests instead interact with the test instance.
"""
monkeysession.setattr(requests, "get", test_client.get)
monkeysession.setattr(requests, "post", test_client.post)
monkeysession.setattr(requests, "put", test_client.put)
Expand Down
4 changes: 4 additions & 0 deletions tests/fixtures/application_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
"uri": pydash.get(integration_config, "fides_example.uri"),
"username": pydash.get(integration_config, "fides_example.username"),
"password": pydash.get(integration_config, "fides_example.password"),
"polling_timeout": pydash.get(
integration_config, "fides_example.polling_timeout"
),
},
}

Expand Down Expand Up @@ -1604,6 +1607,7 @@ def test_fides_client(
fides_connector_example_secrets["uri"],
fides_connector_example_secrets["username"],
fides_connector_example_secrets["password"],
fides_connector_example_secrets["polling_timeout"]
)


Expand Down
3 changes: 2 additions & 1 deletion tests/ops/api/v1/endpoints/test_config_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ def test_get_application_config(

# then we test that we can GET them
auth_header = generate_auth_header([scopes.CONFIG_READ])
response = api_client.get(
response = api_client.request(
"GET",
url,
headers=auth_header,
params={"api_set": True},
Expand Down
Loading

0 comments on commit 98663d3

Please sign in to comment.