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

package_dir = \
{'': 'src'}

packages = \
['hark_lang',
 'hark_lang.cli',
 'hark_lang.cloud',
 'hark_lang.controllers',
 'hark_lang.executors',
 'hark_lang.hark_compiler',
 'hark_lang.hark_parser',
 'hark_lang.machine',
 'hark_lang.run']

package_data = \
{'': ['*'], 'hark_lang': ['dist_data/hark.toml']}

install_requires = \
['PyInquirer>=1.0.3,<2.0.0',
 'boto3',
 'botocore',
 'coloredlogs>=14.0,<15.0',
 'colorful>=0.5.4,<0.6.0',
 'deterministic_zip>=0.1,<0.2',
 'docopt',
 'gql>=2.0.0,<3.0.0',
 'graphviz>=0.13.2,<0.14.0',
 'parsy>=1.3.0,<2.0.0',
 'pydot>=1.4.1,<2.0.0',
 'pynamodb',
 'pyyaml>=5.3.1,<6.0.0',
 'schema>=0.7.2,<0.8.0',
 'sly>=0.4,<0.5',
 'texttable>=1.6.2,<2.0.0',
 'toml>=0.10.1,<0.11.0',
 'yaspin>=0.17.0,<0.18.0']

entry_points = \
{'console_scripts': ['hark = hark_lang.cli.main:main']}

