Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/mkdocs #53

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Docs
on:
push:
branches:
- master
- main
- 'feature/**'
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure Git Credentials
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- uses: actions/setup-python@v5
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v4
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force --clean -f mkdocs/mkdocs.yml
9 changes: 9 additions & 0 deletions mkdocs/docs/Testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# Tests

To run the tests suite:

- make sure you have a MongoDB database running on `localhost:27017` (you can
spawn one with `docker-compose up -d`);
- install developers requirements with `pip install -r requirements.txt`;
- run `pytest`.
28 changes: 28 additions & 0 deletions mkdocs/docs/compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Compatibility

We support all Python and MongoDB versions supported by [PyMongo][pymongo],
namely:

- CPython 3.7+ and PyPy3.7+
- MongoDB 3.6, 4.0, 4.2, 4.4, and 5.0.

As a backend, Mongo-Thingy supports the following libraries:

- Synchronous:

* [PyMongo][pymongo] (default)
* [Mongomock][mongomock]
* [MontyDB][montydb]

- Asynchronous:

* [Motor][motor] (default when Motor is installed)
* [Motor][motor] with Tornado (default when Motor and Tornado are installed)
* [Mongomock-Motor][mongomock-motor]

# Install

```sh
pip install mongo-thingy
```

35 changes: 35 additions & 0 deletions mkdocs/docs/discovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Database/collection "discovery"

### Default behaviour

```python
>>> class AuthenticationGroup(Thingy):
... pass

>>> connect("mongodb://localhost/")
>>> AuthenticationGroup.collection
Collection(Database(MongoClient(host=['localhost:27017'], ...), 'authentication'), 'group')
```

### Use mismatching names for Thingy class and database collection

You can either specify the collection name:

```python
>>> class Foo(Thingy):
... collection_name = "bar"
```

or the collection directly:

```python
>>> class Foo(Thingy):
... collection = db.bar
```

You can then check what collection is being used with:

```python
>>> Foo.collection
Collection(Database(MongoClient('localhost', 27017), 'database'), 'bar')
```
53 changes: 53 additions & 0 deletions mkdocs/docs/example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Examples

## First steps

### Connect, insert and find thingies

```python
>>> from mongo_thingy import connect, Thingy
>>> connect("mongodb://localhost/test")

>>> class User(Thingy):
... pass

>>> user = User({"name": "Mr. Foo", "age": 42}).save()
>>> User.count_documents()
1
>>> User.find_one({"age": 42})
User({'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 42})
```

In an AsyncIO (or Tornado) environment, use the asynchronous class instead:

```python
>>> from mongo_thingy import connect, AsyncThingy
>>> connect("mongodb://localhost/test")

>>> class User(AsyncThingy):
... pass

>>> user = await User({"name": "Mr. Foo", "age": 42}).save()
>>> await User.count_documents()
1
>>> await User.find_one({"age": 42})
User({'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 42})
```

To use another backend than the default ones, just pass its client class with
``client_cls``:

```python
>>> import mongomock
>>> connect(client_cls=mongomock.MongoClient)
```

### Update a thingy

```python
>>> user.age
42
>>> user.age = 1337
>>> user.save()
User({'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337})
```
42 changes: 42 additions & 0 deletions mkdocs/docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[pymongo]: https://github.com/mongodb/mongo-python-driver
[thingy]: https://github.com/Refty/thingy
[mongomock]: https://github.com/mongomock/mongomock
[montydb]: https://github.com/davidlatwe/montydb
[motor]: https://github.com/mongodb/motor
[mongomock-motor]: https://github.com/michaelkryukov/mongomock_motor

