Skip to content

Commit

Permalink
Merge branch 'main' of github.com:mongodb-labs/flask-pymongo into INT…
Browse files Browse the repository at this point in the history
…PYTHON-380-finishing
  • Loading branch information
blink1073 committed Jan 15, 2025
2 parents 188ab5c + 5436690 commit 521cc5d
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 172 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
- run: just install
- run: just lint
- run: just docs
- run: just doctest
build:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
2 changes: 0 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ actual bugs and improvement requests.
- All new features must include a test. Flask-PyMongo is tested against a
matrix of all supported versions of Flask, PyMongo, and MongoDB, so tests
ensure that your change works for all users.
- There is also a `style` build. Please ensure your code conforms to
Flask-PyMongo's style rules with `tox -e style`
- Use [Sphinx](http://www.sphinx-doc.org/en/master/)-style docstrings

## Recommended development environment
Expand Down
153 changes: 0 additions & 153 deletions docs/Makefile

This file was deleted.

2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named "sphinx.ext.*") or your custom ones.
extensions = ["sphinx.ext.intersphinx", "sphinx.ext.autodoc"]
extensions = ["sphinx.ext.intersphinx", "sphinx.ext.autodoc", "sphinx.ext.doctest"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
Expand Down
7 changes: 3 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,8 @@ versions.

Flask-PyMongo is tested against `supported versions
<https://www.mongodb.com/support-policy>`_ of MongoDB, and Python
and 3.8+. For the exact list of version combinations that are tested and
known to be compatible, see the `envlist` in `tox.ini
<https://github.com/dcrosta/flask-pymongo/blob/master/tox.ini>`_.
and 3.9+. For the exact list of version combinations that are tested and
known to be compatible.


Helpers
Expand Down Expand Up @@ -109,7 +108,7 @@ constructor. These are passed directly through to the underlying
By default, Flask-PyMongo sets the ``connect`` keyword argument to
``False``, to prevent PyMongo from connecting immediately. PyMongo
itself `is not fork-safe
<http://api.mongodb.com/python/current/faq.html#is-pymongo-fork-safe>`_,
<https://www.mongodb.com/docs/languages/python/pymongo-driver/current/faq/#is-pymongo-fork-safe->`_,
and delaying connection until the app is actually used is necessary to
avoid issues. If you wish to change this default behavior, pass
``connect=True`` as a keyword argument to ``PyMongo``.
Expand Down
2 changes: 0 additions & 2 deletions docs/requirements.txt

This file was deleted.

3 changes: 0 additions & 3 deletions examples/wiki/wiki.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,4 @@ def save_upload(filename: str) -> str | Response:


if __name__ == "__main__":
import doctest

doctest.testmod()
app.run(debug=True)
29 changes: 23 additions & 6 deletions flask_pymongo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def init_app(self, app: Flask, uri: str | None = None, *args: Any, **kwargs: Any
database_name = parsed_uri["database"]

# Try to delay connecting, in case the app is loaded before forking, per
# http://api.mongodb.com/python/current/faq.html#is-pymongo-fork-safe
# https://www.mongodb.com/docs/languages/python/pymongo-driver/current/faq/#is-pymongo-fork-safe-
kwargs.setdefault("connect", False)
if DriverInfo is not None:
kwargs.setdefault("driver", DriverInfo("Flask-PyMongo", __version__))
Expand All @@ -123,7 +123,12 @@ def init_app(self, app: Flask, uri: str | None = None, *args: Any, **kwargs: Any

# view helpers
def send_file(
self, filename: str, base: str = "fs", version: int = -1, cache_for: int = 31536000
self,
filename: str,
base: str = "fs",
version: int = -1,
cache_for: int = 31536000,
db: str | None = None,
) -> Response:
"""Respond with a file from GridFS.
Expand All @@ -144,6 +149,7 @@ def get_upload(filename):
revision. If no such version exists, return with HTTP status 404.
:param int cache_for: number of seconds that browsers should be
instructed to cache responses
:param str db: the target database, if different from the default database.
"""
if not isinstance(base, str):
raise TypeError("'base' must be string or unicode")
Expand All @@ -152,8 +158,13 @@ def get_upload(filename):
if not isinstance(cache_for, int):
raise TypeError("'cache_for' must be an integer")

assert self.db is not None, "Please initialize the app before calling send_file!"
storage = GridFS(self.db, base)
if db:
db_obj = self.cx[db]
else:
db_obj = self.db

assert db_obj is not None, "Please initialize the app before calling send_file!"
storage = GridFS(db_obj, base)

try:
fileobj = storage.get_version(filename=filename, version=version)
Expand Down Expand Up @@ -189,6 +200,7 @@ def save_file(
fileobj: Any,
base: str = "fs",
content_type: str | None = None,
db: str | None = None,
**kwargs: Any,
) -> Any:
"""Save a file-like object to GridFS using the given filename.
Expand All @@ -207,6 +219,7 @@ def save_upload(filename):
:param str content_type: the MIME content-type of the file. If
``None``, the content-type is guessed from the filename using
:func:`~mimetypes.guess_type`
:param str db: the target database, if different from the default database.
:param kwargs: extra attributes to be stored in the file's document,
passed directly to :meth:`gridfs.GridFS.put`
"""
Expand All @@ -218,7 +231,11 @@ def save_upload(filename):
if content_type is None:
content_type, _ = guess_type(filename)

assert self.db is not None, "Please initialize the app before calling save_file!"
storage = GridFS(self.db, base)
if db:
db_obj = self.cx[db]
else:
db_obj = self.db
assert db_obj is not None, "Please initialize the app before calling save_file!"
storage = GridFS(db_obj, base)
id = storage.put(fileobj, filename=filename, content_type=content_type, **kwargs)
return id
10 changes: 9 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
docs_build := "docs/_build"
sphinx_opts:= "-d " + docs_build + "/doctrees docs"

# Default target executed when no arguments are given.
[private]
default:
Expand All @@ -14,7 +17,12 @@ lint:
uv run pre-commit run --hook-stage manual --all-files

docs:
uv run sphinx-build -T -b html docs docs/_build
uv run sphinx-build -T -b html {{sphinx_opts}} {{docs_build}}

doctest:
uv run python -m doctest -v examples/wiki/wiki.py
uv run sphinx-build -E -b doctest {{sphinx_opts}} {{docs_build}}/doctest
uv run sphinx-build -b linkcheck {{sphinx_opts}} {{docs_build}}/linkcheck

typing:
uv run mypy --install-types --non-interactive .
13 changes: 13 additions & 0 deletions tests/test_gridfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ def test_it_saves_files(self):
gridfs = GridFS(self.mongo.db)
assert gridfs.exists({"filename": "my-file"})

def test_it_saves_files_to_another_db(self):
fileobj = BytesIO(b"these are the bytes")

self.mongo.save_file("my-file", fileobj, db="other")
assert self.mongo.db is not None
gridfs = GridFS(self.mongo.cx["other"])
assert gridfs.exists({"filename": "my-file"})

def test_it_saves_files_with_props(self):
fileobj = BytesIO(b"these are the bytes")

Expand All @@ -56,6 +64,7 @@ def setUp(self):
# make it bigger than 1 gridfs chunk
self.myfile = BytesIO(b"a" * 500 * 1024)
self.mongo.save_file("myfile.txt", self.myfile)
self.mongo.save_file("my_other_file.txt", self.myfile, db="other")

def test_it_404s_for_missing_files(self):
with pytest.raises(NotFound):
Expand All @@ -65,6 +74,10 @@ def test_it_sets_content_type(self):
resp = self.mongo.send_file("myfile.txt")
assert resp.content_type.startswith("text/plain")

def test_it_sends_file_to_another_db(self):
resp = self.mongo.send_file("my_other_file.txt", db="other")
assert resp.content_type.startswith("text/plain")

def test_it_sets_content_length(self):
resp = self.mongo.send_file("myfile.txt")
assert resp.content_length == len(self.myfile.getvalue())
Expand Down

0 comments on commit 521cc5d

Please sign in to comment.