Skip to content

Commit 6056a6a

Browse files
author
Jon Walker
authored
Merge pull request #17 from sassoftware/dev
Merge Dev
2 parents a962c14 + ebc4d3d commit 6056a6a

23 files changed

+3635
-127
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ Unreleased
33
----------
44
**Improvements**
55
- Added `update_module` and `delete_module` methods to MAS service.
6-
6+
7+
**Changed**
8+
- Added `replace` parameter to `sasctl.tasks.publish_model`
9+
- `Session` hostname's can now be specified in HTTP format: 'http://example.com'.
10+
11+
**Bugfixes**
12+
- Renamed `microanalytic_store` service to `microanalytic_score`
13+
714

815
v1.0.1 (2019-07-31)
916
-------------------

CONTRIBUTING.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@ integration testing without requiring a running SAS Viya environment, the
3131
[Betamax](https://pypi.org/project/betamax/) package is used to record and
3232
replay network interactions.
3333

34-
In addition, [Tox](https://tox.readthedocs.io) is used to test
35-
compatibility with different Python version.
34+
In addition, [Tox](https://tox.readthedocs.io) is used to automate common development tasks
35+
such as testing, linting, and building documentation.
3636

3737
All packages required for development and testing are listed in
38-
[test_requirements.txt](test_requirements.txt) and can be easily installed with
39-
```
40-
pip install -r test_requirements.txt
41-
```
42-
38+
[tox.ini](tox.ini), but it should be unecessary to install these manually. Running `tox`
39+
from the project root directory will automatically build virtual environments for all
40+
Python interpreters found on the system and then install the required packages in those environments.
4341

4442
Before a pull request will be accepted:
4543
- contributions must pass existing regression tests located in tests/
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
sasctl.services.microanalytic\_store
1+
sasctl.services.microanalytic\_score
22
====================================
33

4-
.. automodule:: sasctl._services.microanalytic_store
4+
.. automodule:: sasctl._services.microanalytic_score
55
:members:
66
:undoc-members:
77
:show-inheritance:

doc/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
'betamax': ('https://betamax.readthedocs.io/en/latest/', None),
5555
'requests': (
5656
'https://2.python-requests.org/en/master/', None),
57-
'tox': ('https://tox.readthedocs.io/en/latest/', None)}
57+
'tox': ('https://tox.readthedocs.io/en/latest/', None),
58+
'flake8': ('http://flake8.pycqa.org/en/latest/', None)}
5859

5960
todo_include_todos = True
6061

doc/index.rst

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ If not already present, these packages will be downloaded and install automatica
3333
The following additional packages are recommended for full functionality:
3434

3535
- swat
36-
37-
38-
All required and recommended packages are listed in `requirements.txt` and can be installed easily with::
39-
40-
pip install -r requirements.txt
36+
- kerberos
4137

4238

4339
Installation
@@ -47,10 +43,14 @@ For basic functionality::
4743

4844
pip install sasctl
4945

50-
For full functionality::
5146

47+
Functionality that depends on additional packages can be installed using the following::
48+
49+
pip install sasctl[swat]
50+
pip install sasctl[kerberos]
5251
pip install sasctl[all]
5352

53+
5454
Quickstart
5555
----------
5656

@@ -347,7 +347,8 @@ simple code examples that demonstrate how to use various features are always wel
347347

348348

349349
All documentation is contained in the :file:`doc/` directory of the source repository and is written in `reStructuredText`_.
350-
The .rst files are then processed by `Sphinx`_ to produce the final documentation.
350+
The .rst files are then processed by `Sphinx`_ to produce the final documentation. See the :ref:`tox_commands` section for
351+
details on how to build the final documentation.
351352

352353
.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html
353354
.. _`Sphinx`: http://www.sphinx-doc.org/en/master/
@@ -370,11 +371,13 @@ the copyright to your contribution, this simply gives us permission to use and r
370371
part of the project.
371372

372373
1. Fork the repository
373-
#. Ensure you're environment has the necessary packages:
374+
#. Run all unit and integration tests and ensure they pass. This can be easily accomplished by running the following:
375+
376+
:command:`tox`
374377

375-
:command:`pip install -r test_requirements.txt`
378+
See :ref:`tox_commands` for more information on using Tox.
376379

377-
3. Run all unit and integration tests and ensure they pass. If any tests fail, you should investigate and correct the failure *before* making any changes.
380+
3. If any tests fail, you should investigate and correct the failure *before* making any changes.
378381
#. Make your code changes
379382
#. Include new tests that validate your changes
380383
#. Rerun all unit and integration tests and ensure they pass.
@@ -388,6 +391,8 @@ All code submissions must meet the following requirements before the pull reques
388391

389392
.. _`numpydoc`: https://numpydoc.readthedocs.io/en/latest/format.html
390393

394+
395+
391396
.. _testing:
392397

393398
Testing
@@ -416,6 +421,63 @@ And finally, the :doc:`tox <tox:index>` module is used to ensure that **sasctl**
416421
Python versions.
417422

418423

424+
.. _tox_commands:
425+
426+
Useful Tox Commands
427+
+++++++++++++++++++
428+
:mod:`tox` is used to automate common development tasks such as testing, linting, and building documentation.
429+
Running :program:`tox` from the project root directory will automatically build virtual environments for all Python interpreters
430+
found on the system and then install the required packages necessary to perform a given task. The simplest way to run Tox is:
431+
432+
.. code::
433+
434+
$ tox
435+
436+
This will run the :mod:`flake8` linter followed by :mod:`pytest` to test the code against all Python runtimes
437+
found on the machine. One of the great features of Tox is the ability to run specific tasks by specifying the environment to run.
438+
A few useful environments are listed below, where **XX** indicates a Python version present in your development environment,
439+
such as '27' or '36'.
440+
441+
#.
442+
.. code::
443+
444+
$ tox -e pyXX-flake8
445+
446+
Runs the flake8 linter against all **sasctl** source code.
447+
448+
#.
449+
.. code::
450+
451+
$ tox -e pyXX-flake8 src/sasctl/tasks.py
452+
453+
Runs the flake8 linter against a specific file.
454+
455+
#.
456+
.. code::
457+
458+
$ tox -e pyXX-tests
459+
460+
Runs all tests using the specified Python interpreter.
461+
462+
#.
463+
.. code::
464+
465+
$ tox -e pyXX-doc
466+
467+
Builds the documentation.
468+
469+
#.
470+
.. code::
471+
472+
$ tox -e pyXX-tests -- python
473+
474+
Starts a Python REPL in an environment with **sasctl** already installed.
475+
476+
For additional information on configuring and using Tox, see the official :doc:`documentation <tox:index>` or Sean Hammond's excellent `tutorial`_.
477+
478+
.. _`tutorial`: https://seanh.cc/post/tox-tutorial/
479+
480+
419481
Release History
420482
---------------
421483

requirements.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/sasctl/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Copyright © 2019, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
55
# SPDX-License-Identifier: Apache-2.0
66

7-
__version__ = '1.0.1'
7+
__version__ = '1.1.0'
88
__author__ = 'SAS'
99
__credits__ = ['Yi Jian Ching, Lucas De Paula, Peter Tobac, Chris Toth, Jon '
1010
'Walker']

src/sasctl/_services/model_publish.py

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,33 @@
44
# Copyright © 2019, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
55
# SPDX-License-Identifier: Apache-2.0
66

7+
"""Enables publishing objects such as models to various destinations."""
8+
79
import re
810

911
from .service import Service
12+
from .model_repository import ModelRepository
1013

1114

1215
class ModelPublish(Service):
13-
"""The Model Publish API provides support for publishing objects (such as
14-
models) to CAS, Hadoop, SAS Micro Analytic Service, or Teradata.
16+
"""Enables publishing objects such as models to various destinations.
17+
18+
The service provides methods for managing publish destinations like CAS,
19+
Hadoop, Teradata, or SAS Micro Analytic Service
1520
"""
21+
1622
_SERVICE_ROOT = '/modelPublish'
23+
_model_repository = ModelRepository()
1724

1825
@staticmethod
1926
def _publish_name(name):
2027
"""Create a valid module name from an input string.
2128
22-
Model Publishing only permits names that adhere to the following restrictions:
29+
Model Publishing only permits names that adhere to the following
30+
restrictions:
2331
- Name must start with a letter or an underscore.
24-
- Name may not contain any spaces or special characters other than underscore.
32+
- Name may not contain any spaces or special characters other than
33+
underscore.
2534
2635
Parameters
2736
----------
@@ -30,8 +39,8 @@ def _publish_name(name):
3039
Returns
3140
-------
3241
str
33-
"""
3442
43+
"""
3544
# Remove all non-word characters
3645
name = re.sub(r'[^\w]', '', str(name))
3746

@@ -41,31 +50,53 @@ def _publish_name(name):
4150

4251
return name
4352

44-
def list_models(self):
45-
return self.get('/models').get('items', [])
53+
@classmethod
54+
def list_models(cls):
55+
return cls.get('/models').get('items', [])
4656

47-
def list_destinations(self):
48-
return self.get('/destinations').get('items', [])
57+
list_destinations, get_destination, update_destination, \
58+
delete_destination = Service._crud_funcs('/destinations',
59+
'destination')
4960

50-
def publish_model(self, model, destination, name=None, code=None,
61+
@classmethod
62+
def publish_model(cls, model, destination, name=None, code=None,
5163
notes=None):
64+
"""
5265
66+
Parameters
67+
----------
68+
model : str or dict
69+
The name or id of the model, or a dictionary representation of
70+
the model.
71+
destination : str or dict
72+
The name or id of the publishing destination, or a dictionary
73+
representation of the destination
74+
name : str, optional
75+
Name of the published model. Defaults to the model name.
76+
code : str, optional
77+
The code to be published.
78+
notes
79+
80+
Returns
81+
-------
82+
83+
"""
5384
code_types = {
5485
'ds2package': 'ds2',
5586
'datastep': 'datastep',
5687
'': ''
5788
}
5889

59-
model = services.model_repository.get_model(model)
60-
model_uri = services.model_repository.get_model_link(model, 'self')
90+
model = cls._model_repository.get_model(model)
91+
model_uri = cls._model_repository.get_model_link(model, 'cls')
6192

6293
# Get score code from registry if no code specified
6394
if code is None:
64-
code_link = services.model_repository.get_model_link(model,
65-
'scoreCode',
66-
True)
95+
code_link = cls._model_repository.get_model_link(model,
96+
'scoreCode',
97+
True)
6798
if code_link:
68-
code = get(code_link['href'])
99+
code = cls.get(code_link['href'])
69100

70101
request = dict(
71102
name=name or model.get('name'),
@@ -84,7 +115,6 @@ def publish_model(self, model, destination, name=None, code=None,
84115
}
85116

86117
request['modelContents'] = [modelContents]
87-
return self.post('/models', json=request, headers={
88-
'Content-Type': 'application/vnd.sas.models.publishing.request+json'})
89-
90-
118+
return cls.post('/models', json=request, headers={
119+
'Content-Type':
120+
'application/vnd.sas.models.publishing.request+json'})

0 commit comments

Comments
 (0)