Skip to content

Commit

Permalink
Cleanup doc blocks (#194)
Browse files Browse the repository at this point in the history
* linting + comments

* refactor to reduce complexity

* escape foward slash

* fresh code gen

* linting cosmetics
  • Loading branch information
philkra authored Feb 25, 2024
1 parent e71f212 commit d761acc
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 75 deletions.
134 changes: 76 additions & 58 deletions codegen/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import json
import logging
import re
import textwrap
from typing import Any, Dict

import coloredlogs
Expand All @@ -35,7 +34,7 @@

from xata.helpers import to_rfc339

VERSION = "2.0.0"
VERSION = "2.1.0"

coloredlogs.install(level="INFO")
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
Expand Down Expand Up @@ -186,7 +185,8 @@ def generate_endpoint(path: str, method: str, endpoint: dict, parameters: list,
else:
endpoint_params = get_endpoint_params(path, endpoint, parameters, references)
if "description" in endpoint:
desc = endpoint["description"].strip()
# poor man's escape of "\" as linter does not like it
desc = endpoint["description"].replace("\\", "\\\\").strip()
else:
logging.info("missing description for %s.%s - using summary." % (path, endpoint["operationId"]))
desc = endpoint["summary"].strip()
Expand Down Expand Up @@ -259,56 +259,13 @@ def get_endpoint_params(path: str, endpoint: dict, parameters: dict, references:
"response_content_types": [],
}
if len(parameters) > 0:
# Check for convience param swaps
curated_param_list = []
for r in parameters:
if "$ref" in r and r["$ref"] == REF_DB_BRANCH_NAME_PARAM:
logging.debug("adding smart value for %s" % "#/components/parameters/DBBranchNameParam")
# push two new params to cover for string creation
curated_param_list.append(OPTIONAL_CURATED_PARAM_DB_NAME)
curated_param_list.append(OPTIONAL_CURATED_PARAM_BRANCH_NAME)
skel["smart_db_branch_name"] = True
elif "$ref" in r and r["$ref"] == REF_WORKSPACE_ID_PARAM:
# and endpoint['operationId'] not in REF_WORKSPACE_ID_PARAM_EXCLUSIONS:
logging.debug("adding smart value for %s" % "#/components/parameters/WorkspaceIdParam")
curated_param_list.append(OPTIONAL_CURATED_PARAM_WORKSPACE_ID)
skel["smart_workspace_id"] = True
else:
curated_param_list.append(r)
body = _generate_enpoint_param_list(parameters)
curated_param_list = body["params"]
skel["smart_db_branch_name"] = body["smart_db_branch_name"]
skel["smart_workspace_id"] = body["smart_workspace_id"]

for r in curated_param_list:
p = None
# if not in ref: endpoint specific params
if "$ref" in r and r["$ref"] in references:
p = references[r["$ref"]]
if "$ref" in p["schema"]:
p["type"] = type_replacement(references[p["schema"]["$ref"]]["type"])
elif "type" in p["schema"]:
p["type"] = type_replacement(p["schema"]["type"])
else:
logging.error("could resolve type of '%s' in the lookup." % r["$ref"])
exit(11)
# else if name not in r: method specific params
elif "name" in r:
p = r
p["type"] = type_replacement(r["schema"]["type"])
# else fail with code: 11
else:
logging.error("could resolve reference %s in the lookup." % r["$ref"])
exit(11)

if "required" not in p:
p["required"] = False
if "description" not in p:
p["description"] = ""

p["name"] = p["name"].strip()
p["nameParam"] = get_param_name(p["name"])
p["description"] = p["description"].strip()
p["trueType"] = p["type"]
if not p["required"]:
p["type"] += " = None"

p = _prepare_endpoint_param(r, references)
skel["list"].append(p)

if p["in"] == "path":
Expand Down Expand Up @@ -358,17 +315,78 @@ def get_endpoint_params(path: str, endpoint: dict, parameters: dict, references:
}
)

skel["list"] = _sanitize_enpoint_list(skel["list"], skel["has_optional_params"])
return skel


def _prepare_endpoint_param(r, references: list) -> list:
p = None
# if not in ref: endpoint specific params
if "$ref" in r and r["$ref"] in references:
p = references[r["$ref"]]
if "$ref" in p["schema"]:
p["type"] = type_replacement(references[p["schema"]["$ref"]]["type"])
elif "type" in p["schema"]:
p["type"] = type_replacement(p["schema"]["type"])
else:
logging.error("could resolve type of '%s' in the lookup." % r["$ref"])
exit(11)
# else if name not in r: method specific params
elif "name" in r:
p = r
p["type"] = type_replacement(r["schema"]["type"])
# else fail with code: 11
else:
logging.error("could resolve reference %s in the lookup." % r["$ref"])
exit(11)

if "required" not in p:
p["required"] = False
if "description" not in p:
p["description"] = ""
p["name"] = p["name"].strip()
p["nameParam"] = get_param_name(p["name"])
p["description"] = p["description"].strip()
p["trueType"] = p["type"]
if not p["required"]:
p["type"] += " = None"

return p


def _generate_enpoint_param_list(parameters: list) -> list:
resp = {
"params": [],
"smart_db_branch_name": False,
"smart_workspace_id": False,
}
for r in parameters:
if "$ref" in r and r["$ref"] == REF_DB_BRANCH_NAME_PARAM:
logging.debug("adding smart value for %s" % "#/components/parameters/DBBranchNameParam")
# push two new params to cover for string creation
resp["params"].append(OPTIONAL_CURATED_PARAM_DB_NAME)
resp["params"].append(OPTIONAL_CURATED_PARAM_BRANCH_NAME)
resp["smart_db_branch_name"] = True
elif "$ref" in r and r["$ref"] == REF_WORKSPACE_ID_PARAM:
# and endpoint['operationId'] not in REF_WORKSPACE_ID_PARAM_EXCLUSIONS:
logging.debug("adding smart value for %s" % "#/components/parameters/WorkspaceIdParam")
resp["params"].append(OPTIONAL_CURATED_PARAM_WORKSPACE_ID)
resp["smart_workspace_id"] = True
else:
resp["params"].append(r)
return resp


def _sanitize_enpoint_list(lst: list, has_optional_params: bool) -> list:
# reorder for optional params to be last
if has_optional_params:
lst = [e for e in lst if e["required"]] + [e for e in lst if not e["required"]]
# Remove duplicates
tmp = {}
for p in skel["list"]:
for p in lst:
if p["name"].lower() not in tmp:
tmp[p["name"].lower()] = p
skel["list"] = tmp.values()

# reorder for optional params to be last
if skel["has_optional_params"]:
skel["list"] = [e for e in skel["list"] if e["required"]] + [e for e in skel["list"] if not e["required"]]
return skel
return tmp.values()


def resolve_references(spec: dict) -> dict:
Expand Down
13 changes: 7 additions & 6 deletions tests/integration-tests/files_transormations_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
import pytest
import utils
from faker import Faker
from PIL import Image, ImageChops

from xata.client import XataClient

# from PIL import Image, ImageChops


class TestFilesTransformations(object):
def setup_class(self):
Expand Down Expand Up @@ -90,7 +91,7 @@ def test_with_nested_operations(self):
upload = self.client.records().insert("Attachments", payload, columns=["one_file.url"])
assert upload.is_success()

img = utils.get_file_content(utils.get_file_name("images/03.png"))
# img = utils.get_file_content(utils.get_file_name("images/03.png"))
self.client.files().transform(
upload["one_file"]["url"],
{"rotate": 180, "blur": 50, "trim": {"top": 20, "right": 30, "bottom": 20, "left": 0}},
Expand Down Expand Up @@ -127,18 +128,18 @@ def test_unknown_operations(self):
upload = self.client.records().insert("Attachments", payload, columns=["one_file.url"])
assert upload.is_success()

with pytest.raises(Exception) as e:
with pytest.raises(Exception):
self.client.files().transform(upload["one_file"]["url"], {})

with pytest.raises(Exception) as e:
with pytest.raises(Exception):
self.client.files().transform(upload["one_file"]["url"], {"donkey": "kong"})

def test_unknown_image_id(self):
# must fail with a 403
with pytest.raises(Exception) as e:
with pytest.raises(Exception):
self.client.files().transform("https://us-east-1.storage.xata.sh/lalala", {"rotate": 90})

def test_invalid_url(self):
# must fail with a 403
with pytest.raises(Exception) as e:
with pytest.raises(Exception):
self.client.files().transform("https:/xata.sh/oh-hello", {"rotate": 90})
2 changes: 0 additions & 2 deletions tests/integration-tests/helpers_bulkprocessor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
# under the License.
#

import time

import pytest
import utils
from faker import Faker
Expand Down
4 changes: 2 additions & 2 deletions xata/api/migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def compare_branch_with_user_schema(
headers = {"content-type": "application/json"}
return self.request("POST", url_path, headers, payload)

def compare_schemas(self, payload: dict, db_name: str = None, branch_name: str = None) -> ApiResponse:
def compare_schemas(self, branch_name: str, payload: dict, db_name: str = None) -> ApiResponse:
"""
Compare branch schemas.
Expand All @@ -180,9 +180,9 @@ def compare_schemas(self, payload: dict, db_name: str = None, branch_name: str =
- 5XX: Unexpected Error
- default: Unexpected Error
:param branch_name: str The Database Name
:param payload: dict content
:param db_name: str = None The name of the database to query. Default: database name from the client.
:param branch_name: str = None The name of the branch to query. Default: branch name from the client.
:returns ApiResponse
"""
Expand Down
2 changes: 1 addition & 1 deletion xata/api/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def insert_with_id(
if_version: int = None,
) -> ApiResponse:
"""
By default, IDs are auto-generated when data is insterted into Xata. Sending a request to this endpoint allows us to insert a record with a pre-existing ID, bypassing the default automatic ID generation.
By default, IDs are auto-generated when data is inserted into Xata. Sending a request to this endpoint allows us to insert a record with a pre-existing ID, bypassing the default automatic ID generation.
Reference: https://xata.io/docs/api-reference/db/db_branch_name/tables/table_name/data/record_id#insert-record-with-id
Path: /db/{db_branch_name}/tables/{table_name}/data/{record_id}
Expand Down
10 changes: 5 additions & 5 deletions xata/api/search_and_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def query(self, table_name: str, payload: dict = None, db_name: str = None, bran
}
```
For usage, see also the [API Guide](https://xata.io/docs/api-guide/get).
For usage, see also the [Xata SDK documentation](https://xata.io/docs/sdk/get).
### Column selection
Expand Down Expand Up @@ -459,7 +459,7 @@ def query(self, table_name: str, payload: dict = None, db_name: str = None, bran
* `*` matches zero or more characters
* `?` matches exactly one character
If you want to match a string that contains a wildcard character, you can escape them using a backslash (`\`). You can escape a backslash by usign another backslash.
If you want to match a string that contains a wildcard character, you can escape them using a backslash (`\\`). You can escape a backslash by usign another backslash.
You can also use the `$endsWith` and `$startsWith` operators:
Expand Down Expand Up @@ -888,7 +888,7 @@ def search_table(self, table_name: str, payload: dict, db_name: str = None, bran
"""
Run a free text search operation in a particular table.
The endpoint accepts a `query` parameter that is used for the free text search and a set of structured filters (via the `filter` parameter) that are applied before the search. The `filter` parameter uses the same syntax as the [query endpoint](/api-reference/db/db_branch_name/tables/table_name/) with the following exceptions:
The endpoint accepts a `query` parameter that is used for the free text search and a set of structured filters (via the `filter` parameter) that are applied before the search. The `filter` parameter uses the same syntax as the [query endpoint](/docs/api-reference/db/db_branch_name/tables/table_name/query#filtering) with the following exceptions:
* filters `$contains`, `$startsWith`, `$endsWith` don't work on columns of type `text`
* filtering on columns of type `multiple` is currently unsupported
Expand Down Expand Up @@ -1137,10 +1137,10 @@ def aggregate(self, table_name: str, payload: dict, db_name: str = None, branch_
While the summary endpoint is served from a transactional store and the results are strongly
consistent, the aggregate endpoint is served from our columnar store and the results are
only eventually consistent. On the other hand, the aggregate endpoint uses a
store that is more appropiate for analytics, makes use of approximative algorithms
store that is more appropriate for analytics, makes use of approximation algorithms
(e.g for cardinality), and is generally faster and can do more complex aggregations.
For usage, see the [API Guide](https://xata.io/docs/api-guide/aggregate).
For usage, see the [Aggregation documentation](https://xata.io/docs/sdk/aggregate).
Reference: https://xata.io/docs/api-reference/db/db_branch_name/tables/table_name/aggregate#run-aggregations-over-a-table
Path: /db/{db_branch_name}/tables/{table_name}/aggregate
Expand Down
2 changes: 1 addition & 1 deletion xata/api_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def status_code(self) -> int:
:returns int
"""
return self.response.status_code

@property
def error_message(self) -> Union[str, None]:
"""
Expand Down

0 comments on commit d761acc

Please sign in to comment.