# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['rspace_client', 'rspace_client.eln', 'rspace_client.inv']

package_data = \
{'': ['*'],
 'rspace_client': ['.spyproject/config/*', '.spyproject/config/defaults/*']}

install_requires = \
['beautifulsoup4>=4.9.3,<5.0.0', 'requests>=2.25.1,<3.0.0']

setup_kwargs = {
    'name': 'rspace-client',
    'version': '2.0.0a0',
    'description': 'A client for calling RSpace ELN and Inventory APIs',
    'long_description': '# rspace-client-python\n\nThis project contains a client which helps calling RSpace ELN and Inventory APIs. There are some example Python scripts.\n\nTo begin with, you\'ll need an account on an RSpace server and an API key which you can get from your [profile page](https://researchspace.helpdocs.io/article/v0dxtfvj7u-rspace-api-introduction\n).\nYou can sign up for a free RSpace account at https://community.researchspace.com\n\nIn these examples we\'ll be using the rspace_client package (code is in rspace_client folder) which provides an abstraction over lower-level libraries. \nIt\'s compatible with Python 3.7 onwards, based on analysis by [vermin](https://pypi.org/project/vermin/vermin) \n\nAll the code listed here is in the project.\n\nFor full details of our API spec please see https://$RSPACE_API/public/apiDocs\n\nSee [DEVELOPING.md](DEVELOPING.md) for details of running tests.\n\n\nTo install rspace-client and its dependencies, run\n\n```bash\npip3 install rspace-client\n```\n\nYou may need to install `requests` module:\n\n``` bash\npip3 install  requests\n```\n\n### Using the rspace_client library in your own code\n\nYou\'ll need a running RSpace instance to send requests to.\n\nThe simplest way to read in the URL and API key is from environment variables, e.g.\n\n```\nbash> export RSPACE_URL=https:/myrspace.com\nbash> export RSPACE_API_KEY=abcdefgh...\n```\nsubstituting in your own values.\n\n```\nimport os\nimport rspace_client.inv.inv as inv\nimport rspace_client.eln.eln as eln\n\n\ninv_cli = inv.InventoryClient(os.getenv("RSPACE_URL"), os.getenv("RSPACE_API_KEY"))\neln_cli = eln.ELNClient(os.getenv("RSPACE_URL"), os.getenv("RSPACE_API_KEY"))\n\nsamples = inv_cli.list_samples())\nprint (f"There are {samples[\'totalHits\']} samples")\n\nprint(eln_cli.get_status())\n```\n\n## Running example scripts\n\nTo run the example scripts in the examples folder, cd to that folder, then run\n\n```bash\npython3 ExampleScript.py $RSPACE_URL $RSPACE_API_KEY\n```\n\nreplacing ExampleScript.py with the name of the script you want to run.\n\n### A basic query to list documents\n\nFirst of all we\'ll get our URL and key from a command-line parameters.\n\n```python\nparser = argparse.ArgumentParser()\nparser.add_argument("server", help="RSpace server URL (for example, https://community.researchspace.com)", type=str)\nparser.add_argument("apiKey", help="RSpace API key can be found on \'My Profile\'", type=str)\nargs = parser.parse_args()\n\nclient = rspace_client.Client(args.server, args.apiKey)\ndocuments = client.get_documents()\n```\n\nIn the above example, the \'documents\' variable is a dictionary that can easily be accessed for data:\n\n```python\nprint(document[\'name\'], document[\'id\'], document[\'lastModified\'])\n```\n\n#### Iterating over pages of results\n\nThe JSON response also contains a `_links` field that uses HATEOAS conventions to provide links to related content. For document listings and searches, links to `previous`, `next`, `first` and `last` pages are provided when needed.\n\nUsing this approach we can iterate through pages of results, getting summary information for each document.\n\n```python\nwhile client.link_exists(response, \'next\'):\n    print(\'Retrieving next page...\')\n    response = client.get_link_contents(response, \'next\')\n```\n\nA complete example of this is `examples/paging_through_results.py`.\n\n### Searching\n\nRSpace API provides  two sorts of search - a basic search that searches all searchable fields, and an advanced search where more fine-grained queries can be made and combined with boolean operators.\n\nA simple search can be run by calling get_documents with a query parameter:\n\n```python\n  response = client.get_documents(query=\'query_text\')\n\n```\n\nHere are some examples of advanced search constructs:\n\n```python   \n    // search by tag:\n    search = json.dumps([terms:[[query:"ATag", queryType:"tag"]]])\n    \n    // by name\n    search = json.dumps([terms:[[query:"AName", queryType:"name"]]])\n    \n    // for items created on a given date using IS0-8601 or yyyy-MM-dd format\n    search = json.dumps([terms:[[query:"2016-07-23", queryType:"created"]]])\n    \n    // for items modified between 2  dates using IS0-8601 or yyyy-MM-dd format\n    search = json.dumps([terms:[[query:"2016-07-23;2016-08-23 ", queryType:"lastModified"]]])\n    \n    // for items last modified on either of 2  dates:\n    search = json.dumps([operator:"or",terms:[[query:"2015-07-06", queryType:"lastModified"],\n                                    [query:"2015-07-07", queryType:"lastModified"] ])\n\n    // search for documents created from a given form:\n    search = json.dumps([terms:[[query:"Basic Document", queryType:"form"]]])\n    \n    // search for documents created from a given form and a specific tag:\n    search = json.dumps([operator:"and", terms:[[query:"Basic Document", queryType:"form"], [query:"ATag", queryType:"tag"]]])        \n```\n\nor by using AdvancedQueryBuilder\n\n```python\n# Creation date (documents created between 2017-01-01 and 2017-12-01\nadvanced_query = rspace_client.AdvancedQueryBuilder().\\\n    add_term(\'2017-01-01;2017-12-01\', rspace_client.AdvancedQueryBuilder.QueryType.CREATED).\\\n    get_advanced_query()\n```\n\nTo submit these queries pass them as a parameter to `get_get_documents_advanced_query`:\n\n```python\n    response = client.get_documents_advanced_query(advanced_query)\n    for document in response[\'documents\']:\n        print(document[\'name\'], document[\'id\'], document[\'lastModified\'])\n\n```\n\n### Retrieving document content\n\nContent can be retrieved from the endpoint `/documents/{id}` where {id} is a documentID.\n\nHere is an example retrieving a document in CSV format taken from `forms.py` script:\n\n```python\nadvanced_query = rspace_client.AdvancedQueryBuilder(operator=\'and\').\\\n    add_term(form_id, rspace_client.AdvancedQueryBuilder.QueryType.FORM).\\\n    get_advanced_query()\n\nresponse = client.get_documents_advanced_query(advanced_query)\n\nprint(\'Found answers:\')\nfor document in response[\'documents\']:\n    print(\'Answer name:\', document[\'name\'])\n    document_response = client.get_document_csv(document[\'id\'])\n    print(document_response)\n\n```\n\n### Getting attached files\n\nHere\'s an example where we download file attachments associated with some documents. The code is in `download_attachments.py`. \n\n```python\ntry:\n    response = client.get_document(doc_id=document_id)\n    for field in response[\'fields\']:\n        for file in field[\'files\']:\n            download_metadata_link = client.get_link_contents(file, \'self\')\n            filename = \'/tmp/\' + download_metadata_link[\'name\']\n            print(\'Downloading to file\', filename)\n            client.download_link_to_file(client.get_link(download_metadata_link, \'enclosure\'), filename)\nexcept ValueError:\n    print(\'Document with id %s not found\' % str(document_id))\n```\n\n### Creating / editing a new document\n\nA document can be created by sending a POST request to `/documents`. Document name, form from which the document is created, tags and field values can be specified. The example code is in `create_document.py`.\n\n```python\n# Creating a new Basic document in Api Inbox folder\nnew_document = client.create_document(name=\'Python API Example Basic Document\', tags=[\'Python\', \'API\', \'example\'],\n                                      fields=[{\'content\': \'Some example text\'}])\n```\n\nYou can also supply the `parentFolderId` of the workspace folder you want the document created in:\n\n\n```python\n# Creating a new Basic document in specified folder:\nnew_document = client.create_document(name=\'Python API Example Basic Document\', tags=[\'Python\', \'API\', \'example\'],\n                                      fields=[{\'content\': \'Some example text\'}], parent_folder_id=21);\n```\n\nIt is possible to edit a document by sending a PUT request to `/documents/{id}`, where {id} is a documentID. Document name, tags and field values can be edited.\n\n```python\n# Editing the document to link to the uploaded file\nclient.update_document(document[\'id\'], fields=[{\'content\': \'Edited example text.\'}])\n```\n\n### Uploading a file to gallery\n\nAny file that can be uploaded by using the UI can be uploaded by sending a POST request to `/files`. Also, it is possible to link to the file from any document as shown in `create_document.py` example.\n\n```python\n# Uploading a file to the gallery\nwith open(\'resources/2017-05-10_1670091041_CNVts.csv\', \'rb\') as f:\n    new_file = client.upload_file(f, caption=\'some caption\')\n```\n\n\n### Linking to files and other RSpace documents\n\nThere is a convenient syntax to link to either files or other RSpace documents.\n\nTo include links to files in your document content, you can use the syntax <fileId=12345> where \'12345\' is the ID of a file uploaded through the\n`files/` endpoint.\n\n\n```python\n# Editing a document to link to an uploaded file\nclient.update_document(new_document[\'id\'], fields=[{\n    \'content\': \'Some example text. Link to the uploaded file: <fileId={}>\'.format(new_file[\'id\'])\n}])\n```\n\nTo include links to RSpace documents, folders or notebooks in your document content, you can use the syntax <docId=12345> where \'12345\' is the ID of an RSpace document,folder or notebook. E.g.\n\n\n```python\n# Editing a document to link to another RSpace document\nclient.update_document(new_document[\'id\'], fields=[{\n    \'content\': \'Some example text. Link to another document: <docId={}>\'.format(anotherDocument[\'id\'])\n}])\n```\n\n### Activity\n\nAccess to the information that is available from the RSpace audit trail. This provides logged information on \'who did what, when’.\n\nFor example, to get all activity for a particular document:\n\n```python\nresponse = client.get_activity(global_id=document_id)\n\nprint(\'Activities for document {}:\'.format(document_id))\nfor activity in response[\'activities\']:\n    print(activity)\n```\n\nTo get all activity related to documents being created or modified last week:\n\n```python\ndate_from = date.today() - timedelta(days=7)\nresponse = client.get_activity(date_from=date_from, domains=[\'RECORD\'], actions=[\'CREATE\', \'WRITE\'])\n\nprint(\'All activity related to documents being created or modified from {} to now:\'.format(date_from.isoformat()))\nfor activity in response[\'activities\']:\n    print(activity)\n```\n\n### Creating a Folder / Notebook\n\nA folder can be created by sending a POST request to `/folders`. All arguments are optional. Name, parent folder id and whether to create a notebook can be specified. For example, to create a folder named \'Testing Folder\', `create_folder` method can be used:\n\n```python\n# Creating a folder named \'Testing Folder\'\nnew_folder = client.create_folder(\'Testing Folder\')\n```\n\nNotebooks can be created by setting `notebook=True`. To create a new notebook inside the previously created folder:\n\n```python\n# Creating a notebook named \'Testing Notebook\' inside the previously created folder:\nnew_notebook = client.create_folder(\'Testing Notebook\', parent_folder_id=new_folder[\'globalId\'], notebook=True)\n```\n\nThere are some restrictions on where you can create folders and notebooks, which are required to maintain consistent behaviour with the web application.\n\n* You can\'t create folders or notebooks inside notebooks\n* You can\'t create notebooks inside the Shared Folder; create them in a User folder first, then share. (Sharing is not yet supported in the API, but you can do this in the web application).\n\n\n### Getting Information About a Folder / Notebook\n\nFolder or notebook information can be retrieved by sending a GET request to `/folders/{folderId}` where folder id is a numerical ID of a folder or a notebook. Python client accepts both numerical IDs and global IDs. Method `get_folder` can be used to get information about a folder:\n\n```python\n# Get information about a folder\nfolder_info = client.get_folder(\'FL123\')  # or client.get_folder(123)\nprint(folder_info[\'globalId\'], folder_info[\'name\'])\n```\n\n### Forms\n\nPublished forms can be listed by sending a GET request to `/forms`. The results might be paginated if there are too many forms (see `create_form.py` example for a more in depth usage example).\n\n```python\n# Listing all published forms\nresponse = client.get_forms()\nfor form in response[\'forms\']:\n    print(form[\'globalId\'], form[\'name\'])\n```\n\nA new form can be created by sending a POST request to `/forms`. Name, tags (optionally) and fields can be specified. Currently, supported types of form fields are: \'String\', \'Text\', \'Number\', \'Radio\', \'Date\'. More information about the available parameters can be found in [API documentation](https://community.researchspace.com/public/apiDocs) or by looking at `create_form.py` source code.\n\n```python\n# Creating a new form\nfields = [\n    {\n      "name": "A String Field",\n      "type": "String",\n      "defaultValue": "An optional default value"\n    }\n]\nclient.create_form(\'Test Form\', tags=[\'testing\', \'example\'], fields=fields)\n```\n\nForm information can be retrieved by sending a GET request to `/forms/{formId}` where formId is a numerical ID of a form. Python client accepts both numerical IDs and global IDs. \n```python\n# Getting information about a form\nresponse = client.get_form(\'FM3\')  # or client.get_form(3)\nprint(\'Retrieved information about a form:\', response[\'globalId\'], response[\'name\'])\nprint(\'Fields:\')\nfor field in response[\'fields\']:\n    print(field[\'type\'], field[\'name\'])\n```\n\nA newly created form is not available to create documents from until it has been published. Sending a POST request to `/forms/{formId}/publish` publishes a form.\n```python\n# Publishing form FM123\nclient.publish_form(\'FM123\')  # or client.publish_form(123)\n\n# Unpublish the form\nclient.unpublish_form(\'FM123\')  # or client.unpublish_form(123)\n```\n\nIt is possible to share a form with your groups. Once it is shared the `accessControl.groupPermissionType` property is `READ`.\n```python\n# Sharing form FM123\nclient.share_form(\'FM123\')\n\n# Unsharing the form\nclient.unshare_form(\'FM123\')\n```\n\n### Export\n\nYou can programmatically export your work in HTML or XML format. This might be useful if you want to make scheduled backups, for example. If you\'re an admin or PI you can export a particular user\'s work if you have permission.\n\nYou can also export specific documents, notebooks or folders. _Note_ this requires RSpace 1.69.19 or later.\n\nBecause export can be quite time-consuming, this is an asynchronous operation. On initial export you will receive a link to a job that you can query for progress updates. When the export has completed there will be a link to access the exported file - which may be very large.\n\nThis Python API client provides an easy to use method that handles starting an export, polling the job\'s status and downloading the exported archive once it\'s ready. For example, to export current user\'s work in XML format: \n```python\nexport_archive_file_path = client.download_export(\'xml\', \'user\', file_path=\'/tmp\')\n```\n\nThere are ```start_export(self, format, scope, id=None)``` and ```get_job_status(self, job_id)``` functions to start the export and check its status as well.\n',
    'author': 'Research Innovations Ltd',
    'author_email': 'richard@researchspace.com',
    'maintainer': 'Richard Adams',
    'maintainer_email': 'richard@researchspace.com',
    'url': 'https://github.com/rspace-os/rspace-client-python',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7.11,<4.0.0',
}


setup(**setup_kwargs)
