Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
eugene-kulak committed Feb 4, 2022
1 parent 8812763 commit 16b7dc1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ def __init__(self, api: FacebookAdsApi, interval: pendulum.Period):
self._attempt_number = 1

@property
def key(self) -> str:
def key(self) -> Any:
"""Job identifier, in most cases start of the interval"""
return str(self._interval.start.date())
return self._interval.start

@abstractmethod
def start(self):
Expand Down Expand Up @@ -176,20 +176,18 @@ def split_job(self) -> "AsyncJob":
"""
campaign_params = dict(copy.deepcopy(self._params))
# get campaigns from attribution window as well (28 day + 1 current day)
new_start = self._interval.start.date() - pendulum.duration(days=28 + 1)
new_start = self._interval.start - pendulum.duration(days=28 + 1)
campaign_params.update(fields=["campaign_id"], level="campaign")
campaign_params["time_range"].update(since=new_start.to_date_string())
campaign_params.pop("time_increment") # query all days
result = self._edge_object.get_insights(params=campaign_params)
campaign_ids = set(row["campaign_id"] for row in result)
logger.info(
"Got %(num)s campaigns for period %(period)s: %(campaign_ids)s",
num=len(campaign_ids),
period=self._params["time_range"],
campaign_ids=campaign_ids,
)

jobs = [InsightAsyncJob(api=self._api, edge_object=Campaign(pk), params=self._params) for pk in campaign_ids]
logger.info(f"Got {len(campaign_ids)} campaigns for period {self._interval}: {campaign_ids}")

jobs = [
InsightAsyncJob(api=self._api, edge_object=Campaign(pk), params=self._params, interval=self._interval)
for pk in campaign_ids
]
return ParentAsyncJob(api=self._api, interval=self._interval, jobs=jobs)

def start(self):
Expand All @@ -199,13 +197,7 @@ def start(self):

self._job = self._edge_object.get_insights(params=self._params, is_async=True)
self._start_time = pendulum.now()
logger.info(
"Created AdReportRun: %(job_id)s to sync insights %(time_range)s with breakdown %(breakdowns)s for %(obj)s",
job_id=self._job["report_run_id"],
time_range=self._params["time_range"],
breakdowns=self._params["breakdowns"],
obj=self._edge_object,
)
logger.info(f"{self}: created AdReportRun")

def restart(self):
"""Restart failed job"""
Expand All @@ -218,7 +210,7 @@ def restart(self):
self._finish_time = None
self._attempt_number += 1
self.start()
logger.info("%s: restarted", self)
logger.info(f"{self}: restarted.")

@property
def elapsed_time(self) -> Optional[pendulum.duration]:
Expand Down Expand Up @@ -250,20 +242,17 @@ def _batch_success_handler(self, response: FacebookResponse):

def _batch_failure_handler(self, response: FacebookResponse):
"""Update job status from response"""
logger.info("Request failed with response: %s", response.body())
logger.info(f"{self}: Request failed with response: {response.body()}.")

def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
"""Method to retrieve job's status, separated because of retry handler"""
if not self._job:
raise RuntimeError(f"{self}: Incorrect usage of the method - the job is not started")

if self.completed:
logger.info(
"%(job)s is %(percent)s complete (%(status)s)",
job=self,
percent=self._job["async_percent_completion"],
status=self._job["async_status"],
)
job_status = self._job["async_status"]
percent = self._job["async_percent_completion"]
logger.info(f"{self}: is {percent} complete ({job_status})")
# No need to update job status if its already completed
return

