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

packages = \
['beanie',
 'beanie.executors',
 'beanie.migrations',
 'beanie.migrations.controllers',
 'beanie.odm',
 'beanie.odm.interfaces',
 'beanie.odm.operators',
 'beanie.odm.operators.find',
 'beanie.odm.operators.update',
 'beanie.odm.queries',
 'beanie.odm.utils']

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

install_requires = \
['click>=7.1.2,<8.0.0',
 'motor>=2.1.0,<3.0.0',
 'pydantic>=1.8,<2.0',
 'toml>=0.10.2,<0.11.0']

entry_points = \
{'console_scripts': ['beanie = beanie.executors.migrate:migrations']}

setup_kwargs = {
    'name': 'beanie',
    'version': '1.1.2',
    'description': 'Asynchronous Python ODM for MongoDB',
    'long_description': '[![Beanie](https://raw.githubusercontent.com/roman-right/beanie/main/assets/logo/with_text.svg)](https://github.com/roman-right/beanie)\n\n## Overview\n\n[Beanie](https://github.com/roman-right/beanie) - is an Asynchronous Python\nobject-document mapper (ODM) for MongoDB, based\non [Motor](https://motor.readthedocs.io/en/stable/)\nand [Pydantic](https://pydantic-docs.helpmanual.io/).\n\nWhen using Beanie each database collection has a corresponding `Document` that\nis used to interact with that collection. In addition to retrieving data,\nBeanie allows you to add, update, or delete documents from the collection as\nwell.\n\nBeanie saves you time by removing boiler-plate code and it helps you focus on\nthe parts of your app that actually matter.\n\nData and schema migrations are supported by Beanie out of the box.\n\n## Installation\n\n### PIP\n\n```shell\npip install beanie\n```\n\n### Poetry\n\n```shell\npoetry add beanie\n```\n\n## Getting Started\n\n### Document\n\nThe `Document` class in Beanie is responsible for mapping and handling the data\nfrom the collection. It is inherited from the `BaseModel` Pydantic class, so it\nfollows the same data typing and parsing behavior.\n\nEach document has `id` fields of type `PydanticObjectId` (Can be changed, if you prefer another type) which reflects the\nunique `_id` field in\nMongoDB. [MongoDB doc](https://docs.mongodb.com/manual/reference/glossary/#term-id)\n\n```python\nfrom typing import Optional\nfrom pydantic import BaseModel\nfrom beanie import Document, Indexed\n\n\nclass Category(BaseModel):\n    name: str\n    description: str\n\n\nclass Product(Document):  # This is the model\n    name: str\n    description: Optional[str] = None\n    price: Indexed(float)\n    category: Category\n\n    class Collection:\n        name = "products"\n```\n\nMore details about Documents, collections, and indexes configuration could be\nfound in the [documentation](https://roman-right.github.io/beanie/).\n\n### Initialization\n\nBeanie uses Motor as an async database engine. To init previously created\ndocuments, you should provide the Motor database instance and list of your\ndocument models to the `init_beanie(...)` function, as it is shown in the\nexample:\n\n```python\nimport motor\nfrom beanie import init_beanie\n\n\nasync def init():\n    # Crete Motor client\n    client = motor.motor_asyncio.AsyncIOMotorClient(\n        "mongodb://user:pass@host:27017"\n    )\n\n    # Init beanie with the Product document class\n    await init_beanie(database=client.db_name, document_models=[Product])\n\n```\n\n### Create\n\nBeanie supports and single document creation and batch inserts:\n\n#### Insert one\n\n```python\nbar = Product(name="Tony\'s", price=5.95, category=Category(name="Chocolate"))\nawait bar.insert()\n```\n\n#### Insert many\n\n```python\nmilka = Product(name="Milka", price=3.05, category=chocolate)\npeanut_bar = Product(name="Peanut Bar", price=4.44, category=chocolate)\nawait Product.insert_many([milka, peanut_bar])\n```\n\nOther details and examples could be found in the [documentation](https://roman-right.github.io/beanie/insert/)\n\n### Find\n\n#### Get\n\nThe simplest way to get the document is to get it by the `id` field.\nMethod `get()` is responsible for this:\n\n```python\nbar = await Product.get(PydanticObjectId("608da169eb9e17281f0ab2ff"))\n```\n\n#### Find One\n\nTo get a single document by any other search criteria you can use `find_one()`\nmethod. It responds with awaitable object `FindOne`, which returns `Document`\ninstance or `None` on `await`\n\n```python\nbar = await Product.find_one(\n    Product.name == "Peanut Bar",\n    Product.category.name == "Chocolate"\n)\n```\n\n`FindOne` supports projections to grab and return data in needed format only\n\n```python\nclass ProductShortView(BaseModel):\n    name: str\n    price: float\n\n\nbar = await Product.find_one(\n    Product.name == "Peanut Bar"\n).project(ProductShortView)\n```\n\n#### Find Many\n\nTo find many documents `find` or `find_many` (which is the same) method could\nbe used. These methods return the `FindMany` instance, which implements\nthe `async generator` pattern. It means found documents are available in\nthe `async for` loop:\n\n```python\nasync for product in Product.find(\n        Product.category.name == "Chocolate"\n):\n    print(product)\n```\n\nThe `to_list` method will put all the found documents on the list\n\n```python\nproducts = await Product.find(\n    Product.category.name == "Chocolate"\n).to_list()\n```\n\n`FindMany` supports chain filtering, where you can build your filter query with\nmany `find` methods\n\n```python\nchocolates = await Product.find(\n    Product.category.name == "Chocolate").find(\n    Product.price < 5).to_list()\n```\n\nYou can sort, skip, limit and project with `FindMany` query too\n\n```python\nclass ProductShortView(BaseModel):\n    name: str\n    price: float\n\n\nproducts = await Product.find(\n    Product.category.name == "Chocolate",\n    Product.price < 3.5\n).sort(-Product.price).limit(10).project(ProductShortView)\n\n```\n\n#### Query Building\n\nAnd `FindOne` and `FindMany` support native python comparison operators, Beanie\nfind operators and native PyMongo find query syntax.\n\n**Python comparison operators**\n\n```python\nchocolates = await Product.find(\n    Product.category.name == "Chocolate").find(\n    Product.price < 5).to_list()\n```\n\n**Beanie Find Operators** are classes - wrappers over MongoDB find operators.\n\n```python\nfrom beanie.operators import In\n\nproducts = await Product.find(\n    In(Product.price, [1, 2, 3, 4, 5])\n).to_list()\n```\n\nHere you can see `In` operator, which reflects `$in`. The whole list of the\nfind operators could be\nfound [here](https://roman-right.github.io/beanie/api/operators/find/)\n\n**Native PyMongo find query syntax**\n\n```python\nproducts = await Product.find(\n    {"$in": {"price": [1, 2, 3, 4, 5]}}\n).to_list()\n```\n\n#### All\n\nTo get all the documents `find_all` or `all` methods can be used.\n\n```python\nall_products = await Product.all().to_list()\n```\n\nInformation about sorting, skips, limits, and projections could be found in\nthe [documentation](https://roman-right.github.io/beanie/find/)\n\n### Update\n\n#### Saving changes to existing documents\n\nThe easiest way to change a document in the database is using either the `replace` or `save` methods on a altered document. These methods both write the document to the database, but `replace` will raise an exception when the document does not exist yet, while `save` will insert the document. \n\nUsing save:\n```python\nbar = await Product.find_one(Product.name == "Milka")\nbar.price = 10\nawait bar.save()\n```\nOr similairly using replace, which trows a `ValueError` if the document does not have an `id` yet, or a `beanie.exceptions.DocumentNotFound` if it does but the id is not present in the collection:\n```python\nbar.price = 10\ntry:\n    await bar.update()\nexcept (ValueError, beanie.exceptions.DocumentNotFound):\n    print("Can\'t replace a non existing document")\n```\n\nNote however that these methods requires multiple queries to the database and replace the entire document with the new version. A more tailered solution can often be created by applying update queries directly on the database level, see the explination below.\n\n#### Update Methods\n\n`Document`, `FindMany` and `FindOne`\nimplement [UpdateMethods](https://roman-right.github.io/beanie/api/interfaces/#updatemethods)\ninterface. It supports `update`, `set`, `inc` and `current_date` methods.\n\n#### Document\n\nImplementing `UpdateMethods` interface `Document` instance\ncreates [UpdateOne](https://roman-right.github.io/beanie/api/queries/#updateone)\nobject and provides self id as the search criteria there. Then `UpdateOne`\ninstance is handling all the update operations.\n\n`update` method is used to update the document data. It supports native Pymongo\nsyntax and Beanie Update operators.\n\nNative syntax\n\n```python\nbar = await Product.find_one(Product.name == "Milka")\nawait bar.update({"$set": {Product.price: 10}})\n```\n\nUpdate operatos\n\n```python\nawait bar.update(Set({Product.price: 10}))\n```\n\nThe whole list of the Beanie update operators can be\nfound [by link](https://roman-right.github.io/beanie/api/operators/update/)\n\n`inc`, `set` and `current_date` methods are popular update operations preset.\nNext example shows how to add `1` to the document\'s price:\n\n```python\nawait bar.inc({Product.price: 1})\n```\n\n#### Update One\n\nImplementing `UpdateMethods` interface `Document` instance\ncreates [UpdateOne](https://roman-right.github.io/beanie/api/queries/#updateone)\nobject and provides search criteria there. All the update methods work the same\nway as for the `Document` instance.\n\nNative syntax\n\n```python\nawait Product.find_one(\n    Product.name == "Milka"\n).update({"$set": {Product.price: 10}})\n```\n\nUpdate Operators\n\n```python\nawait Product.find_one(\n    Product.name == "Milka"\n).update(Set({Product.price: 10}))\n```\n\nPreset Methods\n\n```python\nawait Product.find_one(\n    Product.name == "Milka"\n).inc({Product.price: 1})\n```\n\n#### Update Many\n\n`FindMany` uses the same patter as `FindOne` but creates `UpdateMany` instance\ninstead of `UpdateOne` respectively. It supports `UpdateMethods` too.\n\n```python\nawait Product.find(\n    Product.category.name == "Chocolate"\n).update({"$set": {Product.price: 100}})\n```\n\nMore details and examples about update queries could be found in\nthe [documentation](https://roman-right.github.io/beanie/update/)\n\n### Delete\n\n`delete()` method is supported and by the `Document` instances, and by the `FindOne`\nand by the `FindMany` instances. It deletes documents using id or search\ncriteria respectively.\n\n#### Document\n\n```python\nbar = await Product.find_one(Product.name == "Milka")\nawait bar.delete()\n```\n\n#### One\n\n```python\nawait Product.find_one(Product.name == "Milka").delete()\n```\n\n#### Many\n\n```python\nawait Product.find(\n    Product.category.name == "Chocolate"\n).delete()\n```\n\n#### ALL\n\n```python\nawait Product.delete_all()\n```\n\nMore information could be found in the [documentation](https://roman-right.github.io/beanie/delete/)\n\n### Aggregate\n\nYou can aggregate and over the whole collection, using `aggregate()` method of the `Document` class, and over search criteria, using `FindMany` instance. \n\n#### Aggregation Methods\n\n`FindMany` and `Document` classes implements [AggregateMethods](https://roman-right.github.io/beanie/api/interfaces/#aggregatemethods) interface with preset methods\n\nExample of average calculation:\n\n*With search criteria*\n```python\navg_price = await Product.find(\n    Product.category.name == "Chocolate"\n).avg(Product.price)\n```\n\n*Over the whole collection*\n```python\navg_price = await Product.avg(Product.price)\n```\n\n#### Native syntax\n\nYou can use the native PyMongo syntax of the aggregation pipelines to aggregate over the whole collection or over the subset too. `projection_model` parameter is responsible for the output format. It will return dictionaries, if this parameter is not provided.\n\n```python\nclass OutputItem(BaseModel):\n    id: str = Field(None, alias="_id")\n    total: int\n\n\nresult = await Product.find(\n    Product.category.name == "Chocolate").aggregate(\n    [{"$group": {"_id": "$category.name", "total": {"$avg": "$price"}}}],\n    projection_model=OutputItem\n).to_list()\n\n```\n\n### Documentation\n\n- **[Doc](https://roman-right.github.io/beanie/)** -\n  Usage examples with descriptions\n- **[API](https://roman-right.github.io/beanie/api/document/)** - Full list of\n  the classes and methods\n\n### Example Projects\n\n- **[FastAPI Demo](https://github.com/roman-right/beanie-fastapi-demo)** -\n  Beanie and FastAPI collaboration demonstration. CRUD and Aggregation.\n- **[Indexes Demo](https://github.com/roman-right/beanie-index-demo)** -\n  Regular and Geo Indexes usage example wrapped to a microservice.\n\n### Articles\n\n- **[Announcing Beanie - MongoDB ODM](https://dev.to/romanright/announcing-beanie-mongodb-odm-56e)**\n- **[Build a Cocktail API with Beanie and MongoDB](https://developer.mongodb.com/article/beanie-odm-fastapi-cocktails/)**\n- **[MongoDB indexes with Beanie](https://dev.to/romanright/mongodb-indexes-with-beanie-43e8)**\n- **[Beanie Projections. Reducing network and database load.](https://dev.to/romanright/beanie-projections-reducing-network-and-database-load-3bih)**\n\n### Resources\n\n- **[GitHub](https://github.com/roman-right/beanie)** - GitHub page of the\n  project\n- **[Changelog](https://roman-right.github.io/beanie/changelog)** - list of all\n  the valuable changes\n- **[Discord](https://discord.gg/ZTTnM7rMaz)** - ask your questions, share\n  ideas or just say `Hello!!`\n\n----\nSupported by [JetBrains](https://jb.gg/OpenSource)\n\n[![JetBrains](https://raw.githubusercontent.com/roman-right/beanie/main/assets/logo/jetbrains.svg)](https://jb.gg/OpenSource)\n',
    'author': 'Roman',
    'author_email': 'roman-right@protonmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/roman-right/beanie',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.6.1,<4.0',
}


setup(**setup_kwargs)
