diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5147813a --- /dev/null +++ b/.gitignore @@ -0,0 +1,109 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +VERSION + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage-*.xml +results-*.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# Pycharm +.idea/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..6922a8e4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +sudo: false +language: python +python: +- '2.7' +- '3.5' +- '3.6' +install: +- make prepare +- pip install tox-travis +script: +- make tests +deploy: + distributions: git_version sdist + provider: pypi + user: neptune-deployer + password: + secure: MqNZf74g0qzaJpdKZZgArCPWKnQ96RgAZRflmZcmZVmm5RUZtY0a9xJvdUsODaU5OBpsbJvTdyEzPBRn8XSkM04+KuRhrPRGy6qwgGEeRTNGmkJKiCUuozvJA/2Z6Ou/IdFyRGvmWBWzM6bRrcPIRkKvQ4W22FPXa664lQU36yLLQM2wYBiSzgFAe8QMRboiMZ/bcrxwMn9P2kWxU+mkn3+734yZqlqwtSDenKNdzzJsEtdyUX3cEzALBQSrg/Ukfmo89KMAN7Uq9ATANgSPevJoT86tZPYndUpchXpIOG2i7yVCoRAyyW2o01ZSgjMLyboFr3wkbMJYVn+r2BO7m0xkOOhceUJWtsp3ELklJfAxqhPlTEhpW06XDU8grH36Mq7edeX/a7i8F2EXg8oWsnXqcaUxo3cez7gbn7oc7YpuaWPB6GAdrJtJJsv3gFcdoyBhUoAr+1v+Dq8iBIM3wRYv9wgm/FfS/gNQSMCj1TppIaetWXf+PzDcpFMKVCpX9yWsYWOFpdOqfeVOoQ2EmoQWlU9EjgNQQyPvzzIomuhHvVTGSvKUhUMqkQOETSwDTg2XhUaa/ayDxa+xU5jZLSNhr1Z5wVLraBPH3P9isZNASVD+nGopq9//XRbt96aO/0i4w+XcFWEvBfVzuy7j4bEvkMKjzpw71z25hn+FBz4= + on: + tags: true + skip_existing: true diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..d39f6c87 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at contact@neptune.ml. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..60ff4479 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include requirements.txt +include VERSION +include git_version.py \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..02b07249 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +clean: + rm -fr .tox/ dist/ VERSION + +prepare: + pip install -r requirements.txt -r test_requirements.txt + +build: + python setup.py git_version sdist + +tests: checkstyle_tests unit_tests + +checkstyle_tests: + python -m pylint -j 0 -f parseable neptune_notebooks tests + +unit_tests: + tox diff --git a/README.md b/README.md new file mode 100644 index 00000000..29a1b7a3 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# neptune-notebooks +[![Build Status](https://travis-ci.org/neptune-ml/neptune-notebooks.svg?branch=master)](https://travis-ci.org/neptune-ml/neptune-notebooks) diff --git a/git_version.py b/git_version.py new file mode 100644 index 00000000..e2283809 --- /dev/null +++ b/git_version.py @@ -0,0 +1,54 @@ +# Original source: https://github.com/Changaco/version.py +import os +import re +from distutils.cmd import Command +from subprocess import CalledProcessError, call, check_output + +PREFIX = '' +INITIAL_VERSION = '0.0.0' + +tag_re = re.compile(r'\btag: %s([0-9][^,]*)\b' % PREFIX) +version_re = re.compile('^Version: (.+)$', re.M) + + +def get_git_version(): + if "VERSION" in os.environ: + return os.environ.get("VERSION") + + # Return the version if it has been injected into the file by git-archive + version = tag_re.search('$Format:%D$') + if version: + return version.group(1) + + # Get the version using "git describe". + try: + cmd = 'git describe --tags --match %s[0-9.]* --dirty' % PREFIX + version = check_output(cmd.split()).decode().strip()[len(PREFIX):] + except CalledProcessError: + version = INITIAL_VERSION + '+' + check_output('git rev-parse HEAD'.split()).decode().strip()[:10] + if call('git diff --quiet'.split()) != 0: + version += '.dirty' + + # PEP 440 compatibility + if '-' in version: + version_tokens = version.split('-') + version = version_tokens[0] + '+' + '.'.join(version_tokens[1:]) + + return version + + +class GitVersion(Command): + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + version = get_git_version() + self.distribution.metadata.version = version + + with open('VERSION', 'w') as version_file: + version_file.write(version) diff --git a/notebook/neptune-notebook.js b/jupyter-notebook-plugin/neptune-notebook.js similarity index 100% rename from notebook/neptune-notebook.js rename to jupyter-notebook-plugin/neptune-notebook.js diff --git a/neptune_notebooks/__init__.py b/neptune_notebooks/__init__.py new file mode 100644 index 00000000..62a86a5b --- /dev/null +++ b/neptune_notebooks/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/neptune_notebooks/upload.py b/neptune_notebooks/upload.py new file mode 100644 index 00000000..c91b412c --- /dev/null +++ b/neptune_notebooks/upload.py @@ -0,0 +1,36 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import sys + +import click + +import neptune + + +def upload(path, project): + if not os.path.exists(path): + click.echo("ERROR: File `{}` doesn't exist".format(path), err=True) + sys.exit(1) + + if not os.path.isfile(path): + click.echo("ERROR: `{}` is not a file".format(path), err=True) + sys.exit(1) + + project = neptune.init(project_qualified_name=project) + + click.echo("Uploading notebook {} to project {}.".format(path, project)) diff --git a/neptune_notebooks_plugin/__init__.py b/neptune_notebooks_plugin/__init__.py new file mode 100644 index 00000000..516fa03e --- /dev/null +++ b/neptune_notebooks_plugin/__init__.py @@ -0,0 +1,26 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import click + + +@click.command('notebook') +@click.argument('path', required=True) +@click.option('--project', '-p', help='Project name') +def upload(path, project): + # We do not want to import anything if process was executed for autocompletion purposes. + from neptune_notebooks.upload import upload as run_upload + return run_upload(path=path, project=project) diff --git a/pylintrc b/pylintrc new file mode 100644 index 00000000..a3263d54 --- /dev/null +++ b/pylintrc @@ -0,0 +1,296 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Profiled execution. +profile=no + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins=pylintfileheader + +# File header +file-header=#\n# Copyright \(c\) 2019, Neptune Labs Sp\. z o\.o\.\n#\n# Licensed under the Apache License, Version 2\.0 \(the "License"\);\n# you may not use this file except in compliance with the License\.\n# You may obtain a copy of the License at\n#\n# http://www\.apache\.org/licenses/LICENSE-2\.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an "AS IS" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.\n# See the License for the specific language governing permissions and\n# limitations under the License\.\n#\n + +[MESSAGES CONTROL] + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" + +# R Disable all messages of "Refactor" category. +# C0103 Disable checking variable/function/class names. +# C0111 Allow packages, classes and methods without docstrings. +# W0401, W0614 Allow wildcard imports. +# W0511 Allow TODO/FIXME comments. +# W0703 Allow too broad except clause (Exception). +# I0011 Do not show Locally disabled warnings in report +# C0412 Disable checking imports from package %s are not grouped +disable=R,C0103,C0111,W0401,W0511,W0614,W0703,I0011,C0412 + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. See also the "--disable" option for examples. + +# R0401 Enable detection of cyclic imports. +# R0801 Enable detection of similar code. +# R0921 Enable checking for unused abstract classes. +# R0923 Enable checking for unused interfaces. +enable=R0401,R0801,R0921,R0923 + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=no + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (RP0004). +comment=no + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=10 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=yes + + +[BASIC] + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,apply,input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct attribute names in class +# bodies +class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,x,y,z,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=__.*__ + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the beginning of the name of dummy variables +# (i.e. not used). +dummy-variables-rgx=_$|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=120 + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + +# List of optional constructs for which whitespace checking is disabled +no-space-check=trailing-comma,dict-separator + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject + +# When zope mode is activated, add a predefined set of Zope acquired attributes +# to generated-members. +zope=no + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST,acl_users,aq_parent + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Do not whine about Redefining built-in objects when importing from future.builtins. +redefining-builtins-modules=future.builtins,past.builtins + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +# ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..18575849 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +click>=7.0 +future>=0.17.1 +neptune-client>=0.2.1 +path.py diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..5e409001 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[wheel] +universal = 1 diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..7ffbf374 --- /dev/null +++ b/setup.py @@ -0,0 +1,80 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os + +from setuptools import find_packages, setup + +import git_version + + +def version(): + try: + with open('VERSION') as f: + return f.readline().strip() + except IOError: + return '0.0.0' + + +def main(): + root_dir = os.path.dirname(__file__) + + with open(os.path.join(root_dir, 'requirements.txt')) as f: + requirements = [r.strip() for r in f] + setup( + name='neptune-notebooks', + version=version(), + url='https://github.com/neptune-ml/neptune-notebooks', + license='Apache License 2.0', + author='neptune.ml', + author_email='contact@neptune.ml', + description='Neptune Notebooks', + long_description=__doc__, + packages=find_packages(), + platforms='any', + install_requires=requirements, + entry_points={ + 'neptune.plugins': "notebook = neptune_notebooks_plugin:upload" + }, + cmdclass={ + 'git_version': git_version.GitVersion, + }, + classifiers=[ + # As from http://pypi.python.org/pypi?%3Aaction=list_classifiers + # 'Development Status :: 1 - Planning', + # 'Development Status :: 2 - Pre-Alpha', + # 'Development Status :: 3 - Alpha', + 'Development Status :: 4 - Beta', + # 'Development Status :: 5 - Production/Stable', + # 'Development Status :: 6 - Mature', + # 'Development Status :: 7 - Inactive', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: POSIX', + 'Operating System :: MacOS', + 'Operating System :: Unix', + 'Operating System :: Microsoft :: Windows', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Topic :: Software Development :: Libraries :: Python Modules', + ] + ) + + +if __name__ == "__main__": + main() diff --git a/test_requirements.txt b/test_requirements.txt new file mode 100644 index 00000000..f6f9e2c0 --- /dev/null +++ b/test_requirements.txt @@ -0,0 +1,10 @@ +astroid==1.6.1 +bunch==1.0.1 +mock==2.0.0 +psutil==5.5.0 +pylint==1.9.3 +pylintfileheader==0.0.2 +pytest==4.1.0 +pytest-cov==2.6.1 +pytest-xdist==1.25.0 +tox==3.6.1 \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..62a86a5b --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/tests/neptune_notebooks/__init__.py b/tests/neptune_notebooks/__init__.py new file mode 100644 index 00000000..62a86a5b --- /dev/null +++ b/tests/neptune_notebooks/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/tests/neptune_notebooks/test_upload.py b/tests/neptune_notebooks/test_upload.py new file mode 100644 index 00000000..9365f392 --- /dev/null +++ b/tests/neptune_notebooks/test_upload.py @@ -0,0 +1,22 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import unittest + + +class TestUpload(unittest.TestCase): + + def test_placeholder(self): + pass diff --git a/tests/neptune_notebooks_plugin/__init__.py b/tests/neptune_notebooks_plugin/__init__.py new file mode 100644 index 00000000..62a86a5b --- /dev/null +++ b/tests/neptune_notebooks_plugin/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/tests/neptune_notebooks_plugin/test_plugin.py b/tests/neptune_notebooks_plugin/test_plugin.py new file mode 100644 index 00000000..c1b27c18 --- /dev/null +++ b/tests/neptune_notebooks_plugin/test_plugin.py @@ -0,0 +1,39 @@ +# +# Copyright (c) 2019, Neptune Labs Sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import unittest +import random + +from click.testing import CliRunner + +from neptune_notebooks_plugin import upload + + +class TestPlugin(unittest.TestCase): + runner = CliRunner() + + def test_path_not_exist(self): + path = '/tmp/{}'.format(random.randint(10000, 1000000)) + result = self.runner.invoke(upload, [path]) + self.assertEqual(result.exit_code, 1) + self.assertEqual(result.output.strip(), "ERROR: File `{}` doesn't exist".format(path)) + + def test_path_is_not_file(self): + path = '/tmp/{}'.format(random.randint(10000, 1000000)) + os.mkdir(path) + result = self.runner.invoke(upload, [path]) + self.assertEqual(result.exit_code, 1) + self.assertEqual(result.output.strip(), "ERROR: `{}` is not a file".format(path)) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..f1586069 --- /dev/null +++ b/tox.ini @@ -0,0 +1,29 @@ +[tox] +# platform specification support is available since version 2.0 +minversion = 2.0 +envlist = py{27,35,36}-{linux,win32} + +[testenv] +# See https://docs.python.org/2/library/sys.html#sys.platform for platform codes +platform = linux: linux + win32: win32 + +deps = -rtest_requirements.txt + -rrequirements.txt + +commands = pytest \ + --cov-config tox.ini \ + --cov-report xml:tests/coverage-{envname}.xml \ + --cov . \ + -n 4 \ + --junitxml tests/results-{envname}.xml \ + {posargs} \ + tests/neptune_notebooks + +setenv = PYTHONIOENCODING=UTF-8 + +[coverage:run] +omit = .tox/* + +[coverage:report] +exclude_lines = unittest.main