Expand All @@ -279,25 +268,16 @@ def _check_status(self) -> bool:
:return: True if the job is completed, False - if the job is still running
"""
job_status = self._job["async_status"]
logger.info(
"%(job)s is %(percent)s complete (%(status)s)",
job=self,
percent=self._job["async_percent_completion"],
status=job_status,
)
percent = self._job["async_percent_completion"]
logger.info(f"{self}: is {percent} complete ({job_status})")

if job_status == Status.COMPLETED:
self._finish_time = pendulum.now() # TODO: is not actual running time, but interval between check_status calls
return True
elif job_status in [Status.FAILED, Status.SKIPPED]:
self._finish_time = pendulum.now()
self._failed = True
logger.info(
"%(job)s has status %(status)s after %(elapsed)s seconds.",
job=self,
status=job_status,
elapsed=self.elapsed_time.in_seconds(),
)
logger.info(f"{self}: has status {job_status} after {self.elapsed_time.in_seconds()} seconds.")
return True

return False
Expand All @@ -311,6 +291,5 @@ def get_result(self) -> Any:
def __str__(self) -> str:
"""String representation of the job wrapper."""
job_id = self._job["report_run_id"] if self._job else "<None>"
time_range = self._params["time_range"]
breakdowns = self._params["breakdowns"]
return f"InsightAsyncJob(id={job_id}, {self._edge_object}, time_range={time_range}, breakdowns={breakdowns}"
return f"InsightAsyncJob(id={job_id}, {self._edge_object}, time_range={self._interval}, breakdowns={breakdowns})"
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def _generate_async_jobs(self, params: Mapping) -> Iterator[AsyncJob]:
if ts_start in self._completed_slices:
continue
ts_end = ts_start + pendulum.duration(days=self.time_increment - 1)
interval = pendulum.Period(ts_start, ts_end.date())
interval = pendulum.Period(ts_start, ts_end)
yield InsightAsyncJob(api=self._api.api, edge_object=self._api.account, interval=interval, params=params)

def stream_slices(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import Iterator
from unittest.mock import call

import pendulum
import pytest
from facebook_business.adobjects.adreportrun import AdReportRun
from facebook_business.api import FacebookAdsApiBatch
Expand Down Expand Up @@ -38,23 +39,21 @@ def job_fixture(api, account, mocker):
"fields": ["field1", "field2"],
"time_increment": 1,
"action_attribution_windows": [],
"time_range": {
"since": "2019-01-01",
"until": "2019-01-01",
},
}
interval = pendulum.Period(pendulum.Date(2019, 1, 1), pendulum.Date(2019, 1, 1))

return InsightAsyncJob(edge_object=account, api=api, params=params)
return InsightAsyncJob(edge_object=account, api=api, interval=interval, params=params)


@pytest.fixture(name="grouped_jobs")
def grouped_jobs_fixture(mocker):
return [mocker.Mock(spec=InsightAsyncJob, restart_number=0, failed=False, completed=False) for _ in range(10)]
return [mocker.Mock(spec=InsightAsyncJob, attempt_number=1, failed=False, completed=False) for _ in range(10)]


@pytest.fixture(name="parent_job")
def parent_job_fixture(api, grouped_jobs):
return ParentAsyncJob(api=api, jobs=grouped_jobs)
interval = pendulum.Period(pendulum.Date(2019, 1, 1), pendulum.Date(2019, 1, 1))
return ParentAsyncJob(api=api, jobs=grouped_jobs, interval=interval)


@pytest.fixture(name="started_job")
Expand Down Expand Up @@ -121,12 +120,12 @@ def test_start_already_started(self, job):
job.start()

def test_restart(self, failed_job, api, adreport):
assert failed_job.restart_number == 0
assert failed_job.attempt_number == 1

failed_job.restart()

assert not failed_job.failed, "restart should reset fail flag"
assert failed_job.restart_number == 1
assert failed_job.attempt_number == 2

def test_restart_when_job_not_failed(self, job, api):
job.start()
Expand Down Expand Up @@ -220,9 +219,12 @@ def test_failed_yes(self, failed_job):
assert failed_job.failed, "should return True if the job previously failed"

def test_str(self, api, account):
job = InsightAsyncJob(edge_object=account, api=api, params={"time_range": 123, "breakdowns": [10, 20]})
interval = pendulum.Period(pendulum.Date(2010, 1, 1), pendulum.Date(2011, 1, 1))
job = InsightAsyncJob(
edge_object=account, api=api, params={"breakdowns": [10, 20]}, interval=interval,
)

assert str(job) == f"AdReportRun(id=<None>, {account}, time_range=123, breakdowns=[10, 20]"
assert str(job) == f"InsightAsyncJob(id=<None>, {account}, time_range=<Period [2010-01-01 -> 2011-01-01]>, breakdowns=[10, 20])"

def test_get_result(self, job, adreport):
job.start()
Expand All @@ -233,11 +235,11 @@ def test_get_result(self, job, adreport):
assert result == adreport.get_result.return_value, "should return result from job"

def test_get_result_when_job_is_not_started(self, job):
with pytest.raises(RuntimeError, match=r"Incorrect usage of get_result - the job is not started of failed"):
with pytest.raises(RuntimeError, match=r"Incorrect usage of get_result - the job is not started or failed"):
job.get_result()

def test_get_result_when_job_is_failed(self, failed_job):
with pytest.raises(RuntimeError, match=r"Incorrect usage of get_result - the job is not started of failed"):
with pytest.raises(RuntimeError, match=r"Incorrect usage of get_result - the job is not started or failed"):
failed_job.get_result()

def test_split_job(self, job, account, mocker, api):
Expand All @@ -251,8 +253,7 @@ def test_split_job(self, job, account, mocker, api):
campaign_mock.assert_has_calls([call(1), call(2), call(3)])
assert parent_job_mock.called
assert parent_job
args, kwargs = parent_job_mock.call_args
assert args == (api,)
_args, kwargs = parent_job_mock.call_args
assert len(kwargs["jobs"]) == 3, "number of jobs should match number of campaigns"


Expand All @@ -267,15 +268,15 @@ def test_restart(self, parent_job, grouped_jobs):

# fail some jobs
grouped_jobs[0].failed = True
grouped_jobs[0].restart_number = 1
grouped_jobs[0].attempt_number = 2
grouped_jobs[5].failed = True
grouped_jobs[0].restart_number = 1
grouped_jobs[6].restart_number = 3
grouped_jobs[0].attempt_number = 2
grouped_jobs[6].attempt_number = 3

assert parent_job.failed, "should be failed if any job failed"
parent_job.restart()
assert parent_job.failed
assert parent_job.restart_number == 3, "restart should be max value of all jobs"
assert parent_job.attempt_number == 3, "restart should be max value of all jobs"

def test_completed(self, parent_job, grouped_jobs):
assert not parent_job.completed, "initially not completed"
Expand Down

1 comment on commit 16b7dc1

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SonarQube Report

SonarQube report for Airbyte Connectors Source Facebook Marketing(#9805)

Measures

Name Value Name Value Name Value
Lines of Code 1725 Bugs 1 Code Smells 16
Quality Gate Status ERROR Lines to Cover 227 Reliability Rating B
Coverage 25.6 Vulnerabilities 0 Duplicated Lines (%) 6.1
Security Rating A Duplicated Blocks 2 Blocker Issues 0
Critical Issues 2 Major Issues 22 Minor Issues 176

Detected Issues

Rule File Description Message
python:black_need_format (MINOR) streams/async_job.py Please run one of the commands: "black --config ./pyproject.toml <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/async_job.py:280 Check that attribute exists pendulum.duration? has no attribute "in_seconds" . Code line: ...er.info(f"{self}: has status {job_status} after {self.elapsed_time.in_...
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py:161 Check that attribute exists Module has no attribute "Period"; maybe "period"? . Code line: interval = pendulum.Period(ts_start, ts_end)
python:black_need_format (MINOR) unit_tests/test_async_job.py Please run one of the commands: "black --config ./pyproject.toml <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py Check that attribute exists Module has no attribute "Period"; maybe "period"? . Code line: interval = pendulum.Period(ts_start, ts_end.date())
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S1226 (MINOR) streams/async_job.py:125 Function parameters initial values should not be ignored Introduce a new variable or use its initial value before reassigning 'batch'.
python:mypy_attr_defined (MINOR) streams/async_job.py Check that attribute exists pendulum.duration? has no attribute "in_seconds" . Code line: elapsed=self.elapsed_time.in_seconds(),
python:black_need_format (MINOR) streams/async_job.py Please run one of the commands: "black --config ./pyproject.toml <path_to_updated_folder>" or "./gradlew format" 6 code part(s) should be updated.
python:isort_need_format (MINOR) streams/async_job.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "num" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "period" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "campaign_ids" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "job" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "percent" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "status" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "job" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "percent" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "status" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "job" for "info" of "Logger" . Code line: logger.info(
python:mypy_attr_defined (MINOR) streams/async_job.py Check that attribute exists pendulum.duration? has no attribute "in_seconds" . Code line: ... job=self, status=job_status, elapsed=self.elapsed_time.in_...
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "status" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "elapsed" for "info" of "Logger" . Code line: logger.info(
flake8:E251 (MAJOR) streams/async_job.py unexpected spaces around keyword / parameter equals unexpected spaces around keyword / parameter equals
flake8:E251 (MAJOR) streams/async_job.py unexpected spaces around keyword / parameter equals unexpected spaces around keyword / parameter equals
python:mypy_no_untyped_def (MINOR) streams/async_job.py:65 Check that every function has an annotation Function is missing a return type annotation . Code line: def attempt_number(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:80 Check that every function has an annotation Function is missing a return type annotation . Code line: def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:98 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, jobs: List[AsyncJob], **kwargs):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:125 Check that every function has an annotation Function is missing a return type annotation . Code line: def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:153 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, edge_object: Union[AdAccount, Campaign], params...
python:mypy_arg_type (MINOR) streams/async_job.py:191 Check argument types in calls Argument "jobs" to "ParentAsyncJob" has incompatible type "List[InsightAsyncJob]"; expected "List[AsyncJob]" . Code line: ...turn ParentAsyncJob(api=self._api, interval=self._interval, jobs=jobs)
python:isort_need_format (MINOR) streams/async_job_manager.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py:123 Check that every function has an annotation Function is missing a return type annotation . Code line: def state(self, value: Mapping[str, Any]):
python:mypy_no_untyped_def (MINOR) streams/async_job_manager.py:88 Check that every function has an annotation Function is missing a return type annotation . Code line: def _check_jobs_status(self):
python:isort_need_format (MINOR) unit_tests/test_base_insight_streams.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def stream_slices(
python:mypy_name_defined (MINOR) streams/base_insight_streams.py:129 Check that name is defined Function is missing a return type annotation [no-untyped-def] def get_updated_state(self, current_stream_state: MutableMapping[s...
python:mypy_name_defined (MINOR) streams/base_insight_streams.py:181 Check that name is defined Incompatible types in assignment (expression has type "Mapping[str, Any]", variable has type "MutableMapping[str, Any]") [assignment] self.state = stream_state
python:mypy_misc (MINOR) source_facebook_marketing/spec.py:18 Miscellaneous other checks Enum() expects a string, tuple, list or dict literal as the second argument . Code line: ValidFields = Enum("ValidEnums", AdsInsights.Field.dict)
python:mypy_misc (MINOR) source_facebook_marketing/spec.py:19 Miscellaneous other checks Enum() expects a string, tuple, list or dict literal as the second argument . Code line: ValidBreakdowns = Enum("ValidBreakdowns", AdsInsights.Breakdowns.__dic...
python:mypy_misc (MINOR) source_facebook_marketing/spec.py:20 Miscellaneous other checks Enum() expects a string, tuple, list or dict literal as the second argument . Code line: ValidActionBreakdowns = Enum("ValidActionBreakdowns", AdsInsights.Acti...
python:isort_need_format (MINOR) streams/base_insight_streams.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 2 code part(s) should be updated.
python:isort_need_format (MINOR) unit_tests/test_async_job.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:isort_need_format (MINOR) unit_tests/test_source.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:isort_need_format (MINOR) integration_tests/test_streams.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:isort_need_format (MINOR) source_facebook_marketing/source.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_no_untyped_def (MINOR) streams/async_job.py:57 Check that every function has an annotation Function is missing a return type annotation . Code line: def start(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:103 Check that every function has an annotation Function is missing a return type annotation . Code line: def start(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:193 Check that every function has an annotation Function is missing a return type annotation . Code line: def start(self):
python:isort_need_format (MINOR) unit_tests/test_client.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/init.py:5 Check that attribute exists Module "source_facebook_marketing.streams.streams" does not explicitly export attribute "AdsInsights"; implicit reexport disabled . Code line: from .streams import (
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:40 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, api: "API", include_deleted: bool = False, **kw...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:50 Check that every function has an annotation Function is missing a type annotation . Code line: def _execute_batch(self, batch):
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:61 Check that every function has an annotation Function is missing a return type annotation . Code line: def success(response: FacebookResponse):
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:64 Check that every function has an annotation Function is missing a return type annotation . Code line: def failure(response: FacebookResponse):
python:S1134 (MAJOR) streams/base_streams.py:65 Track uses of "FIXME" tags Take the required action to fix the issue indicated by this "FIXME" comment.
python:mypy_no_redef (MINOR) streams/base_streams.py:74 Check that each name is defined once Name "api_batch" already defined on line 68 . Code line: api_batch: FacebookAdsApiBatch = self._api.api.new_bat...
python:mypy_assignment (MINOR) streams/base_streams.py:91 Check that assigned value is compatible with target Incompatible types in assignment (expression has type "Iterable[MutableMapping[str, Any]]", variable has type "Generator[Any, None, None]") . Code line: loaded_records_iter = self.execute_in_batch(loaded_records...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:105 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def request_params(self, **kwargs) -> MutableMapping[str, Any]:
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:143 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, start_date: datetime, end_date: datetime, **kwa...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:148 Check that every function has an annotation Function is missing a return type annotation . Code line: def get_updated_state(self, current_stream_state: MutableMapping[s...
python:mypy_attr_defined (MINOR) streams/base_streams.py:153 Check that attribute exists Module has no attribute "parse" . Code line: max_cursor = max(pendulum.parse(state_value), pendulum.parse(r...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:162 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def request_params(self, stream_state: Mapping[str, Any], **kwargs...
python:mypy_override (MINOR) streams/base_streams.py:162 Check that method override is compatible with base class Signature of "request_params" incompatible with supertype "FBMarketingStream" . Code line: def request_params(self, stream_state: Mapping[str, Any], **kwargs...
python:mypy_no_any_return (MINOR) streams/base_streams.py:166 Reject returning value with "Any" type if return type is not "Any" Returning Any from function declared to return "MutableMapping[str, Any]" . Code line: return params
python:mypy_attr_defined (MINOR) streams/base_streams.py:171 Check that attribute exists Module has no attribute "parse" . Code line: ...value = self.start_date if not state_value else pendulum.parse(state...
python:mypy_var_annotated (MINOR) streams/streams.py:130 Require variable annotation if type can't be inferred Need type annotation for "breakdowns" (hint: "breakdowns: List[] = ...") . Code line: breakdowns = []
python:mypy_override (MINOR) streams/base_insight_streams.py:86 Check that method override is compatible with base class Signature of "primary_key" incompatible with supertype "FBMarketingStream" . Code line: def primary_key(self) -> Optional[Union[str, List[str], List[List[...
python:mypy_no_untyped_def (MINOR) streams/async_job_manager.py:49 Check that every function has an annotation Function is missing a return type annotation . Code line: def _start_jobs(self):
python:isort_need_format (MINOR) unit_tests/test_async_job_manager.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_index (MINOR) streams/streams.py:61 Check indexing operations Unsupported target for indexed assignment ("Mapping[str, Any]") . Code line: record["thumbnail_data_url"] = fetch_thumbnail_data_ur...
python:isort_need_format (MINOR) source_facebook_marketing/api.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py:125 Check that attribute exists Module has no attribute "parse" . Code line: self._cursor_value = pendulum.parse(value[self.cursor_field])....
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py:126 Check that attribute exists Module has no attribute "parse" . Code line: self._completed_slices = set(pendulum.parse(v).date() for v in...
python:mypy_no_any_return (MINOR) streams/base_insight_streams.py:139 Reject returning value with "Any" type if return type is not "Any" Returning Any from function declared to return "Iterator[Any]" . Code line: return date_range.range("days", self.time_increment)
python:mypy_no_untyped_def (MINOR) source_facebook_marketing/api.py:106 Check that every function has an annotation Function is missing a return type annotation . Code line: def _update_insights_throttle_limit(self, response: FacebookRespon...
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a type annotation . Code line: def chunks(data, n):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a return type annotation . Code line: def restart_number(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, api, jobs: List[AsyncJob]):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a return type annotation . Code line: def restart_number(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, api, edge_object: Any, params: Mapping[str, Any...
python:mypy_attr_defined (MINOR) streams/async_job.py Check that attribute exists Module has no attribute "parse" . Code line: new_start = pendulum.parse(self._params["time_range"]["since"]...
python:mypy_valid_type (MINOR) streams/async_job.py Check that type (annotation) is valid Function is missing a return type annotation [no-untyped-def] def restart_number(self):
flake8:E203 (MAJOR) streams/async_job.py:24 whitespace before ‘:’ whitespace before ':'
python:mypy_no_untyped_def (MINOR) streams/async_job.py:247 Check that every function has an annotation Function is missing a return type annotation . Code line: def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
python:S3776 (CRITICAL) streams/async_job_manager.py Cognitive Complexity of functions should not be too high Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed.
python:S112 (MAJOR) streams/async_job_manager.py "Exception" and "BaseException" should not be raised Replace this generic exception class with a more specific one.
python:mypy_var_annotated (MINOR) streams/async_job_manager.py:47 Require variable annotation if type can't be inferred Need type annotation for "_running_jobs" (hint: "_running_jobs: List[] = ...") . Code line: self._running_jobs = []
python:mypy_name_defined (MINOR) streams/base_insight_streams.py Check that name is defined Function is missing a type annotation for one or more arguments [no-untyped-def] def stream_slices(self, **kwargs) -> Iterable[Optional[Mapping[str...
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py Check that every function has an annotation Function is missing a return type annotation . Code line: def state(self, value: MutableMapping[str, Any]):
python:mypy_misc (MINOR) streams/base_insight_streams.py Miscellaneous other checks "InsightAsyncJob" gets multiple values for keyword argument "edge_object" . Code line: yield InsightAsyncJob(self._api.api, edge_object=self._api...
python:mypy_var_annotated (MINOR) streams/base_insight_streams.py:77 Require variable annotation if type can't be inferred Need type annotation for "_completed_slices" (hint: "_completed_slices: Set[] = ...") . Code line: self._completed_slices = set()
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py:141 Check that every function has an annotation Function is missing a return type annotation . Code line: def _advance_cursor(self):
python:S1134 (MAJOR) streams/base_insight_streams.py:206 Track uses of "FIXME" tags Take the required action to fix the issue indicated by this "FIXME" comment.
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py:219 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def request_params(self, **kwargs) -> MutableMapping[str, Any]:
python:mypy_override (MINOR) streams/base_insight_streams.py:219 Check that method override is compatible with base class Signature of "request_params" incompatible with supertype "FBMarketingIncrementalStream" . Code line: def request_params(self, **kwargs) -> MutableMapping[str, Any]:
python:black_need_format (MINOR) streams/async_job.py Please run one of the commands: "black --config ./pyproject.toml <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/async_job.py:280 Check that attribute exists pendulum.duration? has no attribute "in_seconds" . Code line: ...er.info(f"{self}: has status {job_status} after {self.elapsed_time.in_...
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py:161 Check that attribute exists Module has no attribute "Period"; maybe "period"? . Code line: interval = pendulum.Period(ts_start, ts_end)
python:black_need_format (MINOR) unit_tests/test_async_job.py Please run one of the commands: "black --config ./pyproject.toml <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py Check that attribute exists Module has no attribute "Period"; maybe "period"? . Code line: interval = pendulum.Period(ts_start, ts_end.date())
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S3457 (MAJOR) streams/async_job.py String formatting should be used correctly Add argument(s) corresponding to the message's replacement field(s).
python:S1226 (MINOR) streams/async_job.py:125 Function parameters initial values should not be ignored Introduce a new variable or use its initial value before reassigning 'batch'.
python:mypy_attr_defined (MINOR) streams/async_job.py Check that attribute exists pendulum.duration? has no attribute "in_seconds" . Code line: elapsed=self.elapsed_time.in_seconds(),
python:black_need_format (MINOR) streams/async_job.py Please run one of the commands: "black --config ./pyproject.toml <path_to_updated_folder>" or "./gradlew format" 6 code part(s) should be updated.
python:isort_need_format (MINOR) streams/async_job.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "num" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "period" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "campaign_ids" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "job" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "percent" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "status" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "job" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "percent" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "status" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "job" for "info" of "Logger" . Code line: logger.info(
python:mypy_attr_defined (MINOR) streams/async_job.py Check that attribute exists pendulum.duration? has no attribute "in_seconds" . Code line: ... job=self, status=job_status, elapsed=self.elapsed_time.in_...
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "status" for "info" of "Logger" . Code line: logger.info(
python:mypy_call_arg (MINOR) streams/async_job.py Check number, names and kinds of arguments in calls Unexpected keyword argument "elapsed" for "info" of "Logger" . Code line: logger.info(
flake8:E251 (MAJOR) streams/async_job.py unexpected spaces around keyword / parameter equals unexpected spaces around keyword / parameter equals
flake8:E251 (MAJOR) streams/async_job.py unexpected spaces around keyword / parameter equals unexpected spaces around keyword / parameter equals
python:mypy_no_untyped_def (MINOR) streams/async_job.py:65 Check that every function has an annotation Function is missing a return type annotation . Code line: def attempt_number(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:80 Check that every function has an annotation Function is missing a return type annotation . Code line: def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:98 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, jobs: List[AsyncJob], **kwargs):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:125 Check that every function has an annotation Function is missing a return type annotation . Code line: def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:153 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, edge_object: Union[AdAccount, Campaign], params...
python:mypy_arg_type (MINOR) streams/async_job.py:191 Check argument types in calls Argument "jobs" to "ParentAsyncJob" has incompatible type "List[InsightAsyncJob]"; expected "List[AsyncJob]" . Code line: ...turn ParentAsyncJob(api=self._api, interval=self._interval, jobs=jobs)
python:isort_need_format (MINOR) streams/async_job_manager.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py:123 Check that every function has an annotation Function is missing a return type annotation . Code line: def state(self, value: Mapping[str, Any]):
python:mypy_no_untyped_def (MINOR) streams/async_job_manager.py:88 Check that every function has an annotation Function is missing a return type annotation . Code line: def _check_jobs_status(self):
python:isort_need_format (MINOR) unit_tests/test_base_insight_streams.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def stream_slices(
python:mypy_name_defined (MINOR) streams/base_insight_streams.py:129 Check that name is defined Function is missing a return type annotation [no-untyped-def] def get_updated_state(self, current_stream_state: MutableMapping[s...
python:mypy_name_defined (MINOR) streams/base_insight_streams.py:181 Check that name is defined Incompatible types in assignment (expression has type "Mapping[str, Any]", variable has type "MutableMapping[str, Any]") [assignment] self.state = stream_state
python:mypy_misc (MINOR) source_facebook_marketing/spec.py:18 Miscellaneous other checks Enum() expects a string, tuple, list or dict literal as the second argument . Code line: ValidFields = Enum("ValidEnums", AdsInsights.Field.dict)
python:mypy_misc (MINOR) source_facebook_marketing/spec.py:19 Miscellaneous other checks Enum() expects a string, tuple, list or dict literal as the second argument . Code line: ValidBreakdowns = Enum("ValidBreakdowns", AdsInsights.Breakdowns.__dic...
python:mypy_misc (MINOR) source_facebook_marketing/spec.py:20 Miscellaneous other checks Enum() expects a string, tuple, list or dict literal as the second argument . Code line: ValidActionBreakdowns = Enum("ValidActionBreakdowns", AdsInsights.Acti...
python:isort_need_format (MINOR) streams/base_insight_streams.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 2 code part(s) should be updated.
python:isort_need_format (MINOR) unit_tests/test_async_job.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:isort_need_format (MINOR) unit_tests/test_source.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:isort_need_format (MINOR) integration_tests/test_streams.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:isort_need_format (MINOR) source_facebook_marketing/source.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_no_untyped_def (MINOR) streams/async_job.py:57 Check that every function has an annotation Function is missing a return type annotation . Code line: def start(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:103 Check that every function has an annotation Function is missing a return type annotation . Code line: def start(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py:193 Check that every function has an annotation Function is missing a return type annotation . Code line: def start(self):
python:isort_need_format (MINOR) unit_tests/test_client.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/init.py:5 Check that attribute exists Module "source_facebook_marketing.streams.streams" does not explicitly export attribute "AdsInsights"; implicit reexport disabled . Code line: from .streams import (
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:40 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, api: "API", include_deleted: bool = False, **kw...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:50 Check that every function has an annotation Function is missing a type annotation . Code line: def _execute_batch(self, batch):
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:61 Check that every function has an annotation Function is missing a return type annotation . Code line: def success(response: FacebookResponse):
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:64 Check that every function has an annotation Function is missing a return type annotation . Code line: def failure(response: FacebookResponse):
python:S1134 (MAJOR) streams/base_streams.py:65 Track uses of "FIXME" tags Take the required action to fix the issue indicated by this "FIXME" comment.
python:mypy_no_redef (MINOR) streams/base_streams.py:74 Check that each name is defined once Name "api_batch" already defined on line 68 . Code line: api_batch: FacebookAdsApiBatch = self._api.api.new_bat...
python:mypy_assignment (MINOR) streams/base_streams.py:91 Check that assigned value is compatible with target Incompatible types in assignment (expression has type "Iterable[MutableMapping[str, Any]]", variable has type "Generator[Any, None, None]") . Code line: loaded_records_iter = self.execute_in_batch(loaded_records...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:105 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def request_params(self, **kwargs) -> MutableMapping[str, Any]:
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:143 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, start_date: datetime, end_date: datetime, **kwa...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:148 Check that every function has an annotation Function is missing a return type annotation . Code line: def get_updated_state(self, current_stream_state: MutableMapping[s...
python:mypy_attr_defined (MINOR) streams/base_streams.py:153 Check that attribute exists Module has no attribute "parse" . Code line: max_cursor = max(pendulum.parse(state_value), pendulum.parse(r...
python:mypy_no_untyped_def (MINOR) streams/base_streams.py:162 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def request_params(self, stream_state: Mapping[str, Any], **kwargs...
python:mypy_override (MINOR) streams/base_streams.py:162 Check that method override is compatible with base class Signature of "request_params" incompatible with supertype "FBMarketingStream" . Code line: def request_params(self, stream_state: Mapping[str, Any], **kwargs...
python:mypy_no_any_return (MINOR) streams/base_streams.py:166 Reject returning value with "Any" type if return type is not "Any" Returning Any from function declared to return "MutableMapping[str, Any]" . Code line: return params
python:mypy_attr_defined (MINOR) streams/base_streams.py:171 Check that attribute exists Module has no attribute "parse" . Code line: ...value = self.start_date if not state_value else pendulum.parse(state...
python:mypy_var_annotated (MINOR) streams/streams.py:130 Require variable annotation if type can't be inferred Need type annotation for "breakdowns" (hint: "breakdowns: List[] = ...") . Code line: breakdowns = []
python:mypy_override (MINOR) streams/base_insight_streams.py:86 Check that method override is compatible with base class Signature of "primary_key" incompatible with supertype "FBMarketingStream" . Code line: def primary_key(self) -> Optional[Union[str, List[str], List[List[...
python:mypy_no_untyped_def (MINOR) streams/async_job_manager.py:49 Check that every function has an annotation Function is missing a return type annotation . Code line: def _start_jobs(self):
python:isort_need_format (MINOR) unit_tests/test_async_job_manager.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_index (MINOR) streams/streams.py:61 Check indexing operations Unsupported target for indexed assignment ("Mapping[str, Any]") . Code line: record["thumbnail_data_url"] = fetch_thumbnail_data_ur...
python:isort_need_format (MINOR) source_facebook_marketing/api.py Please run one of the commands: "isort <path_to_updated_folder>" or "./gradlew format" 1 code part(s) should be updated.
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py:125 Check that attribute exists Module has no attribute "parse" . Code line: self._cursor_value = pendulum.parse(value[self.cursor_field])....
python:mypy_attr_defined (MINOR) streams/base_insight_streams.py:126 Check that attribute exists Module has no attribute "parse" . Code line: self._completed_slices = set(pendulum.parse(v).date() for v in...
python:mypy_no_any_return (MINOR) streams/base_insight_streams.py:139 Reject returning value with "Any" type if return type is not "Any" Returning Any from function declared to return "Iterator[Any]" . Code line: return date_range.range("days", self.time_increment)
python:mypy_no_untyped_def (MINOR) source_facebook_marketing/api.py:106 Check that every function has an annotation Function is missing a return type annotation . Code line: def _update_insights_throttle_limit(self, response: FacebookRespon...
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a type annotation . Code line: def chunks(data, n):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a return type annotation . Code line: def restart_number(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, api, jobs: List[AsyncJob]):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a return type annotation . Code line: def restart_number(self):
python:mypy_no_untyped_def (MINOR) streams/async_job.py Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def init(self, api, edge_object: Any, params: Mapping[str, Any...
python:mypy_attr_defined (MINOR) streams/async_job.py Check that attribute exists Module has no attribute "parse" . Code line: new_start = pendulum.parse(self._params["time_range"]["since"]...
python:mypy_valid_type (MINOR) streams/async_job.py Check that type (annotation) is valid Function is missing a return type annotation [no-untyped-def] def restart_number(self):
flake8:E203 (MAJOR) streams/async_job.py:24 whitespace before ‘:’ whitespace before ':'
python:mypy_no_untyped_def (MINOR) streams/async_job.py:247 Check that every function has an annotation Function is missing a return type annotation . Code line: def update_job(self, batch: Optional[FacebookAdsApiBatch] = None):
python:S3776 (CRITICAL) streams/async_job_manager.py Cognitive Complexity of functions should not be too high Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed.
python:S112 (MAJOR) streams/async_job_manager.py "Exception" and "BaseException" should not be raised Replace this generic exception class with a more specific one.
python:mypy_var_annotated (MINOR) streams/async_job_manager.py:47 Require variable annotation if type can't be inferred Need type annotation for "_running_jobs" (hint: "_running_jobs: List[] = ...") . Code line: self._running_jobs = []
python:mypy_name_defined (MINOR) streams/base_insight_streams.py Check that name is defined Function is missing a type annotation for one or more arguments [no-untyped-def] def stream_slices(self, **kwargs) -> Iterable[Optional[Mapping[str...
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py Check that every function has an annotation Function is missing a return type annotation . Code line: def state(self, value: MutableMapping[str, Any]):
python:mypy_misc (MINOR) streams/base_insight_streams.py Miscellaneous other checks "InsightAsyncJob" gets multiple values for keyword argument "edge_object" . Code line: yield InsightAsyncJob(self._api.api, edge_object=self._api...
python:mypy_var_annotated (MINOR) streams/base_insight_streams.py:77 Require variable annotation if type can't be inferred Need type annotation for "_completed_slices" (hint: "_completed_slices: Set[] = ...") . Code line: self._completed_slices = set()
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py:141 Check that every function has an annotation Function is missing a return type annotation . Code line: def _advance_cursor(self):
python:S1134 (MAJOR) streams/base_insight_streams.py:206 Track uses of "FIXME" tags Take the required action to fix the issue indicated by this "FIXME" comment.
python:mypy_no_untyped_def (MINOR) streams/base_insight_streams.py:219 Check that every function has an annotation Function is missing a type annotation for one or more arguments . Code line: def request_params(self, **kwargs) -> MutableMapping[str, Any]:
python:mypy_override (MINOR) streams/base_insight_streams.py:219 Check that method override is compatible with base class Signature of "request_params" incompatible with supertype "FBMarketingIncrementalStream" . Code line: def request_params(self, **kwargs) -> MutableMapping[str, Any]:

Coverage (25.6%)

File Coverage File Coverage
integration_tests/acceptance.py 0.0 integration_tests/conftest.py 0.0
integration_tests/test_streams.py 0.0 main.py 0.0
setup.py 0.0 source_facebook_marketing/init.py 100.0
source_facebook_marketing/api.py 76.7 source_facebook_marketing/source.py 74.3
source_facebook_marketing/spec.py 100.0 source_facebook_marketing/streams/init.py 100.0
source_facebook_marketing/streams/async_job.py 100.0 source_facebook_marketing/streams/async_job_manager.py 48.3
source_facebook_marketing/streams/base_insight_streams.py 87.5 source_facebook_marketing/streams/base_streams.py 79.2
source_facebook_marketing/streams/common.py 97.1 source_facebook_marketing/streams/streams.py 80.0
unit_tests/conftest.py 0.0 unit_tests/test_async_job.py 0.0
unit_tests/test_async_job_manager.py 0.0 unit_tests/test_base_insight_streams.py 0.0
unit_tests/test_client.py 0.0 unit_tests/test_deep_merge.py 0.0
unit_tests/test_source.py 0.0

Please sign in to comment.