Skip to content

Commit 8f02822

Browse files
committed
reorg
1 parent bff10c8 commit 8f02822

File tree

1 file changed

+61
-21
lines changed

1 file changed

+61
-21
lines changed

source/integrations/fastapi-integration.txt

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
.. _pymongo-fastapi:
2+
.. original URL: https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/
23

3-
============================
4-
FastAPI Integration Tutorial
5-
============================
4+
================================
5+
FastAPI Integration and Tutorial
6+
================================
67

78
.. contents:: On this page
89
:local:
@@ -23,8 +24,31 @@ production-ready asynchronous Python framework for building APIs based on
2324
standard Python type hints. In this tutorial, we will create a CRUD application
2425
showing how you can integrate MongoDB with your FastAPI projects.
2526

27+
Mapping
28+
-------
29+
30+
The _id Attribute and ObjectIds
31+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32+
33+
FastAPI encodes and decodes data as JSON strings, which do not support all of the
34+
data types that MongoDB's BSON data type can store. BSON has support for
35+
additional non-JSON-native data types, including ``ObjectId`` which is used for
36+
the default UUID attribute, ``_id``. Because of this, you must convert ``ObjectId``s to
37+
strings before storing them in the ``id`` field.
38+
39+
For for information about how BSON compares to JSON, see this `JSON and BSON
40+
<https://www.mongodb.com/json-and-bson>`__ MongoDB article.
41+
42+
Database Models
43+
~~~~~~~~~~~~~~~
44+
45+
MongoDB collections do not enforce document structure by default, so you have the flexibility to make whatever data-modelling choices best match your application and its performance requirements. So, it's not unusual to create models when working with a MongoDB database.
46+
47+
Tutorial
48+
--------
49+
2650
Prerequisites
27-
-------------
51+
~~~~~~~~~~~~~
2852

2953
- Python v3.9.0 or later
3054
- A MongoDB Atlas cluster
@@ -33,7 +57,7 @@ Prerequisites
3357
account and MongoDB cluster.
3458

3559
Set-up
36-
------
60+
~~~~~~
3761

3862
1. Clone the example code from the `mongodb-with-fastapi repository <https://github.com/mongodb-developer/mongodb-with-fastapi>`__:
3963

@@ -84,7 +108,7 @@ Set-up
84108
:alt: Screenshot of browser and swagger UI
85109

86110
Create Your Application
87-
-----------------------
111+
~~~~~~~~~~~~~~~~~~~~~~~
88112

89113
All the code for the example application is stored in ``app.py``.
90114

@@ -107,12 +131,11 @@ The _id Attribute and ObjectIds
107131
# It will be represented as a `str` on the model so that it can be serialized to JSON.
108132
PyObjectId = Annotated[str, BeforeValidator(str)]
109133

110-
MongoDB stores data as `BSON <https://www.mongodb.com/json-and-bson>`__. FastAPI encodes and decodes data as JSON strings. BSON has support for additional non-JSON-native data types, including ``ObjectId`` which can't be directly encoded as JSON. Because of this, we convert ``ObjectId``s to strings before storing them as the ``id`` field.
134+
111135

112136
Database Models
113137
~~~~~~~~~~~~~~~
114-
115-
Many people think of MongoDB as being schema-less, which is wrong. MongoDB has a flexible schema. That is to say that collections do not enforce document structure by default, so you have the flexibility to make whatever data-modelling choices best match your application and its performance requirements. So, it's not unusual to create models when working with a MongoDB database. Our application has three models, the ``StudentModel``, the ``UpdateStudentModel``, and the ``StudentCollection``.
138+
Our application has three models, the ``StudentModel``, the ``UpdateStudentModel``, and the ``StudentCollection``.
116139

117140
.. code-block:: python
118141

