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

packages = \
['etiket_client',
 'etiket_client.api',
 'etiket_client.api.access',
 'etiket_client.api.collections',
 'etiket_client.api.datasets',
 'etiket_client.api.files',
 'etiket_client.api.metadata',
 'etiket_client.api.scope',
 'etiket_client.api.tus',
 'etiket_client.api.user',
 'etiket_client.models']

package_data = \
{'': ['*']}

install_requires = \
['attrs>=21.3.0',
 'httpx>=0.15.4,<0.23.0',
 'python-dateutil>=2.8.0,<3.0.0',
 'shortuuid>=1.0.11,<2.0.0',
 'tuspy>=1.0.0,<2.0.0']

setup_kwargs = {
    'name': 'etiket-client',
    'version': '0.1.2',
    'description': 'A client library for accessing etiket',
    'long_description': '# etiket-client\n\nA client library for accessing etiket  $e|i>$ \n\n## Logging in to etiket\n\nFirst, create a client:\n\n```python\nfrom etiket_client import Client\n\nclient = Client(base_url="https://etiket.example.com") #of course change base_url\n```\n\nYou can only use the unauthenticated client to call the login endpoint with your credentials to obtain a valid token:\n\n```python\nfrom etiket_client import Client\nfrom etiket_client.api.access import login_for_access_token as get_token\nfrom etiket_client.models import BodyLoginForAccessToken\n\nclient = Client(base_url="https://etiket.example.com")\nform_data = BodyLoginForAccessToken(username=username, password=password)\n\ntoken = get_token.sync(client=client, form_data=form_data)\naccess_token = token.access_token\nrefresh_token = token.refresh_token\n```\n\nOther endpoints require authentication, use `AuthenticatedClient` with obtained access token as above:\n\n```python\nfrom etiket_client import AuthenticatedClient\n\nclient = AuthenticatedClient(\n                base_url="https://etiket.example.com", #of course change base_url\n                token="SuperSecretToken"\n)\n```\n\n## Creating datasets\n\nA minimal example of creating a dataset is shown below. Note that a scope should already be created and available to you. \n\n```python\nimport shortuuid\n\nfrom etiket_client.models import DatasetIn, DatasetOut\nfrom etiket_client.api.datasets import create_dataset\nfrom etiket_client.types import Response\n\n<...you have obtained tokens and created client: AuthenticatedClient...>\n\ndataset_new = DatasetIn(\n                    name=\'awesomedataset\',\n                    uid=shortuuid.ShortUUID().random(length=10),\n                    scope=\'somescope\',\n)\nresponse: DatasetOut = create_dataset.sync(\n                            client=client, \n                            json_body = dataset_new\n)\n# or if you need more info (e.g. status_code)\nresponse: Response[DatasetOut] = create_dataset.sync(\n                                    client=client,\n                                    json_body = dataset_new,\n)\n```\n\nWhen a dataset is created, it requires a unique identifer string, uid. Above we created a random string of length 10 which would be unique enough for a lifetime, but you can choose your own way to create a unique identifier. This also allows already created datasets with a different type of uid (e.g. UUID, TUID) to be added easily to $e|i>$.  A single dataset can then be uniquely identified through \'scope/uid\'. Although, a dataset is uniquely defined by the combination of a scope and uid, it is typically recognized by name, description, ranking and additional user defined metadata. \n\nAdditionally, a list of files can also be defined upon creation of the dataset. Note that the files will **not** be uploaded upon creation of datasets. Upload is done explicitly via `/uploads` endpoint or with `etiket_client.api.tus` methods.   \n\n```python\nfrom etiket_client.models import DatasetIn, DatasetOut\nfrom etiket_client.api.datasets import create_dataset\nfrom etiket_client.types import Response\n\nfile1 = FileDatasetIn(name=\'filename1\',uid=shortuuid.ShortUUID().random(length=10))\nfile2 = FileDatasetIn(name=\'filename2\',uid=shortuuid.ShortUUID().random(length=10))\ndataset_new = DatasetIn(\n                    name=\'awesomedataset\', \n                    scope=\'somescope\',\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0uid=shortuuid.ShortUUID().random(length=10),\n                    files=[file1,file2]\n)\ndataset: DatasetOut = create_dataset.sync(\n                            client=client,\n                            json_body = dataset_new\n)\n```\n\nFiles can of course also be added after dataset creation by calling `etiket_client.api.file.add_file`. \n\n## Collections and metadata\n\nDatasets can be grouped into collections. First a collection needs to be created, and subsequently datasets can be added to the collection:\n\n```python\nfrom etiket_client.models import CollectionIn\nfrom etiket_client.api.collections import create_collection, add_dataset_to_collection\n\ncollection  = create_collection.sync(\n                client=client,\n                json_body=CollectionIn(\n                                name=\'somecollection\',\n                                scope=\'somescope\',\n                          )            \n)\n\nresponse = add_dataset_to_collection.sync(\n                client=client,\n                scope=\'somescope\',\n                name=collection.name,\n                dataset_uuid=dataset.uuid,\n)\n```\n\nDatasets can also be removed from collections. \n\nAdditional user defined metadata can be provided to datasets in JSON format, either upon creation of the dataset by adding a meta field or explicitly via metadata functions:\n\n```python\ndataset_new = DatasetIn(\n                name=\'awesomedataset\',\n                scope=\'somescope\',\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0uid=shortuuid.ShortUUID().random(length=10),\n                files=[file1,file2],\n                meta={\'key1\':\'value1\', \'key2\':[\'value2a\',\'value2b\']},\n)\n```\n\nNote that the JSON document that can be added is limited in format. Only key-value pairs or key-list(values) pairs are allowed, where all keys and values are strings ( more than 2 and less than  20 characters). Arbitrary keys can be added, but not all keys can be used in dataset query. Only a predefined list of keys can be used when  querying datasets: sample, fridge, setup, measurement_type, variablesMeasured, keywords. \n\n## Exploring datasets\n\nA dataset is identified by a scope and UUID, but you can query or list datasets given a scope filtering on additional metadata to be able to browse through datasets:\n\n```python\nfrom etiket_client.api.datasets import get_datasets\n\ndatasets  = get_datasets.sync(\n                client=client,\n                scope=\'somescope\',\n                collection=\'somecollection\',\n                name=\'prefixofdataset\',\n                since=datetime.utcnow() - timedelta(days=100),\n                until=datetime.utcnow() + timedelta(days=1),\n                ranking=0,\n                sample=\'samplename\',\n                fridge=\'bluefors\',                \n)\n```\n\nDatasets are ordered by date of creation and use pagination to limit the number of datasets per request. Use offset and limit to move through pages.\n\nVia the ranking attribute of a dataset you can specify which datasets are filtered out of the query. Only datasets larger than the requested ranking will be returned. In this way, you can favour datasets over others. \n\n## Uploading files\n\nFile uploads are done using the tus.io protocol. `tuspy` package which is included in this client can be used: [tuspy docs](https://tus-py-client.readthedocs.io/en/latest/).\n\nAn etiket upload client can be initalized:\n\n```python\nfrom etiket_client import AuthenticatedClient, UploadClient\n\nclient = AuthenticatedClient(\n                base_url="https://etiket.example.com", #of course change base_url\n                token="SuperSecretToken"\n)\n\n#initialize tus client with autenticated client\ntus = UploadClient(client)\n#or optinally specify scope\ntus = UploadClient(client,scope=scope)\n\n#create uploader by specifying scope and file_uid\nuploader = tus.uploader(\'path/to/file\',scope=scope, file_uid=file_uid)\n\n#or only file_uid if scope is already specified in UploadClient\nuploader = tus.uploader(\'path/to/file\',file_uid=file_uid)\n\n#chunk size is sys.maxsize by default (probably quite large)\n#you can specify chunksize\nuploader = tus.uploader(\'path/to/file\', scope=scope, file_uid=file_uid, chunk_size=1024)\n\n#instead of path provide filestream\nfs = open(\'path/to/file.ext\', mode=)\nuploader = tus.uploader(file_stream=fs, scope=scope, file_uid=file_uid, chunk_size=200)\n\n# Upload a chunk i.e 200 bytes.\nuploader.upload_chunk()\n\n# Uploads the entire file.\n# This uploads chunk by chunk.\nuploader.upload()\n\n# you could increase the chunk size to reduce the\n# number of upload_chunk cycles.\nuploader.chunk_size = 800\nuploader.upload()\n\n# Continue uploading chunks till total chunks uploaded reaches 1000 bytes.\nuploader.upload(stop_at=1000)\n```\n\n\n## Downloading files\n\nFile downloads are done by using the ```get_file``` method. Optionally a range_ header can be added to do a partial download and perform downloads in parallel.\n',
    'author': 'None',
    'author_email': 'None',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
