{"id":42514111,"url":"https://github.com/rspace-os/rspace-client-python","last_synced_at":"2026-01-28T14:33:38.964Z","repository":{"id":16747203,"uuid":"80580138","full_name":"rspace-os/rspace-client-python","owner":"rspace-os","description":"Python SDK and examples for  the RSpace API","archived":false,"fork":false,"pushed_at":"2025-10-24T08:28:35.000Z","size":717,"stargazers_count":17,"open_issues_count":4,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-10-24T10:22:14.684Z","etag":null,"topics":["eln","python","rest-api","rspace"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rspace-os.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-02-01T01:37:21.000Z","updated_at":"2025-08-06T08:22:23.000Z","dependencies_parsed_at":"2022-08-18T01:05:50.419Z","dependency_job_id":"7448f239-9c57-466e-81c4-cab9b7eacb86","html_url":"https://github.com/rspace-os/rspace-client-python","commit_stats":{"total_commits":282,"total_committers":7,"mean_commits":"40.285714285714285","dds":"0.24113475177304966","last_synced_commit":"9b2f0cffe82fd4e85b410daf6d574abcec5c1ca7"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/rspace-os/rspace-client-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspace-os%2Frspace-client-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspace-os%2Frspace-client-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspace-os%2Frspace-client-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspace-os%2Frspace-client-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rspace-os","download_url":"https://codeload.github.com/rspace-os/rspace-client-python/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspace-os%2Frspace-client-python/sbom","scorecard":{"id":787558,"data":{"date":"2025-08-11","repo":{"name":"github.com/rspace-os/rspace-client-python","commit":"d4f9c720777560b3f6b4394803653e30000942be"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Security-Policy","score":4,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Warn: no linked content found","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Code-Review","score":5,"reason":"Found 6/12 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-and-tests.yml:13","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-and-tests.yml:14","Warn: no topLevel permission defined: .github/workflows/codeql-and-tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-and-tests.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/rspace-os/rspace-client-python/codeql-and-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-and-tests.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/rspace-os/rspace-client-python/codeql-and-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-and-tests.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/rspace-os/rspace-client-python/codeql-and-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-and-tests.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/rspace-os/rspace-client-python/codeql-and-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-and-tests.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/rspace-os/rspace-client-python/codeql-and-tests.yml/master?enable=pin","Warn: downloadThenRun not pinned by hash: .github/workflows/codeql-and-tests.yml:47","Info:   0 out of   5 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 1 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T06:29:14.256Z","repository_id":16747203,"created_at":"2025-08-23T06:29:14.256Z","updated_at":"2025-08-23T06:29:14.256Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28846058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T13:02:32.985Z","status":"ssl_error","status_checked_at":"2026-01-28T13:02:04.945Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eln","python","rest-api","rspace"],"created_at":"2026-01-28T14:33:37.116Z","updated_at":"2026-01-28T14:33:38.956Z","avatar_url":"https://github.com/rspace-os.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rspace-client-python\n\nThis project contains a client which helps calling RSpace ELN and Inventory APIs. There are some example Python scripts. \n\nThis client is easy to use in Jupyter notebooks - watch this [video](https://researchspace.helpdocs.io/article/5xqzm36v9t-video-round-trip-data-analysis-using-jupyter-notebook-and-the-rspace-api) for an example.\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. Alternatively, you can run [RSpace locally in Docker](https://github.com/rspace-os/rspace-docker).\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 specification, please see https://\u003cYOUR_RSPACE_DOMAIN\u003e/public/apiDocs\n\nFor example, if you are using `https://community.researchspace.com`,\nthe API documentation is available at `https://community.researchspace.com/public/apiDocs`\n\nSee [DEVELOPING.md](DEVELOPING.md) for details of running tests.\n\nTo install rspace-client and its dependencies, run\n\n```bash\npip install rspace-client==2.6.1\n```\n\n### Compatibility with RSpace server versions\n\n- ELN API compatible with 1.69 or later\n- Inventory API compatible with 1.73 - 1.76 inclusive\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. To use Inventory client you'll\nneed RSpace 1.70 or later/ \n\nThe simplest way to read in the URL and API key is from environment variables, e.g.\n\nOn Linux/MacOS shell\n```\nbash\u003e export RSPACE_URL=https://myrspace.com\nbash\u003e export RSPACE_API_KEY=abcdefgh...\n```\n\nsubstituting in your own values.\n\n```\nimport os\nfrom rspace_client.inv import inv\nfrom rspace_client.eln import eln\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### Using the rspace_client library as PyFilesystem implementation\n\nStarting with rspace-client 2.6.0 rspace-client the library partially implements \n[PyFilesystem](https://docs.pyfilesystem.org/en/latest/index.html) API for accessing \nRSpace Gallery files and RSpace Inventory attachments.\n\nTo start, export the URL and API key into environment variables (as explained before).\n\nTo access the Gallery files construct a `GalleryFilesystem` object.\n```\nfrom rspace_client.eln import fs\n\n# create rspace_fs object which supports generic fs methods (listdir, getinfo etc.)\nrspace_gallery_fs = fs.GalleryFilesystem(os.getenv(\"RSPACE_URL\"), os.getenv(\"RSPACE_API_KEY\"))\n\ncontent = rspace_gallery_fs.listdir(\"/\")\nprint(content)\nfor globalId in content:\n  print(rspace_gallery_fs.getinfo(globalId).raw)\n```\n\nTo access Inventory attachments construct a `InventoryAttachmentFilesystem` object.\n```\nfrom rspace_client.inv import fs\n\nrspace_inv_fs = fs.InventoryAttachmentFilesystem(os.getenv(\"RSPACE_URL\"), os.getenv(\"RSPACE_API_KEY\"))\n\n// list the attachments that an existing record has, in this case a subsample\nrspace_inv_fs.listdir('/SS123')\n\n// get the metadata for a particular attachment\nrspace_inv_fs.getinfo(\"IF123\")\n\n// or download it\nfile_obj = BytesIO()\nrspace_inv_fs.download('/IF123', file_obj)\n\n// or attach a new file\nfile_obj_2 = BytesIO(b'test file content')\nrspace_inv_fs.upload('/SS123', file_obj_2)\n```\n\n\n## Example usage\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.ELNClient(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\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\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 \u003cfileId=12345\u003e 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: \u003cfileId={}\u003e'.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 \u003cdocId=12345\u003e 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: \u003cdocId={}\u003e'.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\n```python\nexport_archive_file_path = client.download_export('xml', 'user', file_path='/tmp')\n```\n\nor to export a group's work in HTML by id, passing an appendable file to record progress (requires \u003e= 2.5):\n\n```python\ngroup_id=12345\nexport_archive_file_path = client.download_export('html', 'group', uid=group_id, file_path='/tmp', progress_log=\"a-writeable-file.log\")\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. When a job is complete, the response contains a download link that can be accessed directly, without making an API call:\n\n```\n\n{\n 'id': 1595,\n 'status': 'COMPLETED',\n 'result': {'expiryDate': '2022-03-12T18:27:52.261Z',\n  'size': 304694398,\n  'checksum': '20038299',\n  'algorithm': 'CRC32'},\n 'percentComplete': 100.0,\n '_links': [{'link': 'https://community.researchspace.com/api/v1/export/RSpace-2022-06-11-18-28-html-123456.zip',\n   'rel': 'enclosure'}]\n}\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frspace-os%2Frspace-client-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frspace-os%2Frspace-client-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frspace-os%2Frspace-client-python/lists"}