setup_kwargs = {
    'name': 'hark-lang',
    'version': '0.5.0',
    'description': 'The Hark Programming Language',
    'long_description': '# The Hark Programming Language\n\n![Tests](https://github.com/condense9/hark-lang/workflows/Build/badge.svg?branch=master) \\\n[![PyPI](https://badge.fury.io/py/hark-lang.svg)](https://pypi.org/project/hark-lang) \\\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) \\\n[![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-380)\n\n> [Formerly, Teal](https://condense9.com/2020/08/formerly-teal).\n> \n> Change your remotes: `git remote set-url origin git@github.com:condense9/hark-lang.git`\n\nHark hides the complexity of AWS Lambda + SQS, so you can build serverless data\nworkflows without managing infrastructure.\n\nDescribe your workflows in a *real programming language* with first-class\nfunctions, concurrency, and native Python inter-op. Test end-to-end locally,\nthen deploy to serverless AWS infrastructure in under 60s and start workflows\nfrom anything that can invoke Lambda.\n\nLike AWS Step Functions but cheaper and much nicer to use (overheads: a little\nLambda runtime, and a DynamoDB for Hark state).\n\nLike Serverless Framework, but handles runtime glue logic in addition to\ndeployment.\n\n*Status*: Hark works well for small workflows: 5-10 Lambda invocations. Larger\nworkflows may cause problems, and there is a known issue caused by DynamoDB\nrestrictions ([#12](https://github.com/condense9/hark-lang/issues/12)).\n\n<!-- As presented at PyCon Africa 2020. (Watch the presentation, or follow along with the examples). -->\n\n<!-- Watch an introduction video. -->\n\n[Get started in 2 minutes](#up-and-running-in-2-minutes).\n\n[Read the documentation](https://hark-book.condense9.com).\n\n[PyCon Africa 2020 Demos!](https://github.com/condense9/hark-demos).\n\n\n## Contributing\n\nHark is growing rapidly, and contributions are [warmly welcomed](CONTRIBUTING.md).\n\n\n## Is Hark for me?\n\nHark *is* for you if:\n- You use Python for processing data, or writing business process workflows.\n- You want an alternative to AWS Step Functions.\n- You don\'t want to to deploy and manage a task platform (Airflow, Celery, etc).\n\n**Data in**: You can invoke Hark like any Lambda function (AWS cli, S3 trigger,\nAPI gateway, etc).\n\n**Data out**: Use the Python libraries you already have for database access.\nHark just connects them together.\n\n**Development**: Hark runs locally, so you can thoroughly test Hark programs\nbefore deployment (using minio and localstack for any additional infrastructure\nthat your code uses.\n\n**Operating**: Hark enables contextual cross-thread logging and stacktraces out\nof the box, since the entire application is described in one place.\n\n| Hark is like...                 | But...                                                                                                        |\n|-------------------------------------|---------------------------------------------------------------------------------------------------------------|\n| AWS Step Functions                  | Hark programs aren\'t bound to AWS and don\'t use Step Functions under the hood (just plain Lambda + DynamoDB). |\n| Orchestrators (Apache Airflow, etc) | You don\'t have to manage infrastructure, or think in terms of DAGs, and you can test everything locally.      |\n| Task runners (Celery, etc)          | You don\'t have to manage infrastructure.                                                                      |\n| Azure Durable Functions             | While powerful, Durable Functions (subjectively) feel complex - their behaviour isn\'t always obvious.         |\n\n\n[Read more...](https://hark-book.condense9.com/why.html)\n\n\n## Up and running in 2 minutes\n\nAll you need:\n- An AWS account, and [AWS CLI](https://github.com/aws/aws-cli#getting-started)\n  configured.\n- A Python 3.8 virtual environment\n\nHark is built with Python, and distributed as a Python package. To install it,\nrun:\n\n```shell\n$ pip install hark-lang\n```\n\nThis gives you the `hark` executable. Try `hark -h`.\n\nCopy the following snippet into a file called `service.hk`:\n\n```\n// service.hk\n\nfn main() {\n  print("Hello World!");\n}\n```\n\nRun it (`-f main` is optional, and `main` is the default):\n\n```shell\n~/new_project $> hark service.hk -f main\n```\n\nInitialise the project (required for deployment):\n\n```shell\n~/new_project $> hark init\n```\n\nAnd deploy the service to your AWS account (requires AWS credentials and\n`AWS_DEFAULT_REGION` to be defined):\n\n```shell\n~/new_project $> hark deploy\n```\n\nFinally, invoke it in AWS (`-f main` is optional, as before):\n\n```shell\n~/new_project $> hark invoke -f main\n```\n\nThat\'s it! You now have a Hark instance configured in your AWS account, built on\nthe AWS serverless platform (S3 + Lambda + DynamoDB). [More info...](https://hark-book.condense9.com/dev/aws.html)\n\nExplore a more complex example: [Fractals](examples/fractals).\n\n[Create an issue](https://github.com/condense9/hark-lang/issues) if none of this\nmakes sense, or you\'d like help getting started.\n\nRead more...\n- [about the language](https://hark-book.condense9.com/language/index.html)\n- [about the development process](https://hark-book.condense9.com/development/index.html)\n- [about configuring Hark](https://hark-book.condense9.com/configuration.html)\n\n\n## Why should I learn a new language?\n\nIt\'s a big ask! There\'s *so much* that\'s missing from a brand new language. For\nnow, think about it like learning a new library or API -- you can do most of the\nhard work in regular Python, using existing packages and code, while Hark lets\nyou express things you can\'t easily do in Python.\n\nThey key concept is this: when running in AWS, Hark threads run in separate\nlambda invocations, and the language comes with primitives to manage these\nthreads.\n\n### Concurrency & Synchronisation\n\nThis is useful when a set computations are related, and must be kept together.\n\n```javascript\n/**\n * Return f(x) + g(x), computing f(x) and g(x) in parallel in two separate\n * threads (Lambda invocations in AWS).\n */\nfn compute(x) {\n  a = async f(x);     // Start computing f(x) in a new thread\n  b = async g(x);     // Likewise with g(x)\n  await a + await b;  // Stop this thread, and resume when {a, b} are ready\n}\n```\n\n*Traditional approach*: Manually store intermediate results in an external\ndatabase, and build the synchronisation logic into the cloud functions `f` and\n`g`, or use an orchestrator service.\n\n[Read more...](https://hark-book.condense9.com/language/threads.html)\n\n\n### Trivial Pipelines\n\nUse this approach when each individual function may take several minutes (and\nhence, together would break the 5 minute AWS Lambda limit).\n\n```javascript\n/**\n * Compute f(g(h(x))), using a separate lambda invocation for each\n * function call.\n */\nfn pipeline(x) {\n  a = async h(x);\n  b = async g(await a);\n  f(await b);\n}\n```\n\n*Traditional approach:* This is functionally similar to a "chain" of AWS Lambda\nfunctions and SQS queues.\n\n\n### Mapping / reducing\n\nHark functions are first-class, and can be passed around (closures and anonymous\nfunctions are planned, giving Hark object-oriented capabilities).\n\n```javascript\n/**\n * Compute [f(element) for element in x], using a separate lambda invocation for\n * each application of f.\n */\nfn map(f, x, accumulator) {\n  if nullp(x) {\n    accumulator\n  }\n  else {\n    // The Hark compiler has tail-recursion optimisation\n    map(func, rest(x), append(accumulator, async f(first(x))))\n  }\n}\n```\n\nThis could be used like:\n\n```javascript\nfn add2(x) {\n  x + 2\n}\n\nfn main() {\n  futures = map(add2, [1, 2, 3, 4], []);\n  // ...\n}\n```\n\n[Read more...](https://hark-book.condense9.com/language/functions.html)\n\n\n## Notes about syntax\n\nThe syntax should look familiar, but there are a couple of things to point out.\n\n### No \'return\' statement\n\nEvery expression must return a value, so there is no `return` statement. The\nlast expression in a \'block\' (expressions between `{` and `}`) is returned\nimplicitly.\n\n```javascript\nfn foo() {\n  "something"\n}\n\nfn main() {\n  print(foo())  // -> prints "something"\n}\n```\n\n### Semi-colons are required...\n\n... when there is more than one expression in a block.\n\nThis is ok:\n\n```javascript\nfn main() {\n  print("done")\n}\n```\n\nSo is this:\n\n```javascript\nfn main() {\n  print("one");\n  print("two")\n}\n```\n\nAnd this:\n\n```javascript\nfn main() {\n  print("one");\n  print("two");\n}\n```\n\nBut this is not ok:\n\n```javascript\nfn main() {\n  print("one")  // <- missing semicolon!\n  print("two")\n}\n```\n\n\n### \'print\' returns the value printed\n\nIn this snippet, "Hello Worlds!" is actually printed twice. First in `bar`, then\nin `main`.\n\n```javascript\nfn bar() {\n  print("Hello Worlds!")\n}\n\nfn main() {\n  print(bar())\n}\n```\n\n```shell\n$> hark -q service.hk\nHello Worlds!\nHello Worlds!\n```\n\n### \'if\' is an expression, and returns a value\n\nThink about it like this: An `if` expression represents a choice between\n*values*.\n\n```javascript\nv = if something { true_value } else { false_value };\n\n// if \'something\' is not true, v is set to null\nv = if something { value };\n```\n\n\n## FAQ\n<!-- NOTE: Taken from guide/src/why.md -->\n\n**Why is this not a library/DSL in Python?**\n\nWhen Hark threads wait on a Future, they stop completely. The Lambda function\nsaves the machine state and then terminates. When the Future resolves, the\nresolving thread restarts any waiting threads by invoking new Lambdas to pick up\nexecution.\n\nTo achieve the same thing in Python, the framework would need to dump the entire\nPython VM state to disk, and then reload it at a later point -- this may be\npossible, but would certainly be non-trivial. An alternative approach would be\nto build a langauge on top of Python that looked similar to Python, but hark\n*wrong* because it was really faking things under the hood.\n\n**How is Hark like Go?**\n\nGoroutines are very lightweight, while Hark `async` functions are pretty heavy --\nthey involve creating a new Lambda (or process, when running locally).\n\nHark\'s concurrency model is similar to Go\'s, but channels are not fully\nimplemented so data can only be sent to/from a thread at call/return points.\n\n**Is this an infrastructure-as-code tool?**\n\nNo, Hark does not do general-purpose infrastructure management. There are\nalready great tools to do that ([Terraform](https://www.terraform.io/),\n[Pulumi](https://www.pulumi.com/), [Serverless\nFramework](https://www.serverless.com/), etc).\n\nInstead, Hark reduces the amount of infrastructure you need. Instead of a\ndistinct Lambda function for every piece of application logic, you only need the\ncore Hark interpreter (purely serverless) infrastructure.\n\nHark will happily manage that infrastructure for you (through `hark deploy` and\n`hark destroy`), or you can set it up with your in-house custom system.\n\n\n## Current Limitations and Roadmap\n\nHark is beta quality, which means that it\'s not thoroughly tested or feature\ncomplete. This is a non-exhaustive list.\n\n### Libraries\n\nOnly one Hark program file is supported, but a module/package system is\n[planned](https://github.com/condense9/hark-lang/issues/9).\n\n### Error Handling\n\nThere\'s no error handling - if your function fails, you\'ll have to restart the\nwhole process manually. An exception handling system is\n[planned](https://github.com/condense9/hark-lang/issues/1).\n\n### Typing\n\nFunction inputs and outputs aren\'t typed. This is a limitation, and will be\nfixed soon, probably using\n[ProtoBufs](https://developers.google.com/protocol-buffers/) as the interface\ndefinition language.\n\n### Calling Arbitrary Services\n\nCurrently you can only call Hark or Python functions -- arbitrary microservices\ncan\'t be called. Before Hark v1.0 is released, this will be possible. You will\nbe able to call a long-running third party service (e.g. an AWS ML service) as a\nnormal Hark function and `await` on the result.\n\n\n---\n\n## About\n\nHark is maintained by [Condense9 Ltd.](https://www.condense9.com/). Get in touch\nwith [ric@condense9.com](ric@condense9.com) for help getting running, or if you\nneed enterprise deployment.\n\nHark started because we couldn\'t find any data engineering tools that were\nproductive and *hark* like software engineering. As an industry, we\'ve spent\ndecades growing a wealth of computer science knowledge, but building data\npipelines in $IaC, or manually crafting workflow DAGs with $AutomationTool,\n*just isn\'t software*.\n\n## License\n\nApache License (Version 2.0). See [LICENSE](LICENSE) for details.\n\n---\n\n[![forthebadge](https://forthebadge.com/images/badges/gluten-free.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/check-it-out.svg)](https://forthebadge.com)\n\n',
    'author': 'Ric da Silva',
    'author_email': 'ric@condense9.com',
    'maintainer': 'Ric da Silva',
    'maintainer_email': 'ric@condense9.com',
    'url': 'https://www.condense9.com',
    'package_dir': package_dir,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
