Skip to content

Commit

Permalink
Update to f-strings
Browse files Browse the repository at this point in the history
  • Loading branch information
jarekwg committed Nov 24, 2024
1 parent 24c1e45 commit 75757d9
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 64 deletions.
11 changes: 5 additions & 6 deletions src/myob/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ class Myob:
def __init__(self, credentials):
if not isinstance(credentials, PartnerCredentials):
raise TypeError(
"Expected a Credentials instance, got %s."
% (type(credentials).__name__,)
f"Expected a Credentials instance, got {type(credentials).__name__}."
)
self.credentials = credentials
self.companyfiles = CompanyFiles(credentials)
Expand All @@ -30,7 +29,8 @@ def info(self):
return self._manager.info()

def __repr__(self):
return "Myob:\n %s" % "\n ".join(["companyfiles", "info"])
options = "\n ".join(["companyfiles", "info"])
return f"Myob:\n {options}"


class CompanyFiles:
Expand Down Expand Up @@ -86,6 +86,5 @@ def __init__(self, raw, credentials):
)

def __repr__(self):
return "CompanyFile:\n %s" % "\n ".join(
sorted(v["name"] for v in ENDPOINTS.values())
)
options = "\n ".join(sorted(v["name"] for v in ENDPOINTS.values()))
return f"CompanyFile:\n {options}"
6 changes: 3 additions & 3 deletions src/myob/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def __init__(
# protected endpoint to ensure they are valid. If not, raise appropriate error.
def authenticate_companyfile(self, company_id, username, password):
"""Store hashed username-password for logging into company file."""
userpass = base64.b64encode(
bytes("%s:%s" % (username, password), "utf-8")
).decode("utf-8")
userpass = base64.b64encode(bytes(f"{username}:{password}", "utf-8")).decode(
"utf-8"
)
self.companyfile_credentials[company_id] = userpass

@property
Expand Down
14 changes: 8 additions & 6 deletions src/myob/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,20 +155,22 @@
METHOD_MAPPING = {
ALL: {
"endpoint": lambda base: base,
"hint": lambda name: "Return all %s for an AccountRight company file."
% pluralise(name),
"hint": lambda name: f"Return all {pluralise(name)} for an AccountRight company file.",
},
GET: {
"endpoint": lambda base: base + "[uid]/",
"hint": lambda name: "Return selected %s." % name,
"hint": lambda name: f"Return selected {name}.",
},
PUT: {
"endpoint": lambda base: base + "[uid]/",
"hint": lambda name: "Update selected %s." % name,
"hint": lambda name: f"Update selected {name}.",
},
POST: {
"endpoint": lambda base: base,
"hint": lambda name: f"Create new {name}.",
},
POST: {"endpoint": lambda base: base, "hint": lambda name: "Create new %s." % name},
DELETE: {
"endpoint": lambda base: base + "[uid]/",
"hint": lambda name: "Delete selected %s." % name,
"hint": lambda name: f"Delete selected {name}.",
},
}
3 changes: 2 additions & 1 deletion src/myob/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ def __init__(self, response, msg=None):
try:
self.errors = response.json()["Errors"]
e = self.errors[0]
self.problem = "%s: %s %s" % (
name, message, details = (
e["Name"],
e["Message"] or "",
e["AdditionalDetails"],
)
self.problem = f"{name}: {message} {details}"
except Exception:
self.errors = []
self.problem = response.reason
Expand Down
71 changes: 24 additions & 47 deletions src/myob/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@


class Manager:
def __init__(
self, name, credentials, company_id=None, endpoints=[], raw_endpoints=[]
):
def __init__(self, name, credentials, company_id=None, endpoints=[], raw_endpoints=[]):
self.credentials = credentials
self.name = "_".join(p for p in name.rstrip("/").split("/") if "[" not in p)
self.base_url = MYOB_BASE_URL
Expand Down Expand Up @@ -61,16 +59,13 @@ def build_method(self, method, endpoint, hint):

def inner(*args, timeout=None, **kwargs):
if args:
raise AttributeError(
"Unnamed args provided. Only keyword args accepted."
)
raise AttributeError("Unnamed args provided. Only keyword args accepted.")

# Ensure all required url kwargs have been provided.
missing_kwargs = set(required_kwargs) - set(kwargs.keys())
if missing_kwargs:
raise KeyError(
"Missing kwargs %s. Endpoint requires %s."
% (list(missing_kwargs), required_kwargs)
f"Missing kwargs {list(missing_kwargs)}. Endpoint requires {required_kwargs}."
)

# Parse kwargs.
Expand All @@ -92,15 +87,11 @@ def inner(*args, timeout=None, **kwargs):
request_kwargs = self.build_request_kwargs(
request_method, data=kwargs.get("data"), **request_kwargs_raw
)
response = requests.request(
request_method, url, timeout=timeout, **request_kwargs
)
response = requests.request(request_method, url, timeout=timeout, **request_kwargs)

if response.status_code == 200:
# We don't want to be deserialising binary responses..
if not response.headers.get("content-type", "").startswith(
"application/json"
):
if not response.headers.get("content-type", "").startswith("application/json"):
return response.content

try:
Expand Down Expand Up @@ -132,15 +123,13 @@ def inner(*args, timeout=None, **kwargs):
raise MyobExceptionUnknown(response)

# Build method name
method_name = "_".join(
p for p in endpoint.rstrip("/").split("/") if "[" not in p
).lower()
method_name = "_".join(p for p in endpoint.rstrip("/").split("/") if "[" not in p).lower()
# If it has no name, use method.
if not method_name:
method_name = method.lower()
# If it already exists, prepend with method to disambiguate.
elif hasattr(self, method_name):
method_name = "%s_%s" % (method.lower(), method_name)
method_name = f"{method.lower()}_{method_name}"
self.method_details[method_name] = {
"kwargs": required_kwargs,
"hint": hint,
Expand All @@ -152,7 +141,7 @@ def build_request_kwargs(self, method, data=None, **kwargs):

# Build headers.
request_kwargs["headers"] = {
"Authorization": "Bearer %s" % self.credentials.oauth_token,
"Authorization": f"Bearer {self.credentials.oauth_token}",
"x-myobapi-key": self.credentials.consumer_key,
"x-myobapi-version": "v2",
}
Expand All @@ -161,9 +150,7 @@ def build_request_kwargs(self, method, data=None, **kwargs):
# Try to look up credentials for the companyfile if they've been set up. Else,
# pass through silently, as the user is likely to have been set up with SSO,
# in which case the credentials are not required.
companyfile_credentials = self.credentials.companyfile_credentials[
self.company_id
]
companyfile_credentials = self.credentials.companyfile_credentials[self.company_id]
request_kwargs["headers"].update(
{
"x-myobapi-cftoken": companyfile_credentials,
Expand All @@ -181,10 +168,10 @@ def build_request_kwargs(self, method, data=None, **kwargs):

def build_value(value):
if issubclass(type(value), date):
return "datetime'%s'" % value
return f"datetime'{value}'"
if isinstance(value, bool):
return str(value).lower()
return "'%s'" % value
return f"'{value}'"

if "raw_filter" in kwargs:
filters.append(kwargs["raw_filter"])
Expand All @@ -202,19 +189,15 @@ def build_value(value):
]:
operator = "eq"
for op in ["lt", "gt"]:
if k.endswith("__%s" % op):
if k.endswith(f"__{op}"):
k = k[:-4]
operator = op
if not isinstance(v, (list, tuple)):
v = [v]
filters.append(
" or ".join("%s %s %s" % (k, operator, build_value(v_)) for v_ in v)
)
filters.append(" or ".join(f"{k} {operator} {build_value(v_)}" for v_ in v))

if filters:
request_kwargs["params"]["$filter"] = " and ".join(
"(%s)" % f for f in filters
)
request_kwargs["params"]["$filter"] = " and ".join(f"({f})" for f in filters)

if "orderby" in kwargs:
request_kwargs["params"]["$orderby"] = kwargs["orderby"]
Expand Down Expand Up @@ -243,21 +226,15 @@ def build_value(value):
return request_kwargs

def __repr__(self):
def print_method(name, args):
return "%s(%s)" % (name, ", ".join(args))
def _get_signature(name, kwargs):
return f"{name}({', '.join(kwargs)})"

formatstr = "%%%is - %%s" % max(
len(print_method(k, v["kwargs"])) for k, v in self.method_details.items()
)
return "%s%s:\n %s" % (
self.name,
self.__class__.__name__,
"\n ".join(
formatstr
% (
print_method(k, v["kwargs"]),
v["hint"],
)
for k, v in sorted(self.method_details.items())
),
def print_method(name, kwargs, hint, offset):
return f"{_get_signature(name, kwargs):>{offset}} - {hint}"

offset = max(len(_get_signature(k, v["kwargs"])) for k, v in self.method_details.items())
options = "\n ".join(
print_method(k, v["kwargs"], v["hint"], offset)
for k, v in sorted(self.method_details.items())
)
return f"{self.name}{self.__class__.__name__}:\n {options}"
2 changes: 1 addition & 1 deletion tests/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def assertEndpointReached(
self, func, params, method, endpoint, mock_request, timeout=None
):
mock_request.return_value.status_code = 200
if endpoint == "/%s/" % CID:
if endpoint == f"/{CID}/":
mock_request.return_value.json.return_value = {"CompanyFile": {"Id": CID}}
func(**params)
full_endpoint = "https://api.myob.com/accountright" + endpoint
Expand Down

0 comments on commit 75757d9

Please sign in to comment.