@@ -122,7 +145,7 @@ Many people think of MongoDB as being schema-less, which is wrong. MongoDB has
122145
"""
123146

124147
# The primary key for the StudentModel, stored as a `str` on the instance.
125-
# This will be aliased to `_id` when sent to MongoDB,
148+
# This will be aliased to ``_id`` when sent to MongoDB,
126149
# but provided as ``id`` in the API requests and responses.
127150
id: Optional[PyObjectId] = Field(alias="_id", default=None)
128151
name: str = Field(...)
@@ -144,9 +167,9 @@ Many people think of MongoDB as being schema-less, which is wrong. MongoDB has
144167

145168
This is the primary model we use as the `response model <https://fastapi.tiangolo.com/tutorial/response-model/>`__ for the majority of our endpoints.
146169

147-
I want to draw attention to the ``id`` field on this model. MongoDB uses ``_id``, but in Python, underscores at the start of attributes have special meaning. If you have an attribute on your model that starts with an underscore, `pydantic <https://pydantic-docs.helpmanual.io/>`__—the data validation framework used by FastAPI—will assume that it is a private variable, meaning you will not be able to assign it a value! To get around this, we name the field ``id`` but give it an alias of `_id`. You also need to set `populate_by_name` to `True` in the model's `model_config`
170+
I want to draw attention to the ``id`` field on this model. MongoDB uses ``_id``, but in Python, underscores at the start of attributes have special meaning. If you have an attribute on your model that starts with an underscore, `pydantic <https://pydantic-docs.helpmanual.io/>`__—the data validation framework used by FastAPI—will assume that it is a private variable, meaning you will not be able to assign it a value! To get around this, we name the field ``id`` but give it an alias of ``_id``. You also need to set ``populate_by_name`` to ``True`` in the model's ``model_config``
148171

149-
We set this ``id`` value automatically to `None`, so you do not need to supply it when creating a new student.
172+
We set this ``id`` value automatically to ``None``, so you do not need to supply it when creating a new student.
150173

151174
.. code-block:: python
152175

@@ -172,12 +195,12 @@ We set this ``id`` value automatically to `None`, so you do not need to supply i
172195
},
173196
)
174197

175-
The `UpdateStudentModel` has two key differences from the `StudentModel`:
198+
The ``UpdateStudentModel`` has two key differences from the ``StudentModel``:
176199

177200
- It does not have an ``id`` attribute as this cannot be modified.
178201
- All fields are optional, so you only need to supply the fields you wish to update.
179202

180-
Finally, `StudentCollection` is defined to encapsulate a list of `StudentModel` instances. In theory, the endpoint could return a top-level list of StudentModels, but there are some vulnerabilities associated with returning JSON responses with top-level lists.
203+
Finally, ``StudentCollection`` is defined to encapsulate a list of ``StudentModel`` instances. In theory, the endpoint could return a top-level list of StudentModels, but there are some vulnerabilities associated with returning JSON responses with top-level lists.
181204

182205
.. code-block:: python
183206

@@ -195,11 +218,28 @@ Application Routes
195218

196219
Our application has five routes:
197220

198-
- POST /students/ - creates a new student.
199-
- GET /students/ - view a list of all students.
200-
- GET /students/{id} - view a single student.
201-
- PUT /students/{id} - update a student.
202-
- DELETE /students/{id} - delete a student.
221+
.. list-table::
222+
:header-rows: 1
223+
:stub-columns: 1
224+
:widths: 25,75
225+
226+
* - Route
227+
- Description
228+
229+
* - ``POST /students/``
230+
- Creates a new student
231+
232+
* - ``GET /students/``
233+
- View a list of all students
234+
235+
* - ``GET /students/{id}``
236+
- View a single student
237+
238+
* - ``PUT /students/{id}``
239+
- Update a student
240+
241+
* - ``DELETE /students/{id}``
242+
- Delete a student
203243

204244
Create Student Route
205245
````````````````````
@@ -236,7 +276,7 @@ FastAPI returns an HTTP ``200`` status code by default; but in this instance, a
236276
Read Routes
237277
+++++++++++
238278

239-
The application has two read routes: one for viewing all students and the other for viewing an individual student.
279+
The application has two read routes: one for viewing all students, and one for viewing an individual student.
240280

241281
.. code-block:: python
242282

@@ -266,7 +306,7 @@ Motor's ``to_list`` method requires a max document count argument. For this exam
266306
)
267307
async def show_student(id: str):
268308
"""
269-
Get the record for a specific student, looked up by `id`.
309+
Get the record for a specific student, looked up by ``id``.
270310
"""
271311
if (
272312
student := await student_collection.find_one({"_id": ObjectId(id)})

0 commit comments

Comments
 (0)