![Mongo-Thingy](https://socialify.git.ci/Refty/mongo-thingy/image?font=Bitter&language=1&logo=https%3A%2F%2Fi.imgur.com%2FLeNC7Zb.png&owner=1&pattern=Charlie%20Brown&theme=Light)

<div align="center">
<a href="https://pypi.org/project/mongo-thingy"><img src="https://img.shields.io/pypi/v/mongo-thingy.svg" alt="PyPI"></a>
<img src="https://img.shields.io/pypi/pyversions/mongo-thingy" alt="Supported Python Versions">
<a href="LICENSE"><img src="https://img.shields.io/github/license/refty/mongo-thingy" alt="License"></a>
<a href="https://github.com/ambv/black"><img src="https://img.shields.io/badge/code%20style-black-black" alt="Code style"></a>
<br/>
<a href="https://github.com/Refty/mongo-thingy/actions"><img src="https://img.shields.io/github/actions/workflow/status/Refty/mongo-thingy/tests.yml?branch=master" alt="Tests"></a>
<a href="https://coveralls.io/github/Refty/mongo-thingy"><img src="https://img.shields.io/coveralls/Refty/mongo-thingy.svg" alt="Tests"></a>
<a href="http://mongo-thingy.readthedocs.io"><img src="https://readthedocs.org/projects/mongo-thingy/badge" alt="Docs"></a>
<br /><br />
</div>

**_Mongo-Thingy_ is the most idiomatic and friendly-yet-powerful way to use
MongoDB with Python.**

It is an _"Object-Document Mapper"_ that gives you full advantage of MongoDB
schema-less design by **not** asking you to define schemas in your code.

What you'll get:

- a simple and robust pure-Python code base, with 100% coverage and few
dependencies;
- [PyMongo][pymongo] query language - no need to learn yet another one;
- both sync and async support! choose what suits you best;
- [Thingy][thingy] views - control what to show, and create fields based on
other fields;
- swappable backend - wanna use SQLite behind the scenes? well, you can;
- versioning *(optional)* - rollback to any point in any thingy history;
- and more!




42 changes: 42 additions & 0 deletions mkdocs/docs/indexing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## Indexes

### Create an index

```python
>>> User.create_index("email", sparse=True, unique=True)
```

### Add one or more indexes, create later

```python
>>> User.add_index("email", sparse=True, unique=True)
>>> User.add_index("username")

>>> User.create_indexes()
```

### Create all indexes of all thingies at once

```python
>>> from mongo_thingy import create_indexes
>>> create_indexes()
```

## Dealing with camelCase data

```python
>>> from mongo_thingy.camelcase import CamelCase

>>> class SystemUser(CamelCase, Thingy):
... collection_name = "systemUsers"

>>> user = SystemUser.find_one()
>>> user.view()
{'_id': ObjectId(...), 'firstName': 'John', 'lastName': 'Doe'}

>>> user.first_name
'John'
>>> user.first_name = "Jonny"
>>> user.save()
SystemUser({'_id': ObjectId(...), firstName: 'Jonny', lastName: 'Doe'})
```
10 changes: 10 additions & 0 deletions mkdocs/docs/sponsors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Sponsors

<div align="center">
&nbsp;&nbsp;&nbsp;
<a href="https://numberly.com/"><img src="https://raw.githubusercontent.com/Refty/mongo-thingy/master/img/numberly.png" alt="Numberly"></a>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
<a href="https://refty.co/"><img src="https://raw.githubusercontent.com/Refty/mongo-thingy/master/img/refty.png" alt="Refty"></a>
&nbsp;&nbsp;&nbsp;
</div>
28 changes: 28 additions & 0 deletions mkdocs/docs/versioning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Versioning

```python
>>> from mongo_thingy.versioned import Versioned

>>> class Article(Versioned, Thingy):
... pass

>>> article = Article(content="Cogito ergo sum")
>>> article.version
0

>>> article.save()
Article({'_id': ObjectId('...'), 'content': 'Cogito ergo sum'})
>>> article.version
1

>>> article.content = "Sum ergo cogito"
>>> article.save()
Article({'_id': ObjectId('...'), 'content': 'Sum ergo cogito'})
>>> article.version
2

>>> article.revert()
Article({'_id': ObjectId('...'), 'content': 'Cogito ergo sum'})
>>> article.version
3
```
56 changes: 56 additions & 0 deletions mkdocs/docs/views.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
## Thingy views power

### Complete information with properties

```python
>>> class User(Thingy):
... @property
... def username(self):
... return "".join(char for char in self.name if char.isalpha())

>>> User.add_view(name="everything", defaults=True, include="username")
>>> user = User.find_one()
>>> user.view("everything")
{'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337, 'username': 'MrFoo'}
```

### Hide sensitive stuff

```python
>>> User.add_view(name="public", defaults=True, exclude="password")
>>> user.password = "t0ps3cr3t"
>>> user.view()
{'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337, 'password': 't0ps3cr3t'}
>>> user.view("public")
{'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337}
```

### Only use certain fields/properties

```python
>>> User.add_view(name="credentials", include=["username", "password"])
>>> user.view("credentials")
{'username': 'MrFoo', 'password': 't0ps3cr3t'}
```

### Apply views on cursors

```python
>>> cursor = User.find()
>>> for credentials in cursor.view("credentials"):
... print(credentials)
{'username': 'MrFoo', 'password': 't0ps3cr3t'}
{'username': 'MrsBar', 'password': '123456789'}
...
```

And if your cursor is already exhausted, you can still apply a view!

```python
>>> users = User.find().to_list(None)
>>> for credentials in users.view("credentials"):
... print(credentials)
{'username': 'MrFoo', 'password': 't0ps3cr3t'}
{'username': 'MrsBar', 'password': '123456789'}
...
```
21 changes: 21 additions & 0 deletions mkdocs/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
site_name: Refty/mongo-thingy
theme:
name: material
palette:
# Palette toggle for light mode
- scheme: default
toggle:
icon: material/brightness-7
name: Switch to dark mode

# Palette toggle for dark mode
- scheme: slate
toggle:
icon: material/brightness-4
name: Switch to light mode
features:
- navigation.instant
- navigation.instant.progress
- toc.integerate
- navigation.top

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ mongomock==4.0.0
mongomock-motor==0.0.14
montydb==2.4.0
tornado==6.3.3
mkdocs-material==9.5.8
motor==3.0.0
pytest==7.0.1
pytest-cov==3.0.0