Skip to content

Release 0.5 #108

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

Merged
merged 31 commits into from
Nov 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5f91af0
Scrub some strings in the test files (#82)
t8y8 Sep 13, 2016
b80333d
Fix encoding bugs in Python2 (non-ASCII characters) (#80)
MiguelSR Sep 19, 2016
01f232f
Add a test to verify #80 (#83)
Sep 19, 2016
a882731
Create CONTRIBUTORS.md (#84)
Sep 30, 2016
8228efa
Fix #87 by working around non-federated sqlproxy connections (#89)
t8y8 Sep 30, 2016
c056ed1
Removing unused imports per linter report (#90)
t8y8 Oct 2, 2016
2afd4c2
#86 Repository location stripping (#88)
Oct 4, 2016
7cc131a
bump version and create changelog (#91)
Oct 7, 2016
4ce9cfa
Add #80 to changelog (#92)
Oct 7, 2016
d938415
Fixing merge conflict with master
Oct 7, 2016
9740b38
one more merge conflict fixed from master
Oct 7, 2016
12aab0e
begin development of v0.5 (#94)
Oct 7, 2016
1aa4fc0
Issue #96: Add port support (#97)
t8y8 Oct 17, 2016
9e1d875
Add caption support for datasources (#99)
Oct 18, 2016
d55f126
clarifying intended label usage (#101)
Oct 25, 2016
ceb17d3
Adding docs that will build via Github Pages (#100)
t8y8 Oct 28, 2016
959efae
Update the devguide to have more meat
t8y8 Oct 30, 2016
07de383
Minor edits.
jdomingu Oct 31, 2016
45bd8f5
Merge pull request #105 from t8y8/devguide-updates
jdomingu Oct 31, 2016
abceda6
begin development of v0.5 (#94)
Oct 7, 2016
a3e9b2e
Issue #96: Add port support (#97)
t8y8 Oct 17, 2016
4b43a6a
Add caption support for datasources (#99)
Oct 18, 2016
248c76d
clarifying intended label usage (#101)
Oct 25, 2016
c18e2eb
Adding docs that will build via Github Pages (#100)
t8y8 Oct 28, 2016
3f38901
Update the devguide to have more meat
t8y8 Oct 30, 2016
6ee666b
Minor edits.
jdomingu Oct 31, 2016
2e35547
Adding docs that will build via Github Pages (#100)
t8y8 Oct 28, 2016
7ac34ec
setup verion number for release
Nov 1, 2016
47d2ccc
Adding changelog for 0.5
Nov 1, 2016
07f8487
Merge pull request #107 from RussTheAerialist/development
Nov 1, 2016
a426a42
Merge pull request #106 from RussTheAerialist/prep-for-0-5
Nov 1, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 05 (01 November 2016)

* Added ability to set the port for connections (#97)
* Added ability to read and write caption for datasources (#99)
* Added documentation

## 0.4 (07 October 2016)

* Add ability to remove repository location (#86)
Expand Down
33 changes: 0 additions & 33 deletions contributing.md

This file was deleted.

1 change: 1 addition & 0 deletions contributing.md
2 changes: 1 addition & 1 deletion docs/_config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Site settings
title: Tableau Document API
email: jdominguez@tableau.com
email: github@tableau.com
description: Programmatically update your Tableau workbooks and data sources.
baseurl: "/document-api-python"
permalinks: pretty
Expand Down
2 changes: 1 addition & 1 deletion docs/_layouts/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<div class="content .col-xs-12 .col-sm-8 .col-md-9">
<h1>{{ page.title }}</h1>
<div class="edit-container">
<a href="https://github.com/tableau/document-api-python/edit/master/{{ page.path }}" class="edit-links"><span class="glyphicon glyphicon-pencil"></span> Edit this page</a>
<a href="https://github.com/tableau/document-api-python/edit/master/docs/{{ page.path }}" class="edit-links"><span class="glyphicon glyphicon-pencil"></span> Edit this page</a>
&nbsp;
<a href="https://github.com/tableau/document-api-python/issues" class="edit-links"><span class="glyphicon glyphicon-flag"></span> Submit an issue</a>
</div>
Expand Down
1 change: 1 addition & 0 deletions docs/docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title: Contributing
layout: docs
---
# Contributing

We welcome contributions to this project!

Expand Down
52 changes: 34 additions & 18 deletions docs/docs/dev-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,67 @@ title: Developer Guide
layout: docs
---

### Making your first patch
<<<<<<< 6ee666bf06d5ab59931100b3955779c35693e33f
## Submitting your first patch

1. Make sure you've signed the CLA
1. Make sure you have [signed the CLA](http://tableau.github.io/#contributor-license-agreement-cla)

1. Clone the repo
1. Fork the repository.

We follow the "Fork and Pull" model as described [here](https://help.github.com/articles/about-collaborative-development-models/).

1. Clone your fork:

```shell
git clone http://github.com/tableau/document-api-python
git clone http://github.com/<your_username>/document-api-python
```

1. Run the tests to make sure everything is peachy
1. Run the tests to make sure everything is peachy:

```shell
python setup.py test
```

1. Set up the feature, fix, or documentation branch.

It is recommended to use the format [issue#]-[type]-[description] (e.g. 13-fix-connection-bug)
It is recommended to use the format issue#-type-description (e.g. 13-fix-connection-bug) like so:

```shell
git checkout -b 13-feature-new-stuff
```

1. Code and Commit!
1. Code and commit!

Here's a quick checklist for ensuring a good pull request:

- Only touch the minimal amount of files possible while still accomplishing the goal.
- Ensure all indentation is done as 4-spaces and your editor is set to unix line endings.
- The code matches PEP8 style guides. If you cloned the repo you can run `pycodestyle .`
- Keep commit messages clean and descriptive.
If the PR is accepted it will get 'Squashed' into a single commit before merging, the commit messages will be used to generate the Merge commit message.

Here's a quick checklist for ensuring a good diff:
1. Add tests.

- The diff touches the minimal amount of files possible while still fufilling the purpose of the diff
- The diff uses Unix line endings
- The diff adheres to our PEP8 style guides. If you've cloned the repo you can run `pycodestyle .`
All of our tests live under the `test/` folder in the repository.
We use `unittest` and the built-in test runner `python setup.py test`.
If a test needs a static file, like a twb/twbx, it should live under `test/assets/`

1. Add Tests
1. Update the documentation.

1. Update Documentation
Our documentation is written in markdown and built with Jekyll on Github Pages. All of the documentation source files can be found in `docs/docs`.

Our documentation is written in markdown and built with [Mkdocs](http://www.mkdocs.org). More information on how to update and build the docs can be found [here](#updating-documentation)
When adding a new feature or improving existing functionality we may ask that you update the documentation along with your code.

If you are just making a PR for documentation updates (adding new docs, fixing typos, improving wording) the easiest method is to use the built in `Edit this file` in the Github UI

1. Run the tests again and make sure they pass!
1. Submit to your fork.

1. Submit to your fork
1. Make a PR as described [here](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) against the 'development' branch.

1. Submit a PR
1. Wait for a review and address any feedback.
While we try and stay on top of all issues and PRs it might take a few days for someone to respond. Politely pinging the PR after a few days with no response is OK, we'll try and respond with a timeline as soon as we are able.

1. Wait for a review, and address any feedback.
1. That's it! When the PR has received :rocket:'s from members of the core team they will merge the PR

<!--
### Updating Documentation
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='tableaudocumentapi',
version='0.4',
version='0.5',
author='Tableau',
author_email='github@tableau.com',
url='https://github.com/tableau/document-api-python',
Expand Down
23 changes: 22 additions & 1 deletion tableaudocumentapi/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,20 @@ def __init__(self, connxml):
self._username = connxml.get('username')
self._authentication = connxml.get('authentication')
self._class = connxml.get('class')
self._port = connxml.get('port', None)

def __repr__(self):
return "'<Connection server='{}' dbname='{}' @ {}>'".format(self._server, self._dbname, hex(id(self)))

@classmethod
def from_attributes(cls, server, dbname, username, dbclass, authentication=''):
def from_attributes(cls, server, dbname, username, dbclass, port=None, authentication=''):
root = ET.Element('connection', authentication=authentication)
xml = cls(root)
xml.server = server
xml.dbname = dbname
xml.username = username
xml.dbclass = dbclass
xml.port = port

return xml

Expand Down Expand Up @@ -133,3 +135,22 @@ def dbclass(self, value):

self._class = value
self._connectionXML.set('class', value)

###########
# port
###########
@property
def port(self):
return self._port

@port.setter
def port(self, value):
self._port = value
# If port is None we remove the element and don't write it to XML
if value is None:
try:
del self._connectionXML.attrib['port']
except KeyError:
pass
else:
self._connectionXML.set('port', value)
15 changes: 15 additions & 0 deletions tableaudocumentapi/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def __init__(self, dsxml, filename=None):
self._name = self._datasourceXML.get('name') or self._datasourceXML.get(
'formatted-name') # TDS files don't have a name attribute
self._version = self._datasourceXML.get('version')
self._caption = self._datasourceXML.get('caption', '')
self._connection_parser = ConnectionParser(
self._datasourceXML, version=self._version)
self._connections = self._connection_parser.get_connections()
Expand Down Expand Up @@ -207,6 +208,20 @@ def name(self):
def version(self):
return self._version

@property
def caption(self):
return self._caption

@caption.setter
def caption(self, value):
self._datasourceXML.set('caption', value)
self._caption = value

@caption.deleter
def caption(self):
del self._datasourceXML.attrib['caption']
self._caption = ''

###########
# connections
###########
Expand Down
2 changes: 1 addition & 1 deletion test/assets/CONNECTION.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<connection authentication='sspi' class='sqlserver' dbname='TestV1' odbc-native-protocol='yes' one-time-sql='' server='mssql2012' username=''></connection>
<connection authentication='sspi' class='sqlserver' dbname='TestV1' odbc-native-protocol='yes' one-time-sql='' server='mssql2012' username='' port='1433'></connection>
3 changes: 2 additions & 1 deletion test/assets/datasource_test.tds
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version='1.0' encoding='utf-8' ?>
<datasource formatted-name='postgres.1of3kl00aoax5d1a1ejma1397430' inline='true' source-platform='mac' version='9.3' xmlns:user='http://www.tableausoftware.com/xml/user'>
<datasource caption='foo' formatted-name='postgres.1of3kl00aoax5d1a1ejma1397430' inline='true' source-platform='mac'
version='9.3' xmlns:user='http://www.tableausoftware.com/xml/user'>
<repository-location />
<connection authentication='username-password' class='postgres' dbname='TestV1' odbc-native-protocol='yes' port='5432' server='postgres91.test.tsi.lan' username='test'>
<relation name='xy' table='[public].[xy]' type='table' />
Expand Down
18 changes: 14 additions & 4 deletions test/bvt.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@

TABLEAU_10_TWB = os.path.join(TEST_DIR, 'assets', 'TABLEAU_10_TWB.twb')

TABLEAU_CONNECTION_XML = ET.parse(os.path.join(
TEST_DIR, 'assets', 'CONNECTION.xml')).getroot()
TABLEAU_CONNECTION_XML = os.path.join(TEST_DIR, 'assets', 'CONNECTION.xml')

TABLEAU_10_TWBX = os.path.join(TEST_DIR, 'assets', 'TABLEAU_10_TWBX.twbx')

Expand Down Expand Up @@ -51,7 +50,7 @@ def test_can_extract_federated_connections(self):
class ConnectionModelTests(unittest.TestCase):

def setUp(self):
self.connection = TABLEAU_CONNECTION_XML
self.connection = ET.parse(TABLEAU_CONNECTION_XML).getroot()

def test_can_read_attributes_from_connection(self):
conn = Connection(self.connection)
Expand All @@ -60,15 +59,24 @@ def test_can_read_attributes_from_connection(self):
self.assertEqual(conn.server, 'mssql2012')
self.assertEqual(conn.dbclass, 'sqlserver')
self.assertEqual(conn.authentication, 'sspi')
self.assertEqual(conn.port, '1433')

def test_can_write_attributes_to_connection(self):
conn = Connection(self.connection)
conn.dbname = 'BubblesInMyDrink'
conn.server = 'mssql2014'
conn.username = 'bob'
conn.port = '1337'
self.assertEqual(conn.dbname, 'BubblesInMyDrink')
self.assertEqual(conn.username, 'bob')
self.assertEqual(conn.server, 'mssql2014')
self.assertEqual(conn.port, '1337')

def test_can_delete_port_from_connection(self):
conn = Connection(self.connection)
conn.port = None
self.assertEqual(conn.port, None)
self.assertIsNone(conn._connectionXML.get('port'))

def test_bad_dbclass_rasies_attribute_error(self):
conn = Connection(self.connection)
Expand All @@ -90,11 +98,13 @@ def test_can_create_datasource_from_connections(self):
conn1 = Connection.from_attributes(
server='a', dbname='b', username='c', dbclass='mysql', authentication='d')
conn2 = Connection.from_attributes(
server='1', dbname='2', username='3', dbclass='mysql', authentication='7')
server='1', dbname='2', username='3', dbclass='mysql', port='1337', authentication='7')
ds = Datasource.from_connections('test', connections=[conn1, conn2])

self.assertEqual(ds.connections[0].server, 'a')
self.assertEqual(ds.connections[0].port, None)
self.assertEqual(ds.connections[1].server, '1')
self.assertEqual(ds.connections[1].port, '1337')


class ConnectionParserInComplicatedWorkbooks(unittest.TestCase):
Expand Down
43 changes: 42 additions & 1 deletion test/test_datasource.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import unittest
import os
import os.path
import shutil
import tempfile
import unittest


from tableaudocumentapi import Datasource, Workbook

Expand All @@ -22,6 +26,19 @@ class DataSourceFieldsTDS(unittest.TestCase):

def setUp(self):
self.ds = Datasource.from_file(TEST_TDS_FILE)
self.to_delete = set()

def cleanUp(self):
for path in self.to_delete:
if os.path.isdir(path):
shutil.rmtree(path, ignore_errors=True)
elif os.path.isfile(path):
os.unlink(path)

def get_temp_file(self, filename):
tempdir = tempfile.mkdtemp('tda-datasource')
self.to_delete.add(tempdir)
return os.path.join(tempdir, filename)

def test_datasource_returns_correct_fields(self):
self.assertIsNotNone(self.ds.fields)
Expand Down Expand Up @@ -63,6 +80,30 @@ def test_datasource_field_description(self):
self.assertIsNotNone(actual)
self.assertTrue(u'muted gray' in actual)

def test_datasource_caption(self):
actual = self.ds.caption
self.assertIsNotNone(actual)
self.assertEqual(actual, 'foo')

def test_datasource_can_set_caption(self):
filename = self.get_temp_file('test_datasource_can_set_caption')
self.ds.caption = 'bar'
self.ds.save_as(filename)

actual = Datasource.from_file(filename)
self.assertIsNotNone(actual)
self.assertIsNotNone(actual.caption)
self.assertEqual(actual.caption, 'bar')

def test_datasource_can_remove_caption(self):
filename = self.get_temp_file('test_datasource_can_remove_caption')
del self.ds.caption
self.ds.save_as(filename)

actual = Datasource.from_file(filename)
self.assertIsNotNone(actual)
self.assertEqual(actual.caption, '')

def test_datasource_clear_repository_location(self):
filename = os.path.join(TEST_ASSET_DIR, 'clear-repository-test.tds')

Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy