-
Notifications
You must be signed in to change notification settings - Fork 436
Internal server error 500 getting the list of connections of a virtual connection #1558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
There was a request to support Virtual Connections in TSC here, and a PR was merged here. So this bug is a regression. |
Closes tableau#1558 Connection XML element for VirtualConnections has different attribute keys compared to connection XML elements when returned by Datasources, Workbooks, and Flows. This PR adds in flexibility to ConnectionItem's reading of XML to account for both sets of attributes that may be present elements.
This was challenging to troubleshoot, so leaving some notes here. First, setup resources in AWS using Terraform. terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.86.0"
}
}
required_version = ">= 1.9"
}
provider "aws" {
region = "us-west-2"
}
variable "prefix" {
type = string
description = "Prefix for resources"
}
resource "local_file" "this" {
content = "col1,col2\nval1,val2"
filename = "example.csv"
}
resource "aws_s3_bucket" "this" {
bucket = replace("${var.prefix}_bucket", "_", "-")
force_destroy = true
}
resource "aws_s3_object" "this" {
bucket = aws_s3_bucket.this.bucket
key = "input/${local_file.this.filename}"
source = local_file.this.filename
}
resource "aws_glue_catalog_database" "this" {
name = "${var.prefix}_db"
}
resource "aws_glue_catalog_table" "this" {
catalog_id = aws_glue_catalog_database.this.catalog_id
database_name = aws_glue_catalog_database.this.name
name = "${var.prefix}_table"
parameters = {
"classification" = "csv"
}
table_type = "EXTERNAL_TABLE"
storage_descriptor {
compressed = false
input_format = "org.apache.hadoop.mapred.TextInputFormat"
location = "s3://${aws_s3_bucket.this.bucket}/${dirname(aws_s3_object.this.key)}"
output_format = "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"
columns {
name = "col1"
type = "string"
}
columns {
name Use the access key and secret key created to populate the virtual connection on the server. Connections can only be created via the Web UI, and not the REST API, so I don't have an example of that. I also named it "bug" so I could find it easier during the script. Then rotate the keys, create the json, and run the python script. terraform taint aws_iam_access_key.this
terraform plan -out tfplan
terraform apply tfplan
terraform output -json > keys.json Then run the python script: #/// script
# requires_python = ">=3.9"
# dependencies = ["tableauserverclient==0.35", "python-dotenv"]
#///
import json
import os
from pathlib import Path
from dotenv import load_dotenv
import tableauserverclient as TSC
load_dotenv()
def update_environment() -> None:
with (Path(__file__).parent / "keys.json").open() as f:
keys = json.load(f)
for k,v in keys.items():
os.environ[k] = v["value"]
def main() -> None:
server = TSC.Server(os.getenv("TABLEAU_SERVER"), use_server_version=True)
auth = TSC.PersonalAccessTokenAuth(
token_name=os.environ["TOKEN_NAME"],
personal_access_token=os.environ["TOKEN_SECRET"],
site_id=os.environ["TABLEAU_SITE"]
)
with server.auth.sign_in(auth):
for vc in TSC.Pager(server.virtual_connections):
if vc.name != 'bug':
continue
server.virtual_connections.populate_connections(vc)
for conn in vc.connections:
conn: TSC.ConnectionItem
if conn.connection_type != 'athena':
continue
print(f"{conn.server_address}:{conn.server_port}")
target = conn
target.username = os.environ["ak"]
target.password = os.environ["sk"]
print(target)
conn = server.virtual_connections.update_connection_db_connection(vc, target)
print(conn)
if __name__ == "__main__":
update_environment()
main() The failure happens during the updated process as the |
If that is the case, shouldn't it be a 400 error? |
I believe its because the server side doesn't validate whether or not you sent a connection id. It retrieves it from that path. It doesn't make sense for you to "update" the connection with the ID of |
please reopen this issue as I don't think @renoyjohnm's commit fixed it. My test showed the same error with latest version. Versions
To Reproduce (same script) Results (same error) The error occured in the GET request File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/yyy-eWfleEIf-py3.11/lib/python3.11/site-packages/tableauserverclient/server/endpoint/virtual_connections_endpoint.py", line 49, in _get_virtual_database_connections
server_response = self.get_request(f"{self.baseurl}/{virtual_connection.id}/connections", req_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/yyy-eWfleEIf-py3.11/lib/python3.11/site-packages/tableauserverclient/server/endpoint/endpoint.py", line 204, in get_request
return self._make_request(
^^^^^^^^^^^^^^^^^^^
in the unit test of #1566, the GET endpoint is assumed to be working for whatever request params we send. In fact no params were sent in the test. with requests_mock.mock() as m:
m.get(f"{self.baseurl}/{vconn.id}/connections", text=populate_connections_xml.read_text())
vc_out = self.server.virtual_connections.populate_connections(vconn)
connection_list = list(vconn.connections) |
My minimal reproducible example was not able to reproduce this error on v0.37. Can you provide a minimal example that does? import tableauserverclient as TSC
import os
from dotenv import load_dotenv
load_dotenv()
server = TSC.Server(os.environ["TABLEAU_SERVER"], use_server_version=True)
auth = TSC.PersonalAccessTokenAuth(os.environ["TOKEN_NAME"], os.environ["TOKEN_SECRET"], site_id=os.environ["TABLEAU_SITE"])
server.auth.sign_in(auth)
for vc in TSC.Pager(server.virtual_connections):
print(vc.id, vc.name)
server.virtual_connections.populate_connections(vc)
for c in vc.connections:
print(c.server_address) |
@jorwoods I did some debugging. It now looks like a server side issue to me. The minimal example is just making the GET request to The bug you reproduced with your minimal example was an unrelated bug that occured in the update query not the get query. I'm glad you found that one and had it fixed. As for mine, I have filed a support ticket to Tableau support in February, and they dismissed it as a coding issue on my side. So no further actions for now, I probably will look for a different product. |
I don't have a virtual connection with 200 connections, but that said, I did investigate the endpoint. The connections endpoint is indeed paginated, and does return the pagination XML element. I tested passing in a
You passed these in manually? Letting TSC do the heavy lift seems to work for me, as well as letting the |
sorry I meant, for some ids, the GET request to I was using TSC library with local modifications to do the debugging, internally it was sending HTTP requests with I believe when a user started creating a VC, but never fished the creation, Tableau auto-saved the VC as a "draft" although it could be without any info. When we had these objects, the query returned HTTP 500. After deleting the problematic VCs from tableau cloud admin UI, I could use TSC library to update the connections of the rest without issues. If you handle server-side bugs as well, unfortunately, I no longer have those deleted VCs to isolate the bug further, but will raise an issue if I encounter it again. |
Describe the bug
getting the list of connections of a virtual connection throws an internal server error 500
Versions
Details of your environment, including:
To Reproduce
Results
The text was updated successfully, but these errors were encountered: